From c058fa0fb22dc40ef0225b21a97578cddd0aaffa Mon Sep 17 00:00:00 2001 From: Florian Merz Date: Thu, 11 Feb 2021 14:51:05 +0100 Subject: unslug ru: move --- files/ru/a_basic_raycaster/index.html | 50 - files/ru/building_an_extension/index.html | 248 -- files/ru/chrome/index.html | 80 - files/ru/conflicting/glossary/chrome/index.html | 80 + .../cascade_and_inheritance/index.html | 152 ++ .../learn/css/building_blocks/selectors/index.html | 133 + .../index.html | 434 +++ .../css/building_blocks/styling_tables/index.html | 525 ++++ .../building_blocks/values_and_units/index.html | 345 +++ .../first_steps/how_css_is_structured/index.html | 166 ++ .../learn/css/first_steps/how_css_works/index.html | 122 + .../index.html | 110 + .../index.html | 120 + .../conflicting/learn/css/first_steps/index.html | 60 + files/ru/conflicting/learn/css/index.html | 12 + .../learn/css/styling_text/fundamentals/index.html | 152 ++ .../learn/javascript/objects/index.html | 356 +++ files/ru/conflicting/mdn/contribute/index.html | 94 + files/ru/conflicting/mdn/tools/index.html | 13 + files/ru/conflicting/mozilla/add-ons/index.html | 248 ++ .../mozilla/firefox/releases/index.html | 128 + files/ru/conflicting/tools/performance/index.html | 169 ++ files/ru/conflicting/web/accessibility/index.html | 51 + .../api/canvas_api/a_basic_ray-caster/index.html | 50 + .../web/api/crypto/getrandomvalues/index.html | 111 + .../web/api/document_object_model/index.html | 62 + .../index.html | 25 + .../index.html | 38 + files/ru/conflicting/web/api/element/index.html | 45 + .../api/eventtarget/addeventlistener/index.html | 9 + .../api/eventtarget/removeeventlistener/index.html | 92 + .../ru/conflicting/web/api/geolocation/index.html | 103 + .../api/htmlmediaelement/abort_event/index.html | 70 + files/ru/conflicting/web/api/index.html | 131 + files/ru/conflicting/web/api/node/index.html | 26 + .../index.html | 29 + files/ru/conflicting/web/api/push_api/index.html | 420 +++ .../web/api/svgaelement/target/index.html | 107 + .../conflicting/web/api/web_storage_api/index.html | 368 +++ files/ru/conflicting/web/api/webrtc_api/index.html | 35 + .../signaling_and_video_calling/index.html | 351 +++ .../web/api/window/localstorage/index.html | 146 + .../web/api/windoworworkerglobalscope/index.html | 121 + .../index.html | 120 + .../conflicting/web/api/xmlhttprequest/index.html | 282 ++ files/ru/conflicting/web/css/@viewport/index.html | 106 + files/ru/conflicting/web/css/_colon_is/index.html | 190 ++ .../web/css/css_basic_user_interface/index.html | 119 + .../basic_concepts_of_flexbox/index.html | 379 +++ files/ru/conflicting/web/css/gap/index.html | 194 ++ files/ru/conflicting/web/css/url()/index.html | 35 + .../index.html | 94 + files/ru/conflicting/web/guide/index.html | 10 + files/ru/conflicting/web/guide/mobile/index.html | 18 + files/ru/conflicting/web/http/cors/index.html | 213 ++ files/ru/conflicting/web/http/csp/index.html | 43 + .../ru/conflicting/web/javascript/guide/index.html | 923 +++++++ .../web/javascript/guide/introduction/index.html | 159 ++ .../index.html | 142 + .../reference/global_objects/boolean/index.html | 113 + .../reference/global_objects/date/index.html | 229 ++ .../reference/global_objects/error/index.html | 155 ++ .../reference/global_objects/evalerror/index.html | 122 + .../reference/global_objects/function/index.html | 152 ++ .../global_objects/generatorfunction/index.html | 59 + .../global_objects/internalerror/index.html | 100 + .../global_objects/intl/collator/index.html | 109 + .../global_objects/intl/datetimeformat/index.html | 109 + .../global_objects/intl/numberformat/index.html | 109 + .../reference/global_objects/map/index.html | 126 + .../reference/global_objects/number/index.html | 124 + .../reference/global_objects/object/index.html | 205 ++ .../reference/global_objects/promise/index.html | 67 + .../global_objects/proxy/proxy/index.html | 135 + .../reference/global_objects/rangeerror/index.html | 123 + .../global_objects/referenceerror/index.html | 123 + .../reference/global_objects/regexp/index.html | 141 + .../reference/global_objects/set/index.html | 81 + .../reference/global_objects/string/index.html | 230 ++ .../reference/global_objects/symbol/index.html | 107 + .../global_objects/syntaxerror/index.html | 123 + .../reference/global_objects/typedarray/index.html | 129 + .../reference/global_objects/typeerror/index.html | 123 + .../reference/global_objects/urierror/index.html | 123 + .../reference/global_objects/weakmap/index.html | 75 + .../reference/global_objects/weakset/index.html | 142 + .../web/javascript/reference/operators/index.html | 291 ++ .../index.html | 286 ++ .../index.html | 626 +++++ .../index.html | 300 ++ .../index.html | 431 +++ .../reference/statements/switch/index.html | 117 + files/ru/conflicting/web/media/formats/index.html | 517 ++++ .../web/progressive_web_apps/index.html | 48 + .../index.html | 64 + files/ru/dom/document.createelement/index.html | 82 - files/ru/dom/document.images/index.html | 29 - files/ru/dom/dom_reference/events/index.html | 80 - files/ru/dom/dom_reference/examples/index.html | 382 --- files/ru/dom/dom_reference/index.html | 387 --- .../index.html | 50 - .../index.html" | 230 -- files/ru/dom/index.html | 62 - files/ru/dom/using_fullscreen_mode/index.html | 198 -- files/ru/dom/using_web_workers/index.html | 871 ------ .../ru/dom/window.requestanimationframe/index.html | 92 - .../index.html" | 312 --- files/ru/firefox_3_for_developers/index.html | 299 -- files/ru/games/anatomy/index.html | 337 +++ files/ru/games/introduction/index.html | 121 + files/ru/games/tools/asm.js/index.html | 30 + files/ru/games/tools/index.html | 33 + .../bounce_off_the_walls/index.html | 42 + .../build_the_brick_field/index.html | 156 ++ .../collision_detection/index.html | 52 + .../2d_breakout_game_phaser/extra_lives/index.html | 117 + .../2d_breakout_game_phaser/game_over/index.html | 46 + .../tutorials/2d_breakout_game_phaser/index.html | 64 + .../initialize_the_framework/index.html | 95 + .../index.html | 73 + .../move_the_ball/index.html | 48 + .../2d_breakout_game_phaser/physics/index.html | 98 + .../player_paddle_and_controls/index.html | 116 + .../2d_breakout_game_phaser/scaling/index.html | 64 + .../2d_breakout_game_phaser/the_score/index.html | 69 + .../win_the_game/index.html | 54 + .../build_the_brick_field/index.html | 119 + .../collision_detection/index.html | 128 + .../create_the_canvas_and_draw_on_it/index.html | 115 + .../finishing_up/index.html | 103 + .../mouse_controls/index.html | 58 + .../move_the_ball/index.html | 146 + .../index.html" | 103 - .../index.html" | 128 - .../index.html" | 146 - .../index.html" | 119 - .../index.html" | 115 - .../index.html" | 58 - .../bounce_off_the_walls/index.html" | 42 - .../game_over/index.html" | 46 - .../index.html" | 64 - .../initialize_the_framework/index.html" | 95 - .../index.html" | 73 - .../move_the_ball/index.html" | 48 - .../physics/index.html" | 98 - .../scaling/index.html" | 64 - .../index.html" | 117 - .../index.html" | 52 - .../\320\276\321\207\320\272\320\270/index.html" | 69 - .../index.html" | 116 - .../index.html" | 54 - .../index.html" | 156 -- .../index.html" | 337 --- .../\320\262\320\262\320\276\320\264/index.html" | 121 - .../asm.js/index.html" | 30 - .../index.html" | 33 - files/ru/glossary/404/index.html | 15 + files/ru/glossary/502/index.html | 20 + files/ru/glossary/abstraction/index.html | 12 + files/ru/glossary/accessibility/index.html | 33 + files/ru/glossary/adobe_flash/index.html | 21 + files/ru/glossary/ajax/index.html | 32 + files/ru/glossary/algorithm/index.html | 38 + files/ru/glossary/api/index.html | 25 + files/ru/glossary/apple_safari/index.html | 29 + files/ru/glossary/application_context/index.html | 14 + files/ru/glossary/argument/index.html | 24 + files/ru/glossary/aria/index.html | 19 + files/ru/glossary/arpa/index.html | 20 + files/ru/glossary/arpanet/index.html | 19 + files/ru/glossary/array/index.html | 36 + files/ru/glossary/ascii/index.html | 15 + files/ru/glossary/asynchronous/index.html | 23 + files/ru/glossary/atag/index.html | 28 + files/ru/glossary/attribute/index.html | 18 + files/ru/glossary/bandwidth/index.html | 15 + files/ru/glossary/base64/index.html | 138 + files/ru/glossary/baseline/index.html | 30 + files/ru/glossary/bidi/index.html | 25 + files/ru/glossary/bigint/index.html | 28 + files/ru/glossary/blink/index.html | 16 + files/ru/glossary/block/scripting/index.html | 20 + .../index.html" | 20 - files/ru/glossary/boolean/index.html | 62 + files/ru/glossary/bootstrap/index.html | 22 + files/ru/glossary/browser/index.html | 24 + files/ru/glossary/browsing_context/index.html | 19 + files/ru/glossary/buffer/index.html | 21 + "files/ru/glossary/b\303\251zier_curve/index.html" | 32 + files/ru/glossary/cache/index.html | 14 + files/ru/glossary/cacheable/index.html | 59 + files/ru/glossary/call_stack/index.html | 102 + files/ru/glossary/callback_function/index.html | 70 + files/ru/glossary/canvas/index.html | 37 + files/ru/glossary/card_sorting/index.html | 17 + files/ru/glossary/cdn/index.html | 21 + files/ru/glossary/certified/index.html | 25 + files/ru/glossary/character/index.html | 20 + files/ru/glossary/character_encoding/index.html | 27 + files/ru/glossary/chrome/index.html | 11 + files/ru/glossary/cia/index.html | 17 + files/ru/glossary/class/index.html | 23 + files/ru/glossary/cms/index.html | 16 + files/ru/glossary/codec/index.html | 20 + files/ru/glossary/compile/index.html | 29 + files/ru/glossary/computer_programming/index.html | 24 + files/ru/glossary/conditional/index.html | 34 + files/ru/glossary/constant/index.html | 19 + files/ru/glossary/constructor/index.html | 47 + files/ru/glossary/cookie/index.html | 21 + files/ru/glossary/copyleft/index.html | 19 + files/ru/glossary/cors/index.html | 46 + files/ru/glossary/crawler/index.html | 23 + files/ru/glossary/crlf/index.html | 13 + files/ru/glossary/csp/index.html | 27 + files/ru/glossary/csrf/index.html | 16 + files/ru/glossary/css/index.html | 48 + files/ru/glossary/css_preprocessor/index.html | 24 + files/ru/glossary/css_selector/index.html | 73 + files/ru/glossary/data_structure/index.html | 17 + files/ru/glossary/decryption/index.html | 22 + files/ru/glossary/developer_tools/index.html | 27 + files/ru/glossary/dns/index.html | 24 + files/ru/glossary/doctype/index.html | 28 + files/ru/glossary/dom/index.html | 27 + files/ru/glossary/domain/index.html | 17 + files/ru/glossary/domain_name/index.html | 23 + files/ru/glossary/dos_attack/index.html | 32 + .../dynamic_programming_language/index.html | 16 + files/ru/glossary/ecma/index.html | 17 + files/ru/glossary/ecmascript/index.html | 22 + files/ru/glossary/element/index.html | 20 + files/ru/glossary/empty_element/index.html | 35 + files/ru/glossary/encapsulation/index.html | 18 + files/ru/glossary/entity/index.html | 59 + files/ru/glossary/entity_header/index.html | 25 + files/ru/glossary/event/index.html | 25 + files/ru/glossary/expando/index.html | 10 + files/ru/glossary/falsy/index.html | 93 + files/ru/glossary/first-class_function/index.html | 32 + .../ru/glossary/first_contentful_paint/index.html | 15 + files/ru/glossary/first_cpu_idle/index.html | 8 + files/ru/glossary/first_input_delay/index.html | 15 + files/ru/glossary/first_interactive/index.html | 14 + .../ru/glossary/first_meaningful_paint/index.html | 12 + files/ru/glossary/first_paint/index.html | 14 + files/ru/glossary/flex_item/index.html | 34 + files/ru/glossary/flexbox/index.html | 44 + files/ru/glossary/forbidden_header_name/index.html | 44 + .../forbidden_response_header_name/index.html | 25 + files/ru/glossary/fps/index.html | 20 + files/ru/glossary/ftp/index.html | 22 + files/ru/glossary/function/index.html | 77 + files/ru/glossary/gecko/index.html | 31 + files/ru/glossary/general_header/index.html | 8 + files/ru/glossary/git/index.html | 18 + files/ru/glossary/global_object/index.html | 66 + files/ru/glossary/global_variable/index.html | 18 + files/ru/glossary/grid/index.html | 75 + files/ru/glossary/grid_column/index.html | 30 + files/ru/glossary/hash/index.html | 14 + files/ru/glossary/head/index.html | 15 + .../high-level_programming_language/index.html | 10 + files/ru/glossary/hoisting/index.html | 74 + files/ru/glossary/host/index.html | 20 + files/ru/glossary/html/index.html | 47 + files/ru/glossary/html5/index.html | 19 + files/ru/glossary/http/index.html | 25 + files/ru/glossary/http_2/index.html | 31 + files/ru/glossary/https/index.html | 17 + files/ru/glossary/hypertext/index.html | 27 + files/ru/glossary/iana/index.html | 13 + files/ru/glossary/icann/index.html | 13 + files/ru/glossary/idempotent/index.html | 49 + files/ru/glossary/identifier/index.html | 19 + files/ru/glossary/ietf/index.html | 21 + files/ru/glossary/iife/index.html | 61 + files/ru/glossary/index.html | 24 + files/ru/glossary/indexeddb/index.html | 19 + .../glossary/information_architecture/index.html | 14 + files/ru/glossary/internet/index.html | 31 + files/ru/glossary/ip_address/index.html | 22 + files/ru/glossary/iso/index.html | 19 + files/ru/glossary/isp/index.html | 20 + files/ru/glossary/java/index.html | 22 + files/ru/glossary/javascript/index.html | 45 + files/ru/glossary/jpeg/index.html | 17 + files/ru/glossary/jquery/index.html | 35 + files/ru/glossary/json/index.html | 29 + files/ru/glossary/loop/index.html | 88 + files/ru/glossary/main_axis/index.html | 46 + files/ru/glossary/mathml/index.html | 26 + files/ru/glossary/metadata/index.html | 20 + files/ru/glossary/method/index.html | 43 + .../microsoft_internet_explorer/index.html | 41 + files/ru/glossary/mime_type/index.html | 26 + files/ru/glossary/mixin/index.html | 24 + files/ru/glossary/node.js/index.html | 29 + files/ru/glossary/null/index.html | 28 + files/ru/glossary/number/index.html | 25 + files/ru/glossary/object/index.html | 26 + files/ru/glossary/oop/index.html | 21 + files/ru/glossary/opengl/index.html | 16 + files/ru/glossary/origin/index.html | 52 + files/ru/glossary/php/index.html | 16 + files/ru/glossary/pixel/index.html | 19 + files/ru/glossary/polifill/index.html | 13 - files/ru/glossary/polymorphism/index.html | 24 + files/ru/glossary/port/index.html | 22 + files/ru/glossary/primitive/index.html | 105 + files/ru/glossary/privileged_code/index.html | 10 + files/ru/glossary/progressive_web_apps/index.html | 18 + files/ru/glossary/promise/index.html | 32 + files/ru/glossary/property/index.html | 12 + files/ru/glossary/protocol/index.html | 21 + .../prototype-based_programming/index.html | 17 + files/ru/glossary/prototype/index.html | 18 + files/ru/glossary/proxy_server/index.html | 24 + files/ru/glossary/pseudo-element/index.html | 18 + files/ru/glossary/pseudocode/index.html | 17 + files/ru/glossary/reflow/index.html | 12 + files/ru/glossary/regular_expression/index.html | 26 + files/ru/glossary/request_header/index.html | 43 + files/ru/glossary/responsive_web_design/index.html | 20 + files/ru/glossary/round_trip_time_(rtt)/index.html | 28 + files/ru/glossary/safe/index.html | 43 + files/ru/glossary/scroll_container/index.html | 25 + files/ru/glossary/sdp/index.html | 31 + .../self-executing_anonymous_function/index.html | 8 + files/ru/glossary/semantics/index.html | 98 + files/ru/glossary/seo/index.html | 35 + files/ru/glossary/server/index.html | 25 + files/ru/glossary/sgml/index.html | 18 + files/ru/glossary/simple_header/index.html | 39 + .../ru/glossary/simple_response_header/index.html | 6 + files/ru/glossary/sloppy_mode/index.html | 21 + files/ru/glossary/specification/index.html | 23 + files/ru/glossary/speculative_parsing/index.html | 33 + files/ru/glossary/statement/index.html | 27 + files/ru/glossary/static_typing/index.html | 17 + files/ru/glossary/string/index.html | 20 + files/ru/glossary/svg/index.html | 41 + files/ru/glossary/symbol/index.html | 24 + files/ru/glossary/synchronous/index.html | 23 + files/ru/glossary/tag/index.html | 28 + files/ru/glossary/tcp/index.html | 23 + files/ru/glossary/time_to_first_byte/index.html | 18 + files/ru/glossary/time_to_interactive/index.html | 20 + files/ru/glossary/tls/index.html | 24 + files/ru/glossary/truthy/index.html | 39 + files/ru/glossary/type/index.html | 23 + files/ru/glossary/type_coercion/index.html | 44 + files/ru/glossary/type_conversion/index.html | 30 + files/ru/glossary/ui/index.html | 19 + files/ru/glossary/undefined/index.html | 8 + files/ru/glossary/url/index.html | 30 + files/ru/glossary/user_agent/index.html | 28 + files/ru/glossary/variable/index.html | 14 + files/ru/glossary/vendor_prefix/index.html | 75 + files/ru/glossary/viewport/index.html | 110 + files/ru/glossary/w3c/index.html | 26 + files/ru/glossary/wai/index.html | 15 + files/ru/glossary/webkit/index.html | 24 + files/ru/glossary/websockets/index.html | 35 + files/ru/glossary/whatwg/index.html | 26 + files/ru/glossary/whitespace/index.html | 36 + files/ru/glossary/world_wide_web/index.html | 40 + files/ru/glossary/wrapper/index.html | 16 + files/ru/glossary/xhr_(xmlhttprequest)/index.html | 23 + files/ru/glossary/xhtml/index.html | 32 + files/ru/glossary/xml/index.html | 17 + .../ru/html/html5/constraint_validation/index.html | 343 --- files/ru/html/html5/index.html | 171 -- .../index.html" | 26 - files/ru/introduction_(alternate)/index.html | 24 - .../accessibility_troubleshooting/index.html | 101 + .../accessibility/css_and_javascript/index.html | 357 +++ files/ru/learn/accessibility/html/index.html | 537 ++++ files/ru/learn/accessibility/index.html | 55 + files/ru/learn/accessibility/mobile/index.html | 304 +++ files/ru/learn/accessibility/multimedia/index.html | 360 +++ .../learn/accessibility/wai-aria_basics/index.html | 416 +++ .../accessibility/what_is_accessibility/index.html | 210 ++ .../how_does_the_internet_work/index.html | 102 + .../index.html | 118 + .../what_are_browser_developer_tools/index.html | 172 ++ .../what_are_hyperlinks/index.html | 102 + .../what_is_a_domain_name/index.html | 155 ++ .../common_questions/what_is_a_url/index.html | 161 ++ .../what_is_a_web_server/index.html | 128 + .../css/building_blocks/cascade_tasks/index.html | 51 + .../fundamental_css_comprehension/index.html | 123 + .../selectors/attribute_selectors/index.html | 160 ++ .../selectors/combinators/index.html | 113 + .../learn/css/building_blocks/selectors/index.html | 235 ++ .../pseudo-classes_and_pseudo-elements/index.html | 415 +++ .../selectors/selectors_tasks/index.html | 137 + .../type_class_and_id_selectors/index.html | 130 + .../index.html" | 51 - .../attribute_selectors/index.html" | 160 -- .../combinators/index.html" | 113 - .../index.html" | 235 -- .../pseudo-classes_and_pseudo-elements/index.html" | 415 --- .../type_class_and_id_selectors/index.html" | 130 - .../index.html" | 137 - .../css/css_layout/multicol_skills/index.html | 78 + .../css_layout/multiple-column_layout/index.html | 468 ++++ .../ru/learn/css/css_layout/normal_flow/index.html | 96 + .../css/css_layout/position_skills/index.html | 64 + .../css/css_layout/responsive_design/index.html | 328 +++ .../index.html" | 468 ---- .../index.html" | 78 - .../index.html" | 64 - .../index.html" | 96 - .../index.html" | 328 --- files/ru/learn/css/css_properties/index.html | 133 - .../first_steps/how_css_is_structured/index.html | 528 ++++ .../learn/css/first_steps/what_is_css/index.html | 130 + .../index.html" | 528 ---- .../index.html" | 130 - files/ru/learn/css/howto/css_faq/index.html | 182 ++ files/ru/learn/css/howto/index.html | 86 + .../ponimanie_osnov_css/index.html | 123 - .../css/styling_text/styling_lists/index.html | 389 +++ .../styling_text/typesetting_a_homepage/index.html | 126 + .../ru/learn/css/styling_text/web_fonts/index.html | 203 ++ .../index.html" | 203 -- .../index.html" | 126 - .../index.html" | 389 --- .../learn/css/\320\272\320\260\320\272/index.html" | 86 - .../discover_browser_developer_tools/index.html | 172 -- .../forms/basic_native_form_controls/index.html | 690 +++++ files/ru/learn/forms/form_validation/index.html | 906 ++++++ .../how_to_build_custom_form_controls/index.html | 792 ++++++ .../forms/how_to_structure_a_web_form/index.html | 320 +++ files/ru/learn/forms/index.html | 78 + .../sending_and_retrieving_form_data/index.html | 352 +++ .../sending_forms_through_javascript/index.html | 391 +++ files/ru/learn/forms/styling_web_forms/index.html | 381 +++ files/ru/learn/forms/your_first_form/index.html | 305 +++ files/ru/learn/front-end_web_developer/index.html | 195 ++ .../installing_basic_software/index.html | 78 + .../the_web_and_web_standards/index.html | 167 ++ .../index.html" | 167 -- .../index.html" | 78 - files/ru/learn/how_the_internet_works/index.html | 102 - .../how_to_build_custom_form_widgets/index.html | 792 ------ .../forms/how_to_structure_an_html_form/index.html | 320 --- files/ru/learn/html/forms/index.html | 78 - .../sending_forms_through_javascript/index.html | 391 --- .../learn/html/forms/styling_html_forms/index.html | 381 --- .../index.html" | 906 ------ .../index.html" | 305 --- .../index.html" | 352 --- .../index.html" | 690 ----- .../author_fast-loading_html_pages/index.html | 204 ++ files/ru/learn/html/howto/index.html | 153 ++ .../html/howto/use_data_attributes/index.html | 129 + .../advanced_text_formatting/index.html | 679 +++++ .../creating_hyperlinks/index.html | 435 +++ .../introduction_to_html/debugging_html/index.html | 181 ++ .../document_and_website_structure/index.html | 291 ++ .../getting_started/index.html | 772 ++++++ .../html_text_fundamentals/index.html | 994 +++++++ .../ru/learn/html/introduction_to_html/index.html | 67 + .../marking_up_a_letter/index.html | 101 + .../structuring_a_page_of_content/index.html | 101 + .../the_head_metadata_in_html/index.html | 300 ++ .../adding_vector_graphics_to_the_web/index.html | 351 +++ .../images_in_html/index.html | 364 +++ .../test_your_skills_colon__html_images/index.html | 74 + .../mozilla_splash_page/index.html | 106 + .../index.html" | 351 --- .../index.html" | 106 - .../index.html" | 364 --- .../index.html" | 74 - .../advanced_text_formatting/index.html" | 679 ----- .../debugging_html/index.html" | 181 -- .../html_text_fundamentals/index.html" | 994 ------- .../index.html" | 67 - .../marking_up_a_letter/index.html" | 101 - .../structuring_a_page_of_content/index.html" | 101 - .../the_head_metadata_in_html/index.html" | 300 -- .../index.html" | 772 ------ .../index.html" | 435 --- .../index.html" | 291 -- .../index.html" | 153 -- .../asynchronous/timeouts_and_intervals/index.html | 638 +++++ .../index.html" | 638 ----- .../javascript/building_blocks/events/index.html | 606 ++++ .../index.html" | 606 ---- .../first_steps/a_first_splash/index.html | 675 +++++ .../learn/javascript/first_steps/arrays/index.html | 678 +++++ files/ru/learn/javascript/first_steps/index.html | 56 + .../learn/javascript/first_steps/math/index.html | 423 +++ .../first_steps/silly_story_generator/index.html | 148 + .../javascript/first_steps/strings/index.html | 284 ++ .../first_steps/useful_string_methods/index.html | 723 +++++ .../javascript/first_steps/variables/index.html | 372 +++ .../first_steps/what_is_javascript/index.html | 339 +++ .../first_steps/what_went_wrong/index.html | 249 ++ .../adding_bouncing_balls_features/index.html | 212 ++ .../ru/learn/javascript/objects/basics/index.html | 257 ++ files/ru/learn/javascript/objects/index.html | 47 + .../javascript/objects/inheritance/index.html | 266 ++ files/ru/learn/javascript/objects/json/index.html | 353 +++ .../objects/object-oriented_js/index.html | 286 ++ .../objects/object_building_practice/index.html | 302 ++ .../objects/object_prototypes/index.html | 285 ++ .../adding_bouncing_balls_features/index.html" | 212 -- .../index.html" | 47 - .../inheritance/index.html" | 266 -- .../json/index.html" | 353 --- .../object-oriented_js/index.html" | 286 -- .../object_building_practice/index.html" | 302 -- .../object_prototypes/index.html" | 285 -- .../index.html" | 257 -- .../a_first_splash/index.html" | 675 ----- .../arrays/index.html" | 678 ----- .../index.html" | 56 - .../math/index.html" | 423 --- .../useful_string_methods/index.html" | 723 ----- .../variables/index.html" | 372 --- .../what_is_javascript/index.html" | 339 --- .../index.html" | 148 - .../index.html" | 284 -- .../index.html" | 249 -- .../index.html | 118 - .../server-side/django/authentication/index.html | 688 +++++ .../learn/server-side/django/deployment/index.html | 680 +++++ .../server-side/django/introduction/index.html | 257 ++ .../learn/server-side/django/sessions/index.html | 181 ++ .../index.html" | 688 ----- .../index.html" | 257 -- .../index.html" | 680 ----- .../index.html" | 181 -- .../tutorial_local_library_website/index.html | 73 + .../index.html" | 73 - .../first_steps/website_security/index.html | 169 ++ .../index.html" | 169 -- .../client-side_javascript_frameworks/index.html | 137 + .../react_getting_started/index.html | 462 ++++ files/ru/learn/tools_and_testing/github/index.html | 84 + .../index.html" | 84 - .../index.html" | 137 - .../react_getting_started/index.html" | 462 ---- .../ru/learn/understanding_domain_names/index.html | 155 -- .../understanding_links_on_the_web/index.html | 102 - files/ru/learn/understanding_urls/index.html | 161 -- .../accessibility_troubleshooting/index.html" | 101 - .../css_and_javascript/index.html" | 357 --- .../html/index.html" | 537 ---- .../index.html" | 55 - .../mobile/index.html" | 304 --- .../multimedia/index.html" | 360 --- .../wai-aria_basics/index.html" | 416 --- .../what_is_accessibility/index.html" | 210 -- .../index.html" | 85 - .../index.html" | 195 -- .../index.html" | 128 - files/ru/mdn/at_ten/index.html | 39 + .../creating_and_editing_pages/index.html | 182 -- .../index.html | 34 + .../index.html | 184 ++ .../howto/create_an_mdn_account/index.html | 42 - .../howto/create_and_edit_pages/index.html | 182 ++ .../howto/do_a_technical_review/index.html | 57 - .../howto/do_an_editorial_review/index.html | 52 - .../index.html" | 34 - .../index.html" | 41 - .../index.html" | 74 - .../index.html" | 184 -- files/ru/mdn/contribute/processes/index.html | 14 + .../index.html" | 14 - files/ru/mdn/editor/basics/index.html | 62 - .../ru/mdn/editor/basics/page_controls/index.html | 37 - files/ru/mdn/editor/basics/toolbar/index.html | 256 -- files/ru/mdn/editor/index.html | 47 - files/ru/mdn/editor/source_mode/index.html | 128 - files/ru/mdn/editor/tables/index.html | 162 -- .../index.html" | 146 - .../index.html" | 78 - .../index.html" | 31 - .../index.html" | 181 -- .../index.html" | 187 -- files/ru/mdn/kuma/index.html | 25 - .../troubleshooting_kumascript_errors/index.html | 62 - .../simple_live_sample_demo/index.html | 37 - .../tools/kumascript/troubleshooting/index.html | 62 + files/ru/mdn/tools/page_watching/index.html | 50 - files/ru/mdn/tools/search/index.html | 104 + files/ru/mdn/tools/unsupported_get_api/index.html | 100 + files/ru/mdn/tools/url-suffix/index.html | 100 - files/ru/mdn/user_guide/advanced_search/index.html | 104 - files/ru/mdn/user_guide/deleting_pages/index.html | 16 - files/ru/mdn/user_guide/feeds/index.html | 73 - files/ru/mdn/user_guide/index.html | 13 - files/ru/mdn/user_guide/linking_to_mdn/index.html | 63 - files/ru/mdn/yari/index.html | 25 + .../conversations/index.html" | 53 - .../index.html" | 53 - .../whats_happening/index.html" | 37 - .../working_in_community/index.html" | 108 - files/ru/mdn_at_ten/contributing_to_mdn/index.html | 94 - files/ru/mdn_at_ten/index.html | 39 - .../webextensions/internationalization/index.html | 405 +++ .../webextensions/modify_a_web_page/index.html | 238 ++ .../index.html" | 405 --- .../index.html" | 238 -- .../index.html" | 218 -- .../developer_guide/introduction/index.html | 24 + .../mozilla/developer_guide/source_code/index.html | 9 + .../index.html" | 9 - .../1.5/using_firefox_1.5_caching/index.html | 210 ++ files/ru/mozilla/firefox/releases/3.5/index.html | 312 +++ files/ru/mozilla/firefox/releases/3/index.html | 299 ++ files/ru/orphaned/glossary/polifill/index.html | 13 + .../ru/orphaned/learn/how_to_contribute/index.html | 85 + .../learn/html/forms/html5_updates/index.html | 149 + .../orphaned/mdn/about/linking_to_mdn/index.html | 63 + .../mdn/community/conversations/index.html | 53 + files/ru/orphaned/mdn/community/index.html | 53 + .../mdn/community/whats_happening/index.html | 37 + .../mdn/community/working_in_community/index.html | 108 + .../howto/create_an_mdn_account/index.html | 42 + .../howto/do_a_technical_review/index.html | 57 + .../howto/do_an_editorial_review/index.html | 52 + .../howto/set_the_summary_for_a_page/index.html | 41 + .../howto/tag_javascript_pages/index.html | 74 + files/ru/orphaned/mdn/editor/basics/index.html | 62 + .../mdn/editor/basics/page_controls/index.html | 37 + .../orphaned/mdn/editor/basics/toolbar/index.html | 256 ++ files/ru/orphaned/mdn/editor/images/index.html | 78 + files/ru/orphaned/mdn/editor/index.html | 47 + .../mdn/editor/keyboard_shortcuts/index.html | 146 + files/ru/orphaned/mdn/editor/links/index.html | 187 ++ files/ru/orphaned/mdn/editor/redirects/index.html | 31 + .../ru/orphaned/mdn/editor/source_mode/index.html | 128 + .../mdn/editor/syntax_highlighting/index.html | 181 ++ files/ru/orphaned/mdn/editor/tables/index.html | 162 ++ .../simple_live_sample_demo/index.html | 37 + files/ru/orphaned/mdn/tools/feeds/index.html | 73 + .../ru/orphaned/mdn/tools/page_deletion/index.html | 16 + .../ru/orphaned/mdn/tools/page_watching/index.html | 50 + .../add-ons/webextensions/debugging/index.html | 218 ++ files/ru/orphaned/toolkit_api/index.html | 18 + .../tools/add-ons/dom_inspector/index.html | 57 + files/ru/orphaned/tools/add-ons/index.html | 15 + .../checking_authenticity_with_password/index.html | 33 + .../index.html" | 6 + .../orphaned/web/html/element/element/index.html | 112 + .../web/html/global_attributes/dropzone/index.html | 43 + .../index.html" | 68 + .../global_objects/array/prototype/index.html | 171 ++ .../asyncfunction/prototype/index.html | 55 + .../index.html" | 136 + .../orphaned/web/manifest/serviceworker/index.html | 91 + .../information_security_basics/index.html | 30 + .../orphaned/web/svg/attribute/onload/index.html | 5 + files/ru/orphaned/xml_in_mozilla/index.html | 56 + files/ru/orphaned/xpcnativewrapper/index.html | 108 + files/ru/orphaned/xpcom/index.html | 16 + .../index.html" | 14 + .../index.html" | 8 + .../index.html" | 68 + .../index.html" | 18 + .../index.html" | 15 + .../index.html" | 6 + .../index.html" | 5 + .../index.html" | 81 + .../index.html" | 10 + .../index.html" | 34 + .../index.html" | 274 ++ .../index.html" | 25 + .../index.html" | 15 + .../index.html" | 6 + .../index.html" | 81 + .../index.html" | 224 ++ .../index.html" | 64 + .../index.html" | 5 + .../\321\202\320\265\320\274\321\213/index.html" | 14 + files/ru/plugins/roadmap/index.html | 71 + .../\320\277\320\273\320\260\320\275/index.html" | 71 - files/ru/toolkit_api/index.html | 18 - files/ru/tools/accessibility_inspector/index.html | 166 ++ files/ru/tools/add-ons/dom_inspector/index.html | 57 - files/ru/tools/add-ons/index.html | 15 - files/ru/tools/browser_console/index.html | 180 ++ .../debugger/how_to/debug_eval_sources/index.html | 36 + .../how_to/pretty-print_a_minified_file/index.html | 10 + .../index.html" | 36 - .../index.html" | 10 - .../page_inspector/how_to/edit_fonts/index.html | 24 + .../how_to/examine_event_listeners/index.html | 28 + .../how_to/open_the_inspector/index.html | 19 + .../how_to/otkrytie_inspektora/index.html | 19 - .../how_to/select_an_element/index.html | 29 + .../how_to/vybor_elementa/index.html | 29 - .../index.html" | 28 - .../index.html" | 24 - .../page_inspector/keyboard_shortcuts/index.html | 13 + .../index.html" | 13 - files/ru/tools/performance/index.html | 95 + files/ru/tools/performance/waterfall/index.html | 386 +++ files/ru/tools/profiler/index.html | 169 -- files/ru/tools/release_notes/index.html | 128 - files/ru/tools/responsive_design_mode/index.html | 100 + files/ru/tools/responsive_design_view/index.html | 100 - files/ru/tools/rulers/index.html | 24 + .../web_console/opening_the_web_console/index.html | 23 - files/ru/tools/web_console/ui_tour/index.html | 23 + .../index.html" | 166 -- .../index.html" | 180 -- .../index.html" | 24 - .../index.html" | 95 - .../waterfall/index.html" | 386 --- files/ru/using_firefox_1.5_caching/index.html | 210 -- .../index.html" | 51 - .../web/api/audiocontext/createpanner/index.html | 211 -- .../ru/web/api/audiocontext/currenttime/index.html | 97 - .../api/audiocontext/decodeaudiodata/index.html | 220 -- .../api/baseaudiocontext/createpanner/index.html | 211 ++ .../api/baseaudiocontext/currenttime/index.html | 97 + .../baseaudiocontext/decodeaudiodata/index.html | 220 ++ .../tutorial/applying_styles_and_colors/index.html | 726 +++++ .../tutorial/basic_animations/index.html | 308 +++ .../api/canvas_api/tutorial/compositing/index.html | 108 + .../canvas_api/tutorial/drawing_shapes/index.html | 582 ++++ .../canvas_api/tutorial/drawing_text/index.html | 166 ++ .../canvas_api/tutorial/using_images/index.html | 333 +++ .../index.html" | 333 --- .../index.html" | 108 - .../index.html" | 308 --- .../index.html" | 726 ----- .../index.html" | 166 -- .../index.html" | 582 ---- files/ru/web/api/crypto/getrandomvalues/index.html | 73 + .../managing_screen_orientation/index.html | 183 ++ .../index.html" | 183 -- files/ru/web/api/document/activeelement/index.html | 165 -- files/ru/web/api/document/async/index.html | 35 - files/ru/web/api/document/createelement/index.html | 82 + files/ru/web/api/document/getselection/index.html | 9 - files/ru/web/api/document/images/index.html | 29 + .../api/document/readystatechange_event/index.html | 90 + .../api/document_object_model/events/index.html | 80 + .../api/document_object_model/examples/index.html | 382 +++ files/ru/web/api/document_object_model/index.html | 387 +++ .../document_object_model/introduction/index.html | 230 ++ .../index.html | 50 + .../documentorshadowroot/activeelement/index.html | 165 ++ .../documentorshadowroot/getselection/index.html | 9 + files/ru/web/api/element/accesskey/index.html | 74 - files/ru/web/api/element/blur_event/index.html | 153 ++ files/ru/web/api/element/error_event/index.html | 95 + files/ru/web/api/element/focusin_event/index.html | 123 + files/ru/web/api/element/focusout_event/index.html | 126 + .../web/api/elementcssinlinestyle/style/index.html | 78 + .../ru/web/api/eventtarget/attachevent/index.html | 9 - .../ru/web/api/eventtarget/detachevent/index.html | 92 - .../introduction/index.html | 291 ++ .../index.html" | 291 -- files/ru/web/api/fullscreen_api/index.html | 198 ++ .../api/geolocation/using_geolocation/index.html | 91 - .../using_the_geolocation_api/index.html | 170 -- files/ru/web/api/geolocation_api/index.html | 91 + .../using_the_geolocation_api/index.html | 170 ++ .../drag_operations/index.html | 314 +++ files/ru/web/api/html_drag_and_drop_api/index.html | 72 + .../ru/web/api/htmlaudioelement/audio()/index.html | 85 - files/ru/web/api/htmlaudioelement/audio/index.html | 85 + files/ru/web/api/htmlelement/accesskey/index.html | 74 + files/ru/web/api/htmlelement/dataset/index.html | 114 - files/ru/web/api/htmlelement/innertext/index.html | 46 + files/ru/web/api/htmlelement/nonce/index.html | 44 - files/ru/web/api/htmlelement/style/index.html | 78 - files/ru/web/api/htmlelement/tabindex/index.html | 134 - .../api/htmlelement/transitionend_event/index.html | 165 ++ .../api/htmlmediaelement/seeking_event/index.html | 80 + .../api/htmlorforeignelement/dataset/index.html | 114 + .../web/api/htmlorforeignelement/nonce/index.html | 44 + .../api/htmlorforeignelement/tabindex/index.html | 134 + .../echocancellation/index.html | 77 + .../index.html" | 77 - files/ru/web/api/navigator/connection/index.html | 100 + files/ru/web/api/navigatorgeolocation/index.html | 103 - .../api/networkinformation/connection/index.html | 100 - files/ru/web/api/node.replacechild/index.html | 64 - files/ru/web/api/node/baseuriobject/index.html | 26 - files/ru/web/api/node/innertext/index.html | 46 - files/ru/web/api/node/nodeprincipal/index.html | 29 - files/ru/web/api/node/replacechild/index.html | 64 + .../nextelementsibling/index.html | 173 ++ .../index.html | 173 -- files/ru/web/api/notation/index.html | 52 + files/ru/web/api/page_visibility_api/index.html | 195 ++ .../web/api/push_api/using_the_push_api/index.html | 420 --- .../api/randomsource/getrandomvalues/index.html | 73 - files/ru/web/api/randomsource/index.html | 111 - files/ru/web/api/slotable/index.html | 45 - files/ru/web/api/storage/localstorage/index.html | 146 - .../api/svgaelement/svgalement.target/index.html | 107 - .../checking_authenticity_with_password/index.html | 33 - .../web_workers_api/using_web_workers/index.html | 871 ++++++ .../creating_3d_objects_using_webgl/index.html | 131 + .../index.html" | 131 - .../ru/web/api/webrtc_api/connectivity/index.html | 70 + files/ru/web/api/webrtc_api/protocols/index.html | 38 + .../ru/web/api/webrtc_api/webrtc_basics/index.html | 351 --- .../index.html" | 38 - .../index.html" | 70 - files/ru/web/api/websockets_api/index.html | 58 + .../index.html | 195 ++ .../api/window/domcontentloaded_event/index.html | 146 + files/ru/web/api/window/load_event/index.html | 88 + .../api/window/requestanimationframe/index.html | 92 + .../api/window/unhandledrejection_event/index.html | 49 + .../base64_encoding_and_decoding/index.html | 138 - files/ru/web/api/windowbase64/btoa/index.html | 141 - files/ru/web/api/windowbase64/index.html | 121 - .../api/windoworworkerglobalscope/btoa/index.html | 141 + .../settimeout/index.html | 260 ++ files/ru/web/api/windowtimers/index.html | 120 - .../ru/web/api/windowtimers/settimeout/index.html | 260 -- files/ru/web/api/xmldocument/async/index.html | 35 + .../api/xmlhttprequest/loadstart_event/index.html | 89 + .../index.html" | 195 -- .../index.html" | 52 - files/ru/web/css/@viewport/user-zoom/index.html | 106 - files/ru/web/css/_colon_any/index.html | 190 -- files/ru/web/css/actual_value/index.html | 40 + files/ru/web/css/box_model/index.html | 66 - files/ru/web/css/comments/index.html | 50 + files/ru/web/css/common_css_questions/index.html | 182 -- .../ispolzovanie_css_animatciy/index.html | 388 --- .../css_animations/using_css_animations/index.html | 388 +++ .../border-radius_generator/index.html | 1599 +++++++++++ .../index.html" | 1599 ----------- .../box-shadow_generator/index.html | 2884 ++++++++++++++++++++ .../web/css/css_background_and_borders/index.html | 155 -- .../index.html" | 53 - .../web/css/css_backgrounds_and_borders/index.html | 155 ++ .../using_multiple_backgrounds/index.html | 53 + .../index.html | 120 + .../index.html" | 120 - .../css_box_model/box-shadow_generator/index.html | 2884 -------------------- .../introduction_to_the_css_box_model/index.html | 66 + files/ru/web/css/css_color/index.html | 117 + files/ru/web/css/css_colors/index.html | 117 - .../using_multi-column_layouts/index.html | 124 + .../aligning_items_in_a_flex_container/index.html | 213 ++ .../index.html | 194 ++ .../using_css_flexible_boxes/index.html | 379 --- .../index.html" | 213 -- .../index.html" | 194 -- .../index.html | 123 + .../intro_to_formatting_contexts/index.html | 85 + .../index.html" | 123 - .../index.html" | 85 - .../index.html | 498 ---- .../index.html | 498 ++++ .../css_grid_layout/grid_template_areas/index.html | 529 ++++ .../line-based_placement_with_css_grid/index.html | 652 +++++ .../index.html" | 529 ---- .../index.html" | 652 ----- .../adding_z-index/index.html | 157 ++ .../understanding_z_index/index.html | 51 + .../stacking_without_z-index/index.html | 140 + files/ru/web/css/css_selectors/index.html | 122 + .../index.html | 62 + files/ru/web/css/css_user_interface/index.html | 119 - .../index.html" | 122 - .../index.html" | 62 - files/ru/web/css/filter-function/url/index.html | 35 - files/ru/web/css/grid-gap/index.html | 194 -- files/ru/web/css/layout_mode/index.html | 28 + files/ru/web/css/length/index.html | 153 ++ .../media_queries/testing_media_queries/index.html | 83 + .../index.html" | 83 - files/ru/web/css/pseudo-classes/index.html | 146 + files/ru/web/css/replaced_element/index.html | 49 + files/ru/web/css/specified_value/index.html | 43 + files/ru/web/css/syntax/index.html | 76 + files/ru/web/css/url/index.html | 94 - .../ru/web/css/visual_formatting_model/index.html | 209 ++ .../index.html" | 40 - .../index.html" | 49 - .../index.html" | 146 - .../index.html" | 153 -- .../index.html" | 76 - .../index.html" | 28 - .../index.html" | 50 - .../index.html" | 43 - files/ru/web/events/abort/index.html | 70 - files/ru/web/events/blur/index.html | 153 -- files/ru/web/events/domcontentloaded/index.html | 146 - files/ru/web/events/error/index.html | 95 - files/ru/web/events/focusin/index.html | 123 - files/ru/web/events/focusout/index.html | 126 - files/ru/web/events/load/index.html | 88 - files/ru/web/events/loadstart/index.html | 89 - files/ru/web/events/readystatechange/index.html | 90 - files/ru/web/events/transitionend/index.html | 165 -- files/ru/web/events/unhandledrejection/index.html | 49 - files/ru/web/guide/ajax/getting_started/index.html | 258 ++ .../index.html" | 258 -- .../index.html" | 6 - files/ru/web/guide/api/dom/index.html | 38 - files/ru/web/guide/api/dom/storage/index.html | 368 --- files/ru/web/guide/api/webrtc/index.html | 35 - .../cascading_and_inheritance/index.html | 152 -- .../web/guide/css/getting_started/color/index.html | 345 --- .../css/getting_started/how_css_works/index.html | 122 - files/ru/web/guide/css/getting_started/index.html | 60 - .../css/getting_started/readable_css/index.html | 166 -- .../guide/css/getting_started/selectors/index.html | 434 --- .../getting_started/svg_\320\270_css/index.html" | 213 -- .../css/getting_started/text_styles/index.html | 152 -- .../css/getting_started/what_is_css/index.html | 120 - .../css/getting_started/why_use_css/index.html | 110 - .../index.html" | 525 ---- files/ru/web/guide/css/index.html | 12 - .../adding_z-index/index.html | 157 -- .../web/guide/css/understanding_z_index/index.html | 51 - .../stacking_without_z-index/index.html | 140 - .../css/using_multi-column_layouts/index.html | 124 - .../guide/css/visual_formatting_model/index.html | 209 -- .../creating_and_triggering_events/index.html | 92 + .../index.html" | 92 - files/ru/web/guide/graphics/index.html | 41 + .../html/drag_and_drop/drag_operations/index.html | 314 --- files/ru/web/guide/html/drag_and_drop/index.html | 72 - .../html/html5/constraint_validation/index.html | 343 +++ files/ru/web/guide/html/html5/index.html | 171 ++ .../html/html5/introduction_to_html5/index.html | 26 + .../index.html | 375 --- .../index.html | 204 -- .../guide/html/using_data_attributes/index.html | 129 - .../using_html_sections_and_outlines/index.html | 375 +++ .../index.html" | 149 - files/ru/web/guide/performance/index.html | 20 + .../index.html" | 41 - .../index.html" | 20 - .../ru/web/html/attributes/crossorigin/index.html | 130 + .../web/html/cors_settings_attributes/index.html | 130 - files/ru/web/html/element/button/index.html | 363 +++ files/ru/web/html/element/element/index.html | 112 - files/ru/web/html/element/link/index.html | 336 +++ .../html/element/video/seeking_event/index.html | 80 - .../index.html" | 363 --- .../index.html" | 336 --- .../web/html/global_attributes/dropzone/index.html | 43 - files/ru/web/html/inline_elements/index.html | 51 + files/ru/web/html/link_types/index.html | 502 ++++ .../index.html | 33 - files/ru/web/html/reference/index.html | 32 + .../html/using_the_application_cache/index.html | 327 +++ .../index.html" | 327 --- .../index.html" | 517 ---- .../index.html" | 32 - .../index.html" | 51 - .../index.html" | 502 ---- files/ru/web/http/authentication/index.html | 123 + .../identifying_resources_on_the_web/index.html | 188 ++ .../identifying_resources_on_the_web_ru/index.html | 188 -- files/ru/web/http/caching/index.html | 165 ++ files/ru/web/http/cookies/index.html | 173 ++ .../ru/web/http/headers/accept-charset/index.html | 83 + .../ru/web/http/headers/accept-language/index.html | 94 + files/ru/web/http/headers/accept-patch/index.html | 83 + files/ru/web/http/headers/accept-ranges/index.html | 77 + files/ru/web/http/headers/accept/index.html | 89 + .../access-control-allow-headers/index.html | 93 + .../access-control-allow-methods/index.html | 85 + .../headers/access-control-allow-origin/index.html | 94 + .../http/headers/access-control-max-age/index.html | 69 + files/ru/web/http/headers/authorization/index.html | 91 + files/ru/web/http/headers/cache-control/index.html | 173 ++ files/ru/web/http/headers/connection/index.html | 53 + .../http/headers/content-disposition/index.html | 137 + .../web/http/headers/content-encoding/index.html | 107 + .../web/http/headers/content-language/index.html | 103 + .../ru/web/http/headers/content-length/index.html | 67 + files/ru/web/http/headers/content-type/index.html | 111 + files/ru/web/http/headers/date/index.html | 86 + files/ru/web/http/headers/dnt/index.html | 83 + files/ru/web/http/headers/etag/index.html | 98 + files/ru/web/http/headers/expect/index.html | 87 + files/ru/web/http/headers/expires/index.html | 80 + files/ru/web/http/headers/host/index.html | 72 + files/ru/web/http/headers/if-match/index.html | 86 + .../web/http/headers/if-modified-since/index.html | 94 + .../http/headers/if-unmodified-since/index.html | 103 + files/ru/web/http/headers/index.html | 573 ++++ files/ru/web/http/headers/last-modified/index.html | 94 + files/ru/web/http/headers/origin/index.html | 77 + files/ru/web/http/headers/pragma/index.html | 78 + files/ru/web/http/headers/range/index.html | 88 + files/ru/web/http/headers/referer/index.html | 94 + files/ru/web/http/headers/retry-after/index.html | 86 + files/ru/web/http/headers/set-cookie/index.html | 193 ++ .../headers/strict-transport-security/index.html | 112 + files/ru/web/http/headers/vary/index.html | 81 + .../http/headers/x-content-type-options/index.html | 83 + .../ru/web/http/headers/x-forwarded-for/index.html | 72 + .../web/http/headers/x-xss-protection/index.html | 87 + .../web/http/server-side_access_control/index.html | 213 -- .../index.html" | 123 - .../accept-charset/index.html" | 83 - .../accept-language/index.html" | 94 - .../accept-patch/index.html" | 83 - .../accept-ranges/index.html" | 77 - .../accept/index.html" | 89 - .../access-control-allow-headers/index.html" | 93 - .../access-control-allow-methods/index.html" | 85 - .../access-control-allow-origin/index.html" | 94 - .../access-control-max-age/index.html" | 69 - .../authorization/index.html" | 91 - .../cache-control/index.html" | 173 -- .../connection/index.html" | 53 - .../content-disposition/index.html" | 137 - .../content-encoding/index.html" | 107 - .../content-language/index.html" | 103 - .../content-length/index.html" | 67 - .../content-type/index.html" | 111 - .../date/index.html" | 86 - .../dnt/index.html" | 83 - .../etag/index.html" | 98 - .../expect/index.html" | 87 - .../expires/index.html" | 80 - .../host/index.html" | 72 - .../if-match/index.html" | 86 - .../if-modified-since/index.html" | 94 - .../if-unmodified-since/index.html" | 103 - .../index.html" | 573 ---- .../last-modified/index.html" | 94 - .../origin/index.html" | 77 - .../pragma/index.html" | 78 - .../range/index.html" | 88 - .../referer/index.html" | 94 - .../retry-after/index.html" | 86 - .../set-cookie/index.html" | 193 -- .../strict-transport-security/index.html" | 112 - .../vary/index.html" | 81 - .../x-content-type-options/index.html" | 83 - .../x-forwarded-for/index.html" | 72 - .../x-xss-protection/index.html" | 87 - .../\320\272\321\203\320\272\320\270/index.html" | 173 -- .../index.html" | 165 -- .../ru/web/javascript/about_javascript/index.html | 60 + files/ru/web/javascript/guide/about/index.html | 159 -- .../web/javascript/guide/introduction/index.html | 159 ++ .../guide/ispolzovanie_promisov/index.html | 321 --- .../guide/javascript_overview/index.html | 142 - .../guide/loops_and_iteration/index.html | 362 +++ .../guide/predefined_core_objects/index.html | 923 ------- .../web/javascript/guide/using_promises/index.html | 321 +++ .../index.html" | 159 -- .../index.html" | 68 - .../index.html" | 362 --- .../index.html | 356 --- .../index.html" | 44 - files/ru/web/javascript/reference/about/index.html | 50 + .../reference/classes/class_fields/index.html | 350 --- .../classes/private_class_fields/index.html | 205 ++ .../classes/public_class_fields/index.html | 350 +++ .../index.html" | 205 -- .../reference/errors/var_hides_argument/index.html | 60 + .../index.html" | 60 - .../functions/method_definitions/index.html | 191 ++ .../index.html" | 191 -- .../global_objects/array/prototype/index.html | 171 -- .../asyncfunction/prototype/index.html | 55 - .../global_objects/boolean/prototype/index.html | 113 - .../global_objects/date/prototype/index.html | 229 -- .../global_objects/error/prototype/index.html | 155 -- .../global_objects/evalerror/prototype/index.html | 122 - .../global_objects/function/prototype/index.html | 152 -- .../generatorfunction/prototype/index.html | 59 - .../internalerror/prototype/index.html | 100 - .../intl/collator/prototype/index.html | 109 - .../intl/datetimeformat/prototype/index.html | 109 - .../intl/numberformat/prototype/index.html | 109 - .../global_objects/map/prototype/index.html | 126 - .../index.html" | 136 - .../global_objects/number/prototype/index.html | 124 - .../global_objects/object/prototype/index.html | 205 -- .../global_objects/promise/prototype/index.html | 67 - .../proxy/handler/deleteproperty/index.html | 131 - .../global_objects/proxy/handler/index.html | 135 - .../global_objects/proxy/handler/set/index.html | 179 -- .../proxy/proxy/deleteproperty/index.html | 131 + .../global_objects/proxy/proxy/set/index.html | 179 ++ .../global_objects/rangeerror/prototype/index.html | 123 - .../referenceerror/prototype/index.html | 123 - .../global_objects/regexp/prototype/index.html | 141 - .../global_objects/set/prototype/index.html | 81 - .../global_objects/string/prototype/index.html | 230 -- .../global_objects/string/trimend/index.html | 93 + .../global_objects/string/trimleft/index.html | 93 - .../global_objects/string/trimright/index.html | 93 - .../global_objects/string/trimstart/index.html | 93 + .../global_objects/symbol/prototype/index.html | 107 - .../syntaxerror/prototype/index.html | 123 - .../global_objects/typedarray/prototype/index.html | 129 - .../global_objects/typeerror/prototype/index.html | 123 - .../global_objects/urierror/prototype/index.html | 123 - .../global_objects/weakmap/prototype/index.html | 75 - .../global_objects/weakset/prototype/index.html | 142 - .../operators/arithmetic_operators/index.html | 291 -- .../reference/operators/assignment/index.html | 66 + .../operators/assignment_operators/index.html | 431 --- .../operators/bitwise_operators/index.html | 626 ----- .../reference/operators/comma_operator/index.html | 103 + .../operators/conditional_operator/index.html | 169 ++ .../reference/operators/grouping/index.html | 91 + .../operators/pipeline_operator/index.html | 77 + .../index.html" | 91 - .../index.html" | 77 - .../index.html" | 300 -- .../index.html" | 103 - .../index.html" | 286 -- .../index.html" | 66 - .../index.html" | 169 -- .../reference/statements/block/index.html | 177 ++ .../reference/statements/default/index.html | 117 - .../\320\261\320\273\320\276\320\272/index.html" | 177 -- .../reference/template_literals/index.html | 243 ++ .../reference/template_strings/index.html | 243 -- .../reference/\320\276\320\261/index.html" | 50 - files/ru/web/javascript/shells/index.html | 44 + .../web/javascript/\320\276_javascript/index.html" | 60 - files/ru/web/manifest/serviceworker/index.html | 91 - files/ru/web/mathml/attribute/index.html | 484 ++++ .../deriving_the_quadratic_formula/index.html | 18 + files/ru/web/mathml/examples/index.html | 26 + .../examples/mathml_pythagorean_theorem/index.html | 29 + .../index.html" | 484 ---- .../deriving_the_quadratic_formula/index.html" | 18 - .../index.html" | 26 - .../mathml_pythagorean_theorem/index.html" | 29 - .../ru/web/media/formats/webrtc_codecs/index.html | 483 ++++ .../index.html" | 483 ---- .../index.html | 174 ++ files/ru/web/performance/fundamentals/index.html | 224 ++ .../index.html" | 224 -- .../index.html" | 174 -- .../index.html" | 64 - files/ru/web/security/csp/index.html | 43 - .../information_security_basics/index.html | 30 - files/ru/web/svg/attribute/onload/index.html | 5 - files/ru/web/svg/element/a/index.html | 151 + files/ru/web/svg/element/animate/index.html | 81 + files/ru/web/svg/element/animatemotion/index.html | 112 + files/ru/web/svg/element/circle/index.html | 109 + files/ru/web/svg/element/defs/index.html | 101 + files/ru/web/svg/element/ellipse/index.html | 129 + files/ru/web/svg/element/feblend/index.html | 115 + files/ru/web/svg/element/foreignobject/index.html | 119 + files/ru/web/svg/element/g/index.html | 98 + files/ru/web/svg/element/image/index.html | 94 + files/ru/web/svg/element/index.html | 253 ++ files/ru/web/svg/element/line/index.html | 104 + files/ru/web/svg/element/lineargradient/index.html | 105 + files/ru/web/svg/element/path/index.html | 98 + files/ru/web/svg/element/pattern/index.html | 125 + files/ru/web/svg/element/polygon/index.html | 95 + files/ru/web/svg/element/radialgradient/index.html | 108 + files/ru/web/svg/element/rect/index.html | 115 + files/ru/web/svg/element/svg/index.html | 119 + files/ru/web/svg/element/text/index.html | 211 ++ files/ru/web/svg/element/use/index.html | 126 + files/ru/web/svg/tutorial/basic_shapes/index.html | 144 + .../svg/tutorial/basic_transformations/index.html | 98 + files/ru/web/svg/tutorial/introduction/index.html | 44 + files/ru/web/svg/tutorial/positions/index.html | 48 + files/ru/web/svg/tutorial/svg_and_css/index.html | 213 ++ .../index.html" | 98 - .../index.html" | 44 - .../index.html" | 144 - .../index.html" | 48 - .../a/index.html" | 151 - .../animate/index.html" | 81 - .../animatemotion/index.html" | 112 - .../circle/index.html" | 109 - .../defs/index.html" | 101 - .../ellipse/index.html" | 129 - .../feblend/index.html" | 115 - .../foreignobject/index.html" | 119 - .../g/index.html" | 98 - .../image/index.html" | 94 - .../index.html" | 253 -- .../line/index.html" | 104 - .../lineargradient/index.html" | 105 - .../path/index.html" | 98 - .../pattern/index.html" | 125 - .../polygon/index.html" | 95 - .../radialgradient/index.html" | 108 - .../rect/index.html" | 115 - .../svg/index.html" | 119 - .../text/index.html" | 211 -- .../use/index.html" | 126 - .../using_custom_elements/index.html | 243 ++ .../index.html" | 243 -- files/ru/web/webapi/index.html | 131 - files/ru/web/xpath/functions/floor/index.html | 21 + files/ru/web/xpath/functions/index.html | 6 + files/ru/web/xpath/funkcje/floor/index.html | 21 - files/ru/web/xpath/funkcje/index.html | 6 - files/ru/web_development/mobile/index.html | 18 - .../mobile/responsive_design/index.html | 48 - files/ru/websockets/index.html | 58 - .../index.html | 195 -- files/ru/xml_in_mozilla/index.html | 56 - files/ru/xmlhttprequest/index.html | 282 -- files/ru/xpcnativewrapper/index.html | 108 - files/ru/xpcom/index.html | 16 - .../index.html" | 10 - .../index.html" | 14 - .../index.html" | 8 - .../index.html" | 68 - .../index.html" | 18 - .../index.html" | 15 - .../index.html" | 6 - .../index.html" | 5 - .../index.html" | 81 - .../index.html" | 25 - .../index.html" | 10 - .../index.html" | 34 - .../404/index.html" | 15 - .../502/index.html" | 20 - .../abstraction/index.html" | 12 - .../adobe-flash/index.html" | 21 - .../ajax/index.html" | 32 - .../algorithm/index.html" | 38 - .../api/index.html" | 25 - .../apple_safari/index.html" | 29 - .../application_context/index.html" | 14 - .../aria/index.html" | 19 - .../arpa/index.html" | 20 - .../arpanet/index.html" | 19 - .../ascii/index.html" | 15 - .../asynchronous/index.html" | 23 - .../atag/index.html" | 28 - .../bandwidth/index.html" | 15 - .../baseline/index.html" | 30 - .../bidi/index.html" | 25 - .../bigint/index.html" | 28 - .../blink/index.html" | 16 - .../boolean/index.html" | 62 - .../bootstrap/index.html" | 22 - .../browser/index.html" | 24 - .../browsing_context/index.html" | 19 - .../b\303\251zier_curve/index.html" | 32 - .../cacheable/index.html" | 59 - .../call_stack/index.html" | 102 - .../canvas/index.html" | 37 - .../card_sorting/index.html" | 17 - .../cdn/index.html" | 21 - .../character/index.html" | 20 - .../character_encoding/index.html" | 27 - .../chrome/index.html" | 11 - .../class/index.html" | 23 - .../cms/index.html" | 16 - .../codec/index.html" | 20 - .../compile/index.html" | 29 - .../computer_programming/index.html" | 24 - .../conditional/index.html" | 34 - .../constructor/index.html" | 47 - .../cookie/index.html" | 21 - .../copyleft/index.html" | 19 - .../cors/index.html" | 46 - .../crawler/index.html" | 23 - .../crlf/index.html" | 13 - .../csp/index.html" | 27 - .../csrf/index.html" | 16 - .../css/index.html" | 48 - .../css_preprocessor/index.html" | 24 - .../css_selector/index.html" | 73 - .../data_structure/index.html" | 17 - .../dns/index.html" | 24 - .../doctype/index.html" | 28 - .../dom/index.html" | 27 - .../domain_name/index.html" | 23 - .../dos_attack/index.html" | 32 - .../dynamic_programming_language/index.html" | 16 - .../ecma/index.html" | 17 - .../ecmascript/index.html" | 22 - .../empty_element/index.html" | 35 - .../encapsulation/index.html" | 18 - .../entity_header/index.html" | 25 - .../event/index.html" | 25 - .../expando/index.html" | 10 - .../falsy/index.html" | 93 - .../first-class_function/index.html" | 32 - .../first_contentful_paint/index.html" | 15 - .../first_cpu_idle/index.html" | 8 - .../first_input_delay/index.html" | 15 - .../first_interactive/index.html" | 14 - .../first_meaningful_paint/index.html" | 12 - .../first_paint/index.html" | 14 - .../flex_item/index.html" | 34 - .../flexbox/index.html" | 44 - .../forbidden_header_name/index.html" | 44 - .../fps/index.html" | 20 - .../ftp/index.html" | 22 - .../gecko/index.html" | 31 - .../general_header/index.html" | 8 - .../git/index.html" | 18 - .../global_object/index.html" | 66 - .../global_variable/index.html" | 18 - .../grid/index.html" | 75 - .../grid_column/index.html" | 30 - .../host/index.html" | 20 - .../html/index.html" | 47 - .../html5/index.html" | 19 - .../http/index.html" | 25 - .../http_2/index.html" | 31 - .../https/index.html" | 17 - .../iana/index.html" | 13 - .../icann/index.html" | 13 - .../idempotent/index.html" | 49 - .../identifier/index.html" | 19 - .../ietf/index.html" | 21 - .../iife/index.html" | 61 - .../index.html" | 24 - .../indexeddb/index.html" | 19 - .../information_architecture/index.html" | 14 - .../internet/index.html" | 31 - .../ip_address/index.html" | 22 - .../iso/index.html" | 19 - .../java/index.html" | 22 - .../javascript/index.html" | 45 - .../jpeg/index.html" | 17 - .../jquery/index.html" | 35 - .../json/index.html" | 29 - .../loop/index.html" | 88 - .../main_axis/index.html" | 46 - .../mathml/index.html" | 26 - .../method/index.html" | 43 - .../microsoft_internet_explorer/index.html" | 41 - .../mime_type/index.html" | 26 - .../mixin/index.html" | 24 - .../node.js/index.html" | 29 - .../null/index.html" | 28 - .../number/index.html" | 25 - .../object/index.html" | 26 - .../oop/index.html" | 21 - .../opengl/index.html" | 16 - .../origin/index.html" | 52 - .../php/index.html" | 16 - .../pixel/index.html" | 19 - .../polymorphism/index.html" | 24 - .../primitive/index.html" | 105 - .../privileged_code/index.html" | 10 - .../progressive_web_apps/index.html" | 18 - .../promise/index.html" | 32 - .../property/index.html" | 12 - .../prototype-based_programming/index.html" | 17 - .../pseudo-element/index.html" | 18 - .../pseudocode/index.html" | 17 - .../reflow/index.html" | 12 - .../regular_expression/index.html" | 26 - .../request_header/index.html" | 43 - .../responsive_web_design/index.html" | 20 - .../round_trip_time_(rtt)/index.html" | 28 - .../safe/index.html" | 43 - .../scroll_container/index.html" | 25 - .../sdp/index.html" | 31 - .../self-executing_anonymous_function/index.html" | 8 - .../semantics/index.html" | 98 - .../seo/index.html" | 35 - .../server/index.html" | 25 - .../sgml/index.html" | 18 - .../simple_response_header/index.html" | 6 - .../sloppy_mode/index.html" | 21 - .../specification/index.html" | 23 - .../svg/index.html" | 41 - .../symbol/index.html" | 24 - .../tcp/index.html" | 23 - .../time_to_first_byte/index.html" | 18 - .../time_to_interactive/index.html" | 20 - .../tls/index.html" | 24 - .../truthy/index.html" | 39 - .../type/index.html" | 23 - .../type_coercion/index.html" | 44 - .../type_conversion/index.html" | 30 - .../ui/index.html" | 19 - .../undefined/index.html" | 8 - .../url/index.html" | 30 - .../user_agent/index.html" | 28 - .../variable/index.html" | 14 - .../vendor_prefix/index.html" | 75 - .../viewport/index.html" | 110 - .../w3c/index.html" | 26 - .../wai/index.html" | 15 - .../webkit/index.html" | 24 - .../websockets/index.html" | 35 - .../whatwg/index.html" | 26 - .../world_wide_web/index.html" | 40 - .../wrapper/index.html" | 16 - .../xhr_(xmlhttprequest)/index.html" | 23 - .../xhtml/index.html" | 32 - .../xml/index.html" | 17 - .../index.html" | 24 - .../index.html" | 18 - .../index.html" | 21 - .../index.html" | 27 - .../index.html" | 10 - .../index.html" | 27 - .../index.html" | 22 - .../index.html" | 17 - .../index.html" | 33 - .../index.html" | 15 - .../index.html" | 25 - .../index.html" | 27 - .../index.html" | 20 - .../index.html" | 19 - .../\320\272\321\206\320\264/index.html" | 17 - .../\320\272\321\215\321\210/index.html" | 14 - .../index.html" | 36 - .../index.html" | 20 - .../index.html" | 74 - .../\320\277\320\276\321\200\321\202/index.html" | 22 - .../index.html" | 36 - .../index.html" | 24 - .../index.html" | 39 - .../index.html" | 21 - .../index.html" | 18 - .../index.html" | 25 - .../index.html" | 23 - .../index.html" | 17 - .../index.html" | 20 - .../index.html" | 59 - .../\321\202\320\265\320\263/index.html" | 28 - .../index.html" | 77 - .../index.html" | 70 - .../\321\205\320\265\321\210/index.html" | 14 - .../index.html" | 20 - .../index.html" | 274 -- .../index.html" | 25 - .../index.html" | 15 - .../index.html" | 6 - .../index.html" | 81 - .../index.html" | 224 -- .../index.html" | 64 - .../index.html" | 5 - .../\321\202\320\265\320\274\321\213/index.html" | 14 - 1448 files changed, 93564 insertions(+), 93564 deletions(-) delete mode 100644 files/ru/a_basic_raycaster/index.html delete mode 100644 files/ru/building_an_extension/index.html delete mode 100644 files/ru/chrome/index.html create mode 100644 files/ru/conflicting/glossary/chrome/index.html create mode 100644 files/ru/conflicting/learn/css/building_blocks/cascade_and_inheritance/index.html create mode 100644 files/ru/conflicting/learn/css/building_blocks/selectors/index.html create mode 100644 files/ru/conflicting/learn/css/building_blocks/selectors_918fb6c37a4d06789bc062c48d591992/index.html create mode 100644 files/ru/conflicting/learn/css/building_blocks/styling_tables/index.html create mode 100644 files/ru/conflicting/learn/css/building_blocks/values_and_units/index.html create mode 100644 files/ru/conflicting/learn/css/first_steps/how_css_is_structured/index.html create mode 100644 files/ru/conflicting/learn/css/first_steps/how_css_works/index.html create mode 100644 files/ru/conflicting/learn/css/first_steps/how_css_works_64ba4331a7a5f4319c6e06b06ccdd521/index.html create mode 100644 files/ru/conflicting/learn/css/first_steps/how_css_works_b66915031fb62b5fee1201086144e209/index.html create mode 100644 files/ru/conflicting/learn/css/first_steps/index.html create mode 100644 files/ru/conflicting/learn/css/index.html create mode 100644 files/ru/conflicting/learn/css/styling_text/fundamentals/index.html create mode 100644 files/ru/conflicting/learn/javascript/objects/index.html create mode 100644 files/ru/conflicting/mdn/contribute/index.html create mode 100644 files/ru/conflicting/mdn/tools/index.html create mode 100644 files/ru/conflicting/mozilla/add-ons/index.html create mode 100644 files/ru/conflicting/mozilla/firefox/releases/index.html create mode 100644 files/ru/conflicting/tools/performance/index.html create mode 100644 files/ru/conflicting/web/accessibility/index.html create mode 100644 files/ru/conflicting/web/api/canvas_api/a_basic_ray-caster/index.html create mode 100644 files/ru/conflicting/web/api/crypto/getrandomvalues/index.html create mode 100644 files/ru/conflicting/web/api/document_object_model/index.html create mode 100644 files/ru/conflicting/web/api/document_object_model_5521049528397035462607d58539e0cc/index.html create mode 100644 files/ru/conflicting/web/api/document_object_model_dd00a71ceceac547ab464128db6bd8ef/index.html create mode 100644 files/ru/conflicting/web/api/element/index.html create mode 100644 files/ru/conflicting/web/api/eventtarget/addeventlistener/index.html create mode 100644 files/ru/conflicting/web/api/eventtarget/removeeventlistener/index.html create mode 100644 files/ru/conflicting/web/api/geolocation/index.html create mode 100644 files/ru/conflicting/web/api/htmlmediaelement/abort_event/index.html create mode 100644 files/ru/conflicting/web/api/index.html create mode 100644 files/ru/conflicting/web/api/node/index.html create mode 100644 files/ru/conflicting/web/api/node_378aed5ed6869e50853edbc988cf9556/index.html create mode 100644 files/ru/conflicting/web/api/push_api/index.html create mode 100644 files/ru/conflicting/web/api/svgaelement/target/index.html create mode 100644 files/ru/conflicting/web/api/web_storage_api/index.html create mode 100644 files/ru/conflicting/web/api/webrtc_api/index.html create mode 100644 files/ru/conflicting/web/api/webrtc_api/signaling_and_video_calling/index.html create mode 100644 files/ru/conflicting/web/api/window/localstorage/index.html create mode 100644 files/ru/conflicting/web/api/windoworworkerglobalscope/index.html create mode 100644 files/ru/conflicting/web/api/windoworworkerglobalscope_e2691f7ad05781a30c5fc5bb3b3f633a/index.html create mode 100644 files/ru/conflicting/web/api/xmlhttprequest/index.html create mode 100644 files/ru/conflicting/web/css/@viewport/index.html create mode 100644 files/ru/conflicting/web/css/_colon_is/index.html create mode 100644 files/ru/conflicting/web/css/css_basic_user_interface/index.html create mode 100644 files/ru/conflicting/web/css/css_flexible_box_layout/basic_concepts_of_flexbox/index.html create mode 100644 files/ru/conflicting/web/css/gap/index.html create mode 100644 files/ru/conflicting/web/css/url()/index.html create mode 100644 files/ru/conflicting/web/css/url()_168028c4e5edd9e19c061adb4b604d4f/index.html create mode 100644 files/ru/conflicting/web/guide/index.html create mode 100644 files/ru/conflicting/web/guide/mobile/index.html create mode 100644 files/ru/conflicting/web/http/cors/index.html create mode 100644 files/ru/conflicting/web/http/csp/index.html create mode 100644 files/ru/conflicting/web/javascript/guide/index.html create mode 100644 files/ru/conflicting/web/javascript/guide/introduction/index.html create mode 100644 files/ru/conflicting/web/javascript/guide/introduction_6f341ba6db4b060ccbd8dce4a0d5214b/index.html create mode 100644 files/ru/conflicting/web/javascript/reference/global_objects/boolean/index.html create mode 100644 files/ru/conflicting/web/javascript/reference/global_objects/date/index.html create mode 100644 files/ru/conflicting/web/javascript/reference/global_objects/error/index.html create mode 100644 files/ru/conflicting/web/javascript/reference/global_objects/evalerror/index.html create mode 100644 files/ru/conflicting/web/javascript/reference/global_objects/function/index.html create mode 100644 files/ru/conflicting/web/javascript/reference/global_objects/generatorfunction/index.html create mode 100644 files/ru/conflicting/web/javascript/reference/global_objects/internalerror/index.html create mode 100644 files/ru/conflicting/web/javascript/reference/global_objects/intl/collator/index.html create mode 100644 files/ru/conflicting/web/javascript/reference/global_objects/intl/datetimeformat/index.html create mode 100644 files/ru/conflicting/web/javascript/reference/global_objects/intl/numberformat/index.html create mode 100644 files/ru/conflicting/web/javascript/reference/global_objects/map/index.html create mode 100644 files/ru/conflicting/web/javascript/reference/global_objects/number/index.html create mode 100644 files/ru/conflicting/web/javascript/reference/global_objects/object/index.html create mode 100644 files/ru/conflicting/web/javascript/reference/global_objects/promise/index.html create mode 100644 files/ru/conflicting/web/javascript/reference/global_objects/proxy/proxy/index.html create mode 100644 files/ru/conflicting/web/javascript/reference/global_objects/rangeerror/index.html create mode 100644 files/ru/conflicting/web/javascript/reference/global_objects/referenceerror/index.html create mode 100644 files/ru/conflicting/web/javascript/reference/global_objects/regexp/index.html create mode 100644 files/ru/conflicting/web/javascript/reference/global_objects/set/index.html create mode 100644 files/ru/conflicting/web/javascript/reference/global_objects/string/index.html create mode 100644 files/ru/conflicting/web/javascript/reference/global_objects/symbol/index.html create mode 100644 files/ru/conflicting/web/javascript/reference/global_objects/syntaxerror/index.html create mode 100644 files/ru/conflicting/web/javascript/reference/global_objects/typedarray/index.html create mode 100644 files/ru/conflicting/web/javascript/reference/global_objects/typeerror/index.html create mode 100644 files/ru/conflicting/web/javascript/reference/global_objects/urierror/index.html create mode 100644 files/ru/conflicting/web/javascript/reference/global_objects/weakmap/index.html create mode 100644 files/ru/conflicting/web/javascript/reference/global_objects/weakset/index.html create mode 100644 files/ru/conflicting/web/javascript/reference/operators/index.html create mode 100644 files/ru/conflicting/web/javascript/reference/operators_69135a8d5772f8b6e45265523df05d89/index.html create mode 100644 files/ru/conflicting/web/javascript/reference/operators_7c8eb9475d97a4a734c5991857698560/index.html create mode 100644 files/ru/conflicting/web/javascript/reference/operators_843c998343f0cdaa5699874c806d4cea/index.html create mode 100644 files/ru/conflicting/web/javascript/reference/operators_8d54701de06af40a7c984517cbe87b3e/index.html create mode 100644 files/ru/conflicting/web/javascript/reference/statements/switch/index.html create mode 100644 files/ru/conflicting/web/media/formats/index.html create mode 100644 files/ru/conflicting/web/progressive_web_apps/index.html create mode 100644 files/ru/conflicting/web/progressive_web_apps_628955cdadd77b10ec99de034fc76374/index.html delete mode 100644 files/ru/dom/document.createelement/index.html delete mode 100644 files/ru/dom/document.images/index.html delete mode 100644 files/ru/dom/dom_reference/events/index.html delete mode 100644 files/ru/dom/dom_reference/examples/index.html delete mode 100644 files/ru/dom/dom_reference/index.html delete mode 100644 files/ru/dom/dom_reference/locating_dom_elements_using_selectors/index.html delete mode 100644 "files/ru/dom/dom_reference/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265/index.html" delete mode 100644 files/ru/dom/index.html delete mode 100644 files/ru/dom/using_fullscreen_mode/index.html delete mode 100644 files/ru/dom/using_web_workers/index.html delete mode 100644 files/ru/dom/window.requestanimationframe/index.html delete mode 100644 "files/ru/firefox_3.5_\320\264\320\273\321\217_\321\200\320\260\320\267\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\260/index.html" delete mode 100644 files/ru/firefox_3_for_developers/index.html create mode 100644 files/ru/games/anatomy/index.html create mode 100644 files/ru/games/introduction/index.html create mode 100644 files/ru/games/tools/asm.js/index.html create mode 100644 files/ru/games/tools/index.html create mode 100644 files/ru/games/tutorials/2d_breakout_game_phaser/bounce_off_the_walls/index.html create mode 100644 files/ru/games/tutorials/2d_breakout_game_phaser/build_the_brick_field/index.html create mode 100644 files/ru/games/tutorials/2d_breakout_game_phaser/collision_detection/index.html create mode 100644 files/ru/games/tutorials/2d_breakout_game_phaser/extra_lives/index.html create mode 100644 files/ru/games/tutorials/2d_breakout_game_phaser/game_over/index.html create mode 100644 files/ru/games/tutorials/2d_breakout_game_phaser/index.html create mode 100644 files/ru/games/tutorials/2d_breakout_game_phaser/initialize_the_framework/index.html create mode 100644 files/ru/games/tutorials/2d_breakout_game_phaser/load_the_assets_and_print_them_on_screen/index.html create mode 100644 files/ru/games/tutorials/2d_breakout_game_phaser/move_the_ball/index.html create mode 100644 files/ru/games/tutorials/2d_breakout_game_phaser/physics/index.html create mode 100644 files/ru/games/tutorials/2d_breakout_game_phaser/player_paddle_and_controls/index.html create mode 100644 files/ru/games/tutorials/2d_breakout_game_phaser/scaling/index.html create mode 100644 files/ru/games/tutorials/2d_breakout_game_phaser/the_score/index.html create mode 100644 files/ru/games/tutorials/2d_breakout_game_phaser/win_the_game/index.html create mode 100644 files/ru/games/tutorials/2d_breakout_game_pure_javascript/build_the_brick_field/index.html create mode 100644 files/ru/games/tutorials/2d_breakout_game_pure_javascript/collision_detection/index.html create mode 100644 files/ru/games/tutorials/2d_breakout_game_pure_javascript/create_the_canvas_and_draw_on_it/index.html create mode 100644 files/ru/games/tutorials/2d_breakout_game_pure_javascript/finishing_up/index.html create mode 100644 files/ru/games/tutorials/2d_breakout_game_pure_javascript/mouse_controls/index.html create mode 100644 files/ru/games/tutorials/2d_breakout_game_pure_javascript/move_the_ball/index.html delete mode 100644 "files/ru/games/tutorials/2d_breakout_game_pure_javascript/\320\267\320\260\320\272\320\273\321\216\321\207\320\265\320\275\320\270\320\265/index.html" delete mode 100644 "files/ru/games/tutorials/2d_breakout_game_pure_javascript/\320\276\320\261\320\275\320\260\321\200\321\203\320\266\320\265\320\275\320\270\320\265_\321\201\321\202\320\276\320\273\320\272\320\275\320\276\320\262\320\265\320\275\320\270\320\271/index.html" delete mode 100644 "files/ru/games/tutorials/2d_breakout_game_pure_javascript/\320\277\320\265\321\200\320\265\320\274\320\265\321\201\321\202\320\270\321\202\321\214_\320\274\321\217\321\207/index.html" delete mode 100644 "files/ru/games/tutorials/2d_breakout_game_pure_javascript/\321\201\320\276\320\267\320\264\320\260\320\265\320\274_\320\267\320\276\320\275\321\203_\320\272\320\270\321\200\320\277\320\270\321\207\320\265\320\271/index.html" delete mode 100644 "files/ru/games/tutorials/2d_breakout_game_pure_javascript/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_canvas_\320\270_\321\200\320\270\321\201\320\276\320\262\320\260\320\275\320\270\320\265_\320\275\320\260_\320\275\321\221\320\274/index.html" delete mode 100644 "files/ru/games/tutorials/2d_breakout_game_pure_javascript/\321\203\320\277\321\200\320\260\320\262\320\273\320\265\320\275\320\270\320\265_\320\274\321\213\321\210\321\214\321\216/index.html" delete mode 100644 "files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/bounce_off_the_walls/index.html" delete mode 100644 "files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/game_over/index.html" delete mode 100644 "files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/index.html" delete mode 100644 "files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/initialize_the_framework/index.html" delete mode 100644 "files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/load_the_assets_and_print_them_on_screen/index.html" delete mode 100644 "files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/move_the_ball/index.html" delete mode 100644 "files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/physics/index.html" delete mode 100644 "files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/scaling/index.html" delete mode 100644 "files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/\320\266\320\270\320\267\320\275\320\270/index.html" delete mode 100644 "files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/\320\276\320\261\321\200\320\260\320\261\320\276\321\202\320\272\320\260_\320\272\320\276\320\273\320\273\320\270\320\267\320\270\320\271/index.html" delete mode 100644 "files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/\320\276\321\207\320\272\320\270/index.html" delete mode 100644 "files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/\320\277\320\273\320\260\321\202\321\204\320\276\321\200\320\274\320\260_\320\270_\321\203\320\277\321\200\320\260\320\262\320\273\320\265\320\275\320\270\320\265/index.html" delete mode 100644 "files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/\320\277\320\276\320\261\320\265\320\264\320\260/index.html" delete mode 100644 "files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\320\272\320\270\321\200\320\277\320\270\321\207\320\265\320\271/index.html" delete mode 100644 "files/ru/games/\320\260\320\275\320\260\321\202\320\276\320\274\320\270\321\217/index.html" delete mode 100644 "files/ru/games/\320\262\320\262\320\276\320\264/index.html" delete mode 100644 "files/ru/games/\320\270\320\275\321\201\321\202\321\200\321\203\320\274\320\265\320\275\321\202\321\213/asm.js/index.html" delete mode 100644 "files/ru/games/\320\270\320\275\321\201\321\202\321\200\321\203\320\274\320\265\320\275\321\202\321\213/index.html" create mode 100644 files/ru/glossary/404/index.html create mode 100644 files/ru/glossary/502/index.html create mode 100644 files/ru/glossary/abstraction/index.html create mode 100644 files/ru/glossary/accessibility/index.html create mode 100644 files/ru/glossary/adobe_flash/index.html create mode 100644 files/ru/glossary/ajax/index.html create mode 100644 files/ru/glossary/algorithm/index.html create mode 100644 files/ru/glossary/api/index.html create mode 100644 files/ru/glossary/apple_safari/index.html create mode 100644 files/ru/glossary/application_context/index.html create mode 100644 files/ru/glossary/argument/index.html create mode 100644 files/ru/glossary/aria/index.html create mode 100644 files/ru/glossary/arpa/index.html create mode 100644 files/ru/glossary/arpanet/index.html create mode 100644 files/ru/glossary/array/index.html create mode 100644 files/ru/glossary/ascii/index.html create mode 100644 files/ru/glossary/asynchronous/index.html create mode 100644 files/ru/glossary/atag/index.html create mode 100644 files/ru/glossary/attribute/index.html create mode 100644 files/ru/glossary/bandwidth/index.html create mode 100644 files/ru/glossary/base64/index.html create mode 100644 files/ru/glossary/baseline/index.html create mode 100644 files/ru/glossary/bidi/index.html create mode 100644 files/ru/glossary/bigint/index.html create mode 100644 files/ru/glossary/blink/index.html create mode 100644 files/ru/glossary/block/scripting/index.html delete mode 100644 "files/ru/glossary/block/\321\201\320\272\321\200\320\270\320\277\321\202\320\270\320\275\320\263/index.html" create mode 100644 files/ru/glossary/boolean/index.html create mode 100644 files/ru/glossary/bootstrap/index.html create mode 100644 files/ru/glossary/browser/index.html create mode 100644 files/ru/glossary/browsing_context/index.html create mode 100644 files/ru/glossary/buffer/index.html create mode 100644 "files/ru/glossary/b\303\251zier_curve/index.html" create mode 100644 files/ru/glossary/cache/index.html create mode 100644 files/ru/glossary/cacheable/index.html create mode 100644 files/ru/glossary/call_stack/index.html create mode 100644 files/ru/glossary/callback_function/index.html create mode 100644 files/ru/glossary/canvas/index.html create mode 100644 files/ru/glossary/card_sorting/index.html create mode 100644 files/ru/glossary/cdn/index.html create mode 100644 files/ru/glossary/certified/index.html create mode 100644 files/ru/glossary/character/index.html create mode 100644 files/ru/glossary/character_encoding/index.html create mode 100644 files/ru/glossary/chrome/index.html create mode 100644 files/ru/glossary/cia/index.html create mode 100644 files/ru/glossary/class/index.html create mode 100644 files/ru/glossary/cms/index.html create mode 100644 files/ru/glossary/codec/index.html create mode 100644 files/ru/glossary/compile/index.html create mode 100644 files/ru/glossary/computer_programming/index.html create mode 100644 files/ru/glossary/conditional/index.html create mode 100644 files/ru/glossary/constant/index.html create mode 100644 files/ru/glossary/constructor/index.html create mode 100644 files/ru/glossary/cookie/index.html create mode 100644 files/ru/glossary/copyleft/index.html create mode 100644 files/ru/glossary/cors/index.html create mode 100644 files/ru/glossary/crawler/index.html create mode 100644 files/ru/glossary/crlf/index.html create mode 100644 files/ru/glossary/csp/index.html create mode 100644 files/ru/glossary/csrf/index.html create mode 100644 files/ru/glossary/css/index.html create mode 100644 files/ru/glossary/css_preprocessor/index.html create mode 100644 files/ru/glossary/css_selector/index.html create mode 100644 files/ru/glossary/data_structure/index.html create mode 100644 files/ru/glossary/decryption/index.html create mode 100644 files/ru/glossary/developer_tools/index.html create mode 100644 files/ru/glossary/dns/index.html create mode 100644 files/ru/glossary/doctype/index.html create mode 100644 files/ru/glossary/dom/index.html create mode 100644 files/ru/glossary/domain/index.html create mode 100644 files/ru/glossary/domain_name/index.html create mode 100644 files/ru/glossary/dos_attack/index.html create mode 100644 files/ru/glossary/dynamic_programming_language/index.html create mode 100644 files/ru/glossary/ecma/index.html create mode 100644 files/ru/glossary/ecmascript/index.html create mode 100644 files/ru/glossary/element/index.html create mode 100644 files/ru/glossary/empty_element/index.html create mode 100644 files/ru/glossary/encapsulation/index.html create mode 100644 files/ru/glossary/entity/index.html create mode 100644 files/ru/glossary/entity_header/index.html create mode 100644 files/ru/glossary/event/index.html create mode 100644 files/ru/glossary/expando/index.html create mode 100644 files/ru/glossary/falsy/index.html create mode 100644 files/ru/glossary/first-class_function/index.html create mode 100644 files/ru/glossary/first_contentful_paint/index.html create mode 100644 files/ru/glossary/first_cpu_idle/index.html create mode 100644 files/ru/glossary/first_input_delay/index.html create mode 100644 files/ru/glossary/first_interactive/index.html create mode 100644 files/ru/glossary/first_meaningful_paint/index.html create mode 100644 files/ru/glossary/first_paint/index.html create mode 100644 files/ru/glossary/flex_item/index.html create mode 100644 files/ru/glossary/flexbox/index.html create mode 100644 files/ru/glossary/forbidden_header_name/index.html create mode 100644 files/ru/glossary/forbidden_response_header_name/index.html create mode 100644 files/ru/glossary/fps/index.html create mode 100644 files/ru/glossary/ftp/index.html create mode 100644 files/ru/glossary/function/index.html create mode 100644 files/ru/glossary/gecko/index.html create mode 100644 files/ru/glossary/general_header/index.html create mode 100644 files/ru/glossary/git/index.html create mode 100644 files/ru/glossary/global_object/index.html create mode 100644 files/ru/glossary/global_variable/index.html create mode 100644 files/ru/glossary/grid/index.html create mode 100644 files/ru/glossary/grid_column/index.html create mode 100644 files/ru/glossary/hash/index.html create mode 100644 files/ru/glossary/head/index.html create mode 100644 files/ru/glossary/high-level_programming_language/index.html create mode 100644 files/ru/glossary/hoisting/index.html create mode 100644 files/ru/glossary/host/index.html create mode 100644 files/ru/glossary/html/index.html create mode 100644 files/ru/glossary/html5/index.html create mode 100644 files/ru/glossary/http/index.html create mode 100644 files/ru/glossary/http_2/index.html create mode 100644 files/ru/glossary/https/index.html create mode 100644 files/ru/glossary/hypertext/index.html create mode 100644 files/ru/glossary/iana/index.html create mode 100644 files/ru/glossary/icann/index.html create mode 100644 files/ru/glossary/idempotent/index.html create mode 100644 files/ru/glossary/identifier/index.html create mode 100644 files/ru/glossary/ietf/index.html create mode 100644 files/ru/glossary/iife/index.html create mode 100644 files/ru/glossary/index.html create mode 100644 files/ru/glossary/indexeddb/index.html create mode 100644 files/ru/glossary/information_architecture/index.html create mode 100644 files/ru/glossary/internet/index.html create mode 100644 files/ru/glossary/ip_address/index.html create mode 100644 files/ru/glossary/iso/index.html create mode 100644 files/ru/glossary/isp/index.html create mode 100644 files/ru/glossary/java/index.html create mode 100644 files/ru/glossary/javascript/index.html create mode 100644 files/ru/glossary/jpeg/index.html create mode 100644 files/ru/glossary/jquery/index.html create mode 100644 files/ru/glossary/json/index.html create mode 100644 files/ru/glossary/loop/index.html create mode 100644 files/ru/glossary/main_axis/index.html create mode 100644 files/ru/glossary/mathml/index.html create mode 100644 files/ru/glossary/metadata/index.html create mode 100644 files/ru/glossary/method/index.html create mode 100644 files/ru/glossary/microsoft_internet_explorer/index.html create mode 100644 files/ru/glossary/mime_type/index.html create mode 100644 files/ru/glossary/mixin/index.html create mode 100644 files/ru/glossary/node.js/index.html create mode 100644 files/ru/glossary/null/index.html create mode 100644 files/ru/glossary/number/index.html create mode 100644 files/ru/glossary/object/index.html create mode 100644 files/ru/glossary/oop/index.html create mode 100644 files/ru/glossary/opengl/index.html create mode 100644 files/ru/glossary/origin/index.html create mode 100644 files/ru/glossary/php/index.html create mode 100644 files/ru/glossary/pixel/index.html delete mode 100644 files/ru/glossary/polifill/index.html create mode 100644 files/ru/glossary/polymorphism/index.html create mode 100644 files/ru/glossary/port/index.html create mode 100644 files/ru/glossary/primitive/index.html create mode 100644 files/ru/glossary/privileged_code/index.html create mode 100644 files/ru/glossary/progressive_web_apps/index.html create mode 100644 files/ru/glossary/promise/index.html create mode 100644 files/ru/glossary/property/index.html create mode 100644 files/ru/glossary/protocol/index.html create mode 100644 files/ru/glossary/prototype-based_programming/index.html create mode 100644 files/ru/glossary/prototype/index.html create mode 100644 files/ru/glossary/proxy_server/index.html create mode 100644 files/ru/glossary/pseudo-element/index.html create mode 100644 files/ru/glossary/pseudocode/index.html create mode 100644 files/ru/glossary/reflow/index.html create mode 100644 files/ru/glossary/regular_expression/index.html create mode 100644 files/ru/glossary/request_header/index.html create mode 100644 files/ru/glossary/responsive_web_design/index.html create mode 100644 files/ru/glossary/round_trip_time_(rtt)/index.html create mode 100644 files/ru/glossary/safe/index.html create mode 100644 files/ru/glossary/scroll_container/index.html create mode 100644 files/ru/glossary/sdp/index.html create mode 100644 files/ru/glossary/self-executing_anonymous_function/index.html create mode 100644 files/ru/glossary/semantics/index.html create mode 100644 files/ru/glossary/seo/index.html create mode 100644 files/ru/glossary/server/index.html create mode 100644 files/ru/glossary/sgml/index.html create mode 100644 files/ru/glossary/simple_header/index.html create mode 100644 files/ru/glossary/simple_response_header/index.html create mode 100644 files/ru/glossary/sloppy_mode/index.html create mode 100644 files/ru/glossary/specification/index.html create mode 100644 files/ru/glossary/speculative_parsing/index.html create mode 100644 files/ru/glossary/statement/index.html create mode 100644 files/ru/glossary/static_typing/index.html create mode 100644 files/ru/glossary/string/index.html create mode 100644 files/ru/glossary/svg/index.html create mode 100644 files/ru/glossary/symbol/index.html create mode 100644 files/ru/glossary/synchronous/index.html create mode 100644 files/ru/glossary/tag/index.html create mode 100644 files/ru/glossary/tcp/index.html create mode 100644 files/ru/glossary/time_to_first_byte/index.html create mode 100644 files/ru/glossary/time_to_interactive/index.html create mode 100644 files/ru/glossary/tls/index.html create mode 100644 files/ru/glossary/truthy/index.html create mode 100644 files/ru/glossary/type/index.html create mode 100644 files/ru/glossary/type_coercion/index.html create mode 100644 files/ru/glossary/type_conversion/index.html create mode 100644 files/ru/glossary/ui/index.html create mode 100644 files/ru/glossary/undefined/index.html create mode 100644 files/ru/glossary/url/index.html create mode 100644 files/ru/glossary/user_agent/index.html create mode 100644 files/ru/glossary/variable/index.html create mode 100644 files/ru/glossary/vendor_prefix/index.html create mode 100644 files/ru/glossary/viewport/index.html create mode 100644 files/ru/glossary/w3c/index.html create mode 100644 files/ru/glossary/wai/index.html create mode 100644 files/ru/glossary/webkit/index.html create mode 100644 files/ru/glossary/websockets/index.html create mode 100644 files/ru/glossary/whatwg/index.html create mode 100644 files/ru/glossary/whitespace/index.html create mode 100644 files/ru/glossary/world_wide_web/index.html create mode 100644 files/ru/glossary/wrapper/index.html create mode 100644 files/ru/glossary/xhr_(xmlhttprequest)/index.html create mode 100644 files/ru/glossary/xhtml/index.html create mode 100644 files/ru/glossary/xml/index.html delete mode 100644 files/ru/html/html5/constraint_validation/index.html delete mode 100644 files/ru/html/html5/index.html delete mode 100644 "files/ru/html/html5/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html5/index.html" delete mode 100644 files/ru/introduction_(alternate)/index.html create mode 100644 files/ru/learn/accessibility/accessibility_troubleshooting/index.html create mode 100644 files/ru/learn/accessibility/css_and_javascript/index.html create mode 100644 files/ru/learn/accessibility/html/index.html create mode 100644 files/ru/learn/accessibility/index.html create mode 100644 files/ru/learn/accessibility/mobile/index.html create mode 100644 files/ru/learn/accessibility/multimedia/index.html create mode 100644 files/ru/learn/accessibility/wai-aria_basics/index.html create mode 100644 files/ru/learn/accessibility/what_is_accessibility/index.html create mode 100644 files/ru/learn/common_questions/how_does_the_internet_work/index.html create mode 100644 files/ru/learn/common_questions/pages_sites_servers_and_search_engines/index.html create mode 100644 files/ru/learn/common_questions/what_are_browser_developer_tools/index.html create mode 100644 files/ru/learn/common_questions/what_are_hyperlinks/index.html create mode 100644 files/ru/learn/common_questions/what_is_a_domain_name/index.html create mode 100644 files/ru/learn/common_questions/what_is_a_url/index.html create mode 100644 files/ru/learn/common_questions/what_is_a_web_server/index.html create mode 100644 files/ru/learn/css/building_blocks/cascade_tasks/index.html create mode 100644 files/ru/learn/css/building_blocks/fundamental_css_comprehension/index.html create mode 100644 files/ru/learn/css/building_blocks/selectors/attribute_selectors/index.html create mode 100644 files/ru/learn/css/building_blocks/selectors/combinators/index.html create mode 100644 files/ru/learn/css/building_blocks/selectors/index.html create mode 100644 files/ru/learn/css/building_blocks/selectors/pseudo-classes_and_pseudo-elements/index.html create mode 100644 files/ru/learn/css/building_blocks/selectors/selectors_tasks/index.html create mode 100644 files/ru/learn/css/building_blocks/selectors/type_class_and_id_selectors/index.html delete mode 100644 "files/ru/learn/css/building_blocks/\320\272\320\260\321\201\320\272\320\260\320\264_\320\267\320\260\320\264\320\260\321\207\320\270/index.html" delete mode 100644 "files/ru/learn/css/building_blocks/\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/attribute_selectors/index.html" delete mode 100644 "files/ru/learn/css/building_blocks/\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/combinators/index.html" delete mode 100644 "files/ru/learn/css/building_blocks/\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/index.html" delete mode 100644 "files/ru/learn/css/building_blocks/\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/pseudo-classes_and_pseudo-elements/index.html" delete mode 100644 "files/ru/learn/css/building_blocks/\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/type_class_and_id_selectors/index.html" delete mode 100644 "files/ru/learn/css/building_blocks/\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213_\320\267\320\260\320\264\320\260\321\207\320\270/index.html" create mode 100644 files/ru/learn/css/css_layout/multicol_skills/index.html create mode 100644 files/ru/learn/css/css_layout/multiple-column_layout/index.html create mode 100644 files/ru/learn/css/css_layout/normal_flow/index.html create mode 100644 files/ru/learn/css/css_layout/position_skills/index.html create mode 100644 files/ru/learn/css/css_layout/responsive_design/index.html delete mode 100644 "files/ru/learn/css/css_layout/\320\274\320\260\320\272\320\265\321\202_\321\201_\320\275\320\265\321\201\320\272\320\276\320\273\321\214\320\272\320\270\320\274\320\270_\321\201\321\202\320\276\320\273\320\261\321\206\320\260\320\274\320\270/index.html" delete mode 100644 "files/ru/learn/css/css_layout/\320\275\320\260\320\262\321\213\320\272\320\270_multicol/index.html" delete mode 100644 "files/ru/learn/css/css_layout/\320\275\320\260\320\262\321\213\320\272\320\270_\320\277\320\276\320\267\320\270\321\206\320\270\320\276\320\275\320\270\321\200\320\276\320\262\320\260\320\275\320\270\321\217/index.html" delete mode 100644 "files/ru/learn/css/css_layout/\320\275\320\276\321\200\320\274\320\260\320\273\321\214\320\275\321\213\320\271_\320\277\320\276\321\202\320\276\320\272/index.html" delete mode 100644 "files/ru/learn/css/css_layout/\320\276\321\202\320\267\321\213\320\262\321\207\320\270\320\262\321\213\320\271_\320\264\320\270\320\267\320\260\320\271\320\275/index.html" delete mode 100644 files/ru/learn/css/css_properties/index.html create mode 100644 files/ru/learn/css/first_steps/how_css_is_structured/index.html create mode 100644 files/ru/learn/css/first_steps/what_is_css/index.html delete mode 100644 "files/ru/learn/css/first_steps/\320\272\320\260\320\272_\321\201\321\202\321\200\321\203\320\272\321\202\321\203\321\200\320\270\321\200\320\276\320\262\320\260\320\275_css/index.html" delete mode 100644 "files/ru/learn/css/first_steps/\321\207\321\202\320\276_\321\202\320\260\320\272\320\276\320\265_css/index.html" create mode 100644 files/ru/learn/css/howto/css_faq/index.html create mode 100644 files/ru/learn/css/howto/index.html delete mode 100644 files/ru/learn/css/introduction_to_css/ponimanie_osnov_css/index.html create mode 100644 files/ru/learn/css/styling_text/styling_lists/index.html create mode 100644 files/ru/learn/css/styling_text/typesetting_a_homepage/index.html create mode 100644 files/ru/learn/css/styling_text/web_fonts/index.html delete mode 100644 "files/ru/learn/css/styling_text/\320\262\320\265\320\261_\321\210\321\200\320\270\321\204\321\202\321\213/index.html" delete mode 100644 "files/ru/learn/css/styling_text/\320\267\320\260\320\264\320\260\320\275\320\270\320\265_colon__\321\201\321\202\320\270\320\273\320\270\320\267\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265_\321\210\320\272\320\276\320\273\321\214\320\275\320\276\320\263\320\276_\321\201\320\260\320\271\321\202\320\260/index.html" delete mode 100644 "files/ru/learn/css/styling_text/\321\201\321\202\320\270\320\273\320\270\320\267\320\260\321\206\320\270\321\217_\321\201\320\277\320\270\321\201\320\272\320\276\320\262/index.html" delete mode 100644 "files/ru/learn/css/\320\272\320\260\320\272/index.html" delete mode 100644 files/ru/learn/discover_browser_developer_tools/index.html create mode 100644 files/ru/learn/forms/basic_native_form_controls/index.html create mode 100644 files/ru/learn/forms/form_validation/index.html create mode 100644 files/ru/learn/forms/how_to_build_custom_form_controls/index.html create mode 100644 files/ru/learn/forms/how_to_structure_a_web_form/index.html create mode 100644 files/ru/learn/forms/index.html create mode 100644 files/ru/learn/forms/sending_and_retrieving_form_data/index.html create mode 100644 files/ru/learn/forms/sending_forms_through_javascript/index.html create mode 100644 files/ru/learn/forms/styling_web_forms/index.html create mode 100644 files/ru/learn/forms/your_first_form/index.html create mode 100644 files/ru/learn/front-end_web_developer/index.html create mode 100644 files/ru/learn/getting_started_with_the_web/installing_basic_software/index.html create mode 100644 files/ru/learn/getting_started_with_the_web/the_web_and_web_standards/index.html delete mode 100644 "files/ru/learn/getting_started_with_the_web/\320\262\320\265\320\261_\320\270_\320\262\320\265\320\261_\321\201\321\202\320\260\320\275\320\264\320\260\321\200\321\202\321\213/index.html" delete mode 100644 "files/ru/learn/getting_started_with_the_web/\321\203\321\201\321\202\320\260\320\275\320\276\320\262\320\272\320\260_\320\261\320\260\320\267\320\276\320\262\320\276\320\263\320\276_\320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\275\320\276\320\263\320\276_\320\276\320\261\320\265\321\201\320\277\320\265\321\207\320\265\320\275\320\270\321\217/index.html" delete mode 100644 files/ru/learn/how_the_internet_works/index.html delete mode 100644 files/ru/learn/html/forms/how_to_build_custom_form_widgets/index.html delete mode 100644 files/ru/learn/html/forms/how_to_structure_an_html_form/index.html delete mode 100644 files/ru/learn/html/forms/index.html delete mode 100644 files/ru/learn/html/forms/sending_forms_through_javascript/index.html delete mode 100644 files/ru/learn/html/forms/styling_html_forms/index.html delete mode 100644 "files/ru/learn/html/forms/\320\262\320\260\320\273\320\270\320\264\320\260\321\206\320\270\321\217_\321\204\320\276\321\200\320\274\321\213/index.html" delete mode 100644 "files/ru/learn/html/forms/\320\262\320\260\321\210\320\260_\320\277\320\265\321\200\320\262\320\260\321\217_html_\321\204\320\276\321\200\320\274\320\260/index.html" delete mode 100644 "files/ru/learn/html/forms/\320\276\321\202\320\277\321\200\320\260\320\262\320\272\320\260_\320\270_\320\277\320\276\320\273\321\203\321\207\320\265\320\275\320\270\320\265_\320\264\320\260\320\275\320\275\321\213\321\205_\321\204\320\276\321\200\320\274\321\213/index.html" delete mode 100644 "files/ru/learn/html/forms/\321\201\321\202\320\260\320\275\320\264\320\260\321\200\321\202\320\275\321\213\320\265_\320\262\320\270\320\264\320\266\320\265\321\202\321\213_\321\204\320\276\321\200\320\274/index.html" create mode 100644 files/ru/learn/html/howto/author_fast-loading_html_pages/index.html create mode 100644 files/ru/learn/html/howto/index.html create mode 100644 files/ru/learn/html/howto/use_data_attributes/index.html create mode 100644 files/ru/learn/html/introduction_to_html/advanced_text_formatting/index.html create mode 100644 files/ru/learn/html/introduction_to_html/creating_hyperlinks/index.html create mode 100644 files/ru/learn/html/introduction_to_html/debugging_html/index.html create mode 100644 files/ru/learn/html/introduction_to_html/document_and_website_structure/index.html create mode 100644 files/ru/learn/html/introduction_to_html/getting_started/index.html create mode 100644 files/ru/learn/html/introduction_to_html/html_text_fundamentals/index.html create mode 100644 files/ru/learn/html/introduction_to_html/index.html create mode 100644 files/ru/learn/html/introduction_to_html/marking_up_a_letter/index.html create mode 100644 files/ru/learn/html/introduction_to_html/structuring_a_page_of_content/index.html create mode 100644 files/ru/learn/html/introduction_to_html/the_head_metadata_in_html/index.html create mode 100644 files/ru/learn/html/multimedia_and_embedding/adding_vector_graphics_to_the_web/index.html create mode 100644 files/ru/learn/html/multimedia_and_embedding/images_in_html/index.html create mode 100644 files/ru/learn/html/multimedia_and_embedding/images_in_html/test_your_skills_colon__html_images/index.html create mode 100644 files/ru/learn/html/multimedia_and_embedding/mozilla_splash_page/index.html delete mode 100644 "files/ru/learn/html/multimedia_and_embedding/\320\264\320\276\320\261\320\260\320\262\320\273\320\265\320\275\320\270\320\265_r_graphics_to_the_web/index.html" delete mode 100644 "files/ru/learn/html/multimedia_and_embedding/\320\267\320\260\321\201\321\202\320\260\320\262\320\272\320\260_mozilla/index.html" delete mode 100644 "files/ru/learn/html/multimedia_and_embedding/\320\270\320\267\320\276\320\261\321\200\320\260\320\266\320\265\320\275\320\270\321\217_\320\262_html/index.html" delete mode 100644 "files/ru/learn/html/multimedia_and_embedding/\320\270\320\267\320\276\320\261\321\200\320\260\320\266\320\265\320\275\320\270\321\217_\320\262_html/\320\277\321\200\320\276\320\262\320\265\321\200\321\214\321\202\320\265_\321\201\320\262\320\276\320\270_\320\267\320\275\320\260\320\275\320\270\321\217_colon__\320\270\320\267\320\276\320\261\321\200\320\260\320\266\320\265\320\275\320\270\321\217_\320\262_html/index.html" delete mode 100644 "files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/advanced_text_formatting/index.html" delete mode 100644 "files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/debugging_html/index.html" delete mode 100644 "files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/html_text_fundamentals/index.html" delete mode 100644 "files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/index.html" delete mode 100644 "files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/marking_up_a_letter/index.html" delete mode 100644 "files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/structuring_a_page_of_content/index.html" delete mode 100644 "files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/the_head_metadata_in_html/index.html" delete mode 100644 "files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/\320\275\320\260\321\207\320\260\320\273\320\276_\321\200\320\260\320\261\320\276\321\202\321\213/index.html" delete mode 100644 "files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\320\263\320\270\320\277\320\265\321\200\321\201\321\201\321\213\320\273\320\276\320\272/index.html" delete mode 100644 "files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/\321\201\321\202\321\200\321\203\320\272\321\202\321\203\321\200\320\260_\320\264\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\260_\320\270_\320\262\320\265\320\261-\321\201\320\260\320\271\321\202\320\260/index.html" delete mode 100644 "files/ru/learn/html/\321\200\320\265\321\206\320\265\320\277\321\202\321\213/index.html" create mode 100644 files/ru/learn/javascript/asynchronous/timeouts_and_intervals/index.html delete mode 100644 "files/ru/learn/javascript/asynchronous/\321\202\320\260\320\271\320\274\320\260\321\203\321\202\321\213_\320\270_\320\270\320\275\321\202\320\265\321\200\320\262\320\260\320\273\321\213/index.html" create mode 100644 files/ru/learn/javascript/building_blocks/events/index.html delete mode 100644 "files/ru/learn/javascript/building_blocks/\321\201\320\276\320\261\321\213\321\202\320\270\321\217/index.html" create mode 100644 files/ru/learn/javascript/first_steps/a_first_splash/index.html create mode 100644 files/ru/learn/javascript/first_steps/arrays/index.html create mode 100644 files/ru/learn/javascript/first_steps/index.html create mode 100644 files/ru/learn/javascript/first_steps/math/index.html create mode 100644 files/ru/learn/javascript/first_steps/silly_story_generator/index.html create mode 100644 files/ru/learn/javascript/first_steps/strings/index.html create mode 100644 files/ru/learn/javascript/first_steps/useful_string_methods/index.html create mode 100644 files/ru/learn/javascript/first_steps/variables/index.html create mode 100644 files/ru/learn/javascript/first_steps/what_is_javascript/index.html create mode 100644 files/ru/learn/javascript/first_steps/what_went_wrong/index.html create mode 100644 files/ru/learn/javascript/objects/adding_bouncing_balls_features/index.html create mode 100644 files/ru/learn/javascript/objects/basics/index.html create mode 100644 files/ru/learn/javascript/objects/index.html create mode 100644 files/ru/learn/javascript/objects/inheritance/index.html create mode 100644 files/ru/learn/javascript/objects/json/index.html create mode 100644 files/ru/learn/javascript/objects/object-oriented_js/index.html create mode 100644 files/ru/learn/javascript/objects/object_building_practice/index.html create mode 100644 files/ru/learn/javascript/objects/object_prototypes/index.html delete mode 100644 "files/ru/learn/javascript/\320\276\320\261\321\212\320\265\320\272\321\202\321\213/adding_bouncing_balls_features/index.html" delete mode 100644 "files/ru/learn/javascript/\320\276\320\261\321\212\320\265\320\272\321\202\321\213/index.html" delete mode 100644 "files/ru/learn/javascript/\320\276\320\261\321\212\320\265\320\272\321\202\321\213/inheritance/index.html" delete mode 100644 "files/ru/learn/javascript/\320\276\320\261\321\212\320\265\320\272\321\202\321\213/json/index.html" delete mode 100644 "files/ru/learn/javascript/\320\276\320\261\321\212\320\265\320\272\321\202\321\213/object-oriented_js/index.html" delete mode 100644 "files/ru/learn/javascript/\320\276\320\261\321\212\320\265\320\272\321\202\321\213/object_building_practice/index.html" delete mode 100644 "files/ru/learn/javascript/\320\276\320\261\321\212\320\265\320\272\321\202\321\213/object_prototypes/index.html" delete mode 100644 "files/ru/learn/javascript/\320\276\320\261\321\212\320\265\320\272\321\202\321\213/\320\276\321\201\320\275\320\276\320\262\321\213/index.html" delete mode 100644 "files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/a_first_splash/index.html" delete mode 100644 "files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/arrays/index.html" delete mode 100644 "files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/index.html" delete mode 100644 "files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/math/index.html" delete mode 100644 "files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/useful_string_methods/index.html" delete mode 100644 "files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/variables/index.html" delete mode 100644 "files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/what_is_javascript/index.html" delete mode 100644 "files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/\321\201\320\276\320\267\320\264\320\260\321\202\320\265\320\273\321\214_\320\263\320\273\321\203\321\213\321\205_\320\270\321\201\321\202\320\276\321\200\320\270\320\271/index.html" delete mode 100644 "files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/\321\201\321\202\321\200\320\276\320\272\320\270/index.html" delete mode 100644 "files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/\321\207\321\202\320\276_\320\277\320\276\321\210\320\273\320\276_\320\275\320\265_\321\202\320\260\320\272/index.html" delete mode 100644 files/ru/learn/pages_sites_servers_and_search_engines/index.html create mode 100644 files/ru/learn/server-side/django/authentication/index.html create mode 100644 files/ru/learn/server-side/django/deployment/index.html create mode 100644 files/ru/learn/server-side/django/introduction/index.html create mode 100644 files/ru/learn/server-side/django/sessions/index.html delete mode 100644 "files/ru/learn/server-side/django/\320\260\321\203\321\202\320\265\320\275\321\202\320\270\321\204\320\270\320\272\320\260\321\206\320\270\321\217/index.html" delete mode 100644 "files/ru/learn/server-side/django/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265/index.html" delete mode 100644 "files/ru/learn/server-side/django/\321\200\320\260\320\267\320\262\320\276\321\200\320\260\321\207\320\270\320\262\320\260\320\275\320\270\320\265/index.html" delete mode 100644 "files/ru/learn/server-side/django/\321\201\320\265\321\201\321\201\320\270\320\270/index.html" create mode 100644 files/ru/learn/server-side/express_nodejs/tutorial_local_library_website/index.html delete mode 100644 "files/ru/learn/server-side/express_nodejs/\321\203\321\207\320\265\320\261\320\275\320\270\320\272_\321\201\320\260\320\271\321\202_local_library/index.html" create mode 100644 files/ru/learn/server-side/first_steps/website_security/index.html delete mode 100644 "files/ru/learn/server-side/first_steps/\320\262\320\265\320\261_\320\261\320\265\320\267\320\276\320\277\320\260\321\201\320\275\320\276\321\201\321\202\321\214/index.html" create mode 100644 files/ru/learn/tools_and_testing/client-side_javascript_frameworks/index.html create mode 100644 files/ru/learn/tools_and_testing/client-side_javascript_frameworks/react_getting_started/index.html create mode 100644 files/ru/learn/tools_and_testing/github/index.html delete mode 100644 "files/ru/learn/tools_and_testing/\320\263\320\270\321\202\321\205\320\260\320\261/index.html" delete mode 100644 "files/ru/learn/tools_and_testing/\321\204\321\200\320\276\320\275\321\202\320\265\320\275\320\264_javascript_\321\204\321\200\320\265\320\271\320\274\320\262\320\276\321\200\320\272\320\270/index.html" delete mode 100644 "files/ru/learn/tools_and_testing/\321\204\321\200\320\276\320\275\321\202\320\265\320\275\320\264_javascript_\321\204\321\200\320\265\320\271\320\274\320\262\320\276\321\200\320\272\320\270/react_getting_started/index.html" delete mode 100644 files/ru/learn/understanding_domain_names/index.html delete mode 100644 files/ru/learn/understanding_links_on_the_web/index.html delete mode 100644 files/ru/learn/understanding_urls/index.html delete mode 100644 "files/ru/learn/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/accessibility_troubleshooting/index.html" delete mode 100644 "files/ru/learn/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/css_and_javascript/index.html" delete mode 100644 "files/ru/learn/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/html/index.html" delete mode 100644 "files/ru/learn/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/index.html" delete mode 100644 "files/ru/learn/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/mobile/index.html" delete mode 100644 "files/ru/learn/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/multimedia/index.html" delete mode 100644 "files/ru/learn/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/wai-aria_basics/index.html" delete mode 100644 "files/ru/learn/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/what_is_accessibility/index.html" delete mode 100644 "files/ru/learn/\320\272\320\260\320\272_\321\201\320\264\320\265\320\273\320\260\321\202\321\214_\320\262\320\272\320\273\320\260\320\264/index.html" delete mode 100644 "files/ru/learn/\321\204\321\200\320\276\320\275\321\202\320\265\320\275\320\264_\321\200\320\260\320\267\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272/index.html" delete mode 100644 "files/ru/learn/\321\207\321\202\320\276_\321\202\320\260\320\272\320\276\320\265_\320\262\320\265\320\261_\321\201\320\265\321\200\320\262\320\265\321\200/index.html" create mode 100644 files/ru/mdn/at_ten/index.html delete mode 100644 files/ru/mdn/contribute/creating_and_editing_pages/index.html create mode 100644 files/ru/mdn/contribute/howto/add_or_update_browser_compatibility_data/index.html create mode 100644 files/ru/mdn/contribute/howto/create_an_interactive_exercise_to_help_learning_the_web/index.html delete mode 100644 files/ru/mdn/contribute/howto/create_an_mdn_account/index.html create mode 100644 files/ru/mdn/contribute/howto/create_and_edit_pages/index.html delete mode 100644 files/ru/mdn/contribute/howto/do_a_technical_review/index.html delete mode 100644 files/ru/mdn/contribute/howto/do_an_editorial_review/index.html delete mode 100644 "files/ru/mdn/contribute/howto/\320\264\320\276\320\261\320\260\320\262\320\270\321\202\321\214_\320\270\320\273\320\270_\320\276\320\261\320\275\320\276\320\262\320\270\321\202\321\214_\320\264\320\260\320\275\320\275\321\213\320\265_\320\276_\320\261\321\200\320\260\321\203\320\267\320\265\321\200\320\275\320\276\320\271_\321\201\320\276\320\262\320\274\320\265\321\201\321\202\320\270\320\274\320\276\321\201\321\202\320\270/index.html" delete mode 100644 "files/ru/mdn/contribute/howto/\320\272\320\260\320\272_\320\276\320\277\321\202\320\270\320\274\320\270\320\267\320\270\321\200\320\276\320\262\320\260\321\202\321\214_\321\201\321\202\321\200\320\260\320\275\320\270\321\206\321\213/index.html" delete mode 100644 "files/ru/mdn/contribute/howto/\320\274\320\265\321\202\320\272\320\270_javascript_\321\201\321\202\321\200\320\260\320\275\320\270\321\206/index.html" delete mode 100644 "files/ru/mdn/contribute/howto/\321\201\320\276\320\267\320\264\320\260\320\271_\320\270\320\275\321\202\320\265\321\200\320\260\320\272\321\202\320\270\320\262\320\275\320\276\320\265_\321\203\320\277\321\200\320\260\320\266\320\275\320\265\320\275\320\270\320\265_\320\264\320\273\321\217_\320\277\320\276\320\274\320\276\321\211\320\270_\320\262_\320\270\320\267\321\203\321\207\320\265\320\275\320\270\320\270_\320\262\320\265\320\261\320\260/index.html" create mode 100644 files/ru/mdn/contribute/processes/index.html delete mode 100644 "files/ru/mdn/contribute/\320\277\321\200\320\276\321\206\320\265\321\201\321\201\321\213/index.html" delete mode 100644 files/ru/mdn/editor/basics/index.html delete mode 100644 files/ru/mdn/editor/basics/page_controls/index.html delete mode 100644 files/ru/mdn/editor/basics/toolbar/index.html delete mode 100644 files/ru/mdn/editor/index.html delete mode 100644 files/ru/mdn/editor/source_mode/index.html delete mode 100644 files/ru/mdn/editor/tables/index.html delete mode 100644 "files/ru/mdn/editor/\320\263\320\276\321\200\321\217\321\207\320\270\320\265_\320\272\320\273\320\260\320\262\320\270\321\210\320\270/index.html" delete mode 100644 "files/ru/mdn/editor/\320\272\320\260\321\200\321\202\320\270\320\275\320\272\320\270/index.html" delete mode 100644 "files/ru/mdn/editor/\320\277\320\265\321\200\320\265\320\275\320\260\320\277\321\200\320\260\320\262\320\273\320\265\320\275\320\270\320\265/index.html" delete mode 100644 "files/ru/mdn/editor/\321\201\320\270\320\275\321\202\320\260\320\272\321\201\320\270\321\207\320\265\321\201\320\272\320\270\320\265_\320\262\321\213\320\264\320\265\320\273\320\265\320\275\320\270\321\217/index.html" delete mode 100644 "files/ru/mdn/editor/\321\201\321\201\321\213\320\273\320\272\320\270/index.html" delete mode 100644 files/ru/mdn/kuma/index.html delete mode 100644 files/ru/mdn/kuma/troubleshooting_kumascript_errors/index.html delete mode 100644 files/ru/mdn/structures/live_samples/simple_live_sample_demo/index.html create mode 100644 files/ru/mdn/tools/kumascript/troubleshooting/index.html delete mode 100644 files/ru/mdn/tools/page_watching/index.html create mode 100644 files/ru/mdn/tools/search/index.html create mode 100644 files/ru/mdn/tools/unsupported_get_api/index.html delete mode 100644 files/ru/mdn/tools/url-suffix/index.html delete mode 100644 files/ru/mdn/user_guide/advanced_search/index.html delete mode 100644 files/ru/mdn/user_guide/deleting_pages/index.html delete mode 100644 files/ru/mdn/user_guide/feeds/index.html delete mode 100644 files/ru/mdn/user_guide/index.html delete mode 100644 files/ru/mdn/user_guide/linking_to_mdn/index.html create mode 100644 files/ru/mdn/yari/index.html delete mode 100644 "files/ru/mdn/\321\201\320\276\320\276\320\261\321\211\320\265\321\201\321\202\320\262\320\276/conversations/index.html" delete mode 100644 "files/ru/mdn/\321\201\320\276\320\276\320\261\321\211\320\265\321\201\321\202\320\262\320\276/index.html" delete mode 100644 "files/ru/mdn/\321\201\320\276\320\276\320\261\321\211\320\265\321\201\321\202\320\262\320\276/whats_happening/index.html" delete mode 100644 "files/ru/mdn/\321\201\320\276\320\276\320\261\321\211\320\265\321\201\321\202\320\262\320\276/working_in_community/index.html" delete mode 100644 files/ru/mdn_at_ten/contributing_to_mdn/index.html delete mode 100644 files/ru/mdn_at_ten/index.html create mode 100644 files/ru/mozilla/add-ons/webextensions/internationalization/index.html create mode 100644 files/ru/mozilla/add-ons/webextensions/modify_a_web_page/index.html delete mode 100644 "files/ru/mozilla/add-ons/webextensions/\320\270\320\275\321\202\320\265\321\200\320\275\320\260\321\206\320\270\320\276\320\275\320\260\320\273\320\270\320\267\320\260\321\206\320\270\321\217/index.html" delete mode 100644 "files/ru/mozilla/add-ons/webextensions/\320\274\320\276\320\264\320\270\321\204\320\270\320\272\320\260\321\206\320\270\321\217_\320\262\320\265\320\261_\321\201\321\202\321\200\320\260\320\275\320\270\321\206\321\213/index.html" delete mode 100644 "files/ru/mozilla/add-ons/webextensions/\320\277\320\265\321\200\320\265\320\262\320\276\320\264/index.html" create mode 100644 files/ru/mozilla/developer_guide/introduction/index.html create mode 100644 files/ru/mozilla/developer_guide/source_code/index.html delete mode 100644 "files/ru/mozilla/developer_guide/\320\270\321\201\321\205\320\276\320\264\320\275\321\213\320\271_\320\272\320\276\320\264/index.html" create mode 100644 files/ru/mozilla/firefox/releases/1.5/using_firefox_1.5_caching/index.html create mode 100644 files/ru/mozilla/firefox/releases/3.5/index.html create mode 100644 files/ru/mozilla/firefox/releases/3/index.html create mode 100644 files/ru/orphaned/glossary/polifill/index.html create mode 100644 files/ru/orphaned/learn/how_to_contribute/index.html create mode 100644 files/ru/orphaned/learn/html/forms/html5_updates/index.html create mode 100644 files/ru/orphaned/mdn/about/linking_to_mdn/index.html create mode 100644 files/ru/orphaned/mdn/community/conversations/index.html create mode 100644 files/ru/orphaned/mdn/community/index.html create mode 100644 files/ru/orphaned/mdn/community/whats_happening/index.html create mode 100644 files/ru/orphaned/mdn/community/working_in_community/index.html create mode 100644 files/ru/orphaned/mdn/contribute/howto/create_an_mdn_account/index.html create mode 100644 files/ru/orphaned/mdn/contribute/howto/do_a_technical_review/index.html create mode 100644 files/ru/orphaned/mdn/contribute/howto/do_an_editorial_review/index.html create mode 100644 files/ru/orphaned/mdn/contribute/howto/set_the_summary_for_a_page/index.html create mode 100644 files/ru/orphaned/mdn/contribute/howto/tag_javascript_pages/index.html create mode 100644 files/ru/orphaned/mdn/editor/basics/index.html create mode 100644 files/ru/orphaned/mdn/editor/basics/page_controls/index.html create mode 100644 files/ru/orphaned/mdn/editor/basics/toolbar/index.html create mode 100644 files/ru/orphaned/mdn/editor/images/index.html create mode 100644 files/ru/orphaned/mdn/editor/index.html create mode 100644 files/ru/orphaned/mdn/editor/keyboard_shortcuts/index.html create mode 100644 files/ru/orphaned/mdn/editor/links/index.html create mode 100644 files/ru/orphaned/mdn/editor/redirects/index.html create mode 100644 files/ru/orphaned/mdn/editor/source_mode/index.html create mode 100644 files/ru/orphaned/mdn/editor/syntax_highlighting/index.html create mode 100644 files/ru/orphaned/mdn/editor/tables/index.html create mode 100644 files/ru/orphaned/mdn/structures/live_samples/simple_live_sample_demo/index.html create mode 100644 files/ru/orphaned/mdn/tools/feeds/index.html create mode 100644 files/ru/orphaned/mdn/tools/page_deletion/index.html create mode 100644 files/ru/orphaned/mdn/tools/page_watching/index.html create mode 100644 files/ru/orphaned/mozilla/add-ons/webextensions/debugging/index.html create mode 100644 files/ru/orphaned/toolkit_api/index.html create mode 100644 files/ru/orphaned/tools/add-ons/dom_inspector/index.html create mode 100644 files/ru/orphaned/tools/add-ons/index.html create mode 100644 files/ru/orphaned/web/api/web_crypto_api/checking_authenticity_with_password/index.html create mode 100644 "files/ru/orphaned/web/guide/ajax/\321\201_\321\207\320\265\320\263\320\276_\320\275\320\260\321\207\320\260\321\202\321\214_question_/index.html" create mode 100644 files/ru/orphaned/web/html/element/element/index.html create mode 100644 files/ru/orphaned/web/html/global_attributes/dropzone/index.html create mode 100644 "files/ru/orphaned/web/javascript/guide/\320\276\320\261_\321\215\321\202\320\276\320\274_\321\200\321\203\320\272\320\276\320\262\320\276\320\264\321\201\321\202\320\262\320\265/index.html" create mode 100644 files/ru/orphaned/web/javascript/reference/global_objects/array/prototype/index.html create mode 100644 files/ru/orphaned/web/javascript/reference/global_objects/asyncfunction/prototype/index.html create mode 100644 "files/ru/orphaned/web/javascript/reference/global_objects/math/\320\274\320\265\321\202\320\276\320\264_math.max()_/index.html" create mode 100644 files/ru/orphaned/web/manifest/serviceworker/index.html create mode 100644 files/ru/orphaned/web/security/information_security_basics/index.html create mode 100644 files/ru/orphaned/web/svg/attribute/onload/index.html create mode 100644 files/ru/orphaned/xml_in_mozilla/index.html create mode 100644 files/ru/orphaned/xpcnativewrapper/index.html create mode 100644 files/ru/orphaned/xpcom/index.html create mode 100644 "files/ru/orphaned/\320\262\320\265\320\261-\321\201\321\202\320\260\320\275\320\264\320\260\321\200\321\202\321\213/index.html" create mode 100644 "files/ru/orphaned/\320\262\320\276\320\277\321\200\320\276\321\201\321\213_\320\261\320\265\320\267_\320\276\321\202\320\262\320\265\321\202\320\276\320\262/index.html" create mode 100644 "files/ru/orphaned/\320\264\320\270\320\275\320\260\320\274\320\270\321\207\320\265\321\201\320\272\320\270_\320\270\320\267\320\274\320\265\320\275\321\217\320\265\320\274\321\213\320\271_\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\214\321\201\320\272\320\270\320\271_\320\270\320\275\321\202\320\265\321\200\321\204\320\265\320\271\321\201_\320\275\320\260_xul/index.html" create mode 100644 "files/ru/orphaned/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/index.html" create mode 100644 "files/ru/orphaned/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\276\320\272_\321\201\321\201\321\213\320\273\320\272\320\270/index.html" create mode 100644 "files/ru/orphaned/\320\272\320\276\320\275\321\202\321\200\320\276\320\273\321\214_\320\272\320\260\321\207\320\265\321\201\321\202\320\262\320\260/index.html" create mode 100644 "files/ru/orphaned/\320\273\320\276\320\272\320\260\320\273\320\270\320\267\320\260\321\206\320\270\321\217/index.html" create mode 100644 "files/ru/orphaned/\320\275\320\260\321\201\321\202\321\200\320\276\320\271\320\272\320\260_\321\201\321\200\320\265\320\264\321\213_\321\200\320\260\320\267\321\200\320\260\320\261\320\276\321\202\320\272\320\270_\321\200\320\260\321\201\321\210\320\270\321\200\320\265\320\275\320\270\320\271/index.html" create mode 100644 "files/ru/orphaned/\320\277\320\265\321\200\320\265\321\205\320\276\320\264_\321\201_internet_explorer_\320\275\320\260_mozilla/index.html" create mode 100644 "files/ru/orphaned/\321\201\320\261\320\276\321\200\320\272\320\260_\320\270_\321\203\321\201\321\202\320\260\320\275\320\276\320\262\320\272\320\260/index.html" create mode 100644 "files/ru/orphaned/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\321\200\320\260\321\201\321\210\320\270\321\200\320\265\320\275\320\270\321\217/index.html" create mode 100644 "files/ru/orphaned/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\321\200\320\260\321\201\321\210\320\270\321\200\320\265\320\275\320\270\321\217/\320\275\320\260\321\201\321\202\321\200\320\276\320\271\320\272\320\260_firefox_\320\264\320\273\321\217_\321\200\320\260\320\267\321\200\320\260\320\261\320\276\321\202\320\272\320\270/index.html" create mode 100644 "files/ru/orphaned/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\321\200\320\260\321\201\321\210\320\270\321\200\320\265\320\275\320\270\321\217/\320\275\320\260\321\201\321\202\321\200\320\276\320\271\320\272\320\260_firefox_\320\264\320\273\321\217_\321\200\320\260\320\267\321\200\320\260\320\261\320\276\321\202\320\272\320\270_\321\200\320\260\321\201\321\210\320\270\321\200\320\265\320\275\320\270\320\271/index.html" create mode 100644 "files/ru/orphaned/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\321\200\320\260\321\201\321\210\320\270\321\200\320\265\320\275\320\270\321\217_\320\264\320\273\321\217_firefox_\321\201_\320\270\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265\320\274_mozilla_build_system/index.html" create mode 100644 "files/ru/orphaned/\321\201\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\260\321\217_\320\270\320\275\321\204\320\276\321\200\320\274\320\260\321\206\320\270\321\217_\320\277\320\276_gecko_dom/index.html" create mode 100644 "files/ru/orphaned/\321\201\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\260\321\217_\320\270\320\275\321\204\320\276\321\200\320\274\320\260\321\206\320\270\321\217_\320\277\320\276_gecko_dom/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265/index.html" create mode 100644 "files/ru/orphaned/\321\201\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\260\321\217_\320\270\320\275\321\204\320\276\321\200\320\274\320\260\321\206\320\270\321\217_\320\277\320\276_gecko_dom/\320\277\321\200\320\265\320\264\320\270\321\201\320\273\320\276\320\262\320\270\320\265/index.html" create mode 100644 "files/ru/orphaned/\321\201\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\260\321\217_\320\270\320\275\321\204\320\276\321\200\320\274\320\260\321\206\320\270\321\217_\320\277\320\276_gecko_dom/\320\277\321\200\320\270\320\274\320\265\321\200\321\213/index.html" create mode 100644 "files/ru/orphaned/\321\202\320\265\320\274\321\213/index.html" create mode 100644 files/ru/plugins/roadmap/index.html delete mode 100644 "files/ru/plugins/\320\277\320\273\320\260\320\275/index.html" delete mode 100644 files/ru/toolkit_api/index.html create mode 100644 files/ru/tools/accessibility_inspector/index.html delete mode 100644 files/ru/tools/add-ons/dom_inspector/index.html delete mode 100644 files/ru/tools/add-ons/index.html create mode 100644 files/ru/tools/browser_console/index.html create mode 100644 files/ru/tools/debugger/how_to/debug_eval_sources/index.html create mode 100644 files/ru/tools/debugger/how_to/pretty-print_a_minified_file/index.html delete mode 100644 "files/ru/tools/debugger/how_to/\320\276\321\202\320\273\320\260\320\264\320\272\320\260_\320\272\320\276\320\264\320\260_\320\262\320\275\321\203\321\202\321\200\320\270_eval/index.html" delete mode 100644 "files/ru/tools/debugger/how_to/\321\200\320\260\320\261\320\276\321\202\320\260_\321\201_\320\274\320\270\320\275\320\270\321\204\320\270\321\206\320\270\321\200\320\276\320\262\320\260\320\275\320\275\321\213\320\274_\320\272\320\276\320\264\320\276\320\274/index.html" create mode 100644 files/ru/tools/page_inspector/how_to/edit_fonts/index.html create mode 100644 files/ru/tools/page_inspector/how_to/examine_event_listeners/index.html create mode 100644 files/ru/tools/page_inspector/how_to/open_the_inspector/index.html delete mode 100644 files/ru/tools/page_inspector/how_to/otkrytie_inspektora/index.html create mode 100644 files/ru/tools/page_inspector/how_to/select_an_element/index.html delete mode 100644 files/ru/tools/page_inspector/how_to/vybor_elementa/index.html delete mode 100644 "files/ru/tools/page_inspector/how_to/\320\270\321\201\321\201\320\273\320\265\320\264\320\276\320\262\320\260\321\202\321\214_event_listeners/index.html" delete mode 100644 "files/ru/tools/page_inspector/how_to/\320\277\321\200\320\276\321\201\320\274\320\276\321\202\321\200_\321\210\321\200\320\270\321\204\321\202\320\276\320\262/index.html" create mode 100644 files/ru/tools/page_inspector/keyboard_shortcuts/index.html delete mode 100644 "files/ru/tools/page_inspector/\321\201\320\276\321\207\320\265\321\202\320\260\320\275\320\270\321\217_\320\272\320\273\320\260\320\262\320\270\321\210/index.html" create mode 100644 files/ru/tools/performance/index.html create mode 100644 files/ru/tools/performance/waterfall/index.html delete mode 100644 files/ru/tools/profiler/index.html delete mode 100644 files/ru/tools/release_notes/index.html create mode 100644 files/ru/tools/responsive_design_mode/index.html delete mode 100644 files/ru/tools/responsive_design_view/index.html create mode 100644 files/ru/tools/rulers/index.html delete mode 100644 files/ru/tools/web_console/opening_the_web_console/index.html create mode 100644 files/ru/tools/web_console/ui_tour/index.html delete mode 100644 "files/ru/tools/\320\270\320\275\321\201\320\277\320\265\320\272\321\202\320\276\321\200_\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\320\270/index.html" delete mode 100644 "files/ru/tools/\320\272\320\276\320\275\321\201\320\276\320\273\321\214_\320\261\321\200\320\260\321\203\320\267\320\265\321\200\320\260/index.html" delete mode 100644 "files/ru/tools/\320\273\320\270\320\275\320\265\320\271\320\272\320\270/index.html" delete mode 100644 "files/ru/tools/\320\277\321\200\320\276\320\270\320\267\320\262\320\276\320\264\320\270\321\202\320\265\320\273\321\214\320\275\320\276\321\201\321\202\321\214/index.html" delete mode 100644 "files/ru/tools/\320\277\321\200\320\276\320\270\320\267\320\262\320\276\320\264\320\270\321\202\320\265\320\273\321\214\320\275\320\276\321\201\321\202\321\214/waterfall/index.html" delete mode 100644 files/ru/using_firefox_1.5_caching/index.html delete mode 100644 "files/ru/web/accessibility/\320\262\320\265\320\261-\321\200\320\260\320\267\321\200\320\260\320\261\320\276\321\202\320\272\320\260/index.html" delete mode 100644 files/ru/web/api/audiocontext/createpanner/index.html delete mode 100644 files/ru/web/api/audiocontext/currenttime/index.html delete mode 100644 files/ru/web/api/audiocontext/decodeaudiodata/index.html create mode 100644 files/ru/web/api/baseaudiocontext/createpanner/index.html create mode 100644 files/ru/web/api/baseaudiocontext/currenttime/index.html create mode 100644 files/ru/web/api/baseaudiocontext/decodeaudiodata/index.html create mode 100644 files/ru/web/api/canvas_api/tutorial/applying_styles_and_colors/index.html create mode 100644 files/ru/web/api/canvas_api/tutorial/basic_animations/index.html create mode 100644 files/ru/web/api/canvas_api/tutorial/compositing/index.html create mode 100644 files/ru/web/api/canvas_api/tutorial/drawing_shapes/index.html create mode 100644 files/ru/web/api/canvas_api/tutorial/drawing_text/index.html create mode 100644 files/ru/web/api/canvas_api/tutorial/using_images/index.html delete mode 100644 "files/ru/web/api/canvas_api/tutorial/\320\270\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265_\320\270\320\267\320\276\320\261\321\200\320\260\320\266\320\265\320\275\320\270\320\271/index.html" delete mode 100644 "files/ru/web/api/canvas_api/tutorial/\320\272\320\276\320\274\320\277\320\276\320\267\320\270\321\206\320\270\320\270/index.html" delete mode 100644 "files/ru/web/api/canvas_api/tutorial/\320\276\321\201\320\275\320\276\320\262\321\213_\320\260\320\275\320\270\320\274\320\260\321\206\320\270\320\270/index.html" delete mode 100644 "files/ru/web/api/canvas_api/tutorial/\320\277\321\200\320\270\320\274\320\265\320\275\320\265\320\275\320\270\320\265_\321\201\321\202\320\270\320\273\320\265\320\271_\320\270_\321\206\320\262\320\265\321\202\320\276\320\262/index.html" delete mode 100644 "files/ru/web/api/canvas_api/tutorial/\321\200\320\270\321\201\320\276\320\262\320\260\320\275\320\270\320\265_\321\202\320\265\320\272\321\201\321\202\320\260/index.html" delete mode 100644 "files/ru/web/api/canvas_api/tutorial/\321\200\320\270\321\201\320\276\320\262\320\260\320\275\320\270\320\265_\321\204\320\270\320\263\321\203\321\200/index.html" create mode 100644 files/ru/web/api/crypto/getrandomvalues/index.html create mode 100644 files/ru/web/api/css_object_model/managing_screen_orientation/index.html delete mode 100644 "files/ru/web/api/css_object_model/\320\276\321\200\320\270\320\265\320\275\321\202\320\260\321\206\320\270\321\217_\321\215\320\272\321\200\320\260\320\275\320\260/index.html" delete mode 100644 files/ru/web/api/document/activeelement/index.html delete mode 100644 files/ru/web/api/document/async/index.html create mode 100644 files/ru/web/api/document/createelement/index.html delete mode 100644 files/ru/web/api/document/getselection/index.html create mode 100644 files/ru/web/api/document/images/index.html create mode 100644 files/ru/web/api/document/readystatechange_event/index.html create mode 100644 files/ru/web/api/document_object_model/events/index.html create mode 100644 files/ru/web/api/document_object_model/examples/index.html create mode 100644 files/ru/web/api/document_object_model/index.html create mode 100644 files/ru/web/api/document_object_model/introduction/index.html create mode 100644 files/ru/web/api/document_object_model/locating_dom_elements_using_selectors/index.html create mode 100644 files/ru/web/api/documentorshadowroot/activeelement/index.html create mode 100644 files/ru/web/api/documentorshadowroot/getselection/index.html delete mode 100644 files/ru/web/api/element/accesskey/index.html create mode 100644 files/ru/web/api/element/blur_event/index.html create mode 100644 files/ru/web/api/element/error_event/index.html create mode 100644 files/ru/web/api/element/focusin_event/index.html create mode 100644 files/ru/web/api/element/focusout_event/index.html create mode 100644 files/ru/web/api/elementcssinlinestyle/style/index.html delete mode 100644 files/ru/web/api/eventtarget/attachevent/index.html delete mode 100644 files/ru/web/api/eventtarget/detachevent/index.html create mode 100644 files/ru/web/api/file_and_directory_entries_api/introduction/index.html delete mode 100644 "files/ru/web/api/file_and_directory_entries_api/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265/index.html" create mode 100644 files/ru/web/api/fullscreen_api/index.html delete mode 100644 files/ru/web/api/geolocation/using_geolocation/index.html delete mode 100644 files/ru/web/api/geolocation/using_geolocation/using_the_geolocation_api/index.html create mode 100644 files/ru/web/api/geolocation_api/index.html create mode 100644 files/ru/web/api/geolocation_api/using_the_geolocation_api/index.html create mode 100644 files/ru/web/api/html_drag_and_drop_api/drag_operations/index.html create mode 100644 files/ru/web/api/html_drag_and_drop_api/index.html delete mode 100644 files/ru/web/api/htmlaudioelement/audio()/index.html create mode 100644 files/ru/web/api/htmlaudioelement/audio/index.html create mode 100644 files/ru/web/api/htmlelement/accesskey/index.html delete mode 100644 files/ru/web/api/htmlelement/dataset/index.html create mode 100644 files/ru/web/api/htmlelement/innertext/index.html delete mode 100644 files/ru/web/api/htmlelement/nonce/index.html delete mode 100644 files/ru/web/api/htmlelement/style/index.html delete mode 100644 files/ru/web/api/htmlelement/tabindex/index.html create mode 100644 files/ru/web/api/htmlelement/transitionend_event/index.html create mode 100644 files/ru/web/api/htmlmediaelement/seeking_event/index.html create mode 100644 files/ru/web/api/htmlorforeignelement/dataset/index.html create mode 100644 files/ru/web/api/htmlorforeignelement/nonce/index.html create mode 100644 files/ru/web/api/htmlorforeignelement/tabindex/index.html create mode 100644 files/ru/web/api/mediatrackconstraints/echocancellation/index.html delete mode 100644 "files/ru/web/api/mediatrackconstraints/\321\215\321\205\320\276\320\277\320\276\320\264\320\260\320\262\320\273\320\265\320\275\320\270\320\265/index.html" create mode 100644 files/ru/web/api/navigator/connection/index.html delete mode 100644 files/ru/web/api/navigatorgeolocation/index.html delete mode 100644 files/ru/web/api/networkinformation/connection/index.html delete mode 100644 files/ru/web/api/node.replacechild/index.html delete mode 100644 files/ru/web/api/node/baseuriobject/index.html delete mode 100644 files/ru/web/api/node/innertext/index.html delete mode 100644 files/ru/web/api/node/nodeprincipal/index.html create mode 100644 files/ru/web/api/node/replacechild/index.html create mode 100644 files/ru/web/api/nondocumenttypechildnode/nextelementsibling/index.html delete mode 100644 files/ru/web/api/nondocumenttypechildnode/nondocumenttypechildnode.nextelementsibling/index.html create mode 100644 files/ru/web/api/notation/index.html create mode 100644 files/ru/web/api/page_visibility_api/index.html delete mode 100644 files/ru/web/api/push_api/using_the_push_api/index.html delete mode 100644 files/ru/web/api/randomsource/getrandomvalues/index.html delete mode 100644 files/ru/web/api/randomsource/index.html delete mode 100644 files/ru/web/api/slotable/index.html delete mode 100644 files/ru/web/api/storage/localstorage/index.html delete mode 100644 files/ru/web/api/svgaelement/svgalement.target/index.html delete mode 100644 files/ru/web/api/web_crypto_api/checking_authenticity_with_password/index.html create mode 100644 files/ru/web/api/web_workers_api/using_web_workers/index.html create mode 100644 files/ru/web/api/webgl_api/tutorial/creating_3d_objects_using_webgl/index.html delete mode 100644 "files/ru/web/api/webgl_api/tutorial/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_3d_\320\276\320\261\321\212\320\265\320\272\321\202\320\276\320\262_\321\201_\320\277\320\276\320\274\320\276\321\211\321\214\321\216_webgl/index.html" create mode 100644 files/ru/web/api/webrtc_api/connectivity/index.html create mode 100644 files/ru/web/api/webrtc_api/protocols/index.html delete mode 100644 files/ru/web/api/webrtc_api/webrtc_basics/index.html delete mode 100644 "files/ru/web/api/webrtc_api/\320\277\321\200\320\276\321\202\320\276\320\272\320\276\320\273\321\213/index.html" delete mode 100644 "files/ru/web/api/webrtc_api/\321\201\320\262\321\217\320\267\321\214/index.html" create mode 100644 files/ru/web/api/websockets_api/index.html create mode 100644 files/ru/web/api/websockets_api/writing_websocket_client_applications/index.html create mode 100644 files/ru/web/api/window/domcontentloaded_event/index.html create mode 100644 files/ru/web/api/window/load_event/index.html create mode 100644 files/ru/web/api/window/requestanimationframe/index.html create mode 100644 files/ru/web/api/window/unhandledrejection_event/index.html delete mode 100644 files/ru/web/api/windowbase64/base64_encoding_and_decoding/index.html delete mode 100644 files/ru/web/api/windowbase64/btoa/index.html delete mode 100644 files/ru/web/api/windowbase64/index.html create mode 100644 files/ru/web/api/windoworworkerglobalscope/btoa/index.html create mode 100644 files/ru/web/api/windoworworkerglobalscope/settimeout/index.html delete mode 100644 files/ru/web/api/windowtimers/index.html delete mode 100644 files/ru/web/api/windowtimers/settimeout/index.html create mode 100644 files/ru/web/api/xmldocument/async/index.html create mode 100644 files/ru/web/api/xmlhttprequest/loadstart_event/index.html delete mode 100644 "files/ru/web/api/\320\262\320\270\320\264\320\270\320\274\320\276\321\201\321\202\321\214_\321\201\321\202\321\200\320\260\320\275\320\270\321\206\321\213_api/index.html" delete mode 100644 "files/ru/web/api/\320\275\320\276\321\202\320\260\321\206\320\270\321\217/index.html" delete mode 100644 files/ru/web/css/@viewport/user-zoom/index.html delete mode 100644 files/ru/web/css/_colon_any/index.html create mode 100644 files/ru/web/css/actual_value/index.html delete mode 100644 files/ru/web/css/box_model/index.html create mode 100644 files/ru/web/css/comments/index.html delete mode 100644 files/ru/web/css/common_css_questions/index.html delete mode 100644 files/ru/web/css/css_animations/ispolzovanie_css_animatciy/index.html create mode 100644 files/ru/web/css/css_animations/using_css_animations/index.html create mode 100644 files/ru/web/css/css_background_and_borders/border-radius_generator/index.html delete mode 100644 "files/ru/web/css/css_background_and_borders/border-radius_\320\263\320\265\320\275\320\265\321\200\320\260\321\202\320\276\321\200/index.html" create mode 100644 files/ru/web/css/css_background_and_borders/box-shadow_generator/index.html delete mode 100644 files/ru/web/css/css_background_and_borders/index.html delete mode 100644 "files/ru/web/css/css_background_and_borders/\320\274\320\275\320\276\320\266\320\265\321\201\321\202\320\262\320\265\320\275\320\275\321\213\320\265_\321\204\320\276\320\275\321\213/index.html" create mode 100644 files/ru/web/css/css_backgrounds_and_borders/index.html create mode 100644 files/ru/web/css/css_backgrounds_and_borders/using_multiple_backgrounds/index.html create mode 100644 files/ru/web/css/css_basic_user_interface/using_url_values_for_the_cursor_property/index.html delete mode 100644 "files/ru/web/css/css_basic_user_interface/\320\270\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265_url_\320\267\320\275\320\260\321\207\320\265\320\275\320\270\320\271_\320\264\320\273\321\217_\321\201\320\262\320\276\320\271\321\201\321\202\320\262\320\260_cursor/index.html" delete mode 100644 files/ru/web/css/css_box_model/box-shadow_generator/index.html create mode 100644 files/ru/web/css/css_box_model/introduction_to_the_css_box_model/index.html create mode 100644 files/ru/web/css/css_color/index.html delete mode 100644 files/ru/web/css/css_colors/index.html create mode 100644 files/ru/web/css/css_columns/using_multi-column_layouts/index.html create mode 100644 files/ru/web/css/css_flexible_box_layout/aligning_items_in_a_flex_container/index.html create mode 100644 files/ru/web/css/css_flexible_box_layout/controlling_ratios_of_flex_items_along_the_main_ax/index.html delete mode 100644 files/ru/web/css/css_flexible_box_layout/using_css_flexible_boxes/index.html delete mode 100644 "files/ru/web/css/css_flexible_box_layout/\320\262\321\213\321\200\320\260\320\262\320\275\320\270\320\262\320\260\320\275\320\270\320\265_\321\215\320\273\320\265\320\274\320\265\320\275\321\202\320\276\320\262_\320\262_flex_\320\272\320\276\320\275\321\202\320\265\320\271\320\275\320\265\321\200\320\265/index.html" delete mode 100644 "files/ru/web/css/css_flexible_box_layout/\320\272\320\276\320\275\321\202\321\200\320\276\320\273\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265_\321\201\320\276\320\276\321\202\320\275\320\276\321\210\320\265\320\275\320\270\321\217_\321\215\320\273\320\265\320\274\320\265\320\275\321\202\320\276\320\262_\320\262\320\264\320\276\320\273\321\214_\320\263\320\273\320\260\320\262\320\275\320\276\320\271_\320\276\321\201\320\270/index.html" create mode 100644 files/ru/web/css/css_flow_layout/block_and_inline_layout_in_normal_flow/index.html create mode 100644 files/ru/web/css/css_flow_layout/intro_to_formatting_contexts/index.html delete mode 100644 "files/ru/web/css/css_flow_layout/\320\261\320\273\320\276\321\207\320\275\320\276\320\265_\320\270_\321\201\321\202\321\200\320\276\321\207\320\275\320\276\320\265_\321\200\320\260\320\267\320\274\320\265\321\211\320\265\320\275\320\270\320\265_\320\262_\320\275\320\276\321\200\320\274\320\260\320\273\321\214\320\275\320\276\320\274_\320\277\320\276\321\202\320\276\320\272\320\265/index.html" delete mode 100644 "files/ru/web/css/css_flow_layout/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_\320\272\320\276\320\275\321\202\320\265\320\272\321\201\321\202\321\213_\321\204\320\276\321\200\320\274\320\260\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\321\217/index.html" delete mode 100644 files/ru/web/css/css_grid_layout/css_grid,_logical_values_and_writing_modes/index.html create mode 100644 files/ru/web/css/css_grid_layout/css_grid_logical_values_and_writing_modes/index.html create mode 100644 files/ru/web/css/css_grid_layout/grid_template_areas/index.html create mode 100644 files/ru/web/css/css_grid_layout/line-based_placement_with_css_grid/index.html delete mode 100644 "files/ru/web/css/css_grid_layout/\320\263\321\200\320\270\320\264-\320\276\320\261\320\273\320\260\321\201\321\202\320\270/index.html" delete mode 100644 "files/ru/web/css/css_grid_layout/\321\200\320\260\321\201\320\277\320\276\320\273\320\276\320\266\320\265\320\275\320\270\320\265_\321\215\320\273\320\265\320\274\320\265\320\275\321\202\320\276\320\262_\320\277\320\276_\320\263\321\200\320\270\320\264-\320\273\320\270\320\275\320\270\321\217\320\274_\321\201_\320\277\320\276\320\274\320\276\321\211\321\214\321\216_css_grid/index.html" create mode 100644 files/ru/web/css/css_positioning/understanding_z_index/adding_z-index/index.html create mode 100644 files/ru/web/css/css_positioning/understanding_z_index/index.html create mode 100644 files/ru/web/css/css_positioning/understanding_z_index/stacking_without_z-index/index.html create mode 100644 files/ru/web/css/css_selectors/index.html create mode 100644 files/ru/web/css/css_selectors/using_the__colon_target_pseudo-class_in_selectors/index.html delete mode 100644 files/ru/web/css/css_user_interface/index.html delete mode 100644 "files/ru/web/css/css_\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/index.html" delete mode 100644 "files/ru/web/css/css_\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/using_the__colon_target_pseudo-class_in_selectors/index.html" delete mode 100644 files/ru/web/css/filter-function/url/index.html delete mode 100644 files/ru/web/css/grid-gap/index.html create mode 100644 files/ru/web/css/layout_mode/index.html create mode 100644 files/ru/web/css/length/index.html create mode 100644 files/ru/web/css/media_queries/testing_media_queries/index.html delete mode 100644 "files/ru/web/css/media_queries/\321\202\320\265\321\201\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265_\320\274\320\265\320\264\320\270\320\260_\320\267\320\260\320\277\321\200\320\276\321\201\321\213/index.html" create mode 100644 files/ru/web/css/pseudo-classes/index.html create mode 100644 files/ru/web/css/replaced_element/index.html create mode 100644 files/ru/web/css/specified_value/index.html create mode 100644 files/ru/web/css/syntax/index.html delete mode 100644 files/ru/web/css/url/index.html create mode 100644 files/ru/web/css/visual_formatting_model/index.html delete mode 100644 "files/ru/web/css/\320\264\320\265\320\271\321\201\321\202\320\262\320\270\321\202\320\265\320\273\321\214\320\275\320\276\320\265_\320\267\320\275\320\260\321\207\320\265\320\275\320\270\320\265/index.html" delete mode 100644 "files/ru/web/css/\320\267\320\260\320\274\320\265\321\211\320\260\320\265\320\274\321\213\320\271_\321\215\320\273\320\265\320\274\320\265\320\275\321\202/index.html" delete mode 100644 "files/ru/web/css/\320\277\321\201\320\265\320\262\320\264\320\276-\320\272\320\273\320\260\321\201\321\201\321\213/index.html" delete mode 100644 "files/ru/web/css/\321\200\320\260\320\267\320\274\320\265\321\200/index.html" delete mode 100644 "files/ru/web/css/\321\201\320\270\320\275\321\202\320\260\320\272\321\201\320\270\321\201/index.html" delete mode 100644 "files/ru/web/css/\321\201\320\277\320\276\321\201\320\276\320\261_\321\200\320\260\321\201\320\277\320\276\320\273\320\276\320\266\320\265\320\275\320\270\321\217/index.html" delete mode 100644 "files/ru/web/css/\321\202\320\270\321\205\320\270\320\271/index.html" delete mode 100644 "files/ru/web/css/\321\203\320\272\320\260\320\267\320\260\320\275\320\275\320\276\320\265_\320\267\320\275\320\260\321\207\320\265\320\275\320\270\320\265/index.html" delete mode 100644 files/ru/web/events/abort/index.html delete mode 100644 files/ru/web/events/blur/index.html delete mode 100644 files/ru/web/events/domcontentloaded/index.html delete mode 100644 files/ru/web/events/error/index.html delete mode 100644 files/ru/web/events/focusin/index.html delete mode 100644 files/ru/web/events/focusout/index.html delete mode 100644 files/ru/web/events/load/index.html delete mode 100644 files/ru/web/events/loadstart/index.html delete mode 100644 files/ru/web/events/readystatechange/index.html delete mode 100644 files/ru/web/events/transitionend/index.html delete mode 100644 files/ru/web/events/unhandledrejection/index.html create mode 100644 files/ru/web/guide/ajax/getting_started/index.html delete mode 100644 "files/ru/web/guide/ajax/\321\201_\321\207\320\265\320\263\320\276_\320\275\320\260\321\207\320\260\321\202\321\214/index.html" delete mode 100644 "files/ru/web/guide/ajax/\321\201_\321\207\320\265\320\263\320\276_\320\275\320\260\321\207\320\260\321\202\321\214_question_/index.html" delete mode 100644 files/ru/web/guide/api/dom/index.html delete mode 100644 files/ru/web/guide/api/dom/storage/index.html delete mode 100644 files/ru/web/guide/api/webrtc/index.html delete mode 100644 files/ru/web/guide/css/getting_started/cascading_and_inheritance/index.html delete mode 100644 files/ru/web/guide/css/getting_started/color/index.html delete mode 100644 files/ru/web/guide/css/getting_started/how_css_works/index.html delete mode 100644 files/ru/web/guide/css/getting_started/index.html delete mode 100644 files/ru/web/guide/css/getting_started/readable_css/index.html delete mode 100644 files/ru/web/guide/css/getting_started/selectors/index.html delete mode 100644 "files/ru/web/guide/css/getting_started/svg_\320\270_css/index.html" delete mode 100644 files/ru/web/guide/css/getting_started/text_styles/index.html delete mode 100644 files/ru/web/guide/css/getting_started/what_is_css/index.html delete mode 100644 files/ru/web/guide/css/getting_started/why_use_css/index.html delete mode 100644 "files/ru/web/guide/css/getting_started/\321\202\320\260\320\261\320\273\320\270\321\206\321\213/index.html" delete mode 100644 files/ru/web/guide/css/index.html delete mode 100644 files/ru/web/guide/css/understanding_z_index/adding_z-index/index.html delete mode 100644 files/ru/web/guide/css/understanding_z_index/index.html delete mode 100644 files/ru/web/guide/css/understanding_z_index/stacking_without_z-index/index.html delete mode 100644 files/ru/web/guide/css/using_multi-column_layouts/index.html delete mode 100644 files/ru/web/guide/css/visual_formatting_model/index.html create mode 100644 files/ru/web/guide/events/creating_and_triggering_events/index.html delete mode 100644 "files/ru/web/guide/events/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\320\270_\320\262\321\213\320\267\320\276\320\262_\321\201\320\276\320\261\321\213\321\202\320\270\320\271/index.html" create mode 100644 files/ru/web/guide/graphics/index.html delete mode 100644 files/ru/web/guide/html/drag_and_drop/drag_operations/index.html delete mode 100644 files/ru/web/guide/html/drag_and_drop/index.html create mode 100644 files/ru/web/guide/html/html5/constraint_validation/index.html create mode 100644 files/ru/web/guide/html/html5/index.html create mode 100644 files/ru/web/guide/html/html5/introduction_to_html5/index.html delete mode 100644 files/ru/web/guide/html/sections_and_outlines_of_an_html5_document/index.html delete mode 100644 files/ru/web/guide/html/tips_for_authoring_fast-loading_html_pages/index.html delete mode 100644 files/ru/web/guide/html/using_data_attributes/index.html create mode 100644 files/ru/web/guide/html/using_html_sections_and_outlines/index.html delete mode 100644 "files/ru/web/guide/html/\321\204\320\276\321\200\320\274\321\213_\320\262_html/index.html" create mode 100644 files/ru/web/guide/performance/index.html delete mode 100644 "files/ru/web/guide/\320\263\321\200\320\260\321\204\320\270\320\272\320\260/index.html" delete mode 100644 "files/ru/web/guide/\320\277\321\200\320\276\320\270\320\267\320\262\320\276\320\264\320\270\321\202\320\265\320\273\321\214\320\275\320\276\321\201\321\202\321\214/index.html" create mode 100644 files/ru/web/html/attributes/crossorigin/index.html delete mode 100644 files/ru/web/html/cors_settings_attributes/index.html create mode 100644 files/ru/web/html/element/button/index.html delete mode 100644 files/ru/web/html/element/element/index.html create mode 100644 files/ru/web/html/element/link/index.html delete mode 100644 files/ru/web/html/element/video/seeking_event/index.html delete mode 100644 "files/ru/web/html/element/\320\272\320\275\320\276\320\277\320\272\320\260/index.html" delete mode 100644 "files/ru/web/html/element/\321\201\321\201\321\213\320\273\320\272\320\260/index.html" delete mode 100644 files/ru/web/html/global_attributes/dropzone/index.html create mode 100644 files/ru/web/html/inline_elements/index.html create mode 100644 files/ru/web/html/link_types/index.html delete mode 100644 files/ru/web/html/optimizing_your_pages_for_speculative_parsing/index.html create mode 100644 files/ru/web/html/reference/index.html create mode 100644 files/ru/web/html/using_the_application_cache/index.html delete mode 100644 "files/ru/web/html/\320\270\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265_\320\272\321\215\321\210\320\270\321\200\320\276\320\262\320\260\320\275\320\270\321\217_\320\277\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\320\271/index.html" delete mode 100644 "files/ru/web/html/\320\277\320\276\320\264\320\264\320\265\321\200\320\266\320\270\320\262\320\260\320\265\320\274\321\213\320\265_\320\274\320\265\320\264\320\270\320\260_\321\204\320\276\321\200\320\274\320\260\321\202\321\213/index.html" delete mode 100644 "files/ru/web/html/\321\201\321\201\321\213\320\273\320\272\320\270/index.html" delete mode 100644 "files/ru/web/html/\321\201\321\202\321\200\320\276\321\207\320\275\321\213\320\265_\321\215\320\273\320\265\320\274\320\265\320\275\321\202\321\213/index.html" delete mode 100644 "files/ru/web/html/\321\202\320\270\320\277\321\213_\321\201\321\201\321\213\320\273\320\276\320\272/index.html" create mode 100644 files/ru/web/http/authentication/index.html create mode 100644 files/ru/web/http/basics_of_http/identifying_resources_on_the_web/index.html delete mode 100644 files/ru/web/http/basics_of_http/identifying_resources_on_the_web_ru/index.html create mode 100644 files/ru/web/http/caching/index.html create mode 100644 files/ru/web/http/cookies/index.html create mode 100644 files/ru/web/http/headers/accept-charset/index.html create mode 100644 files/ru/web/http/headers/accept-language/index.html create mode 100644 files/ru/web/http/headers/accept-patch/index.html create mode 100644 files/ru/web/http/headers/accept-ranges/index.html create mode 100644 files/ru/web/http/headers/accept/index.html create mode 100644 files/ru/web/http/headers/access-control-allow-headers/index.html create mode 100644 files/ru/web/http/headers/access-control-allow-methods/index.html create mode 100644 files/ru/web/http/headers/access-control-allow-origin/index.html create mode 100644 files/ru/web/http/headers/access-control-max-age/index.html create mode 100644 files/ru/web/http/headers/authorization/index.html create mode 100644 files/ru/web/http/headers/cache-control/index.html create mode 100644 files/ru/web/http/headers/connection/index.html create mode 100644 files/ru/web/http/headers/content-disposition/index.html create mode 100644 files/ru/web/http/headers/content-encoding/index.html create mode 100644 files/ru/web/http/headers/content-language/index.html create mode 100644 files/ru/web/http/headers/content-length/index.html create mode 100644 files/ru/web/http/headers/content-type/index.html create mode 100644 files/ru/web/http/headers/date/index.html create mode 100644 files/ru/web/http/headers/dnt/index.html create mode 100644 files/ru/web/http/headers/etag/index.html create mode 100644 files/ru/web/http/headers/expect/index.html create mode 100644 files/ru/web/http/headers/expires/index.html create mode 100644 files/ru/web/http/headers/host/index.html create mode 100644 files/ru/web/http/headers/if-match/index.html create mode 100644 files/ru/web/http/headers/if-modified-since/index.html create mode 100644 files/ru/web/http/headers/if-unmodified-since/index.html create mode 100644 files/ru/web/http/headers/index.html create mode 100644 files/ru/web/http/headers/last-modified/index.html create mode 100644 files/ru/web/http/headers/origin/index.html create mode 100644 files/ru/web/http/headers/pragma/index.html create mode 100644 files/ru/web/http/headers/range/index.html create mode 100644 files/ru/web/http/headers/referer/index.html create mode 100644 files/ru/web/http/headers/retry-after/index.html create mode 100644 files/ru/web/http/headers/set-cookie/index.html create mode 100644 files/ru/web/http/headers/strict-transport-security/index.html create mode 100644 files/ru/web/http/headers/vary/index.html create mode 100644 files/ru/web/http/headers/x-content-type-options/index.html create mode 100644 files/ru/web/http/headers/x-forwarded-for/index.html create mode 100644 files/ru/web/http/headers/x-xss-protection/index.html delete mode 100644 files/ru/web/http/server-side_access_control/index.html delete mode 100644 "files/ru/web/http/\320\260\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/accept-charset/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/accept-language/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/accept-patch/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/accept-ranges/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/accept/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/access-control-allow-headers/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/access-control-allow-methods/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/access-control-allow-origin/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/access-control-max-age/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/authorization/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/cache-control/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/connection/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/content-disposition/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/content-encoding/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/content-language/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/content-length/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/content-type/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/date/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/dnt/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/etag/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/expect/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/expires/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/host/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/if-match/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/if-modified-since/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/if-unmodified-since/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/last-modified/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/origin/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/pragma/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/range/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/referer/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/retry-after/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/set-cookie/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/strict-transport-security/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/vary/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/x-content-type-options/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/x-forwarded-for/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/x-xss-protection/index.html" delete mode 100644 "files/ru/web/http/\320\272\321\203\320\272\320\270/index.html" delete mode 100644 "files/ru/web/http/\320\272\321\215\321\210\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/index.html" create mode 100644 files/ru/web/javascript/about_javascript/index.html delete mode 100644 files/ru/web/javascript/guide/about/index.html create mode 100644 files/ru/web/javascript/guide/introduction/index.html delete mode 100644 files/ru/web/javascript/guide/ispolzovanie_promisov/index.html delete mode 100644 files/ru/web/javascript/guide/javascript_overview/index.html create mode 100644 files/ru/web/javascript/guide/loops_and_iteration/index.html delete mode 100644 files/ru/web/javascript/guide/predefined_core_objects/index.html create mode 100644 files/ru/web/javascript/guide/using_promises/index.html delete mode 100644 "files/ru/web/javascript/guide/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_javascript/index.html" delete mode 100644 "files/ru/web/javascript/guide/\320\276\320\261_\321\215\321\202\320\276\320\274_\321\200\321\203\320\272\320\276\320\262\320\276\320\264\321\201\321\202\320\262\320\265/index.html" delete mode 100644 "files/ru/web/javascript/guide/\321\206\320\270\320\272\320\273\321\213_\320\270_\320\270\321\202\320\265\321\200\320\260\321\206\320\270\320\270/index.html" delete mode 100644 files/ru/web/javascript/introduction_to_object-oriented_javascript/index.html delete mode 100644 "files/ru/web/javascript/javascript_\321\210\320\265\320\273\320\273\321\213/index.html" create mode 100644 files/ru/web/javascript/reference/about/index.html delete mode 100644 files/ru/web/javascript/reference/classes/class_fields/index.html create mode 100644 files/ru/web/javascript/reference/classes/private_class_fields/index.html create mode 100644 files/ru/web/javascript/reference/classes/public_class_fields/index.html delete mode 100644 "files/ru/web/javascript/reference/classes/\320\277\321\200\320\270\320\262\320\260\321\202\320\275\321\213\320\265_\320\277\320\276\320\273\321\217_\320\272\320\273\320\260\321\201\321\201\320\260/index.html" create mode 100644 files/ru/web/javascript/reference/errors/var_hides_argument/index.html delete mode 100644 "files/ru/web/javascript/reference/errors/\320\277\320\265\321\200\320\265\320\274\320\265\320\275\320\275\321\213\320\265_\321\201\320\272\321\200\321\213\320\262\320\260\321\216\321\202_\320\260\321\200\320\263\321\203\320\274\320\265\320\275\321\202/index.html" create mode 100644 files/ru/web/javascript/reference/functions/method_definitions/index.html delete mode 100644 "files/ru/web/javascript/reference/functions/\320\276\320\277\321\200\320\265\320\264\320\265\320\273\320\270\320\275\320\270\320\265_\320\274\320\265\321\202\320\276\320\264\320\276\320\262/index.html" delete mode 100644 files/ru/web/javascript/reference/global_objects/array/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/asyncfunction/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/boolean/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/date/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/error/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/evalerror/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/function/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/generatorfunction/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/internalerror/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/intl/collator/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/intl/datetimeformat/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/intl/numberformat/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/map/prototype/index.html delete mode 100644 "files/ru/web/javascript/reference/global_objects/math/\320\274\320\265\321\202\320\276\320\264_math.max()_/index.html" delete mode 100644 files/ru/web/javascript/reference/global_objects/number/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/object/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/promise/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/proxy/handler/deleteproperty/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/proxy/handler/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/proxy/handler/set/index.html create mode 100644 files/ru/web/javascript/reference/global_objects/proxy/proxy/deleteproperty/index.html create mode 100644 files/ru/web/javascript/reference/global_objects/proxy/proxy/set/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/rangeerror/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/referenceerror/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/regexp/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/set/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/string/prototype/index.html create mode 100644 files/ru/web/javascript/reference/global_objects/string/trimend/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/string/trimleft/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/string/trimright/index.html create mode 100644 files/ru/web/javascript/reference/global_objects/string/trimstart/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/symbol/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/syntaxerror/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/typedarray/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/typeerror/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/urierror/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/weakmap/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/weakset/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/operators/arithmetic_operators/index.html create mode 100644 files/ru/web/javascript/reference/operators/assignment/index.html delete mode 100644 files/ru/web/javascript/reference/operators/assignment_operators/index.html delete mode 100644 files/ru/web/javascript/reference/operators/bitwise_operators/index.html create mode 100644 files/ru/web/javascript/reference/operators/comma_operator/index.html create mode 100644 files/ru/web/javascript/reference/operators/conditional_operator/index.html create mode 100644 files/ru/web/javascript/reference/operators/grouping/index.html create mode 100644 files/ru/web/javascript/reference/operators/pipeline_operator/index.html delete mode 100644 "files/ru/web/javascript/reference/operators/\320\263\321\200\321\203\320\277\320\277\320\270\321\200\320\276\320\262\320\272\320\260/index.html" delete mode 100644 "files/ru/web/javascript/reference/operators/\320\272\320\276\320\275\320\262\320\265\320\271\320\265\321\200\320\275\321\213\320\271_\320\276\320\277\320\265\321\200\320\260\321\202\320\276\321\200/index.html" delete mode 100644 "files/ru/web/javascript/reference/operators/\320\273\320\276\320\263\320\270\321\207\320\265\321\201\320\272\320\270\320\265_\320\276\320\277\320\265\321\200\320\260\321\202\320\276\321\200\321\213/index.html" delete mode 100644 "files/ru/web/javascript/reference/operators/\320\276\320\277\320\265\321\200\320\260\321\202\320\276\321\200_\320\267\320\260\320\277\321\217\321\202\320\260\321\217/index.html" delete mode 100644 "files/ru/web/javascript/reference/operators/\320\276\320\277\320\265\321\200\320\260\321\202\320\276\321\200\321\213_\321\201\321\200\320\260\320\262\320\275\320\265\320\275\320\270\321\217/index.html" delete mode 100644 "files/ru/web/javascript/reference/operators/\320\277\321\200\320\270\321\201\320\262\320\260\320\270\320\262\320\260\320\275\320\270\320\265/index.html" delete mode 100644 "files/ru/web/javascript/reference/operators/\321\203\321\201\320\273\320\276\320\262\320\275\321\213\320\271_\320\276\320\277\320\265\321\200\320\260\321\202\320\276\321\200/index.html" create mode 100644 files/ru/web/javascript/reference/statements/block/index.html delete mode 100644 files/ru/web/javascript/reference/statements/default/index.html delete mode 100644 "files/ru/web/javascript/reference/statements/\320\261\320\273\320\276\320\272/index.html" create mode 100644 files/ru/web/javascript/reference/template_literals/index.html delete mode 100644 files/ru/web/javascript/reference/template_strings/index.html delete mode 100644 "files/ru/web/javascript/reference/\320\276\320\261/index.html" create mode 100644 files/ru/web/javascript/shells/index.html delete mode 100644 "files/ru/web/javascript/\320\276_javascript/index.html" delete mode 100644 files/ru/web/manifest/serviceworker/index.html create mode 100644 files/ru/web/mathml/attribute/index.html create mode 100644 files/ru/web/mathml/examples/deriving_the_quadratic_formula/index.html create mode 100644 files/ru/web/mathml/examples/index.html create mode 100644 files/ru/web/mathml/examples/mathml_pythagorean_theorem/index.html delete mode 100644 "files/ru/web/mathml/\320\260\321\202\321\200\320\270\320\261\321\203\321\202/index.html" delete mode 100644 "files/ru/web/mathml/\320\277\321\200\320\270\320\274\320\265\321\200\321\213/deriving_the_quadratic_formula/index.html" delete mode 100644 "files/ru/web/mathml/\320\277\321\200\320\270\320\274\320\265\321\200\321\213/index.html" delete mode 100644 "files/ru/web/mathml/\320\277\321\200\320\270\320\274\320\265\321\200\321\213/mathml_pythagorean_theorem/index.html" create mode 100644 files/ru/web/media/formats/webrtc_codecs/index.html delete mode 100644 "files/ru/web/media/formats/webrtc_\320\272\320\276\320\264\320\265\320\272\320\270/index.html" create mode 100644 files/ru/web/performance/animation_performance_and_frame_rate/index.html create mode 100644 files/ru/web/performance/fundamentals/index.html delete mode 100644 "files/ru/web/performance/\320\276\321\201\320\275\320\276\320\262\321\213/index.html" delete mode 100644 "files/ru/web/performance/\320\277\321\200\320\276\320\270\320\267\320\262\320\276\320\264\320\270\321\202\320\265\320\273\321\214\320\275\320\276\321\201\321\202\321\214_\320\260\320\275\320\270\320\274\320\260\321\206\320\270\320\270/index.html" delete mode 100644 "files/ru/web/progressive_web_apps/\320\267\320\260\320\274\320\265\321\202\320\275\321\213\320\271/index.html" delete mode 100644 files/ru/web/security/csp/index.html delete mode 100644 files/ru/web/security/information_security_basics/index.html delete mode 100644 files/ru/web/svg/attribute/onload/index.html create mode 100644 files/ru/web/svg/element/a/index.html create mode 100644 files/ru/web/svg/element/animate/index.html create mode 100644 files/ru/web/svg/element/animatemotion/index.html create mode 100644 files/ru/web/svg/element/circle/index.html create mode 100644 files/ru/web/svg/element/defs/index.html create mode 100644 files/ru/web/svg/element/ellipse/index.html create mode 100644 files/ru/web/svg/element/feblend/index.html create mode 100644 files/ru/web/svg/element/foreignobject/index.html create mode 100644 files/ru/web/svg/element/g/index.html create mode 100644 files/ru/web/svg/element/image/index.html create mode 100644 files/ru/web/svg/element/index.html create mode 100644 files/ru/web/svg/element/line/index.html create mode 100644 files/ru/web/svg/element/lineargradient/index.html create mode 100644 files/ru/web/svg/element/path/index.html create mode 100644 files/ru/web/svg/element/pattern/index.html create mode 100644 files/ru/web/svg/element/polygon/index.html create mode 100644 files/ru/web/svg/element/radialgradient/index.html create mode 100644 files/ru/web/svg/element/rect/index.html create mode 100644 files/ru/web/svg/element/svg/index.html create mode 100644 files/ru/web/svg/element/text/index.html create mode 100644 files/ru/web/svg/element/use/index.html create mode 100644 files/ru/web/svg/tutorial/basic_shapes/index.html create mode 100644 files/ru/web/svg/tutorial/basic_transformations/index.html create mode 100644 files/ru/web/svg/tutorial/introduction/index.html create mode 100644 files/ru/web/svg/tutorial/positions/index.html create mode 100644 files/ru/web/svg/tutorial/svg_and_css/index.html delete mode 100644 "files/ru/web/svg/tutorial/\320\261\320\260\320\267\320\276\320\262\321\213\320\265_\320\277\321\200\320\265\320\276\320\261\321\200\320\260\320\267\320\276\320\262\320\260\320\275\320\270\321\217/index.html" delete mode 100644 "files/ru/web/svg/tutorial/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265/index.html" delete mode 100644 "files/ru/web/svg/tutorial/\320\276\321\201\320\275\320\276\320\262\320\275\321\213\320\265_\321\204\320\270\320\263\321\203\321\200\321\213/index.html" delete mode 100644 "files/ru/web/svg/tutorial/\320\277\320\276\320\267\320\270\321\206\320\270\320\270/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/a/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/animate/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/animatemotion/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/circle/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/defs/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/ellipse/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/feblend/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/foreignobject/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/g/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/image/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/line/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/lineargradient/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/path/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/pattern/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/polygon/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/radialgradient/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/rect/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/svg/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/text/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/use/index.html" create mode 100644 files/ru/web/web_components/using_custom_elements/index.html delete mode 100644 "files/ru/web/web_components/\320\270\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265_\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\214\321\201\320\272\320\270\321\205_\321\215\320\273\320\265\320\274\320\265\320\275\321\202\320\276\320\262/index.html" delete mode 100644 files/ru/web/webapi/index.html create mode 100644 files/ru/web/xpath/functions/floor/index.html create mode 100644 files/ru/web/xpath/functions/index.html delete mode 100644 files/ru/web/xpath/funkcje/floor/index.html delete mode 100644 files/ru/web/xpath/funkcje/index.html delete mode 100644 files/ru/web_development/mobile/index.html delete mode 100644 files/ru/web_development/mobile/responsive_design/index.html delete mode 100644 files/ru/websockets/index.html delete mode 100644 files/ru/websockets/writing_websocket_client_applications/index.html delete mode 100644 files/ru/xml_in_mozilla/index.html delete mode 100644 files/ru/xmlhttprequest/index.html delete mode 100644 files/ru/xpcnativewrapper/index.html delete mode 100644 files/ru/xpcom/index.html delete mode 100644 "files/ru/\320\262\320\265\320\261-\321\200\320\260\320\267\321\200\320\260\320\261\320\276\321\202\320\272\320\260/index.html" delete mode 100644 "files/ru/\320\262\320\265\320\261-\321\201\321\202\320\260\320\275\320\264\320\260\321\200\321\202\321\213/index.html" delete mode 100644 "files/ru/\320\262\320\276\320\277\321\200\320\276\321\201\321\213_\320\261\320\265\320\267_\320\276\321\202\320\262\320\265\321\202\320\276\320\262/index.html" delete mode 100644 "files/ru/\320\264\320\270\320\275\320\260\320\274\320\270\321\207\320\265\321\201\320\272\320\270_\320\270\320\267\320\274\320\265\320\275\321\217\320\265\320\274\321\213\320\271_\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\214\321\201\320\272\320\270\320\271_\320\270\320\275\321\202\320\265\321\200\321\204\320\265\320\271\321\201_\320\275\320\260_xul/index.html" delete mode 100644 "files/ru/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/index.html" delete mode 100644 "files/ru/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\276\320\272_\321\201\321\201\321\213\320\273\320\272\320\270/index.html" delete mode 100644 "files/ru/\320\272\320\276\320\275\321\202\321\200\320\276\320\273\321\214_\320\272\320\260\321\207\320\265\321\201\321\202\320\262\320\260/index.html" delete mode 100644 "files/ru/\320\273\320\276\320\272\320\260\320\273\320\270\320\267\320\260\321\206\320\270\321\217/index.html" delete mode 100644 "files/ru/\320\275\320\260\321\201\321\202\321\200\320\276\320\271\320\272\320\260_\321\201\321\200\320\265\320\264\321\213_\321\200\320\260\320\267\321\200\320\260\320\261\320\276\321\202\320\272\320\270_\321\200\320\260\321\201\321\210\320\270\321\200\320\265\320\275\320\270\320\271/index.html" delete mode 100644 "files/ru/\320\276\320\261_\320\276\320\261\321\212\320\265\320\272\321\202\320\275\320\276\320\271_\320\274\320\276\320\264\320\265\320\273\320\270_\320\264\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\260/index.html" delete mode 100644 "files/ru/\320\277\320\265\321\200\320\265\321\205\320\276\320\264_\321\201_internet_explorer_\320\275\320\260_mozilla/index.html" delete mode 100644 "files/ru/\321\201\320\261\320\276\321\200\320\272\320\260_\320\270_\321\203\321\201\321\202\320\260\320\275\320\276\320\262\320\272\320\260/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/404/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/502/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/abstraction/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/adobe-flash/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/ajax/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/algorithm/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/api/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/apple_safari/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/application_context/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/aria/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/arpa/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/arpanet/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/ascii/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/asynchronous/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/atag/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/bandwidth/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/baseline/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/bidi/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/bigint/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/blink/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/boolean/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/bootstrap/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/browser/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/browsing_context/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/b\303\251zier_curve/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/cacheable/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/call_stack/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/canvas/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/card_sorting/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/cdn/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/character/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/character_encoding/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/chrome/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/class/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/cms/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/codec/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/compile/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/computer_programming/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/conditional/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/constructor/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/cookie/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/copyleft/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/cors/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/crawler/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/crlf/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/csp/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/csrf/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/css/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/css_preprocessor/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/css_selector/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/data_structure/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/dns/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/doctype/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/dom/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/domain_name/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/dos_attack/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/dynamic_programming_language/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/ecma/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/ecmascript/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/empty_element/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/encapsulation/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/entity_header/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/event/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/expando/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/falsy/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/first-class_function/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/first_contentful_paint/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/first_cpu_idle/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/first_input_delay/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/first_interactive/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/first_meaningful_paint/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/first_paint/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/flex_item/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/flexbox/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/forbidden_header_name/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/fps/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/ftp/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/gecko/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/general_header/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/git/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/global_object/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/global_variable/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/grid/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/grid_column/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/host/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/html/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/html5/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/http/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/http_2/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/https/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/iana/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/icann/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/idempotent/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/identifier/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/ietf/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/iife/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/indexeddb/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/information_architecture/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/internet/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/ip_address/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/iso/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/java/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/javascript/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/jpeg/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/jquery/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/json/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/loop/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/main_axis/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/mathml/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/method/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/microsoft_internet_explorer/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/mime_type/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/mixin/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/node.js/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/null/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/number/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/object/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/oop/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/opengl/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/origin/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/php/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/pixel/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/polymorphism/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/primitive/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/privileged_code/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/progressive_web_apps/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/promise/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/property/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/prototype-based_programming/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/pseudo-element/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/pseudocode/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/reflow/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/regular_expression/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/request_header/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/responsive_web_design/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/round_trip_time_(rtt)/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/safe/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/scroll_container/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/sdp/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/self-executing_anonymous_function/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/semantics/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/seo/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/server/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/sgml/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/simple_response_header/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/sloppy_mode/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/specification/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/svg/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/symbol/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/tcp/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/time_to_first_byte/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/time_to_interactive/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/tls/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/truthy/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/type/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/type_coercion/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/type_conversion/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/ui/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/undefined/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/url/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/user_agent/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/variable/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/vendor_prefix/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/viewport/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/w3c/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/wai/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/webkit/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/websockets/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/whatwg/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/world_wide_web/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/wrapper/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/xhr_(xmlhttprequest)/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/xhtml/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/xml/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\320\260\321\200\320\263\321\203\320\274\320\265\320\275\321\202/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\320\260\321\202\321\200\320\270\320\261\321\203\321\202/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\320\261\321\203\321\204\320\265\321\200/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\320\262\321\213\321\200\320\260\320\266\320\265\320\275\320\270\320\265/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\320\262\321\213\321\201\320\276\320\272\320\276\321\203\321\200\320\276\320\262\320\275\320\265\320\262\321\213\320\271_\321\217\320\267\321\213\320\272_\320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\270\321\200\320\276\320\262\320\260\320\275\320\270\321\217programming_language/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\320\263\320\270\320\277\320\265\321\200\321\202\320\265\320\272\321\201\321\202/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\320\264\320\265\321\210\320\270\321\204\321\200\320\276\320\262\320\260\320\275\320\270\320\265/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\320\264\320\276\320\274\320\265\320\275/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\276\320\272/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\320\267\320\260\320\277\321\200\320\265\321\211\321\221\320\275\320\275\320\276\320\265_\320\270\320\274\321\217_\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\260_\320\276\321\202\320\262\320\265\321\202\320\260/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\320\270\320\275\321\201\321\202\321\200\321\203\320\274\320\265\320\275\321\202\321\213_\321\200\320\260\320\267\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\260/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\320\270\320\275\321\202\320\265\321\200\320\275\320\265\321\202-\320\277\321\200\320\276\320\262\320\260\320\271\320\264\320\265\321\200/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\320\272\320\276\320\275\321\201\321\202\320\260\320\275\321\202\320\260/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\320\272\321\206\320\264/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\320\272\321\215\321\210/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\320\274\320\260\321\201\321\201\320\270\320\262/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\320\274\320\265\321\202\320\260\320\264\320\260\320\275\320\275\321\213\320\265/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\320\277\320\276\320\264\320\275\321\217\321\202\320\270\320\265/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\320\277\320\276\321\200\321\202/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\320\277\321\200\320\276\320\261\320\265\320\273\321\214\320\275\321\213\320\265_\321\201\320\270\320\274\320\262\320\276\320\273\321\213/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\320\277\321\200\320\276\320\272\321\201\320\270_\321\201\320\265\321\200\320\262\320\265\321\200/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\320\277\321\200\320\276\321\201\321\202\320\276\320\271_\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\276\320\272/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\320\277\321\200\320\276\321\202\320\276\320\272\320\276\320\273/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\320\277\321\200\320\276\321\202\320\276\321\202\320\270\320\277/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\321\201\320\265\321\200\321\202\320\270\321\204\320\270\321\206\320\270\321\200\320\276\320\262\320\260\320\275\320\276/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\321\201\320\270\320\275\321\205\321\200\320\276\320\275\320\275\321\213\320\271/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\321\201\321\202\320\260\321\202\320\270\321\207\320\265\321\201\320\272\320\260\321\217_\321\202\320\270\320\277\320\270\320\267\320\260\321\206\320\270\321\217/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\321\201\321\202\321\200\320\276\320\272\320\260/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\321\201\321\203\321\211\320\275\320\276\321\201\321\202\320\270/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\321\202\320\265\320\263/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\321\204\321\203\320\275\320\272\321\206\320\270\321\217/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\321\204\321\203\320\275\320\272\321\206\320\270\321\217_\320\276\320\261\321\200\320\260\321\202\320\275\320\276\320\263\320\276_\320\262\321\213\320\267\320\276\320\262\320\260/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\321\205\320\265\321\210/index.html" delete mode 100644 "files/ru/\321\201\320\273\320\276\320\262\320\260\321\200\321\214/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/index.html" delete mode 100644 "files/ru/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\321\200\320\260\321\201\321\210\320\270\321\200\320\265\320\275\320\270\321\217/index.html" delete mode 100644 "files/ru/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\321\200\320\260\321\201\321\210\320\270\321\200\320\265\320\275\320\270\321\217/\320\275\320\260\321\201\321\202\321\200\320\276\320\271\320\272\320\260_firefox_\320\264\320\273\321\217_\321\200\320\260\320\267\321\200\320\260\320\261\320\276\321\202\320\272\320\270/index.html" delete mode 100644 "files/ru/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\321\200\320\260\321\201\321\210\320\270\321\200\320\265\320\275\320\270\321\217/\320\275\320\260\321\201\321\202\321\200\320\276\320\271\320\272\320\260_firefox_\320\264\320\273\321\217_\321\200\320\260\320\267\321\200\320\260\320\261\320\276\321\202\320\272\320\270_\321\200\320\260\321\201\321\210\320\270\321\200\320\265\320\275\320\270\320\271/index.html" delete mode 100644 "files/ru/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\321\200\320\260\321\201\321\210\320\270\321\200\320\265\320\275\320\270\321\217_\320\264\320\273\321\217_firefox_\321\201_\320\270\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265\320\274_mozilla_build_system/index.html" delete mode 100644 "files/ru/\321\201\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\260\321\217_\320\270\320\275\321\204\320\276\321\200\320\274\320\260\321\206\320\270\321\217_\320\277\320\276_gecko_dom/index.html" delete mode 100644 "files/ru/\321\201\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\260\321\217_\320\270\320\275\321\204\320\276\321\200\320\274\320\260\321\206\320\270\321\217_\320\277\320\276_gecko_dom/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265/index.html" delete mode 100644 "files/ru/\321\201\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\260\321\217_\320\270\320\275\321\204\320\276\321\200\320\274\320\260\321\206\320\270\321\217_\320\277\320\276_gecko_dom/\320\277\321\200\320\265\320\264\320\270\321\201\320\273\320\276\320\262\320\270\320\265/index.html" delete mode 100644 "files/ru/\321\201\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\260\321\217_\320\270\320\275\321\204\320\276\321\200\320\274\320\260\321\206\320\270\321\217_\320\277\320\276_gecko_dom/\320\277\321\200\320\270\320\274\320\265\321\200\321\213/index.html" delete mode 100644 "files/ru/\321\202\320\265\320\274\321\213/index.html" diff --git a/files/ru/a_basic_raycaster/index.html b/files/ru/a_basic_raycaster/index.html deleted file mode 100644 index 23b14adb7c..0000000000 --- a/files/ru/a_basic_raycaster/index.html +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: A Basic RayCaster -slug: A_Basic_RayCaster -tags: - - Canvas_examples ---- -

 

- -

The raycaster in action

- -

View the live demo.

- -

Why?

- -

After realizing, to my delight, that the nifty <canvas> element I'd been reading about was not only soon to be supported in Firefox, but wasalready supported in the current version of Safari, I had to try a little experiment.

- -

The canvas overview and tutorial I found here at MDC are great, but nobody had written about animation yet, so I thought I'd try a port of a basic raycaster I'd worked on a while ago, and see what sort of performance we can expect from a javascript controlled pixel buffer.

- -

How?

- -

The basic idea is to use setInterval at some arbitrary delay that corresponds to a desired frame rate. After every interval an update function will repaint the canvas showing the current view. I know I could have started with a simpler example, but I'm sure the canvas tutorial will get to that, and I wanted to see if I could do this.

- -

So every update, the raycaster looks to see if you've pressed any keys lately, to conserve calculations by not casting if you're idle. If you have, then the canvas is cleared, the ground and sky are drawn, the camera position and / or orientation are updated and the rays are cast out. As the rays intersect walls, then they render a vertical sliver of canvas in the color of the wall they've hit, blended with a darker version of the color according to the distance to the wall. The height of the sliver is also modulated by the distance from the camera to the wall, and is drawn centered over the horizon line.

- -

The code I ended up with is a regurgitated amalgam of the raycaster chapters from an old André LaMotheTricks of the Game Programming Gurus book (ISBN: 0672305070), and a java raycaster I found online, filtered through my compulsion to rename everything so it makes sense to me, and all the tinkering that had to be done to make things work well.

- -

Results

- -

The canvas in Safari 2.0.1 performed suprisingly well. With the blockiness factor cranked up to render slivers 8 pixels wide, I can run a 320 x 240 window at 24 fps on my Apple mini. Firefox 1.5 Beta 1 is even faster; I can run 320 x 240 at 24 fps with 4 pixel slivers. Not exactly a new member of the ID software family, but pretty decent considering it's a fully interpreted environment, and I didn't have to worry about memory allocation or video modes or coding inner routines in assembler or anything. The code does attempt to be very efficient, using array look-ups of pre-computed values, but I'm no optimization guru, so things could probably be written faster.

- -

Also, it leaves a lot to be desired in terms of trying to be any sort of game engine—there are no wall textures, no sprites, no doors, not even any teleporters to get to another level. But I'm pretty confident all those things could be added given enough time. The canvas API supports pixel copying of images, so textures seem feasible. I'll leave that for another article, probably from another person. =)

- -

The RayCaster

- -

The nice people here have manually copied my files up so you can take a look, and for your hacking enjoyment I've posted the individual file contents as code listings (see below).

- -

So there you are, fire up Safari 1.3+ or Firefox 1.5+ or some other browser that supports the <canvas> element and enjoy!
-
- input.js | Level.js | Player.js | RayCaster.html | RayCaster.js | trace.css | trace.js

- -

See Also

- - - -

{{ languages( { "fr": "fr/Un_raycaster_basique", "ja": "ja/A_Basic_RayCaster", "pl": "pl/Prosty_RayCaster" } ) }}

diff --git a/files/ru/building_an_extension/index.html b/files/ru/building_an_extension/index.html deleted file mode 100644 index f147f764bb..0000000000 --- a/files/ru/building_an_extension/index.html +++ /dev/null @@ -1,248 +0,0 @@ ---- -title: Создание расширения -slug: Building_an_Extension -tags: - - Расширение - - Создание ---- -

Введение

-

Этот урок по шагам покажет Вам как создать простое Расширение – сутью которого является добавление в панель статуса Firefox блока со строкой "Hello, World!"

-
-

Отметьте Данный урок о создании Расширений для Firefox 1.5 и более поздних версий. Другие существующие уроки для создания Расширений, предназначены для более ранних версий.

-

Если Вас интересует урок по созданию Расширения для Thunderbird, смотрите Создание Расширения для Thunderbird

-
-

Настройка окружения

-

Начнём с того, что Расширение распространяется в виде zip архива или Пакетов, с расширением XPI (произносится как “зиппи”).

-

Вот пример типичного XPI файла:

-
exampleExt.xpi:
-              /install.rdf
-              /components/*
-              /components/cmdline.js
-              /defaults/
-              /defaults/preferences/*.js
-              /plugins/*
-              /chrome.manifest
-              /chrome/icons/default/*
-              /chrome/
-              /chrome/content/
-
-
-

Давайте создадим файловою структуру для нашего урока, подобную той что была описана выше, для чего создайте где-нибудь на жёстком диске директорию(например C:\extensions\my_extension\ или ~/extensions/my_extension/).  Создайте в этой директории новую директорию c именем chrome, и создайте в директории chrome директорию с именем code>content.

-

В корне директории вашего Расширения создайте два пустых файла, один назовите chrome.manifest, а другой install.rdf.

-

В итоге у вас должна получиться вот такая структура:

-
<ext path>\
-          install.rdf
-          chrome.manifest
-          chrome\
-             content\
-
-

<pre> #!/bin/sh h=$HOME/moExt mkdir -p $h/my_extension/chrome/content touch $h/my_extension/chrome.manifest $h/my_extension/install.rdf </pre> Более подробную информацию по настройке окружения читайте в статье Setting up extension development environment.

-

Создание файла инсталяции

-

Откройте файл install.rdf который Вы создали на предыдущем этапе и вставьте эти строки:

-
<?xml version="1.0"?>
-
-<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
-
-  <Description about="urn:mozilla:install-manifest">
-    <em:id>sample@example.net</em:id>
-    <em:version>1.0</em:version>
-    <em:type>2</em:type>
-
-    <!-- Указывается приложение для которого может
-            быть установлено Расширение, его максимальная
-            и минимальная поддерживаемая версия. -->
-    <em:targetApplication>
-      <Description>
-        <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
-        <em:minVersion>1.5</em:minVersion>
-        <em:maxVersion>3.0.*</em:maxVersion>
-      </Description>
-    </em:targetApplication>
-
-    <!-- Front End MetaData -->
-    <em:name>sample</em:name>
-    <em:description>A test extension</em:description>
-    <em:creator>Your Name Here</em:creator>
-    <em:homepageURL>http://www.example.com/</em:homepageURL>
-  </Description>
-</RDF>
-
- -

(В Firefox версии 3.0.1, вы не сможете установить для em:minVersion и em:maxVersion значение "3.0.*". Если Вы попытаетесь установить Расширение, то получите ошибку "Not compatible with Firefox 3.0.1". Мне не ясны причины этого, так что я оставлю объяснение тому, кто имеет больше информации по этому поводу. Установка em:minVersion равным "3" и em:maxVersion равным "3.0.*" решило проблему для меня.)

-

Расширения разработанные для работы только с последними версиями Firefox 2.0.0.x, должны иметь установленным максимальную версию в "2.0.0. *". Расширения, разработанные для работы с только с последними версиями Firefox 1.5.0.x, должны иметь установленным максимальную версию "1.5.0. *".

-

Более подробно См. Install Manifests с полным перечнем основных и дополнительных свойств.

-

Сохраните файл.

-

Расширение браузера с помощью XUL

-

Пользовательский интерфейс Firefox написан c использованием XUL и JavaScript.   XUL является языком разметки на основе грамматики XML, которая позволяет описывать такие фрагменты пользовательского интерфейса, как кнопки, меню, панели инструментов, деревья и т.д.  Вся функциональность и обработка действий пользователя осуществляется с помощью JavaScript.

-

Чтобы расширить браузер, мы изменяем различные части интерфейса браузера путём добавления или изменения ”виджетов”. Мы добавляем “виджеты”, вставляя новые элементы, DOM XUL в окно браузера и изменяем их, используя сценарий (скрипт) и присоединяя, обработчики событий.

-

Интерфейс браузера описан в XUL файле, который называется browser.xul ($FIREFOX_INSTALL_DIR/chrome/browser.jar contains content/browser/browser.xul).  В browser.xul, мы можем найти фрагмент описывающий строку состояния, который выглядит вот так:

-
<statusbar id="status-bar">
- ... <statusbarpanel>s ...
-</statusbar>
-
-

<statusbar id="status-bar"> это “точка слияния" для XUL Оверлея.

-
XUL Оверлеи
-

XUL Оверлей - это способ внедрить другие “виджеты” пользовательского интерфейса в основной документ XUL. XUL Оверлей – это .xul файл, в котором определены фрагменты XUL для вставки в определённых “точках слияния” в основном документе. Эти фрагменты, могут определять “виджеты” которые должны быть вставлены, удалены, или изменены.

-

Пример документа XUL Оверлея:

-
<?xml version="1.0"?>
-<overlay id="sample"
-         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
- <statusbar id="status-bar">
-  <statusbarpanel id="my-panel" label="Hello, World"/>
- </statusbar>
-</overlay>
-
-

<statusbar> название status-bar определяет "точку слияния" в пределах окна браузера, к которой мы хотим присоединить.

-

<statusbarpanel> новый “виджет” который мы хотели бы вставить в пределах точки слияния.

-

Возьмите этот простой код и сохраните в новом файле с именем sample.xul и поместите его в директорию chrome/content.

-

Для получения дополнительной информации о присоединении “виджетов” и изменении пользовательского интерфейса, используя Оверлеи, см. далее.

-

Chrome URIs

-

XUL Файлы - это часть пакета Chrome Packages - пакета компонентов пользовательского интерфейса, которые загружаются через chrome://URIs. Вместо того, чтобы загружать их диска, используя file://URI (так как местоположение Firefox в системе может меняться от платформы к платформе и от системы к системе), разработчики Mozilla придумали решение, которое позволяет создать URIs к информационному наполнению XUL, о котором знает установленное приложение.

-

В окне браузера: chrome://browser/content/browser.xul. Напечатайте этот URL в адресной строке Firefox!

-

Chrome URIs состоит из нескольких составляющих:

- -

Так, chrome://foo/skin/bar.png  загружает файл bar.png из темы foo раздела skin.

-

Когда Вы загружаете содержимое, используя Chrome URI, Firefox использует системный реестр Chrome, чтобы транслировать URIs в фактические исходные файлы на диске (или в пакетах JAR).

-

Создание установок Chrome

-

Для получения дополнительной информации об установках Chrome и о поддерживаемых свойствах руководство по Chrome Manifest.

-

Откройте файл с названием chrome.manifest который Вы создали рядом с каталогом chrome в корне исходной иерархии директории Вашего Расширения.

-

Добавьте в него код:

-
content     sample    chrome/content/
-
-

(Не забывайте, косую черту "/"! Без этого пакет не будет зарегистрирован.)

-

Здесь определяется:

-
    -
  1. тип материала в пределах chrome пакета
  2. -
  3. название chrome пакета (удостоверьтесь, что Вы используете все символы в нижнем регистре для имени пакета ("sample"), так как во 2-й версии не поддерживается смешанные регистры и вы получите ошибку {{ Bug(132183) }}
  4. -
  5. местоположение файлов chrome пакета
  6. -
-

Эта строка говорит, что для chrome пакета с именем sample, файлы информационного наполнения находятся в chrome/content, который является путем относительно местоположения chrome.manifest.

-

Заметьте, что content, locale и skin должны быть сохранены как каталоги, с соответствующими именами content, locale и skin в подкаталоге chrome.

-

Сохраните файл. Когда Вы запустите Firefox со своим расширением, (это будет позже в данном уроке), chrome пакет будет зарегистрирован.

-

Регистрация Оверлея

-

Вам нужно присоединить ваш оверлей к окну браузера Firefox, при его отображении. Для этого добавьте следующую строку файл chrome.manifest:

-
overlay chrome://browser/content/browser.xul chrome://sample/content/sample.xul
-
-

Эта строка говорит браузеру, присоединить sample.xul к browser.xul во время загрузки browser.xul.

-

Тестирование

-

Во-первых, мы должны рассказать о своём расширении Firefox. На стадии разработки для Firefox версии 2.0 и выше, вы можете указать Firefox папку, где вы разрабатываете Расширение, и оно будет загружать его каждый раз после перезапуска Firefox.

-
    -
  1. Перейдите в папку вашего профиля по умолчанию. Папка вашего профиля по умолчанию, должна, находится где-то в папке профилей, например в Firefox/Profiles/<profile_id>.default/.
  2. -
  3. Откройте папку extensions. Если ранее вы уже устанавливали, какие либо расширения, то она должна уже существовать.
  4. -
  5. Создайте там, новый текстовый файл и запишите в него путь к папке с вашим расширением, например C:\extensions\my_extension\ или ~/extensions/my_extension/. Сохраните файл, указав в качестве имени идентификатор вашего Расширения, в нашем примере этоsample@example.net.
  6. -
-

(Не забывайте, косую черту, "/"! Без этого ваше расширение не будет зарегистрировано.)

-

(my_extension может не работать! Если имя папки содержит символы подчеркивания.)

-

Теперь всё готово для испытания вашего расширения!

-

Запустите Firefox. Firefox обнаружит ссылку на каталог вашего расширения и установит его. Когда появится окно браузера вы должны увидеть текст "Hello, World!" на правой стороне в панели статуса.

-

Вы можете вернуться и внести необходимые изменения в .xul файл, после чего закрыть и перезапустить Firefox и изменения немедленно вступят в силу.

-

Упаковка

-

Теперь, когда ваше расширение работает, вы можете его упаковать для последующего развертывания и установки.

-

За "зипуйте" папку contents вашего Расширения (не саму папку расширения), и переименуйте получившийся zip файл, так чтобы он имел расширение .xpi. В Windows XP, вы можете сделать это очень просто, выбрав все файлы и вложенные папки в папке вашего расширения, и щелкнув правой кнопкой мыши и выбрав "Send To -> Compressed (Zipped) Folder". Zip файл будет создан. Просто переименуйте его, и готово!

-

В Mac OS X, вы можете нажать правой кнопкой мыши на папке contents вашего Расширения и выбрать "Создать архив ..." для создания архива. Однако, Mac OS X добавляет скрытые файлы в папку. Поэтому следует использовать Terminal, для удаления скрытых файлов (чьи имена начинаются с периода), а затем ввести в командной строке zip команду для создания архива.

-

В Linux, вы аналогичным образом можете использовать в командной строке Zip инструменты.

-

Если у вас установлено Extension Builder вы можете использовать его для сборки .xpi файла (Tools -> Extension Developer -> Extension Builder). Просто выберите каталог, где находится ваше расширение (install.rdf т.д.), и нажмите кнопку Build Extension (Построить расширение). Это расширение имеет множество инструментов для облегчения процесса создания расширений.

-

Теперь загрузите ваш .XPI файл на сервер, и сделайте, так чтобы он определялся как application/x-xpinstall. Вы можете давать ссылку на него и позволить людям скачивать и установить его. Для тестирования нашего. XPI файла можно просто перетащить его в окно менеджера расширений, открыв его через меню Tools -> Extensions в Firefox 1.5.0.x, или Tools -> Add-ons в более поздних версиях.

-
Установка с web-страниц
-

Существует множество путей, которыми вы можете устанавливать ваши расширения прямо с web-страниц, в том числе использование прямых ссылок на файлы XPI и использование InstallTrigger method объекта. Разработчикам расширений и веб разработчикам, рекомендуется использовать для установки XPI методы InstallTrigger, которые дают больше возможностей их пользователям.

-
Использование addons.mozilla.org
-

С помощью сайта Mozilla Add-ons вы может распространять ваше Расширение для бесплатного пользования. Вше расширение будет иметь зеркала на Mozilla, что обеспечит доступность вашего расширения, если оно станет очень популярным. Сайт Mozilla также упрощает установку расширений для пользователей , и автоматически сделает доступными ваши новые версии для пользователей вашей текущей версии, после того как вы загрузите их. Кроме того Mozilla Add-ons позволяет пользователям оставлять комментарии и тем самым обеспечивает обратную связь с Вашим Расширением. Настоятельно рекомендуется использовать Mozilla Add-ons для распространения ваших расширений!

-

Зайдите на http://addons.mozilla.org/developers/ создайте учётную запись и начинайте распространение ваших расширений!

-

Примечание:Ваше Расширение будет скачиваться быстрее и чаще, если у вас будет хорошее описание и скриншоты с вашим расширением в действии.

-
Регистрация расширений в реестре Windows
-

В Windows, информация о расширениях может быть добавлена в реестр, откуда Расширение автоматически будет извлекаться в следующий раз, при загрузке приложения. This allows application installers to easily add integration hooks as extensions. Для получения более подробной информации смотри Adding Extensions using the Windows Registry.

-

Подробнее о XUL Оверлеях

-

Помимо добавления UI виджетов, вы также можете использовать XUL фрагменты для:

- -
<statusbarpanel position="1" .../>
-
-<statusbarpanel insertbefore="other-id" .../>
-
-<statusbarpanel insertafter="other-id" .../>
-
-

Создание новых компонентов UI

-

Вы можете создавать ваши собственные окна и диалоговые окошки в отдельных .xul файлах, обеспечивая их функциональность с помощью описания действий пользователя в .js файлах, используя DOM для манипуляции UI “виджетами”. Вы можете использовать стили из .css файлов для присоединения изображений, установки цвета и т.д.

-

Смотрите документацию по XUL на крупных ресурсах для разработчиков XUL.

-

Файлы По умолчанию

-

Файлы по умолчанию, которые вы используете для профиля пользователя, должны быть помещены в defaults/ в корень в иерархии папок вашего Расширения. По умолчанию .js файлы с настройками должны храниться в defaults/preferences/ - после того как вы поместите их туда они будут автоматически загружаться в системные настройки Firefox при запуске, так что вы сможете получить к ним доступ использую Preferences API.

-

Пример файла настроек по умолчанию:

-
pref("extensions.sample.username", "Joe"); //строка
-pref("extensions.sample.sort", 2); //число
-pref("extensions.sample.showAdvanced", true); //булево
-
-

XPCOM Components

-

Firefox поддерживает XPCOM компоненты в расширениях. Вы можете легко создавать свои собственные компоненты на JavaScript или C + + (с использованием Gecko SDK).

-

Поместите все ваши. JS или. DLL файлы каталог components/ - после установки расширения , они автоматически будут зарегистрированы при первом запуске Firefox.

-

Для получения дополнительной информации см. Как создать XPCOM компонент на JavaScript, Как создать XPCOM компонент с использованием Visual Studio и Cкниги по созданию XPCOM Компонентов.

-
Командная строка приложения
-

Один из возможных вариантов использования пользовательских XPCOM компонентов добавить в командную строку указатель для Firefox или Thunderbird. Вы можете использовать этот метод для запуска ваших расширений, как приложений:

-
 firefox.exe -myapp
-
-

I should move the useful parts of this to the Command Line page. -Nickolay This is done by adding a component containing the function... function NSGetModule(comMgr, fileSpec) { return myAppHandlerModule; } This function is run by firefox each time firefox is started. Firefox registers the myAppHandlerModule's by calling its 'registerSelf()'. Then it obtains the myAppHandlerModule's handler factory via 'getClassObject()'. The handler factory is then used to create the handle using its 'createInstance(). Finally, the handle's 'handle(cmdline)' processes the command line cmdline's handleFlagWithParam() and handleFlag(). Смотрите Chrome: Command Line , а также обсуждения на форуме.

-

Локализация

-

Для поддержки более чем одного языка, вы должны вместо отдельных строк из вашего содержимого использовать "сущности" или a href="mks://localhost/en/XUL_Tutorial/Property_Files" title="en/XUL_Tutorial/Property_Files">"связки строк". Это лучше делать в самом начале разработки Вашего Расширения, а не возвращаться, к этому позже!

-

Информация о локализации хранится в каталоге локализации расширения. Например, чтобы добавить локализацию для нашего расширения, создайте директорию с именем "locale" в каталоге chrome (где находится каталог "content" ) и добавьте следующую строчку в файл chrome.manifest:

-
locale sample en-US chrome/locale/en-US/
-
-

Для создания локализации , значения атрибута в XUL, вы вставляете его значение в .ent (или .dtd) файле который, затем помещаете каталог локализации и который выглядит так:

-
<!ENTITY  button.label     "Click Me!">
-<!ENTITY  button.accesskey "C">
-
-

Затем, подключаете его в верхней части вашего XUL документа ( сразу под строкой ), вот так::

-
<!DOCTYPE window SYSTEM "chrome://packagename/locale/filename.ent">
-
-

где window это localName значение, которое является корневым элементом вашего XUL документа, и свойство SYSTEM значение которого chorm URI к файлу с сущностями. Для примера нашего расширения, мы используем корневой элемент overlay.

-

Для использования сущностей измените ваш XUL, что бы он выглядел так:

-
<button label="&button.label;" accesskey="&button.accesskey;"/>
-
-

Chrome реестр всегда будет загружать тот файл с сущностями, который соответствует текущей выбранной локализации.

-

Для строк которые вы используете в сценарии (скрипте), создайте файл .properties, текстовый файл который будет содержать строки в таком формате:

-
key=value
-
-

а, затем используйте nsIStringBundleService/nsIStringBundle или тег <stringbundle>, чтобы получить значения в сценарии (скрипте).

-

Understanding the Browser

-

Use the DOM Inspector to inspect the browser window or any other XUL window you want to extend.

-

Примечание: DOM Inspector не устанавливается в режиме стандартной установки Firefox. Начиная с версии Firefox 3 Beta 4, DOM Inspector доступен с сайта Firefox Add-ons, как автономное расширение. Для более ранних версий, вам необходимо переустановить FireFox в режиме Пользовательской установки и выбрать путь к DOM Inspector(или Developer Tools в Firefox 1.5), если DOM Inspector'a нет в меню Инструменты (Tools) в вашего браузера.

-

Используйте кнопку Point-and-click icon в верхнем правом углу панели инструментов DOM Inspector для визуального выбора интересующего элемента в окне XUL. После выбора элемента, в окне DOM inspector появится DOM иерархия интересующего Вас элемента.

-

Use the DOM Inspector's right side panel to discover merge points with ids that you can use to insert your elements from overlays. If you cannot discover an element with an id that you can merge into, you may need to attach a script in your overlay and insert your elements when the load event fires on the master XUL window.

-

Debugging Extensions

-

Analytical Tools for Debugging

- -

printf debugging

- -

Advanced debugging

- -

Быстрый старт

-

Вы можете использовать Extension Wizard, инструмент для создания простых Расширений.

-

A Hello World extension similar to what you can generate with the Extension Wizard is explained line-by-line in another tutorial from MozillaZine Knowledge Base.

-

Further information

- diff --git a/files/ru/chrome/index.html b/files/ru/chrome/index.html deleted file mode 100644 index e9f42b17a8..0000000000 --- a/files/ru/chrome/index.html +++ /dev/null @@ -1,80 +0,0 @@ ---- -title: Chrome -slug: Chrome -tags: - - Toolkit API -translation_of: Glossary/Chrome -translation_of_original: Chrome ---- -

Chrome применительно к Mozilla имеет несколько разных значений.

-

Браузерный chrome / Chrome

-
-
- «Браузерный chrome» — это пользовательский интерфейс (UI) самого браузера вокруг отображаемой web-страницы. Иными словами, это всё, что не имеет отношения к контенту страницы.
-
- В общем, chrome — это совокупность элементов, формирующих пользовательский интерфейс приложений или дополнений.
-
-

URL

-
-
- Chrome как протокол вида chrome://, используемый в URL.
-
- Код, загруженный таким образом, имеет расширенные, или - - chrome- - привилегии.
-
- Приложения, основанные на XUL, загружают код своего интерфейса с использованием URL chrome://.
-
-

Привилегии

-
-
- Коду, запущенному с привилегиями chrome, разрешено делать всё, в отличие от веб-контента, который ограничен в своих возможностях.
-
-

Аргумент в window.open

-
-
- Передача аргумента chrome в функцию window.open откроет новое окно браузера без элементов интерфейса.
-
-

Каталог

-
-
- Эта директория, как правило, является частью устанавливаемого приложения, основанного на XUL. Приложения обычно загружают свои UI-файлы из этого каталога.
-
-

Аргумент командной строки

-
-
- Запускает приложение и открывает указанный XUL файл в окне верхнего уровня. Например, команда
-
- mozilla -chrome chrome://inspector/content
-
- запустит DOM Инспектор.
-
-

Пакет

-
-
- Пакет chrome состоит из набора - - провайдеров chrome (providers) - . Существует три базовых типа провайдеров chrome:
-
-
    -
  • Content. Контент может состоять из файлов любого вида, видимых для Mozilla. В частности, ресурс content, как правило, состоит из набора XUL, JavaScript и сборочных файлов XBL.
  • -
  • Locale. Переводы для поддержки нескольких языков. Здесь два основных типа файлов:  DTD файлы и java-подобные файлы свойств.
  • -
  • Skin. Ресурс skin предоставляет полные данные о внешнем виде UI. Состоит из CSS файлов и изображений.
  • -
-
-
-

 

-

chrome.rdf

-
-
- Реестр chrome, хранит список зарегистрированных chrome пакетов и другую информацию. Он был расположен в установочной директории и в профиле. Больше не используется начиная с Gecko 1.8 (Firefox 1.5).
-
-

См. также

-

(Примечание. Хотя оба документа ниже содержат упоминание файлов contents.rdf, более простой способ регистрации ваших chrome ресурсов — это использование Chrome Manifests, поддерживаемых с Firefox 1.5 / Toolkit 1.8)

- -

{{ languages( { "fr": "fr/Chrome", "ja": "ja/Chrome", "pl": "pl/Chrome" ,"ru": "ru/Chrome"} ) }}

diff --git a/files/ru/conflicting/glossary/chrome/index.html b/files/ru/conflicting/glossary/chrome/index.html new file mode 100644 index 0000000000..e9f42b17a8 --- /dev/null +++ b/files/ru/conflicting/glossary/chrome/index.html @@ -0,0 +1,80 @@ +--- +title: Chrome +slug: Chrome +tags: + - Toolkit API +translation_of: Glossary/Chrome +translation_of_original: Chrome +--- +

Chrome применительно к Mozilla имеет несколько разных значений.

+

Браузерный chrome / Chrome

+
+
+ «Браузерный chrome» — это пользовательский интерфейс (UI) самого браузера вокруг отображаемой web-страницы. Иными словами, это всё, что не имеет отношения к контенту страницы.
+
+ В общем, chrome — это совокупность элементов, формирующих пользовательский интерфейс приложений или дополнений.
+
+

URL

+
+
+ Chrome как протокол вида chrome://, используемый в URL.
+
+ Код, загруженный таким образом, имеет расширенные, или + + chrome- + привилегии.
+
+ Приложения, основанные на XUL, загружают код своего интерфейса с использованием URL chrome://.
+
+

Привилегии

+
+
+ Коду, запущенному с привилегиями chrome, разрешено делать всё, в отличие от веб-контента, который ограничен в своих возможностях.
+
+

Аргумент в window.open

+
+
+ Передача аргумента chrome в функцию window.open откроет новое окно браузера без элементов интерфейса.
+
+

Каталог

+
+
+ Эта директория, как правило, является частью устанавливаемого приложения, основанного на XUL. Приложения обычно загружают свои UI-файлы из этого каталога.
+
+

Аргумент командной строки

+
+
+ Запускает приложение и открывает указанный XUL файл в окне верхнего уровня. Например, команда
+
+ mozilla -chrome chrome://inspector/content
+
+ запустит DOM Инспектор.
+
+

Пакет

+
+
+ Пакет chrome состоит из набора + + провайдеров chrome (providers) + . Существует три базовых типа провайдеров chrome:
+
+
    +
  • Content. Контент может состоять из файлов любого вида, видимых для Mozilla. В частности, ресурс content, как правило, состоит из набора XUL, JavaScript и сборочных файлов XBL.
  • +
  • Locale. Переводы для поддержки нескольких языков. Здесь два основных типа файлов:  DTD файлы и java-подобные файлы свойств.
  • +
  • Skin. Ресурс skin предоставляет полные данные о внешнем виде UI. Состоит из CSS файлов и изображений.
  • +
+
+
+

 

+

chrome.rdf

+
+
+ Реестр chrome, хранит список зарегистрированных chrome пакетов и другую информацию. Он был расположен в установочной директории и в профиле. Больше не используется начиная с Gecko 1.8 (Firefox 1.5).
+
+

См. также

+

(Примечание. Хотя оба документа ниже содержат упоминание файлов contents.rdf, более простой способ регистрации ваших chrome ресурсов — это использование Chrome Manifests, поддерживаемых с Firefox 1.5 / Toolkit 1.8)

+ +

{{ languages( { "fr": "fr/Chrome", "ja": "ja/Chrome", "pl": "pl/Chrome" ,"ru": "ru/Chrome"} ) }}

diff --git a/files/ru/conflicting/learn/css/building_blocks/cascade_and_inheritance/index.html b/files/ru/conflicting/learn/css/building_blocks/cascade_and_inheritance/index.html new file mode 100644 index 0000000000..a192eb1d28 --- /dev/null +++ b/files/ru/conflicting/learn/css/building_blocks/cascade_and_inheritance/index.html @@ -0,0 +1,152 @@ +--- +title: Каскадность и наследование +slug: Web/Guide/CSS/Getting_started/Cascading_and_inheritance +tags: + - Beginner + - CSS + - 'CSS:Getting_Started' + - Guide + - Web + - Веб + - Новичку +translation_of: Learn/CSS/Building_blocks/Cascade_and_inheritance +translation_of_original: Web/Guide/CSS/Getting_started/Cascading_and_inheritance +--- +

{{ CSSTutorialTOC() }}

+ +

{{ previousPage("/ru/docs/Web/Guide/CSS/Getting_Started/How_CSS_works", "Как работает CSS")}} Это четвертый раздел руководства CSS для начинающих. Он описывает, как таблицы стилей взаимодействуют в каскаде, и как дочерние элементы наследуют стиль от родительских. Используя наследование, в приведённой ниже задаче вы измените стиль некоторых элементов за один шаг.

+ +

Информация: Каскадность и наследование

+ +

Окончательный стиль элемента можно указать во многих местах, которые комплексно взаимодействуют между собой. Эти комплексные взаимодействия делают CSS мощным, но в то же время, иногда сбивают с толку и порождают сложности при отладке. 

+ +

Три основных источника информации о стилях образовывают каскад. К ним относятся следующие:

+ + + +
    +
  1. Во внешнем файле: в этом учебном руководстве обсуждается преимущественно этот метод указания стилей.
  2. +
  3. В начале документа (раздел заголовок документа): используйте этот метод только для стилей в пределах этой страницы.
  4. +
  5. Для конкретного элемента в теле документа: это наименее поддерживаемый метод, но может быть использован для тестирования.
  6. +
+ +

Стиль пользователя модифицирует стиль браузера по умолчанию. Стиль документа, указанный его автором, изменяет стиль ещё в некоторой мере. В этом обучающем руководстве, вы являетесь автором шаблонного документа, и только вы работаете с авторскими таблицами стилей.

+ +
+
Пример
+ +

Когда вы читаете этот документ в браузере, часть стилей происходит от стилей для HTML по умолчанию вашего браузера.

+ +

Часть стиля может происходить от измененных настроек браузера или измененного файла определения стиля. В Firefox настройки можно изменить в диалоге Предпочтения или же указать стили в файле userContent.css в профиле браузера.

+ +

Часть стиля приходит из таблиц стилей, связываемых с документом вики-сервером.

+
+ +

Когда вы открываете шаблон документа в браузере, элементы {{ HTMLElement("strong") }} имеют более жирный шрифт по сравнению с остальным текстом. Это следует из настроек HTML стилей браузера по умолчанию.

+ +

Элемент {{ HTMLElement("strong") }} красного цвета. Это следует из настроек вашего шаблона таблиц стилей.

+ +

Элементы {{ HTMLElement("strong") }} также наследуют большую часть стилей элемента {{ HTMLElement("p") }} поскольку они являются дочерними. Таким же образом элемент {{ HTMLElement("p") }} наследует большую часть стиля элемента {{ HTMLElement("body") }}.

+ +

Для стилей в каскаде, авторские таблицы стилей имеют приоритет перед стилями для режимов чтения браузера. Последние, в свою очередь, имеют приоритет перед настройками браузера по умолчанию.

+ +

Для наследуемых стилей, собственный стиль дочернего узла имеет приоритет над стилем, унаследованным от родительского узла.

+ +

These are not the only priorities that apply. A later page in this tutorial will explain more.

+ +
+
Подробнее
+ +

CSS также предоставляет способ переопределения стиля в авторском документе для читателя с помощью ключевого слова !important.

+ +

Это означает, что как автор документа, вы не всегда можете точно предсказать, что ваши читатели будут видеть в своём браузере.

+ +

Если вы хотите знать все детали каскадирования и наследования, ознакомьтесь с документом Assigning property values, Cascading, and Inheritance в спецификации CSS.

+
+ +

К действию: Использование наследования

+ +
    +
  1. Откройте CSS-файл примера.
  2. +
  3. Добавьте в файл строку кода, представленную ниже. Не имеет особого значения, в какой части CSS-документа вы расположите эту строку. Тем не менее, добавить его в самом верху будет логично, поскольку в документе элемент {{ HTMLElement("p") }} является родительским по отношению к элементу {{ HTMLElement("strong") }} : +
    p {color: blue; text-decoration: underline;}
    +
    +
  4. +
  5. Теперь сохраните документ и обновите страницу в браузере, чтобы увидеть изменения. Весь текст в абзаце будет подчеркнут, в том числе и начальные буквы. Элемент {{ HTMLElement("strong") }} унаследовал подчеркнутый стиль от родительского элемента {{ HTMLElement("p") }} .
    + +

    Обратите внимание, что элементы {{ HTMLElement("strong") }} всё ещё красные. Красный цвет является их собственным стилем, поэтому имеет приоритет перед синим цветом, заданным для родительского элемента {{ HTMLElement("p") }} . 

    +
  6. +
+ +

До

+ +

HTML

+ +
<p>
+<strong>C</strong>ascading
+<strong>S</strong>tyle
+<strong>S</strong>heets
+</p>
+
+ +

CSS

+ +
strong {color:red}
+
+ +

{{ EmbedLiveSample('Before') }}

+ +

После

+ +

HTML

+ +
<p>
+<strong>C</strong>ascading
+<strong>S</strong>tyle
+<strong>S</strong>heets
+</p>
+
+ +

CSS

+ +
p {color:blue; text-decoration:underline}
+strong {color:red}
+ +

{{ EmbedLiveSample('After') }}

+ +

 

+ +
+
Задание
+Измените таблицу стилей таким образом, чтобы были подчеркнуты только красные буквы: + + + + + + + +
Cascading Style Sheets
+ +
+
Возможное решение
+ +

Переместите объявление подчеркивания из правила для {{ HTMLElement("p") }} в правило для {{ HTMLElement("strong") }}. В результате файл будет выглядеть следующим образом:

+ +
p {color: blue; }
+strong {color: red; text-decoration: underline;}
+
+ +

 

+Hide solution
+Посмотреть вариант решения.
+ +

 

+ +

Что дальше?

+ +

{{ nextPage("/ru/docs/Web/Guide/CSS/Getting_Started/Selectors", "Селекторы")}}Ваш пример таблицы стилей определяет стили для тегов <p> и <STRONG>, изменяя стиль соответствующих элементов по всему документу. В следующем разделе описывается, как задать стиль более избирательными методами.

diff --git a/files/ru/conflicting/learn/css/building_blocks/selectors/index.html b/files/ru/conflicting/learn/css/building_blocks/selectors/index.html new file mode 100644 index 0000000000..a6d9e5d116 --- /dev/null +++ b/files/ru/conflicting/learn/css/building_blocks/selectors/index.html @@ -0,0 +1,133 @@ +--- +title: 'CSS properties: what they are and how to use them' +slug: Learn/CSS/CSS_properties +translation_of: Learn/CSS/Building_blocks/Selectors +translation_of_original: Learn/CSS/CSS_properties +--- +
+

{{Glossary("CSS")}} определяет как должна выглядеть вебстраница. Он использует предопределенные правила вместе с селекторами и свойствами для применения стилей к элементам HTML или группам элементов.

+
+ + + + + + + + + + + + +
Prerequisites:Basics of {{Glossary("HTML")}}, HTML elements, and how to link HTML documents to CSS stylesheets.
Objective:Learn about different CSS selectors and properties enough to style a simple webpage.
+ +

Summary

+ +

Разделение содержимого и стиля делает Веб разработку намного быстрее и проще. Когда вы определяете только стуктуру документа в вашем HTML файле и храните всю информацию о стиле в отдельном файле (называемом stylesheet), вы можете обновлять стили нескольких документов одновременно (а так же экономить ресурсы компьютера).

+ +

CSS syntax consists of easy-to-use, intuitive keywords.

+ +
p {
+   font-family: "Times New Roman", georgia, sans-serif;
+   font-size: 24px;
+}
+ +

In the example above, p is a selector that applies styles to all the {{HTMLElement("p")}} elements at once. The CSS properties font-family and font-size are enclosed within curly braces and the corresponding values, right after the colon, determine the styles.

+ +

There are more than 250 properties you can apply to your document. From text to layout, (almost) anything is possible.

+ +

Active Learning

+ +

There is no active learning available yet. Please, consider contributing.

+ +

Deeper dive

+ +

If properties are fairly simple to use, selectors are another story. Okay, they aren't that hard, and mastering them unleashes the full potential of CSS. In the next examples, we will introduce the most common selectors.

+ +

A CSS rule consists of selectors associated with properties. Selectors specify which elements will receive the properties laid down in the rule. Multiple rules can apply to the same element; the CSS cascade (which we'll discuss later on) determines which rule ends up taking effect in the case of conflicts. For now, just remember that the rule with the most specific selector overrides the rules with more generic selectors.

+ +

The element selector

+ +

Element selectors select HTML elements by element names only. Moreover, like all CSS selectors, you can apply a common set of properties to several elements at once.

+ +

For our first example, let's assume the following HTML code fragment:

+ +
<h1>I'm an example</h1>
+<p>In this example, I'm a paragraph</p>
+<p>And I'm another paragraph</p>
+
+ +

In the following CSS rule, the element selector p applies the given styles simultaneously to all the {{HTMLElement("p")}} elements of our HTML document, preventing extensive rewriting. We are using the {{cssxref("font-family")}} property (which defines the font in which text appears) and the {{cssxref("font-size")}} (which defines text size).

+ +
p {
+  font-family: "Helvetica", Arial, sans-serif;
+  font-size  : 12px;
+}
+ +

The next CSS rule only applies to {{HTMLElement("h1")}} elements. We are using the {{cssxref("font-size")}} property to make our title twice the size of the body text, and the {{cssxref("font-weight")}} property to make the title bold.

+ +
h1 {
+  font-size  : 24px;
+  font-weight: bold;
+}
+ +

The following CSS rule applies the requisite styles to both {{HTMLElement("h1")}} and {{HTMLElement("p")}} elements, potentially removing even more duplication. (This use is called "group selector" or "chain selector". Notice the comma separating the selectors). Here we are using the {{cssxref("color")}} property to specify the same text color for both headings and paragraphs.

+ +
h1, p {
+  color: darkmagenta;
+}
+ +

Here is the result of all this code:

+ +

{{ EmbedLiveSample('The_element_selector') }}

+ +

The id selector

+ +

The id attribute of a particular HTML element uniquely identifies that element. Hence, an id selector is used only when a set of style rules applies to a single element.

+ +

For our next example, let's assume the following HTML code fragment:

+ +
<p id="hello">Hello world!</p> 
+ +

The following CSS rule applies only to that unique identified element. To make a selector into an id selector, you must put a hash character (#) in front of the id name. We are using three properties: {{cssxref("text-align")}} to center the text within the paragraph {{cssxref("border")}} to add a thin line around the paragraph, and {{cssxref("padding")}} to add some extra inner-margin between the text and the border.

+ +
#hello {
+  text-align: center;
+  border    : 1px solid black;
+  padding   : 8px;
+}
+ +

And the result is the following:

+ +

{{ EmbedLiveSample('The_id_selector') }}

+ +

The class selector

+ +

Within HTML, the class attribute lets you apply multiple identifiers to HTML elements. Those identifiers can be used with CSS to match groups of elements regardless of element name.

+ +

For our next example, let's assume the following HTML code fragment:

+ +
<h1 class="hello">Hey there!</h1>
+<p class="hello bye">Let's hang out together!</p>
+<p class="bye">And walk over the mountain</p>
+
+ +

Let's apply a CSS rule for all elements with the class hello. To make the selector into a class selector, put a period/full stop before the class name. We use the {{cssxref("font-style")}} property to italicize the text.

+ +
.hello {
+  font-style: italic;
+}
+ +

And another one for all elements with the class bye. Here we are using the {{cssxref("text-decoration")}} property to draw a line through the text.

+ +
.bye {
+  text-decoration: line-through;
+}
+ +

Here's what happened:

+ +

{{ EmbedLiveSample('The_class_selector') }}

+ +

Next step

+ +

So we've gone over the basics to get started with CSS. You can learn more about text styling or start exploring our CSS Tutorials right away.

diff --git a/files/ru/conflicting/learn/css/building_blocks/selectors_918fb6c37a4d06789bc062c48d591992/index.html b/files/ru/conflicting/learn/css/building_blocks/selectors_918fb6c37a4d06789bc062c48d591992/index.html new file mode 100644 index 0000000000..797aefefa3 --- /dev/null +++ b/files/ru/conflicting/learn/css/building_blocks/selectors_918fb6c37a4d06789bc062c48d591992/index.html @@ -0,0 +1,434 @@ +--- +title: Selectors +slug: Web/Guide/CSS/Getting_started/Selectors +translation_of: Learn/CSS/Building_blocks/Selectors +translation_of_original: Web/Guide/CSS/Getting_started/Selectors +--- +

{{ CSSTutorialTOC() }}

+ +

{{ previousPage("/en-US/docs/Web/Guide/CSS/Getting_Started/Cascading_and_inheritance", "Cascading & inheritance")}}Это пятый раздел руководства CSS для начинающих. В нем объясняется, как можно выборочно применять стили и каким образом различные типы селекторов имеют разные приоритеты.  

+ +

Некоторые атрибуты добавляются к тегам в шаблоне документа, и эти атрибуты используются в шаблоне таблицы стилей.

+ +

Информация: Селекторы

+ +

Ранее мы уже встречались с селекторами. Мы создали строку в файле стилей следующего вида:

+ +
strong {
+  color: red;
+}
+
+ +

В терминологии CSS эта строка полностью является правилом CSS. Это правило начинается со strong, что и называется селектором CSS. Селектор выбирает, к каким элементам DOM применяется правило.

+ +
+
Подробности
+ +

Часть внутри фигурных скобок называется объявлением.

+ +

Ключевое слово colorсвойство, а red - значение.

+ +

Точка с запятой после пары "свойство-значение" отделяет её от других пар "свойство-значение" в том же объявлении.

+ +

Этот учебник ссылается на селектор типа strong как на селектор тега. Спецификация CSS ссылается на него как на селектор типа.

+
+ +

На этой странице учебника объясняются дополнительные сведения о селекторах, которые можно использовать в правилах CSS.

+ +

В дополнение к именам тегов, вы можете использовать в селекторах значения атрибутов. Это позволит вашим правилам быть более избирательными.

+ +

Два атрибута имеют особый статус в CSS. Это class и id.

+ +

Селекторы классов

+ +

Используйте атрибут class в элементе, чтобы назначить элемент именованному классу. Выбор имени класса целиком за вами. Множество элементов в документе может иметь одно и то же значение класса.

+ +

В вашей таблице стилей используйте точку перед именем класса для использования его в качестве селектора.

+ +

Селекторы ID

+ +

Используйте атрибут id в элементе, чтобы назначить идентификатор элементу. Это зависит от вас, какое имя вы выберете для ID. Идентификационное имя должно быть уникальным в документе.

+ +

В таблице стилей введите знак решетки перед идентификатором, когда вы используете его в селекторе.

+ +
+
Пример
+Этот HTML тэг имеет оба элемента, атрибут class и id: + +
<p class="key" id="principal">
+
+ +

Значение идентификатора id, principal, должно быть уникально в документе, но разные тэги в документе, могут иметь одинаковое имя class со значением key.

+ +

Это правило делает все классы(class) со значениемkey зелёными. (Они даже не должны быть все элементами {{ HTMLElement("p") }}.)

+ +
.key {
+  color: green;
+}
+
+ +

Это правило делает один элемент с идентификатором (id) и значением principal полужирным:

+ +
#principal {
+  font-weight: bolder;
+}
+
+
+ +

Селекторы Атрибутов

+ +

Вы не ограничены двумя специальными атрибутами, class и id. Вы можете определить другие атрибуты используя квадратные скобки. Внутри скобок вы задаёте имя атрибута, так же можно указать оператор соответствия и значение. Дополнительно, соответствие может быть установлено как чувствительное к регистру если дописать " i" после значения, но пока не все браузеры это поддерживают. Примеры:

+ +
+
[disabled]
+
Выбирает все элементы с атрибутом "disabled".
+
[type='button']
+
Выбирает элементы с типом "button".
+
[class~=key]
+
Выбирает элементы со значением класса(class) "key" (но не такие как например "keyed", "monkey", "buckeye"). По сути эквивалентно .key.
+
[lang|=es]
+
Выбирает элементы определённые как Spanish. Это включает "es" и "es-MX" но не включает "eu-ES" (что является языком Basque).
+
[title*="example" i]
+
Выбирает элементы в состав которых входит "example", игнорируя регистр. В браузерах, которые не поддерживают флаг "i", этот селектор возможно не найдет ни один элемент.
+
a[href^="https://"]
+
Выбирает все защищённые ссылки.
+
img[src$=".png"]
+
Косвенно выбирает изображения PNG; любые изображения которые являются изображениями PNG но, чей адрес URL не заканчивается на ".png" (такие как в строке запроса) не будут выбраны.
+
+ +

Селекторы псевдокласса

+ +

Псевдокласс класса CSS - это ключевое слово, добавленное в селектор, который задает особое состояние выбранного элемента. Например {{Cssxref (": hover")}} применит стиль, когда пользователь наводит на элемент, указанный селектором.

+ +

Псевдо-классы вместе с псевдоэлементами позволяют применять стиль к элементу не только по отношению к содержанию дерева документов, но и по отношению к внешним факторам, таким как история навигатора ({{ cssxref(":visited") }}, для примера), статус его содержимого (наподобии {{ cssxref(":checked") }} на некоторых элементах формы) или положение мыши (наподобии {{ cssxref(":hover") }} который позволяет узнать, находится ли мышь над элементом или нет). Чтобы просмотреть полный список селекторов, посетите CSS3 Спецификация работы селекторов.

+ +
+
Синтаксис
+ +
selector:pseudo-class {
+  property: value;
+}
+
+
+ +

Список псевдоклассов

+ + + +

Информация: Специфичность

+ +

Несколько правил могут иметь селектор, каждый из которых соответствует одному и тому же элементу. Если свойство задано только одним правилом, конфликт не возникает, и свойство устанавливается в элементе. Если к элементу применяется более одного правила и устанавливает одно и то же свойство, тогда CSS дает приоритет правилу, которое имеет более конкретный селектор. Селектор ID более специфичен, чем селектор класса, псевдокласса или атрибута, который, в свою очередь, более специфичен, чем селектор тегов или псевдоэлементов.

+ +
+
Подробнее
+ +

Вы также можете комбинировать селектор, создавая более конкретный селектор. Например, селектор .key выбирает все элементы, с ключом имени класса key. Селектор p.key отбирает только {{ HTMLElement("p") }} элементы, которые имеют имя класса key.

+
+ +

Если таблица стилей имеет противоречивые правила, и они одинаково специфичны, тогда CSS дает приоритет правилу, которое позже находится в таблице стилей.

+ +

Если у вас возникла проблема с конфликтующими правилами, попробуйте разрешить это, сделав одно из правил более конкретным, чтобы оно имело приоритет. Если вы не можете этого сделать, попробуйте переместить одно из правил ближе к концу таблицы стилей, чтобы оно имело приоритет.

+ +

Информация: Селекторы на основе отношений

+ +

CSS имеет несколько способов выбора элементов на основе отношений между элементами. Вы можете использовать их, чтобы сделать селектора более конкретными.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Общие селекторы, основанные на отношениях
СелекторВыбрано
A EЛюбой E элемент, что является потомком одного из A элемента (то есть: дочерний, или один из дочернего, т.д.)
A > EЛюбой E элемент, что явлется  дочерним (т.е. прямой потомок)  A элемента.
E:first-childЛюбой E элемент, что является первым дочерним элементом родительского элемента.
B + EЛюбой E элемент, что является следующим "братом" B элемента (то есть: следующий ребенок того же родителя)
+ +

Вы можете комбинировать их для выражения сложных отношений.

+ +

Вы можете так же использовать символ * (звездочка), что подразумевает "любой элемент".

+ +
+
Пример
+ +

Таблица HTML имеет аттрибут id , но строки и ячейки не имеют отдельных идентификаторов:

+ +
<table id="data-table-1">
+...
+<tr>
+<td>Prefix</td>
+<td>0001</td>
+<td>default</td>
+</tr>
+...
+
+ +

Эти правила делают первую ячейку в каждой строке подчеркнутой, а "брат" первой ячейки каждой строки зачеркнутой (в примере 2-я ячейка) . Они влияют только на одну конкретную таблицу в документе::

+ +
#data-table-1 td:first-child {text-decoration: underline;}
+#data-table-1 td:first-child + td {text-decoration: line-through;}
+
+ +

Резульат  выглядит  наподобии:

+ + + + + + + +
+ + + + + + + + +
Prefix0001default
+
+
+ +
+
Подробно
+ +

Обычным способом, если вы делаете селектор более конкретным, вы увеличиваете его приоритет.

+ +

Если вы используете эти методы, вы избегаете необходимость указывать в атрибутах class или id на множестве тегов в вашем документе. Вместо этого, CSS выполнит эту работу.

+ +

В больших конструкциях, где скорость важна, вы можете сделать свои таблицы стилей более эффективными, избегая сложных правил, которые зависят от отношений между элементами.

+ +

Дополнительные примеры о таблицах, смотрите Tables на странице ссылок CSS.

+
+ +

Действие: Использование селекторов class и ID

+ +
    +
  1. Измените свой HTML-файл и продублируйте абзац, скопировав его и вставив в него.
  2. +
  3. Затем добавьте аттрибуты id и class  в первую копию, а аттрибут id во вторую копию, как показано ниже. Кроме того, скопируйте и вставьте весь файл снова: +
    <!doctype html>
    +<html>
    +  <head>
    +  <meta charset="UTF-8">
    +  <title>Sample document</title>
    +  <link rel="stylesheet" href="style1.css">
    +  </head>
    +  <body>
    +    <p id="first">
    +      <strong class="carrot">C</strong>ascading
    +      <strong class="spinach">S</strong>tyle
    +      <strong class="spinach">S</strong>heets
    +    </p>
    +    <p id="second">
    +      <strong>C</strong>ascading
    +      <strong>S</strong>tyle
    +      <strong>S</strong>heets
    +    </p>
    +  </body>
    +</html>
    +
    +
  4. +
  5. Теперь отредактируйте свой файл CSS. Замените все содержимое на: +
    strong { color: red; }
    +.carrot { color: orange; }
    +.spinach { color: green; }
    +#first { font-style: italic; }
    +
    +
  6. +
  7. Сохраните файлы и обновите свой браузер, чтобы увидеть результат: + + + + + + + + + +
    Cascading Style Sheets
    Cascading Style Sheets
    + +

    Вы можете попробовать перестроить строки в вашем файле CSS, чтобы показать, что порядок не имеет никакого эффекта.

    + +

    Селекторы классов .carrot и .spinach имеют приоритет над селектором тега strong.

    + +

    Селектор ID #first имеет приоритет над селекторами класс и тег.

    +
  8. +
+ +
+
Вызовы
+ +
    +
  1. Не изменяя свой HTML-файл, добавьте в свой CSS-файл одно правило, которое сохраняет все начальные буквы того же цвета, что и сейчас, но делает весь текст во втором абзаце синим: + + + + + + + + + + +
    Cascading Style Sheets
    Cascading Style Sheets
    +
  2. +
  3. Теперь измените правило, которое вы только что добавили (не изменяя ничего другого), чтобы сделать первый абзац синим: + + + + + + + + + +
    Cascading Style Sheets
    Cascading Style Sheets
    +
  4. +
+ +
+
Possible solution
+ +
    +
  1. Add a rule with an ID selector of #second and a declaration color: blue;, as shown below: + +
    #second { color: blue; }
    +
    + A more specific selector, p#second also works.
  2. +
  3. Change the selector of the new rule to be a tag selector using p: +
    p { color: blue; }
    +
    +
  4. +
+Hide solution
+See a solution for the challenge.
+ +

Действие: Использование селекторов псевдокласса

+ +
    +
  1. Создайте HTML-файл со следующим содержимым: + +
    <!doctype html>
    +<html>
    +  <head>
    +  <meta charset="UTF-8">
    +  <title>Sample document</title>
    +  <link rel="stylesheet" href="style1.css">
    +  </head>
    +  <body>
    +    <p>Go to our <a class="homepage" href="http://www.example.com/" title="Home page">Home page</a>.</p>
    +  </body>
    +</html>
    +
    +
  2. +
  3. Теперь отредактируйте свой файл CSS. Замените все содержимое на: +
    a.homepage:link, a.homepage:visited {
    +  padding: 1px 10px 1px 10px;
    +  color: #fff;
    +  background: #555;
    +  border-radius: 3px;
    +  border: 1px outset rgba(50,50,50,.5);
    +  font-family: georgia, serif;
    +  font-size: 14px;
    +  font-style: italic;
    +  text-decoration: none;
    +}
    +
    +a.homepage:hover, a.homepage:focus, a.homepage:active {
    +  background-color: #666;
    +}
    +
    +
  4. +
  5. Сохраните файлы и обновите свой браузер, чтобы увидеть результат (наведите указатель мыши на следующую ссылку, чтобы увидеть эффект): + + + + + + +
    Перейдите к нашей Домашняя страница 
    +
  6. +
+ +

Действие: Использование селекторов на основе отношений и псевдоклассов

+ +

С помощью селекторов, основанных на связях и псевдоклассах, вы можете создавать сложные каскадные алгоритмы. Это обычная техника, используемая, например, для создания чисто-CSS выпадающее меню ( это только CSS, без использования JavaScript). Суть этого метода заключается в создании правила следующего вида:

+ +
div.menu-bar ul ul {
+  display: none;
+}
+
+div.menu-bar li:hover > ul {
+  display: block;
+}
+ +

для применения к структуре HTML, наподобии следующей:

+ +
<div class="menu-bar">
+  <ul>
+    <li>
+      <a href="example.html">Menu</a>
+      <ul>
+        <li>
+          <a href="example.html">Link</a>
+        </li>
+        <li>
+          <a class="menu-nav" href="example.html">Submenu</a>
+          <ul>
+            <li>
+              <a class="menu-nav" href="example.html">Submenu</a>
+              <ul>
+                <li><a href="example.html">Link</a></li>
+                <li><a href="example.html">Link</a></li>
+                <li><a href="example.html">Link</a></li>
+                <li><a href="example.html">Link</a></li>
+              </ul>
+            </li>
+            <li><a href="example.html">Link</a></li>
+          </ul>
+        </li>
+      </ul>
+    </li>
+  </ul>
+</div>
+
+ +

Смотрите наш полный Пример CSS-основанного выпадающего меню для возможной реплики.

+ +

Что дальше?

+ +

Ваша таблица стилей начинает выглядеть плотной и сложной. Следующая секция описывает пути CSS легкого чтения. {{nextPage("/en-US/docs/Web/Guide/CSS/Getting_Started/Readable_CSS", "Readable CSS")}}

diff --git a/files/ru/conflicting/learn/css/building_blocks/styling_tables/index.html b/files/ru/conflicting/learn/css/building_blocks/styling_tables/index.html new file mode 100644 index 0000000000..82b7edae60 --- /dev/null +++ b/files/ru/conflicting/learn/css/building_blocks/styling_tables/index.html @@ -0,0 +1,525 @@ +--- +title: Таблицы +slug: Web/Guide/CSS/Getting_started/Таблицы +tags: + - CSS + - Веб + - Руководство +translation_of: Learn/CSS/Building_blocks/Styling_tables +translation_of_original: Web/Guide/CSS/Getting_started/Tables +--- +

{{CSSTutorialTOC}}{{previousPage("/ru/docs/Web/Guide/CSS/Getting_Started/Layout", "Layout")}}

+ +

Это 13-я секция руководства CSS Начало работы; оно описывает более продвинутые селекторы и некоторые специфичные способы, которыми вы можете стилизовать таблицу. Вы создаете новый пример документа, содержащий таблицу и таблицу стилей для неё.

+ +

Информация: Таблицы

+ +

Таблица распологает информацию в прямоугольной сетке. Некоторые таблицы могут быть сложными, и для сложных таблиц разные браузеры выдают разный результат.

+ +

Когда вы проектируете ваш документ, используйте таблицы для выражения отношений между кусочками информации. Поэтому это не важно, если различные браузеры отображают информацию слегка различными способами, потому что значение остается ясным.

+ +

Не используйте таблицы необычным способом для создания особенной визуальной разметки. Техники на предыдущей странице руководства (Разметка) предпочтительнее для этой цели.

+ +

Структура таблицы

+ +

В таблице, каждый кусок информации отображается в ячейке (cell).

+ +

Ячейки, лежащие на одной линии, составляют строку (row).

+ +

В некоторыех таблицах, строки могут быть сгруппирированы. Специальная группа строк в начале таблицы - заголовок (header), в конце - нижний колонтитул (footer). Главные строки таблицы - тело (body), и они могут быть также сгруппирированы.

+ +

Ячейки в линии сверху вниз, составляют столбец (column), но столбцы имеют ограниченное приминение в таблицах CSS.

+ +
+
Пример
+ +

Таблица Селекторов, основанных на отношении в Селекторы имеет десять ячеек в пяти строках.

+ +

Первая строка - заголовок. Остальные четыре строки - тело таблицы. Нижнего колонтитула нет.

+ +

У неё два столбца.

+
+ +

Это руководство охватывает только простые таблицы, где результат довольно предсказуемый. В простой таблице, каждая ячейка занимает только одну ячейку в строке и в столбце. Вы можете использовать CSS для сложных таблиц, где ячейки занимают диапазон ячеек более чем одна в строке или столбце, но таблицы, подобно этим находятся вне пределов этого руководства.

+ +

Рамки

+ +

Ячейки не имеют границ.

+ +

У ячеек нет рамок и наполнений. По умолчанию, рамки разделены значениями таблицы, свойство {{cssxref("border-spacing")}}. Вы можете также полностью удалить пространство, установив свойство таблицы {{cssxref("border-collapse")}} в collapse.

+ +
+
Пример
+ +

Здесь три таблицы.

+ +

У таблицы слева интервал рамки 0.5 em. У таблицы по центру он составляет ноль. Таблица справа имеет сжатые границы:

+ + + + + + + + + +
+ + + + + + + + + + + +
ClubsHearts
DiamondsSpades
+
+ + + + + + + + + + + +
ClubsHearts
DiamondsSpades
+
+ + + + + + + + + + + +
ClubsHearts
DiamondsSpades
+
+
+ +

Заголовок

+ +

{{HTMLElement("caption")}} элемент - это метка, которая применяется ко всей таблице. По умолчанию, она отображается вверху таблицы.

+ +

Чтобы переместить её вниз, установите её свойство {{cssxref("caption-side")}} в bottom. Это свойство наследуется, поэтому, в качестве альтернативы вы можете установить это свойство у таблицы или у другого элемента предка.

+ +

Чтобы стилизовать заголовок текста, используйте любое из обычных свойств для текста.

+ +
+
Пример
+ +

У этой таблицы заголовок внизу

+ +
#demo-table > caption {
+  caption-side: bottom;
+  font-style: italic;
+  text-align: right;
+}
+
+ + + + + + + +
+ + + + + + + +
Подходит
+ + + + + + + + + + + +
КлубыСердца
АлмазыЛопаты
+
+
+
+ +

Пустые ячейки

+ +

Вы можете отобразить пустые ячейки (т.е. их рамки и фон) указывав {{cssxref("empty-cells")}}: show; для элемента таблицы.

+ +

Вы можете скрыть их, указав empty-cells: hide;. Тогда, если у элемента родителя ячейки есть фон, он будет отображен через пустую ячейку.

+ +
+
Пример
+ +

Эти таблицы имеют бледно-зелёный фон. Их ячейки имеют бледно-серый фон и тёмно-серые рамки.

+ +

В таблице слева пустая таблица отображается. В таблице справа, она скрыта:

+ + + + + + + + +
+ + + + + + + + + + + +
 Сердца
АлмазыЛопаты
+
+ + + + + + + + + + + +
 Сердца
АлмазыЛопаты
+
+
+ +
+
Детали
+ +

Для подбробной информации о таблицах, смотрите Таблицы в Спецификации CSS.

+ +

Информации там больше, чем в этом руководстве, но она не покрывает различия между браузерами, которые могут влиять на сложные таблицы.

+
+ +

Действие: Стилизация таблицы

+ +
    +
  1. Создайте новый HTML документ, doc3.html. Скопируйте и вставьте содержимое отсюда: + +
    +
    <!DOCTYPE html>
    +<html>
    +  <head>
    +    <title>Документ примера 3</title>
    +    <link rel="stylesheet" href="style3.css">
    +  </head>
    +  <body>
    +    <table id="demo-table">
    +      <caption>Океаны</caption>
    +      <thead>
    +        <tr>
    +          <th></th>
    +          <th>Площадь</th>
    +          <th>Средняя глубина</th>
    +        </tr>
    +        <tr>
    +          <th></th>
    +          <th>млн. км<sup>2</sup></th>
    +          <th>м</th>
    +        </tr>
    +      </thead>
    +      <tbody>
    +        <tr>
    +          <th>Северный Ледовитый</th>
    +          <td>13,000</td>
    +          <td>1,200</td>
    +        </tr>
    +        <tr>
    +          <th>Атлантический</th>
    +          <td>87,000</td>
    +          <td>3,900</td>
    +        </tr>
    +        <tr>
    +          <th>Тихий</th>
    +          <td>180,000</td>
    +          <td>4,000</td>
    +        </tr>
    +        <tr>
    +          <th>Индийский</th>
    +          <td>75,000</td>
    +          <td>3,900</td>
    +        </tr>
    +        <tr>
    +          <th>Южный</th>
    +          <td>20,000</td>
    +          <td>4,500</td>
    +        </tr>
    +      </tbody>
    +      <tfoot>
    +        <tr>
    +          <th>Общая</th>
    +          <td>361,000</td>
    +          <td></td>
    +        </tr>
    +        <tr>
    +          <th>Средняя</th>
    +          <td>72,000</td>
    +          <td>3,800</td>
    +        </tr>
    +      </tfoot>
    +    </table>
    +  </body>
    +</html>
    +
    +
    +
  2. +
  3. Создайте новую таблицу стилей, style3.css. Скопируйте и вставьте содержимое отсюда: +
    /*** Style for doc3.html (Tables) ***/
    +
    +#demo-table {
    +  font: 100% sans-serif;
    +  background-color: #efe;
    +  border-collapse: collapse;
    +  empty-cells: show;
    +  border: 1px solid #7a7;
    +}
    +
    +#demo-table > caption {
    +  text-align: left;
    +  font-weight: bold;
    +  font-size: 200%;
    +  border-bottom: .2em solid #4ca;
    +  margin-bottom: .5em;
    +}
    +
    +
    +/* basic shared rules */
    +#demo-table th,
    +#demo-table td {
    +  text-align: right;
    +  padding-right: .5em;
    +}
    +
    +#demo-table th {
    +  font-weight: bold;
    +  padding-left: .5em;
    +}
    +
    +
    +/* header */
    +#demo-table > thead > tr:first-child > th {
    +  text-align: center;
    +  color: blue;
    +}
    +
    +#demo-table > thead > tr + tr > th {
    +  font-style: italic;
    +  color: gray;
    +}
    +
    +/* fix size of superscript */
    +#demo-table sup {
    +  font-size: 75%;
    +}
    +
    +/* body */
    +#demo-table td {
    +  background-color: #cef;
    +  padding:.5em .5em .5em 3em;
    +}
    +
    +#demo-table tbody th:after {
    +  content: ":";
    +}
    +
    +
    +/* footer */
    +#demo-table tfoot {
    +  font-weight: bold;
    +}
    +
    +#demo-table tfoot th {
    +  color: blue;
    +}
    +
    +#demo-table tfoot th:after {
    +  content: ":";
    +}
    +
    +#demo-table > tfoot td {
    +  background-color: #cee;
    +}
    +
    +#demo-table > tfoot > tr:first-child td {
    +  border-top: .2em solid #7a7;
    +}
    +
    +
  4. +
  5. Откройте документ в вашем браузере. Он должен выглядеть наподобие этого: + + + + + + +
    +

    Океаны

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     ПлощадьСредняя глубина
     млн. км2м
    Северный Ледовитый:13,0001,200
    Атлантический:87,0003,900
    Тихий:180,0004,000
    Индийский:75,0003,900
    Южный:20,0004,500
    Общая:361,000 
    Средняя:72,0003,800
    +
    +
    +
  6. +
  7. Сравните правила в таблице стилей с отображенной таблицей, чтобы гарантировать, что вы понимаете действие для каждого правила. Если вы найдете правило, значение которого вы не понимаете, то закомментируйте его и обновите страницу, чтобы посмотреть, что изменилось. Вот несколько заметок об этой таблице: +
      +
    • Заголовок находится снаружи рамки таблицы.
    • +
    • Если у вас установлен минимальный размер точки в Опциях, это может повлиять на верхний индекс в km2.
    • +
    • Три пустые ячейки. Через две из них  позволено показывать фон таблицы. У третьей есть фон и верхняя рамка.
    • +
    • Двоеточия добавлены с помощью таблицы стилей.
    • +
    +
  8. +
+ +
+
Вызов
+ +

Измените таблицу стилей, чтобы она выглядела, как эта:

+ + + + + + + +
+
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 ПлощадьСредняя глубина
 млн. км2м
Северный Ледовитый:13,0001,200
Атлантический:87,0003,900
Тихий:180,0004,000
Индийский:75,0003,900
Южный:20,0004,500
Общая:361,000 
Средняя:72,0003,800
+
+
+ +

Океаны

+
+
+ +

Посмотреть решение для этой задачи.

+ +

Что дальше?

+ +

{{nextPage("/ru/docs/Web/Guide/CSS/Getting_Started/Media", "Media")}}Это последняя страница в этом руководстве, которая фокусируется на CSS свойствах и значениях. Для полного обзора свойств и значений, смотрите все свойства таблиц в CSS Спецификациях.

+ +

Следующая страница тоже рассматривает цель и структуру CSS таблиц.

diff --git a/files/ru/conflicting/learn/css/building_blocks/values_and_units/index.html b/files/ru/conflicting/learn/css/building_blocks/values_and_units/index.html new file mode 100644 index 0000000000..911a8010b6 --- /dev/null +++ b/files/ru/conflicting/learn/css/building_blocks/values_and_units/index.html @@ -0,0 +1,345 @@ +--- +title: Color +slug: Web/Guide/CSS/Getting_started/Color +translation_of: Learn/CSS/Introduction_to_CSS/Values_and_units#Colors +translation_of_original: Web/Guide/CSS/Getting_started/Color +--- +

{{ CSSTutorialTOC() }}

+ +

{{previousPage("/en-US/docs/Web/Guide/CSS/Getting_Started/Text_styles", "Text styles")}}This is the 8th section of the CSS Getting Started tutorial; it explains how you can specify color in CSS. In your sample stylesheet, you introduce background colors.

+ +

Information: Color

+ +

In this tutorial so far, you have used a limited number of named colors. CSS2 supports 17 named colors in all. Some of the names might not be what you expect:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 black gray silver white 
primariesred lime blue 
secondariesyellow aqua fuchsia 
 maroon orange olive purple green navy teal 
+ +

 

+ +
+
Details
+ +

Your browser might support many more named colors, like:

+ + + + + + + + + + + + + + + + +
dodgerblue peachpuff tan firebrick aquamarine 
+ +

For details of this extended list, see: SVG color keywords in the CSS 3 Color Module. Beware of using color names that your reader's browsers might not support.

+
+ +

For a larger palette, specify the red, green and blue components of the color you want by using a number sign (hash) and three hexadecimal digits in the range 0 – 9, a – f. The letters a – f represent the values 10 – 15:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
black #000
pure red #f00
pure green #0f0
pure blue #00f
white #fff
+ +


+ For the full palette, specify two hexadecimal digits for each component:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
black #000000
pure red #ff0000
pure green #00ff00
pure blue #0000ff
white #ffffff
+ +

You can usually get these six-digit hexadecimal codes from your graphics program or some other tool.

+ +
+
Example
+ +

With a little practice, you can adjust the three-digit colors manually for most purposes:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Start with pure red: #f00
To make it paler, add some green and blue: #f77
To make it more orange, add a little extra green: #fa7
To darken it, reduce all its components: #c74
To reduce its saturation, make its components more equal: #c98
If you make them exactly equal, you get gray: #ccc
+ +

For a pastel shade like pale blue:

+ + + + + + + + + + + + + + +
Start with pure white: #fff
Reduce the other components a little: #eef
+
+ +
+
More details
+ +

You can also specify a color using decimal RGB values in the range 0 – 255, or percentages.

+ +

For example, this is maroon (dark red):

+ +
rgb(128, 0, 0)
+
+ +

For full details of how to specify colors, see: Colors in the CSS Specification.

+ +

For information on matching system colors like Menu and ThreeDFace, see: CSS2 System Colors in the CSS Specification.

+
+ +

Color properties

+ +

You have already used the {{ cssxref("color") }} property on text.

+ +

You can also use the {{ cssxref("background-color") }} property to change elements' backgrounds.

+ +

Backgrounds can be set to transparent to explicitly remove any color, revealing the parent element's background.

+ +
+
Example
+ +

The Example boxes in this tutorial use this pale yellow background:

+ +
background-color: #fffff4;
+
+ +

The More details boxes use this pale gray:

+ +
background-color: #f4f4f4;
+
+
+ +

 

+ +

Action: Using color codes

+ +

Color page

+ +
    +
  1. Edit your CSS file.
  2. +
  3. Make the change shown down here, to give the initial letters a pale blue background. (The layout and comments in your file probably differ from the file shown here. Keep the layout and comments the way you prefer them.)
  4. +
  5. +

    HTML Content

    + +
    <p id = "first"> <strong>C</strong>ascading <strong class="spinach">S</strong>tyle <strong class="spinach">S</strong>heets</p>
    +<p> <strong>C</strong>ascading <strong>S</strong>tyle <strong>S</strong>heets</p>
    +
    + +

    CSS Content

    + +
    /*** CSS Tutorial: Color page ***/
    +
    +/* page font */
    +body {
    +  font: 16px "Comic Sans MS", cursive;
    +}
    +
    +/* paragraphs */
    +p {
    +  color: blue;
    +}
    +#first {
    +  font-style: italic;
    +}
    +
    +/* initial letters */
    +strong {
    +  background-color: #ddf;
    +  color: red;
    +  font: 200% serif;
    +}
    +
    +.spinach {
    +  color: green;
    +  background-color: #ddf;
    +}
    +
    +
    +
  6. +
  7. Save the file and refresh your browser to see the result.
  8. +
  9. The result should be like this:
  10. +
+ +

{{ EmbedLiveSample('Color_page', '', '', '', 'Web/Guide/CSS/Getting_started/Color') }}

+ +
+
Challenge
+ +

In your CSS file, change all the color names to 3-digit color codes without affecting the result.

+ +

(This cannot be done exactly, but you can get close. To do it exactly you need 6-digit codes, and you need to look up the CSS Specification or use a graphics tool to match the colors.)

+ +
+
Possible solution
+ +

The following values are reasonable approximations of the named colors:

+ +
strong {
+  color: #f00; /* red */
+  background-color: #ddf; /* pale blue */
+  font: 200% serif;
+}
+
+.carrot {
+  color: #fa0; /* orange */
+}
+
+.spinach {
+  color: #080; /* dark green */
+}
+
+p {
+  color: #00f; /* blue */
+}
+
+ +

 

+Hide solution
+See a solution for the challenge.
+ +

What next?

+ +

{{nextPage("/en-US/docs/Web/Guide/CSS/Getting_Started/Content", "Content")}}Your sample document and your sample stylesheet strictly separate content from style. The next section explains how you can make exceptions to this strict separation.

diff --git a/files/ru/conflicting/learn/css/first_steps/how_css_is_structured/index.html b/files/ru/conflicting/learn/css/first_steps/how_css_is_structured/index.html new file mode 100644 index 0000000000..9e9a4231a9 --- /dev/null +++ b/files/ru/conflicting/learn/css/first_steps/how_css_is_structured/index.html @@ -0,0 +1,166 @@ +--- +title: Чистый СSS код +slug: Web/Guide/CSS/Getting_started/Readable_CSS +translation_of: Learn/CSS/Introduction_to_CSS/Syntax#Beyond_syntax_make_CSS_readable +translation_of_original: Web/Guide/CSS/Getting_started/Readable_CSS +--- +

{{ CSSTutorialTOC() }}

+ +

{{ previousPage("/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors", "Selectors")}}Это 6-я статья руководства CSS для начинающих; здесь обсуждается стиль и грамматика самого языка CSS. Вы можете изменить пусть к вашему файлу CSS на более удобный для чтения.

+ +

Информация: Чистый код CSS

+ +

Вы можете добавлять пустое пространство и комментарии к вашим стилям, чтобы сделать их более читабельными. Также вы можете группировать селекторы вместе, в случае если те же самые правила стиля применяются к разным элементам.

+ +

Пустое пространство

+ +

Пустое пространство означает фактические пробелы, табуляцию, а также новые строки. Вы можете использовать их, чтобы сделать ваш код более читабельным.

+ +

В макете страницы, данное пространство — это та часть, которая остается без опознавательных знаков: отступы от других элементов (margin) и пространство между колонками и строками.

+ +

Ваш пример файла CSS в настоящее время имеет правила в одной строке, и почти минимум пробелов. В комплексе стилей эта схема будет усложнять читаемость, а значит в нее будет трудно вносить изменения.

+ +

Стиль написания который вы выбираете, как правило, зависит от личных предпочтений, но если ваши css являются частью общих проектов, могут возникнуть трудности с понимаем вашего написания кода.

+ +
+
Примеры
+ +

Некоторые люди пытаются написать код максимально компактно и пишут код в одну строку, даже если он достаточно долгий:

+ +
.carrot {color: orange; text-decoration: underline; font-style: italic;}
+
+ +

Некоторые люди предпочитают писать каждое свойство-значение в отдельной строке:

+ +
.carrot
+{
+color: orange;
+text-decoration: underline;
+font-style: italic;
+}
+
+ +

Некоторые используют отступы — 2 или 4 пробела или табы:

+ +
.carrot {
+  color: orange;
+  text-decoration: underline;
+  font-style: italic;
+}
+
+ +

Некоторые люди все выстраивают вертикально (но такое расположение не лучший вариант для поддержки):

+ +
.carrot
+    {
+    color           : orange;
+    text-decoration : underline;
+    font-style      : italic;
+    }
+
+ +

Некоторые люди используют смешанный пробелы для повышения читаемости.

+ +
.vegetable         { color: green; min-height:  5px; min-width:  5px }
+.vegetable.carrot  { color: orange;    height: 90px;     width: 10px }
+.vegetable.spinach { color: darkgreen; height: 30px;     width: 30px }
+
+
+ +

Некоторые используют вкладки для компоновки элементов, а другие только пробелы.

+ +

Комментарии

+ +

Комментарии в CSS имеют следующий вид: /* комментарий */.

+ +

Вы можете использовать комментарии, чтобы сделать фактические комментарии в css, а также чтобы закомментировать временно часть кода с целью тестирования.

+ +

Часть стилей, которая будет закомментирована, не будет отображатся браузером. Будьте осторожны при комментировании кода, поскольку важно сохранить правильный синтаксис остального кода.

+ +
+
Пример
+ +
/* стиль для начальной буквой C в первом пункте*/
+.carrot {
+  color:            orange;
+  text-decoration:  underline;
+  font-style:       italic;
+  }
+
+
+ +

Группировка селекторов

+ +

Когда многие элементы имеют один и тот же стиль, вы можете указывать группу селекторов, разделяя их запятыми. Декларация применится для всех выбранных элементов.

+ +

В другом месте в таблице стилей можно указать те же селекторы уже индивидуально, чтобы применить индивидуальные правила стилей для них.

+ +
+
Пример
+ +

Это правило делает элементы {{HTMLElement ("h1")}}, {{HTMLElement ("h2")}}, и {{HTMLElement ("h3")}} одного цвета.

+ +

Удобно определить цвет только в одном месте, в случае, если возможны изменения.

+ +
/* цвет для заголовков */
+h1, h2, h3 {color: navy;}
+
+
+ +

Действуем: добавление комментариев и улучшения формата

+ +
    +
  1. Редактируя ваш CSS-файл убедитесь, что он применяет эти правила (в любом порядке): +
    strong {color: red;}
    +.carrot {color: orange;}
    +.spinach {color: green;}
    +#first {font-style: italic;}
    +p {color: blue;}
    +
    +
  2. +
  3. Сделайте его более читабельным, перестраивая его таким образом, какой будете считать более логичным и применяя пробелы и комментарии на свое усмотрение.
  4. +
  5. Сохраните файл и обновите экран браузера, чтобы убедиться, что ваши изменения не повлияли на роботу стилей: + + + + + + + + + +
    Cascading Style Sheets
    Cascading Style Sheets
    +
  6. +
+ +
+
Задание
+ +

Закомментируйте часть стиля не меняя остальное, чтобы сделать первую букву вашего документа красной:

+ + + + + + + + + + +
Cascading Style Sheets
Cascading Style Sheets
+ +

(Существует более чем один способ сделать это).

+ +
+
Possible solution
+One way to do this is to put comment delimiters around the rule for .carrot: + +
/*.carrot {
+  color: orange;
+}*/
+Hide solution
+Посмотреть решение задания.
+ +

Что дальше?

+ +

{{ nextPage("/en-US/docs/Web/Guide/CSS/Getting_Started/Text_styles", "Text styles") }}Ваш образец таблицы стилей использовал курсивный текст и подчеркнутый текст. На следующей странице описаны несколько способов, чтобы указать внешний вид текста в вашем документе.

diff --git a/files/ru/conflicting/learn/css/first_steps/how_css_works/index.html b/files/ru/conflicting/learn/css/first_steps/how_css_works/index.html new file mode 100644 index 0000000000..9edeb9fe1f --- /dev/null +++ b/files/ru/conflicting/learn/css/first_steps/how_css_works/index.html @@ -0,0 +1,122 @@ +--- +title: Как работает CSS +slug: Web/Guide/CSS/Getting_started/How_CSS_works +translation_of: Learn/CSS/First_steps/How_CSS_works +translation_of_original: Web/Guide/CSS/Getting_started/How_CSS_works +--- +

{{ CSSTutorialTOC() }}

+ +

{{ previousPage("/ru/docs/Web/Guide/CSS/Getting_Started/Why_use_CSS", "Зачем нужен CSS?") }} Это третья статья руководства по CSS для начинающих, объясняет, как работает CSS в вашем браузере, а также назначение Объектной Модели Документа (Document Object Model или DOM). Вы также узнаете, как сделать анализ документа.

+ +

Информация: Как работает CSS

+ +

Когда браузер отображает документ, он должен совместить содержимое документа с информацией о стилях для него. Браузер обрабатывает документ в два этапа:

+ +
    +
  1. Браузер преобразует язык разметки и CSS в DOM (Document Object Model). DOM представляет собой документ в памяти компьютера. Он сочетает в себе содержание документа с его стилем.
  2. +
  3. Браузер отображает содержимое DOM.
  4. +
+ +

Язык разметки использует элементы для определения структуры документа. Элемент обозначается с использованием тегов, которые представляют собой строки, начинающиеся с символа '<' и заканчивающиеся '>'. Большинство элементов имеет парные теги: открывающий тег и закрывающий тег. Для открывающего тега, поместите имя элемента между '<' и '>'. Для закрывающего тега, поместите '/'  между '<', и именем элемента.

+ +

В зависимости от языка разметки, некоторые элементы имеют только начальный тег, или тег, где '/' располагается после имени элемента. Элемент так же может быть контейнером, включающим в себя другие элементы. В этом случае они располагаются между открывающим и закрывающим тегами. Не забывайте всегда закрывать теги внутри контейнера.

+ +

DOM имеет древовидную структуру. Каждый элемент, атрибут и запуск текста на языке разметки становится узлом в древовидной структуре. Узлы определяются их взаимодействием с другими узлами DOM. Некоторые элементы становятся родительскими по отношению к другим, дочерним узлам (или узлам-потомкам). В свою очередь, дочерние узлы имеют "братьев" (siblings).

+ +

Понимание DOM поможет вам при разработке, отладке и поддержке CSS, поскольку DOM это место, где встречаются CSS и содержимое документа.

+ +
+
Пример
+ +
 
+В данном примере, тег <p> и его закрывающий тег </p> создают контейнер: + +
<p>
+  <strong>C</strong>ascading
+  <strong>S</strong>tyle
+  <strong>S</strong>heets
+</p>
+
+ +

Живой пример

+ +

{{ EmbedLiveSample('Информация_Как_работает_CSS', '', '', '', 'Web/Guide/CSS/Getting_started/How_CSS_works') }}

+ +

В DOM соответствующий узел P является родительским. Его дочерние узлы - это теги STRONG  и узлы текста. Теги STRONG,  в свою очередь, являются родительскими по отношению к текстовым узлам, которые являются их дочерними узлами:

+ +
P
+├─STRONG
+│ └─"C"
+├─"ascading"
+├─STRONG
+│ └─"S"
+├─"tyle"
+├─STRONG
+│ └─"S"
+└─"heets"
+
+ +

К действию: Анализ DOM

+ +

Использование DOM Inspector

+ +

Для анализа DOM, вам потребуется специальная программа. Вы можете использовать расширение DOM Inspector (DOMi) от Mozilla для анализа DOM. Вам просто нужно установить это расширение в браузере (подробнее см. ниже).

+ +
    +
  1. Используйте браузер Mozilla, чтобы открыть свой HTML-документ.
  2. +
  3. Из строки меню браузера выберите Инструменты > DOM инспектор, или Инструменты > Веб-разработка > Инспектор. +
    +
    Подробнее
    + +

    Если в вашем браузере Mozilla не установлен DOMi, вы можете установить его с сайта дополнений и перезапустить браузер. Затем возвращайтесь к этому руководству.

    + +

    Если вы не хотите устанавливать DOMi (или вы используете браузер не от Mozilla), то можете воспользоваться Рентген-очками, как описано в секции ниже. Или вы можете пропустить эту секцию и перейти к прямо к следующей странице. Если вы пропустите данный раздел, это не помешает вам в дальнейшем освоении руководства.

    +
    +
  4. +
  5. В DOMi разверните узлы вашего документа, нажав на их стрелки. +

    Замечание:  Пустые места в вашем HTML файле DOMi может отображать как пустые текстовые узлы, которые можно игнорировать.

    + +

    Часть результата может выглядеть следующим образом, в зависимости от того, какие узлы вы развернули:

    + +
    │ ▼╴P
    +│ │ │ ▼╴STRONG
    +│ │ └#text
    +│ ├╴#text
    +│ ►╴STRONG
    +│ │
    + +

    При выборе любого узла, вы можете использовать правую панель DOMi's для поиска информации об узле. Например, когда вы выбираете текстовый узел, DOMi показывает вам текст в соответствующей панели.

    + +

    При выборе узла элемента, DOMi анализирует его и предоставляет огромное количество информации, которая содержится в правой панели. Информация о стилях - лишь часть информации, которую там можно просмотреть.

    +
  6. +
+ +
+
Задача
+ +

В DOMi, кликните на узле STRONG.

+ +

Используйте правую панель ДОМи, чтобы выяснить, где цвет для этого узла установлен на красный, и где его внешний вид сделан толще, чем обычный текст.

+ +
+
Possible solution
+ +

In the menu above the right-hand pane, choose CSS Rules. You see two items listed, one that references an internal resource and one that references your stylesheet file. The internal resource defines the font-weight property as bolder; your stylesheet defines the color property as red.

+Hide solution
+Посмотреть решение задачи.
+ +

Использование Рентген-очков

+ +

Рентген-очки показывают меньше информации, чем DOM Инспектор, но проще в установке и использовании.

+ +
    +
  1. Перейдите на домашнюю страницу X-Ray Goggles.
  2. +
  3. Перетащите ссылку X-Ray Googles с этой страницы на панель закладок.
  4. +
  5. Откройте HTML-документ.
  6. +
  7. Запустите Рентген-очки, кликнув по появившейся закладке.
  8. +
  9. Передвигайте курсор мыши по документу для просмотра элементов в документе.
  10. +
+ +

Что дальше?

+ +

{{ nextPage("/ru/docs/Web/Guide/CSS/Getting_Started/Cascading_and_inheritance", "Каскадность и наследование") }}Если вы решили задачу, то увидели, что информация о стиле из более чем одного места взаимодействует для создания окончательного стиля для элемента. На следующей странице объясняется больше об этих взаимодействиях.

diff --git a/files/ru/conflicting/learn/css/first_steps/how_css_works_64ba4331a7a5f4319c6e06b06ccdd521/index.html b/files/ru/conflicting/learn/css/first_steps/how_css_works_64ba4331a7a5f4319c6e06b06ccdd521/index.html new file mode 100644 index 0000000000..3041d28920 --- /dev/null +++ b/files/ru/conflicting/learn/css/first_steps/how_css_works_64ba4331a7a5f4319c6e06b06ccdd521/index.html @@ -0,0 +1,110 @@ +--- +title: Зачем нужен CSS? +slug: Web/Guide/CSS/Getting_started/Why_use_CSS +tags: + - Beginner + - CSS + - 'CSS:Getting_Started' + - Example + - Guide + - Web + - Веб + - Новичку + - Руководство +translation_of: Learn/CSS/First_steps/How_CSS_works +translation_of_original: Web/Guide/CSS/Getting_started/Why_use_CSS +--- +

{{ CSSTutorialTOC() }}

+ +

{{ previousPage("/ru/docs/Web/Guide/CSS/Getting_Started/What_is_CSS", "Что такое CSS?") }}Это вторая статья руководства по CSS для начинающих, объясняющая взаимосвязь между CSS и документами. В ней вы узнаете, как добавить CSS стили для документа, который вы создали в процессе изучения первой статьи.

+ +

Информация: Зачем нужен CSS?

+ +

CSS используется для определения стилей ваших документов, в том числе дизайна, верстки и вариаций макета для различных устройств и размеров экрана. Вы можете разместить стили CSS внутри тега <HEAD> документа с встроенной таблицей стилей, или приложить отдельный CSS-файл, который будет определять ваши стили извне. Чтобы привязать внешнюю таблицу стилей к документу, просто добавьте ссылку на таблицу стилей в заголовке <HEAD> документа.

+ +

У внешней таблицы стилей есть множество преимуществ. Сохранение стилей отдельно от содержания HTML:

+ + + +
+
Пример
+ +

Используя CSS, вы храните информацию о стилях в общих файлах, которые доступны всем страницам. Например, когда документы ссылаются на те таблицы стилей, которые определяют цвет заголовков h2, вы можете применить стиль для тегов заголовков h2 на глобальном уровне путем изменения одного атрибута CSS.

+ +

Когда пользователь открывает веб-страницу, браузер загружает информацию стиля вместе с содержанием страницы.

+ +

Когда пользователь открывает веб-страницу в режиме печати, вы можете предоставить различную информацию о стилях которая сделает страницу более лёгкой для чтения.

+
+ +

Как заставить HTML и CSS работать вместе? В целом, HTML используется для описания содержимого документа, а не его стиля. CSS же используется, чтобы указать стиль документа, но не содержание. Позже в руководстве вы увидите некоторые исключения из этого правила.

+ +
+
Подробнее
+ +

Язык разметки, типа HTML также обеспечивает некоторые способы задания стилей.

+ +

Например, в HTML вы можете использовать тег <B>, чтобы сделать текст жирным, либо указать цвет фона страницы в теге <BODY>.

+ +

При использовании CSS, задание стилей средствами языка разметки обычно не используется, поскольку вся информация о стилях легко доступна для чтения и изменения в CSS-файле.

+
+ +

Действие: Создание таблицы стилей

+ +
    +
  1. Создайте новый текстовый файл в том же каталоге, что и doc1.html, созданный в первой статье.
  2. +
  3. Сохраните его как style1.css. Этот файл будет вашей таблицей стилей.
  4. +
  5. Скопируйте и вставьте в CSS-файл приведённую ниже строку, после чего сохраните файл: +
    strong {color: red;}
    +
    +
  6. +
+ +

Привязка таблицы стилей к документу

+ +
    +
  1. Для привязки вашего документа к таблице стилей, необходимо внести в HTML-файл некоторые исправления. Добавьте строки, приведённые ниже: +
    <!DOCTYPE html>
    +<html>
    +  <head>
    +  <meta charset="UTF-8">
    +  <title>Sample document</title>
    +  <link rel="stylesheet" href="style1.css">
    +  </head>
    +  <body>
    +    <p>
    +      <strong>C</strong>ascading
    +      <strong>S</strong>tyle
    +      <strong>S</strong>heets
    +    </p>
    +  </body>
    +</html>
    +
    +
  2. +
  3. Сохраните файл, и откройте его в браузере. Таблица стилей сделает заглавные буквы красными:
  4. +
+ +

{{ EmbedLiveSample('Действие_Создание_таблицы_стилей', '', '', '', 'Web/Guide/CSS/Getting_started/Why_use_CSS') }}

+ +

{{ LiveSampleLink('Action.3A_Creating_a_stylesheet', 'Просмотреть демо') }}

+ +
+
Задание
+ +

В дополнение к красному, в CSS имеются и другие названия цветов.

+ +

Не открывая подсказку, подберите ещё пять цветовых имён, которые будут работать в CSS.

+ +
+
Возможное решение
+ +

CSS поддерживает общие названия цветов, например orange, yellow, blue, green, или black. Он также поддерживает некоторые более экзотические названия типа chartreuse, fuschia, или burlywood. Посмотрите значения цвета CSS, чтобы ознакомится с полным списком поддерживаемых цветов, а так же методов их задания.

+Скрыть решение
+Посмотреть решение задания.
+ +

Что дальше?

+ +

{{nextPage("/ru/docs/Web/Guide/CSS/Getting_started/How_CSS_works", "Как работает CSS.")}}  Теперь, когда у вас есть образец документа, связанный с отдельной таблицей стилей, вы готовы узнать больше о том, как ваш браузер объединяет их при отображении документа.

diff --git a/files/ru/conflicting/learn/css/first_steps/how_css_works_b66915031fb62b5fee1201086144e209/index.html b/files/ru/conflicting/learn/css/first_steps/how_css_works_b66915031fb62b5fee1201086144e209/index.html new file mode 100644 index 0000000000..95df2fe915 --- /dev/null +++ b/files/ru/conflicting/learn/css/first_steps/how_css_works_b66915031fb62b5fee1201086144e209/index.html @@ -0,0 +1,120 @@ +--- +title: Что такое CSS? +slug: Web/Guide/CSS/Getting_started/What_is_CSS +tags: + - Beginner + - CSS + - 'CSS:Getting_Started' + - Example + - Guide + - Веб + - Новичку +translation_of: Learn/CSS/First_steps/How_CSS_works +translation_of_original: Web/Guide/CSS/Getting_started/What_is_CSS +--- +
{{ CSSTutorialTOC() }}
+ +

{{previousPage("/ru/docs/Web/Guide/CSS/Getting_Started", "CSS для начинающих")}} Эта первая статья руководства по CSS для начинающих кратко объясняет, что такое Cascading Style Sheets (CSS). С её помощью вы сможете создать простой документ, который будете использовать в дальнейших разделах.

+ +

Информация: Что такое CSS

+ +

Каскадные таблицы стилей (Cascading Style Sheets = CSS) — это язык, который отвечает за визуальное представление документов пользователю.

+ +

Под документом мы будем понимать набор информации о структуре страницы, описываемый языком разметки.

+ +

А представление документа пользователю, в свою очередь, означает его преобразование в удобную для восприятия форму. Браузеры, такие как Firefox, Chrome или Internet Explorer, были созданы для визуального отображения документов, например, на экране компьютера, проекторе или вывода через принтер.

+ +
+

Примеры

+ + +
+ +

В этом руководстве блоки с заголовком Подробнее, как нижеследующий, содержат дополнительную информацию и ссылки на ресурсы, позволяющие более глубоко изучить вопрос, которому посвящен тот или иной раздел. Вы можете сразу же воспользоваться этими материалами или же пропустить эти блоки и вернуться к ним позже.

+ +
+
Подробнее
+ +

Документ это не то же самое, что файл. Но, тем не менее, документ может храниться в одном файле.

+ +

Со страницей, которую вы сейчас читаете, дела обстоят немного сложнее. Когда ваш браузер запрашивает данную страницу, сервер обращается к базе данных и генерирует документ, собирая его по частям из нескольких документов, каждый из которых, в свою очередь, может располагаться в нескольких файлах. Однако в этом руководстве вы также сможете работать с документами, каждый из которых представлен одним файлом.

+ +

Больше информации о документах и языках разметки вы найдете в других разделах этого сайта:

+ + + + + + + + + + + + + + + + + + + + +
HTMLо веб-страницах
XMLо структуре документов в общем
SVGо графике
XULо пользовательских интерфейсах в Mozilla
+ +

Во второй части данного руководства вы встретите примеры этих языков разметки.

+
+ +
+
Подробнее
+ +

В терминах CSS программа, которая выводит документ пользователю, так называемому user agent (UA). Браузер — один из видов UA. CSS, таким образом, не предназначен только для браузеров или визуального представления, но в первой части данного руководства вы будете работать с CSS только в браузере.

+ +

Прочие определения и термины, имеющие отношение к CSS, вы можете найти в Определениях спецификации CSS, созданной World Wide Web Consortium (W3C), международным сообществом которое установило открытые стандарты web.

+
+ +

К действию: Создание документа

+ +
    +
  1. Создайте новую папку на вашем компьютере для упражнений.
  2. +
  3. Откройте текстовый редактор и создайте новый текстовый файл. Этот файл будет содержать документ для нескольких следующих упражнений.
  4. +
  5. Скопируйте и вставьте HTML, приведенный ниже, а затем сохраните ваш файл под именем doc1.html. +
    <!DOCTYPE html>
    +<html>
    +  <head>
    +  <meta charset="UTF-8">
    +  <title>Sample document</title>
    +  </head>
    +
    +  <body>
    +    <p>
    +      <strong>C</strong>ascading
    +      <strong>S</strong>tyle
    +      <strong>S</strong>heets
    +    </p>
    +  </body>
    +</html>
    + +

    {{ LiveSampleLink('Action.3A_Creating_a_document', 'Посмотреть демо') }}

    +
  6. +
  7. Откройте новую вкладку или новое окно в вашем браузере и откройте только что созданный файл. +

    Вы должны увидеть строку, в которой заглавные буквы выделены полужирным начертанием:

    + + + + + + + +
    Cascading Style Sheets
    + +

    То, что вы увидите на самом деле, может немного отличаться потому, что настройки по умолчанию вашего браузера и данной энциклопедии наверняка будут отличаться: небольшие различия в шрифте, пробелах и цветах не очень-то и важны.

    +
  8. +
+ +

Что дальше?

+ +

{{nextPage("/ru/docs/Web/Guide/CSS/Getting_Started/Why_use_CSS", "Зачем нужен CSS?")}}В документе, который вы создали, CSS пока что не использовался. В следующем разделе вы научитесь использовать CSS для стилизации документа.

diff --git a/files/ru/conflicting/learn/css/first_steps/index.html b/files/ru/conflicting/learn/css/first_steps/index.html new file mode 100644 index 0000000000..b2f6ebed77 --- /dev/null +++ b/files/ru/conflicting/learn/css/first_steps/index.html @@ -0,0 +1,60 @@ +--- +title: CSS для начинающих +slug: Web/Guide/CSS/Getting_started +tags: + - Beginner + - CSS + - 'CSS:Getting_Started' + - Guide + - Needs + - NeedsBeginnerUpdate + - NeedsTranslation + - NeedsUpdate + - TopicStub + - Web + - Новичку + - Руководство +translation_of: Learn/CSS/First_steps +translation_of_original: Web/Guide/CSS/Getting_started +--- +

Это руководство (самоучитель) познакомит вас с базовыми возможностями и языком (синтаксом) Каскадных таблиц стилей (CSS). CSS используется для изменения внешнего вида структурированного документа, такого как веб-страница. Руководство также включает простые упражнения, которые вы сможете выполнить на своем компьютере и увидеть, как работает CSS, а также его возможности в современных браузерах.

+ +

Данное руководство создано для новичков и всех, кто хотел бы освежить свои знания основ CSS. Если у вас уже есть опыт работы с CSS, на главной странице вы можете найти список обучающих ресурсов, подходящих для вашего уровня.

+ + + +

Что вам нужно для того, чтобы начать

+ + + +

В данном руководстве вам будут встречаться упражнения, которые вам предлагается выполнить для лучшего понимания материала. Их выполнение не является обязательным: вы можете просто читать материал и смотреть на иллюстрации.

+ +

Важно: Руководство включает в себя материалы по работе с цветом в CSS. Эти материалы будет легче пройти, если у вас цветной монитор и нормальное цветовое зрение.

+ +

Как пользоваться руководством

+ +

Наилучшим вариантом будет внимательное и постепенное чтение разделов в строгой последовательности. Если вы пропустите какой-то раздел, вам может оказаться что-то непонятно в следующих главах.

+ +

Часть I: Основы CSS

+ +

На каждой странице, используйте секцию Информация, чтобы понять, как работает CSS. Используйте секцию К действию, чтобы попробовать использовать CSS на вашем компьютере.

+ +

Чтобы проверить усвоенные знания, вам будет полезно решить задачу в конце каждой страницы. Верные решения задач вы всегда можете найти под их описанием в виде ссылки - таким образом, вы не сможете увидеть их случайно.

+ +

Чтобы добиться более глубокого понимания CSS, читайте информацию в блоках с заголовком Подробнее. А также не забудьте посетить приведенные там ссылки.

+ +

Часть II: Возможности CSS

+ +

Вторая часть руководства содержит примеры, которые продемонстрируют вам возможности CSS применительно к другим web-технологиям и технологиям Mozilla. 

+ +
    +
  1. JavaScript
  2. +
  3. SVG графика
  4. +
  5. XML данные
  6. +
  7. XBL байдинг bindings
  8. +
  9. Пользовательские интерфейсы XUL
  10. +
diff --git a/files/ru/conflicting/learn/css/index.html b/files/ru/conflicting/learn/css/index.html new file mode 100644 index 0000000000..7529234ef5 --- /dev/null +++ b/files/ru/conflicting/learn/css/index.html @@ -0,0 +1,12 @@ +--- +title: Руководство разработчика CSS +slug: Web/Guide/CSS +tags: + - CSS + - Landing + - NeedsTranslation + - TopicStub +translation_of: Learn/CSS +translation_of_original: Web/Guide/CSS +--- +prepare for redirect diff --git a/files/ru/conflicting/learn/css/styling_text/fundamentals/index.html b/files/ru/conflicting/learn/css/styling_text/fundamentals/index.html new file mode 100644 index 0000000000..a25565cf79 --- /dev/null +++ b/files/ru/conflicting/learn/css/styling_text/fundamentals/index.html @@ -0,0 +1,152 @@ +--- +title: Text styles +slug: Web/Guide/CSS/Getting_started/Text_styles +translation_of: Learn/CSS/Styling_text/Fundamentals +translation_of_original: Web/Guide/CSS/Getting_started/Text_styles +--- +

{{ CSSTutorialTOC() }}

+ +

{{previousPage("/en-US/docs/Web/Guide/CSS/Getting_Started/Readable_CSS", "Readable CSS")}}This is the 7th section of the CSS Getting Started tutorial; it gives more examples of text styles. You modify your sample stylesheet to use different fonts.

+ +

Information: Text styles

+ +

CSS имеет несколько свойств для стилизации текста.

+ +

There is a convenient shorthand property, {{ cssxref("font") }}, which you can use to specify several aspects at once—for example:

+ + + +
+
Example
+ +
p {
+font: italic 75%/125% "Comic Sans MS", cursive;
+}
+
+ +

This rule sets various font properties, making all paragraphs italic.

+ +

The font size is set to three-quarters of the size in each paragraph's parent element, and the line height is set to 125% (a little more spaced than normal).

+ +

The font typeface is set to Comic Sans MS, but if this typeface is not available then the browser will use its default cursive (hand-written) typeface.

+ +

The rule has the side-effect of turning off bold and small-caps (setting them to normal).

+
+ +

Font faces

+ +

You cannot predict what typefaces the readers of your document will have. When you specify font typefaces, it is a good idea to give a list of alternatives in order of preference.

+ +

End the list with one of the built-in default typefaces: serif, sans-serif, cursive, fantasy or monospace.

+ +

If the typeface does not support some features in the document, then the browser can substitute a different typeface. For example, the document might contain special characters that the typeface does not support. If the browser can find another typeface that has those characters, then it will use the other typeface.

+ +

To specify a typeface on its own, use the {{ cssxref("font-family") }} property.

+ +

Font sizes

+ +

Browser users can override the default font sizes or change the text size while they read a page, so it makes good sense for you to use relative sizes wherever you can.

+ +

You can use some built-in values for font sizes, like small, medium and large. You can also use values relative to the font size of the parent element like: smaller, larger, 150% or 1.5em. An "em" is equivalent to the width of the letter "m" (for the font size of the parent element); thus 1.5em is one-and-a-half times the size of the font of the parent element.

+ +

If necessary you can specify an actual size like: 14px (14 pixels) for a display device or 14pt (14 points) for a printer. This is not accessible for visually impaired users because it does not allow them to change the size. A more accessible strategy is to set a built-in value like medium on a top-level element of the document, and then set relative sizes for all its descendent elements.

+ +

To specify a font size on its own, use the {{ cssxref("font-size") }} property.

+ +

Line height

+ +

The line height specifies the spacing between lines. If your document has long paragraphs with many lines, a larger-than-normal spacing makes it easier to read, especially if the font size is small.

+ +

To specify a line height on its own, use the {{ cssxref("line-height") }} property.

+ +

Decoration

+ +

The separate {{ cssxref("text-decoration") }} property can specify other styles, like underline or line-through. You can set it to none to explicitly remove any decoration.

+ +

Other properties

+ +

To specify italic on its own, use {{ cssxref("font-style") }}: italic;
+ To specify bold on its own, use {{ cssxref("font-weight") }}: bold;
+ To specify small capitals on its own, use {{ cssxref("font-variant") }}: small-caps;

+ +

To turn any of these off individually, you can specify the value normal or inherit.

+ +
+
More details
+ +

You can specify text styles in a variety of other ways.

+ +

For example, some of the properties mentioned here have other values that you can use.

+ +

In a complex stylesheet, avoid using the shorthand font property because of its side-effects (resetting other individual properties).

+ +

For full details of the properties that relate to fonts, see Fonts in the CSS Specification. For full details of text decoration, see Text.

+ +

If you don't want to depend on the typefaces installed on users' systems, you can use {{ cssxref("@font-face") }} to specify an online font. However, this requires that the users have a browser that supports this rule.

+
+ +

Action: Specifying fonts

+ +

For a simple document, you can set the font of the {{ HTMLElement("body") }} element and the rest of the document inherits the settings.

+ +
    +
  1. Edit your CSS file.
  2. +
  3. Add the following rule to change the font throughout the document. The top of the CSS file is a logical place for it, but it has the same effect wherever you put it: +
    body {
    +font: 16px "Comic Sans MS", cursive;
    +}
    +
    +
  4. +
  5. Add a comment explaining the rule, and add white space to make it match your preferred layout.
  6. +
  7. Save the file and refresh your browser to see the effect. If your system has Comic Sans MS, or another cursive font that does not support italic, then your browser chooses a different font face for the italic text in the first line: + + + + + + + + + +
    Cascading Style Sheets
    Cascading Style Sheets
    +
  8. +
  9. From your browser's menu bar, choose View > Text Size > Increase (or View > Zoom > Zoom In). Even though you specified 16 pixels in the style, a user reading the document can change the size.
  10. +
+ +
+
Challenge
+ +

Without changing anything else, make all six initial letters twice the size in the browser's default serif font:

+ + + + + + + + + + +
Cascading Style Sheets
Cascading Style Sheets
+ +
+
Possible solution
+ +

Add the following style declaration to the strong rule:

+ +
  font: 200% serif;
+
+If you use separate declarations for font-size and font-family, then the font-style setting on the first paragraph is not overridden. + +

 

+Hide solution
+See a solution for the challenge.
+ +

What next?

+ +

{{nextPage("/en-US/docs/Web/Guide/CSS/Getting_Started/Color", "Color")}}Your sample document already uses several named colors. The next section lists the names of standard colors and explains how you can specify others.

diff --git a/files/ru/conflicting/learn/javascript/objects/index.html b/files/ru/conflicting/learn/javascript/objects/index.html new file mode 100644 index 0000000000..d07cf043cc --- /dev/null +++ b/files/ru/conflicting/learn/javascript/objects/index.html @@ -0,0 +1,356 @@ +--- +title: Вступление в Объектно-ориентированный JavaScript +slug: Web/JavaScript/Introduction_to_Object-Oriented_JavaScript +translation_of: Learn/JavaScript/Objects +translation_of_original: Web/JavaScript/Introduction_to_Object-Oriented_JavaScript +--- +

Объектно-ориентированный до основания, JavaScript предоставляет мощные и гибкие {{Glossary("OOP")}} возможности. Эта статья начинается с введения в объектно-ориентированное программирование, затем рассматривает модель объекта JavaScript и, наконец, демонстрирует концепции объектно-ориентированного программирования в JavaScript.

+ +

Обзор JavaScript

+ +

Если вы неуверенно владеете такими концепциями JavaScript, как переменные, типы, функции и области видимости, вы можете прочитать об этих темах в Повторное вступление в JavaScript. Вы также можете обратиться к JavaScript Guide.

+ +

Объектно-ориентированное программирование

+ +

Объектно-ориентированное программирование (ООП) — это парадигма программирования, которая использует {{glossary("абстракции")}}, чтобы создавать модели, основанные на объектах реального мира. ООП использует несколько техник из ранее признанных парадигм, включая {{glossary("модульность")}}, {{glossary("полиморфизм")}} и {{glossary("инкапсуляция")}}. На сегодняшний день многие популярные языки программирования (такие как Java, JavaScript, C#, C++, Python, PHP, Ruby и Objective-C) поддерживают ООП.

+ +

ООП представляет программное обеспечение как совокупность взаимодействующих объектов, а не набор функций или просто список команд (как в традиционном представлении). В ООП, каждый объект может получать сообщения, обрабатывать данные, и отправлять сообщения другим объектам. Каждый объект может быть представлен как маленькая независимая машина с отдельной ролью или ответственностью.

+ +

ООП способствует большей гибкости и поддерживаемости в программировании, и широко распространена в крупномасштабном программном инжиниринге. Так как ООП настоятельно подчеркивает модульность, объектно-ориентированный код проще в разработке и проще для понимания впоследствии. Объектно-ориентированный код способствует более точному анализу, кодированию и пониманию сложных ситуаций и процедур, чем методы программирования с меньшей модульностью.1

+ +

Терминология

+ +
+
{{Glossary("Пространство имён")}}
+
Контейнер, который позволяет разработчикам связать весь функционал под уникальным, специфичным для приложения именем.
+
{{Glossary("Класс")}}
+
Определяет характеристики объекта. Класс является описанием шаблона свойств и методов объекта.
+
{{Glossary("Объект")}}
+
Экземпляр класса.
+
{{Glossary("Свойство")}}
+
Характеристика объекта, например, цвет.
+
{{Glossary("Метод")}}
+
Возможности объекта, такие как ходьба. Это подпрограммы или функции, связанные с классом.
+
{{Glossary("Конструктор")}}
+
Метод, вызываемый в момент создания экземпляра объекта. Он, как правило, имеет то же имя, что и класс, содержащий его.
+
{{Glossary("Наследование")}}
+
Класс может наследовать характеристики от другого класса.
+
{{Glossary("Инкапсуляция")}}
+
Способ комплектации данных и методов, которые используют данные.
+
{{Glossary("Абстракция")}}
+
Совокупность комплексных наследований, методов и свойств объекта должны адекватно отражать модель реальности.
+
{{Glossary("Полиморфизм")}}
+
Поли означает "много", а морфизм "формы". Различные классы могут объявить один и тот же метод или свойство.
+
+ +

Для более обширного описания объектно-ориентированного программирования, см {{interwiki("wikipedia", "Объектно-ориентированное_программирование")}} в Wikipedia.

+ +

Прототипное программирование

+ +

Прототипное программирование — это модель ООП которая не использует классы, а вместо этого сначала выполняет поведение класса и затем использует его повторно (эквивалент наследования в языках на базе классов), декорируя (или расширяя) существующие объекты прототипы. (Также называемое бесклассовое, прототипно-ориентированное, или экземплярно-ориентированное программирование.)

+ +

Оригинальный (и наиболее каноничный) пример прототипно-ориентированного языка это {{interwiki("wikipedia", "Self (programming language)", "Self")}} разработанный Дэвидом Ангаром и Ренделлом Смитом. Однако бесклассовый стиль программирования стал набирать популярность позднее, и был принят для таких языков программирования, как JavaScript, Cecil, NewtonScript, Io, MOO, REBOL, Kevo, Squeak (при использовании фреймворка Viewer для манипуляции компонентами Morphic) и некоторых других.1

+ +

Объектно-ориентированное программирование в JavaScript

+ +

Пространство имён

+ +

Пространство имён — это контейнер, который позволяет разработчикам собрать функциональность под уникальным именем приложения. Пространство имён в JavaScript — это объект, содержащий методы, свойства и другие объекты.

+ +
+

Важно отметить, что на уровне языка в JavaScript нет разницы между пространством имён и любым другим объектом. Это отличает JS от множества других объектно-ориентированных языков и может стать причиной путаницы у начинающих JS программистов.

+
+ +

Принцип работы пространства имён в JS прост: создать один глобальный объект и все переменные, методы и функции объявлять как свойства этого объекта. Также использование пространств имён снижает вероятность возникновения конфликтов имён в приложении так как каждый объект приложения является свойством глобального объекта.

+ +

Давайте создадим глобальный объект MYAPP:

+ +
// Глобальное пространство имён
+var MYAPP = MYAPP || {};
+ +

Во фрагменте кода выше мы сначала проверяем определён ли объект MYAPP (в текущем файле или другом файле). Если да, то используем существующий глобальный объект MYAPP, иначе создаём пустой объект MYAPP, в котором мы инкапсулируем все методы, функции, переменные и объекты.

+ +

Также мы можем создать подпространство имён (учтите, что сначала нужно объявить глобальный объект):

+ +
// Подпространство имён
+MYAPP.event = {};
+ +

Далее следует пример синтаксиса создания пространства имён и добавления переменных, функций и методов:

+ +
// Создаём контейнер MYAPP.commonMethod для общих методов и свойств
+MYAPP.commonMethod = {
+  regExForName: "", // определяет регулярное выражение для валидации имени
+  regExForPhone: "", // определяет регулярное выражение для валидации телефона
+  validateName: function(name){
+    // Сделать что-то с name, вы можете получить доступ к переменной regExForName
+    // используя "this.regExForName"
+  },
+
+  validatePhoneNo: function(phoneNo){
+    // Сделать что-то с номером телефона
+  }
+}
+
+// Объект вместе с объявлением методов
+MYAPP.event = {
+    addListener: function(el, type, fn) {
+    // код
+    },
+    removeListener: function(el, type, fn) {
+    // код
+    },
+    getEvent: function(e) {
+    // код
+    }
+
+    // Можно добавить другие свойства и методы
+}
+
+// Синтаксис использования метода addListener:
+MYAPP.event.addListener("yourel", "type", callback);
+ +

Стандартные встроенные объекты

+ +

В JavaScript есть несколько объектов, встроенных в ядро, например {{jsxref("Math")}}, {{jsxref("Object")}}, {{jsxref("Array")}} и {{jsxref("String")}}. Пример ниже показывает как использовать объект Math, чтобы получить случайное число, используя его метод random().

+ +
console.log(Math.random());
+
+ +
Примечание: В данном примере и далее мы будем использовать глобальную функцию {{domxref("console.log()")}}. Если точнее, то функция console.log() не является частью JavaScript, но она поддерживается многими браузерами для облегчения отладки.
+ +

Смотрите JavaScript Reference: Standard built-in objects, чтобы ознакомиться со списком всех встроенных объектов JavaScript.

+ +

Каждый объект в JavaScript является экземпляром объекта Object, следовательно наследует все его свойства и методы.

+ +

Объекты, создаваемые пользователем

+ +

Класс

+ +

JavaScript — это прототипно-ориентированный язык, и в нём нет оператора class, который имеет место в C++ или Java. Иногда это сбивает с толку программистов, привыкших к языкам с оператором class. Вместо этого JavaScript использует функции как конструкторы классов. Объявить класс так же просто как объявить функцию. В примере ниже мы объявляем новый класс Person с пустым конструктором:

+ +
var Person = function () {};
+
+ +

Объект (экземпляр класса)

+ +

Для создания нового экзмепляра объекта obj мы используем оператор new obj, присваивая результат (который имеет тип obj) в переменную.

+ +

В примере выше мы определили класс Person. В примере ниже мы создаём два его экземпляра (person1 и person2).

+ +
var person1 = new Person();
+var person2 = new Person();
+
+ +
Ознакомьтесь с {{jsxref("Object.create()")}}, новым, дополнительным методом инстанцирования, который создаёт неинициализированный экземпляр.
+ +

Конструктор

+ +

Конструктор вызывается в момент создания экземпляра класса (в тот самый момент, когда создается объект). Конструктор является методом класса. В JavaScript функция служит конструктором объекта, поэтому нет необходимости явно определять метод конструктор. Любое действие определенное в конструкторе будет выполненно в момент создания экземпляра класса.

+ +

Конструктор используется для задания свойств объекта или для вызова методов, которые подготовят объект к использованию. Добавление методов и их описаний производится с использованием другого синтаксиса, описанного далее в этой статье.

+ +

В примере ниже, конструктор класса Person выводит в консоль сообщение в момент создания нового экземпляра Person.

+ +
var Person = function () {
+  console.log('instance created');
+};
+
+var person1 = new Person();
+var person2 = new Person();
+
+ +

Свойство (аттрибут объекта)

+ +

Свойства — это переменные, содержащиеся в классе; каждый экземпляр объекта имеет эти свойства. Свойства устанавливаются в конструкторе (функции) класса, таким образом они создаются для каждого экземпляра.

+ +

Ключевое слово this, которое ссылается на текущий объект, позволяет вам работать со свойствами класса. Доступ (чтение и запись) к свойствам снаружи класса осуществляется синтаксисом InstanceName.Property, так же как в C++, Java и некоторых других языках. (Внутри класса для получения и изменения значений свойств используется синтаксис this.Property)

+ +

В примере ниже, мы определяем свойство firstName для класса Person при создании экземпляра:

+ +
var Person = function (firstName) {
+  this.firstName = firstName;
+  console.log('Person instantiated');
+};
+
+var person1 = new Person('Alice');
+var person2 = new Person('Bob');
+
+// Выводит свойство firstName в консоль
+console.log('person1 is ' + person1.firstName); // выведет "person1 is Alice"
+console.log('person2 is ' + person2.firstName); // выведет "person2 is Bob"
+
+ +

Методы

+ +

Методы — это функции (и определяются как функции), но с другой стороны следуют той же логике, что и свойства. Вызов метода похож на доступ к свойству, но вы добавляете () на конце имени метода, возможно, с аргументами. Чтобы объявить метод, присвойте функцию в именованное свойство свойства prototype класса. Потом вы сможете вызвать метод объекта под тем именем, которое вы присвоили функции.

+ +

В примере ниже мы определяем и используем метод sayHello() для класса Person.

+ +
var Person = function (firstName) {
+  this.firstName = firstName;
+};
+
+Person.prototype.sayHello = function() {
+  console.log("Hello, I'm " + this.firstName);
+};
+
+var person1 = new Person("Alice");
+var person2 = new Person("Bob");
+
+// вызываем метод sayHello() класса Person
+person1.sayHello(); // выведет "Hello, I'm Alice"
+person2.sayHello(); // выведет "Hello, I'm Bob"
+
+ +

В JavaScript методы это — обычные объекты функций, связанные с объектом как свойства: это означает, что вы можете вызывать методы "вне контекста". Рассмотрим следующий пример:

+ +
var Person = function (firstName) {
+  this.firstName = firstName;
+};
+
+Person.prototype.sayHello = function() {
+  console.log("Hello, I'm " + this.firstName);
+};
+
+var person1 = new Person("Alice");
+var person2 = new Person("Bob");
+var helloFunction = person1.sayHello;
+
+// выведет "Hello, I'm Alice"
+person1.sayHello();
+
+// выведет "Hello, I'm Bob"
+person2.sayHello();
+
+// выведет "Hello, I'm undefined" (or fails
+// with a TypeError in strict mode)
+helloFunction();
+
+// выведет true
+console.log(helloFunction === person1.sayHello);
+
+// выведет true
+console.log(helloFunction === Person.prototype.sayHello);
+
+// выведет "Hello, I'm Alice"
+helloFunction.call(person1);
+ +

Как показывает пример, все ссылки, которые мы имеем на функцию sayHello — person1, Person.prototype, переменная helloFunction и т.д. — ссылаются на одну и ту же функцию. Значение this в момент вызова функции зависит от того, как мы её вызываем. Наиболее часто мы обращаемся к this в выражениях, где мы получаем функцию из свойства объекта — person1.sayHello() — this устанавливается на объект, из которого мы получили функцию (person1), вот почему person1.sayHello() использует имя "Alice", а person2.sayHello() использует имя "Bob". Но если вызов будет совершён иначе, то this будет иным: вызов this из переменной — helloFunction() — установит this на глобальный объект (window в браузерах). Так как этот объект (вероятно) не имеет свойства firstName, функция выведет "Hello, I'm undefined" (так произойдёт в нестрогом режиме; в strict mode всё будет иначе (ошибка), не будем сейчас вдаваться в подробности, чтобы избежать путаницы). Или мы можем указать this явно с помощью Function#call (или Function#apply) как показано в конце примера.

+ +
Примечание: Смотрите подробнее о this в  Function#call и Function#apply
+ +

Наследование

+ +

Наследование — это способ создать класс как специализированную версию одного или нескольких классов (JavaScript поддерживает только одиночное наследование). Специализированный класс, как правило, называют потомком, а другой класс родителем. В JavaScript наследование осуществляется присвоением экземпляра класса родителя классу потомку. В современных браузерах вы можете реализовать наследование с помощью Object.create.

+ +
Примечание: JavaScript не обнаружит prototype.constructor класса потомка (смотрите Object.prototype) так что мы должны указать его вручную. Смотрите вопрос "Why is it necessary to set the prototype constructor?" на Stackoverflow.
+ +

В примере ниже мы определяем класс Student как потомка класса Person. Потом мы переопределяем метод sayHello() и добавляем метод addGoodBye().

+ +
// Определяем конструктор Person
+var Person = function(firstName) {
+  this.firstName = firstName;
+};
+
+// Добавляем пару методов в Person.prototype
+Person.prototype.walk = function(){
+  console.log("I am walking!");
+};
+
+Person.prototype.sayHello = function(){
+  console.log("Hello, I'm " + this.firstName);
+};
+
+// Определяем конструктор Student
+function Student(firstName, subject) {
+  // Вызываем конструктор родителя, убедившись (используя Function#call)
+  // что "this" в момент вызова установлен корректно
+  Person.call(this, firstName);
+
+  // Инициируем свойства класса Student
+  this.subject = subject;
+};
+
+// Создаём объект Student.prototype, который наследуется от Person.prototype.
+// Примечание: Рспространённая ошибка здесь, это использование "new Person()", чтобы создать
+// Student.prototype. Это неверно по нескольким причинам, не в последнюю очередь
+// потому, что нам нечего передать в Person в качестве аргумента "firstName"
+// Правильное место для вызова Person показано выше, где мы вызываем
+// его в конструкторе Student.
+Student.prototype = Object.create(Person.prototype); // Смотрите примечание выше
+
+// Устанавливаем свойство "constructor" для ссылки на класс Student
+Student.prototype.constructor = Student;
+
+// Заменяем метод "sayHello"
+Student.prototype.sayHello = function(){
+  console.log("Hello, I'm " + this.firstName + ". I'm studying "
+              + this.subject + ".");
+};
+
+// Добавляем метод "sayGoodBye"
+Student.prototype.sayGoodBye = function(){
+  console.log("Goodbye!");
+};
+
+// Пример использования:
+var student1 = new Student("Janet", "Applied Physics");
+student1.sayHello();   // "Hello, I'm Janet. I'm studying Applied Physics."
+student1.walk();       // "I am walking!"
+student1.sayGoodBye(); // "Goodbye!"
+
+// Проверяем, что instanceof работает корректно
+console.log(student1 instanceof Person);  // true
+console.log(student1 instanceof Student); // true
+
+ +

Относительно строки Student.prototype = Object.create(Person.prototype);: В старых движках JavaScript, в которых нет  Object.create можно использовать полифилл (ещё известный как "shim") или функцию которая достигает тех же результатов, такую как:

+ +
function createObject(proto) {
+    function ctor() { }
+    ctor.prototype = proto;
+    return new ctor();
+}
+
+// Пример использования:
+Student.prototype = createObject(Person.prototype);
+
+ +
Примечание: Смотрите Object.create для более подробной информации, и shim для реализации на старых движках.
+ +

Инкапсуляция

+ +

В примере выше классу Student нет необходимости знать о реализации метода walk() класса Person, но он может его использовать; Класс Student не должен явно определять этот метод, пока мы не хотим его изменить. Это называется инкапсуляция, благодаря чему каждый класс собирает данные и методы в одном блоке.

+ +

Сокрытие информации распространённая особенность, часто реализуемая в других языках программирования как приватные и защищённые методы/свойства. Однако в JavaScript можно лишь имитировать нечто подобное, это не является необходимым требованием объектно-ориентированного программирования.2

+ +

Абстракция

+ +

Абстракция это механизм который позволяет смоделировать текущий фрагмент рабочей проблемы, с помощью наследования (специализации) или композиции. JavaScript достигает специализации наследованием, а композиции возможностью экземплярам класса быть значениями атрибутов других объектов.

+ +

В JavaScript класс Function наследуется от класса Object (это демонстрирует специализацию), а свойство Function.prototype это экземпляр класса Object (это демонстрирует композицию).

+ +
var foo = function () {};
+
+// выведет "foo is a Function: true"
+console.log('foo is a Function: ' + (foo instanceof Function));
+
+// выведет "foo.prototype is an Object: true"
+console.log('foo.prototype is an Object: ' + (foo.prototype instanceof Object));
+ +

Полиморфизм

+ +

Так как все методы и свойства определяются внутри свойства prototype, различные классы могут определять методы с одинаковыми именами; методы находятся в области видимости класса в котором они определены, пока два класса не имеют связи родитель-потомок (например, один наследуется от другого в цепочке наследований).

+ +

Примечания

+ +

Это не все способы которыми можно реализовать объектно-ориентированное программирование в JavaScript, который очень гибок в этом отношении. Также способы рассмотренные здесь не отражают всех возможностей JavaScript и не подражают реализации теории объектов в других языках.

+ +

Существуют другие способы, которые реализуют ещё более продвинутое объектно-ориентированное программирование на JavaScript, но они выходят за рамки этой вводной статьи.

+ +

Ссылки

+ +
    +
  1. Wikipedia. "Object-oriented programming"
  2. +
  3. Wikipedia. "Encapsulation (object-oriented programming)"
  4. +
diff --git a/files/ru/conflicting/mdn/contribute/index.html b/files/ru/conflicting/mdn/contribute/index.html new file mode 100644 index 0000000000..a8227dafed --- /dev/null +++ b/files/ru/conflicting/mdn/contribute/index.html @@ -0,0 +1,94 @@ +--- +title: Участие в MDN +slug: MDN_at_ten/Contributing_to_MDN +tags: + - MDN Мета + - Mozilla + - Участие +translation_of: MDN_at_ten/Contributing_to_MDN +--- +
+
+

Как принять участие

+ +

Внести свой вклад в MDN очень просто, и есть два способа начать работу. Вы видите страницу, которую можно улучшить (исправив опечатку, добавив новую информацию или исправив технические ошибки)? Просто нажмите большую синюю кнопку "Редактировать" в верхней части страницы. Вы знаете что-то, чего мы еще не освещаем? Просто создайте новую страницу; наше сообщество замечательных обозревателей и редакторов позаботится о том, чтобы ваша страница соответствовала нашему руководству по оформлению и находилась в нужном месте на сайте. Не переживайте из-за того, чтобы получилось «полностью правильно». Каждый может помочь сделать Интернет лучше.

+
+ +
+
+
+

Присоединяйтесь!

+ +

Присоединяйтесь к нам в обучении мира разработке открытой сети!

+ +

Быстый старт

+
+
+
+
+ +
+
+

Выборка профилей участников

+ +

MDN состоит из огромного сообщества участников. Хотя мы не можем предложить профили всех из них (это было бы очень долго!), Мы можем рассказать кое-что о некоторых из тех, кто внес существенный или важный вклад, а также о тех, кто скорее всего, будет доступен в чате MDN Web Docs, чтобы помочь вам, если вам понадобится помощь в вашем участии.

+ +
+
+

Chris Blizzard
+ Former Director of Evangelism, Mozilla

+ +

Blizzard oversaw and drove Mozilla Developer Center's transition from focusing on Mozilla-specific material to a community-maintained resource useful to a variety of Web developers.

+ +

Николай Пономарёв
+ Доброволец

+ +

Nickolay был одним из самых ранних участников, помогая с первоначальными усилиями по очистке DevEdge. С тех пор он продолжает вносить свой вклад во многих областях, как для веб-стандартов, так и для продуктов Mozilla.

+ +

Andrew Overholt
+ Engineering Manager

+ +

Andrew возглавляет команду разработчиков веб-API. В рамках своей работы он побуждает всех разработчиков DOM и API помочь убедиться, что документация отличная, предоставляет информацию, которая нужна команде разработчиков, просматривает документацию и помогает с примерами кода. Этот пример очень и очень радует команду MDN.

+ +

Jérémie Patonnier
+ Project Manager

+ +

Jérémie начал вносить свой вклад в MDN в 2011 году, документируя свойства SVG, поскольку эта информация была ему нужна для его собственной работы. Jérémie стал лидером французского сообщества MDN, проводя регулярные сессии "Mercredi Docs" (документ среды) в офисе Mozilla Париж. В настоящее время он возглавляет усилия по созданию области обучения, а также по улучшению и упорядочиванию данных о совместимости браузеров в MDN.

+ +

Julien (Sphinx)
+ Доброволец

+ +

Julien внес «львиную долю» усилий на перевод всего раздела JavaScript в MDN на французский язык. Многие другие участники также помогли в этой работе, но Julien провел много ночей и выходных в течение нескольких месяцев, переводя статьи на JavaScript.

+ +

Jeff Walden
+ Software Engineer, JavaScript Engine

+ +

Jeff Walden сейчас входит в команду SpiderMonkey, которая внесла свой вклад в MDN с самого его начала и во многих областях, включая XPCOM, сборку и тестирование Mozilla, JavaScript, CSS и многое другое.

+
+ +
+

Priyanka Nag
+ Доброволец

+ +

Priyanka Nag присоединилась к MDN в 2012 году, но стала активно работать с сообществом MDN только после саммита Mozilla в 2013 году, где она встретилась и работала с Luke Crouch и David Walsh из команды разработчиков MDN; это послужило ее главным вдохновением, чтобы начать вносить свой вклад в MDN. Priyanka в основном любит проповедовать MDN, проводить мероприятия MDN и знакомить с MDN больше людей, а также время от времени вносить некоторые правки в вики. В настоящее время она работает техническим писателем в Red Hat и с гордостью утверждает, что ее интерес к техническому писательству начался с ее вклада в MDN, который в конечном итоге оказал большое влияние на ее решение о карьере.

+ +

Saurabh Nair
+ Доброволец

+ +

Saurabh он вносит свой вклад в MDN с 2011 года и стал более активным в прошлом году. Он входит в команду “spam watch”, которая следит за спам-страницами, удаляя их и запрещая спамеров, как только они появляются. Поскольку он живет в Индии, он может делать это, пока сотрудники MDN в Европе и Северной Америке спят.

+ +

Eric Shepherd (Sheppy)
+ Senior Technical Writer

+ +

{{UserLink("Sheppy")}} был первым штатным писателем, нанятым Mozilla для работы исключительно над документацией для разработчиков, начиная с 3 апреля 2006 года. Он пишет обо всем, что требует освещения, в том числе о вещах, с которыми никто другой не хочет иметь ничего общего. На протяжении многих лет он много писал обо всем, от дополнений до XUL.

+ +

Sebastian Zartner
+ Доброволец

+ +

Sebastian внёс первый вклад в MDNв 2007 году, когда он работал над немецкими переводами, но вскоре он начал работать над английскими. Он внёс большой вклад как в содержание, так и в структуру справочника CSS, включая создание JSON API для страниц CSS и макросов, использующих это API.

+
+
+
+ +
{{TenthCampaignQuote(7)}} {{TenthCampaignQuote(5)}}
+
diff --git a/files/ru/conflicting/mdn/tools/index.html b/files/ru/conflicting/mdn/tools/index.html new file mode 100644 index 0000000000..88a0659232 --- /dev/null +++ b/files/ru/conflicting/mdn/tools/index.html @@ -0,0 +1,13 @@ +--- +title: Руководство пользователя MDN +slug: MDN/User_guide +tags: + - Documentation + - Landing + - MDN +translation_of: MDN/Tools +translation_of_original: MDN/User_guide +--- +
{{MDNSidebar}}

Сайт сети разработчиков Mozilla является продвинутой системой для поиска, чтения и внесения документации и примеров исходного кода для веб-разработчиков (а также для разработчиков под браузер Firefox и ОС Firefox). Руководство пользователя MDN предоставляет статьи, в подробностях описывающие, как использовать MDN для поиска нужной вам документации и, если вы желаете, как помочь сделать материалы лучше: более полными и обширными.

+
+ {{LandingPageListSubpages}}
diff --git a/files/ru/conflicting/mozilla/add-ons/index.html b/files/ru/conflicting/mozilla/add-ons/index.html new file mode 100644 index 0000000000..f147f764bb --- /dev/null +++ b/files/ru/conflicting/mozilla/add-ons/index.html @@ -0,0 +1,248 @@ +--- +title: Создание расширения +slug: Building_an_Extension +tags: + - Расширение + - Создание +--- +

Введение

+

Этот урок по шагам покажет Вам как создать простое Расширение – сутью которого является добавление в панель статуса Firefox блока со строкой "Hello, World!"

+
+

Отметьте Данный урок о создании Расширений для Firefox 1.5 и более поздних версий. Другие существующие уроки для создания Расширений, предназначены для более ранних версий.

+

Если Вас интересует урок по созданию Расширения для Thunderbird, смотрите Создание Расширения для Thunderbird

+
+

Настройка окружения

+

Начнём с того, что Расширение распространяется в виде zip архива или Пакетов, с расширением XPI (произносится как “зиппи”).

+

Вот пример типичного XPI файла:

+
exampleExt.xpi:
+              /install.rdf
+              /components/*
+              /components/cmdline.js
+              /defaults/
+              /defaults/preferences/*.js
+              /plugins/*
+              /chrome.manifest
+              /chrome/icons/default/*
+              /chrome/
+              /chrome/content/
+
+
+

Давайте создадим файловою структуру для нашего урока, подобную той что была описана выше, для чего создайте где-нибудь на жёстком диске директорию(например C:\extensions\my_extension\ или ~/extensions/my_extension/).  Создайте в этой директории новую директорию c именем chrome, и создайте в директории chrome директорию с именем code>content.

+

В корне директории вашего Расширения создайте два пустых файла, один назовите chrome.manifest, а другой install.rdf.

+

В итоге у вас должна получиться вот такая структура:

+
<ext path>\
+          install.rdf
+          chrome.manifest
+          chrome\
+             content\
+
+

<pre> #!/bin/sh h=$HOME/moExt mkdir -p $h/my_extension/chrome/content touch $h/my_extension/chrome.manifest $h/my_extension/install.rdf </pre> Более подробную информацию по настройке окружения читайте в статье Setting up extension development environment.

+

Создание файла инсталяции

+

Откройте файл install.rdf который Вы создали на предыдущем этапе и вставьте эти строки:

+
<?xml version="1.0"?>
+
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+
+  <Description about="urn:mozilla:install-manifest">
+    <em:id>sample@example.net</em:id>
+    <em:version>1.0</em:version>
+    <em:type>2</em:type>
+
+    <!-- Указывается приложение для которого может
+            быть установлено Расширение, его максимальная
+            и минимальная поддерживаемая версия. -->
+    <em:targetApplication>
+      <Description>
+        <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
+        <em:minVersion>1.5</em:minVersion>
+        <em:maxVersion>3.0.*</em:maxVersion>
+      </Description>
+    </em:targetApplication>
+
+    <!-- Front End MetaData -->
+    <em:name>sample</em:name>
+    <em:description>A test extension</em:description>
+    <em:creator>Your Name Here</em:creator>
+    <em:homepageURL>http://www.example.com/</em:homepageURL>
+  </Description>
+</RDF>
+
+ +

(В Firefox версии 3.0.1, вы не сможете установить для em:minVersion и em:maxVersion значение "3.0.*". Если Вы попытаетесь установить Расширение, то получите ошибку "Not compatible with Firefox 3.0.1". Мне не ясны причины этого, так что я оставлю объяснение тому, кто имеет больше информации по этому поводу. Установка em:minVersion равным "3" и em:maxVersion равным "3.0.*" решило проблему для меня.)

+

Расширения разработанные для работы только с последними версиями Firefox 2.0.0.x, должны иметь установленным максимальную версию в "2.0.0. *". Расширения, разработанные для работы с только с последними версиями Firefox 1.5.0.x, должны иметь установленным максимальную версию "1.5.0. *".

+

Более подробно См. Install Manifests с полным перечнем основных и дополнительных свойств.

+

Сохраните файл.

+

Расширение браузера с помощью XUL

+

Пользовательский интерфейс Firefox написан c использованием XUL и JavaScript.   XUL является языком разметки на основе грамматики XML, которая позволяет описывать такие фрагменты пользовательского интерфейса, как кнопки, меню, панели инструментов, деревья и т.д.  Вся функциональность и обработка действий пользователя осуществляется с помощью JavaScript.

+

Чтобы расширить браузер, мы изменяем различные части интерфейса браузера путём добавления или изменения ”виджетов”. Мы добавляем “виджеты”, вставляя новые элементы, DOM XUL в окно браузера и изменяем их, используя сценарий (скрипт) и присоединяя, обработчики событий.

+

Интерфейс браузера описан в XUL файле, который называется browser.xul ($FIREFOX_INSTALL_DIR/chrome/browser.jar contains content/browser/browser.xul).  В browser.xul, мы можем найти фрагмент описывающий строку состояния, который выглядит вот так:

+
<statusbar id="status-bar">
+ ... <statusbarpanel>s ...
+</statusbar>
+
+

<statusbar id="status-bar"> это “точка слияния" для XUL Оверлея.

+
XUL Оверлеи
+

XUL Оверлей - это способ внедрить другие “виджеты” пользовательского интерфейса в основной документ XUL. XUL Оверлей – это .xul файл, в котором определены фрагменты XUL для вставки в определённых “точках слияния” в основном документе. Эти фрагменты, могут определять “виджеты” которые должны быть вставлены, удалены, или изменены.

+

Пример документа XUL Оверлея:

+
<?xml version="1.0"?>
+<overlay id="sample"
+         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <statusbar id="status-bar">
+  <statusbarpanel id="my-panel" label="Hello, World"/>
+ </statusbar>
+</overlay>
+
+

<statusbar> название status-bar определяет "точку слияния" в пределах окна браузера, к которой мы хотим присоединить.

+

<statusbarpanel> новый “виджет” который мы хотели бы вставить в пределах точки слияния.

+

Возьмите этот простой код и сохраните в новом файле с именем sample.xul и поместите его в директорию chrome/content.

+

Для получения дополнительной информации о присоединении “виджетов” и изменении пользовательского интерфейса, используя Оверлеи, см. далее.

+

Chrome URIs

+

XUL Файлы - это часть пакета Chrome Packages - пакета компонентов пользовательского интерфейса, которые загружаются через chrome://URIs. Вместо того, чтобы загружать их диска, используя file://URI (так как местоположение Firefox в системе может меняться от платформы к платформе и от системы к системе), разработчики Mozilla придумали решение, которое позволяет создать URIs к информационному наполнению XUL, о котором знает установленное приложение.

+

В окне браузера: chrome://browser/content/browser.xul. Напечатайте этот URL в адресной строке Firefox!

+

Chrome URIs состоит из нескольких составляющих:

+ +

Так, chrome://foo/skin/bar.png  загружает файл bar.png из темы foo раздела skin.

+

Когда Вы загружаете содержимое, используя Chrome URI, Firefox использует системный реестр Chrome, чтобы транслировать URIs в фактические исходные файлы на диске (или в пакетах JAR).

+

Создание установок Chrome

+

Для получения дополнительной информации об установках Chrome и о поддерживаемых свойствах руководство по Chrome Manifest.

+

Откройте файл с названием chrome.manifest который Вы создали рядом с каталогом chrome в корне исходной иерархии директории Вашего Расширения.

+

Добавьте в него код:

+
content     sample    chrome/content/
+
+

(Не забывайте, косую черту "/"! Без этого пакет не будет зарегистрирован.)

+

Здесь определяется:

+
    +
  1. тип материала в пределах chrome пакета
  2. +
  3. название chrome пакета (удостоверьтесь, что Вы используете все символы в нижнем регистре для имени пакета ("sample"), так как во 2-й версии не поддерживается смешанные регистры и вы получите ошибку {{ Bug(132183) }}
  4. +
  5. местоположение файлов chrome пакета
  6. +
+

Эта строка говорит, что для chrome пакета с именем sample, файлы информационного наполнения находятся в chrome/content, который является путем относительно местоположения chrome.manifest.

+

Заметьте, что content, locale и skin должны быть сохранены как каталоги, с соответствующими именами content, locale и skin в подкаталоге chrome.

+

Сохраните файл. Когда Вы запустите Firefox со своим расширением, (это будет позже в данном уроке), chrome пакет будет зарегистрирован.

+

Регистрация Оверлея

+

Вам нужно присоединить ваш оверлей к окну браузера Firefox, при его отображении. Для этого добавьте следующую строку файл chrome.manifest:

+
overlay chrome://browser/content/browser.xul chrome://sample/content/sample.xul
+
+

Эта строка говорит браузеру, присоединить sample.xul к browser.xul во время загрузки browser.xul.

+

Тестирование

+

Во-первых, мы должны рассказать о своём расширении Firefox. На стадии разработки для Firefox версии 2.0 и выше, вы можете указать Firefox папку, где вы разрабатываете Расширение, и оно будет загружать его каждый раз после перезапуска Firefox.

+
    +
  1. Перейдите в папку вашего профиля по умолчанию. Папка вашего профиля по умолчанию, должна, находится где-то в папке профилей, например в Firefox/Profiles/<profile_id>.default/.
  2. +
  3. Откройте папку extensions. Если ранее вы уже устанавливали, какие либо расширения, то она должна уже существовать.
  4. +
  5. Создайте там, новый текстовый файл и запишите в него путь к папке с вашим расширением, например C:\extensions\my_extension\ или ~/extensions/my_extension/. Сохраните файл, указав в качестве имени идентификатор вашего Расширения, в нашем примере этоsample@example.net.
  6. +
+

(Не забывайте, косую черту, "/"! Без этого ваше расширение не будет зарегистрировано.)

+

(my_extension может не работать! Если имя папки содержит символы подчеркивания.)

+

Теперь всё готово для испытания вашего расширения!

+

Запустите Firefox. Firefox обнаружит ссылку на каталог вашего расширения и установит его. Когда появится окно браузера вы должны увидеть текст "Hello, World!" на правой стороне в панели статуса.

+

Вы можете вернуться и внести необходимые изменения в .xul файл, после чего закрыть и перезапустить Firefox и изменения немедленно вступят в силу.

+

Упаковка

+

Теперь, когда ваше расширение работает, вы можете его упаковать для последующего развертывания и установки.

+

За "зипуйте" папку contents вашего Расширения (не саму папку расширения), и переименуйте получившийся zip файл, так чтобы он имел расширение .xpi. В Windows XP, вы можете сделать это очень просто, выбрав все файлы и вложенные папки в папке вашего расширения, и щелкнув правой кнопкой мыши и выбрав "Send To -> Compressed (Zipped) Folder". Zip файл будет создан. Просто переименуйте его, и готово!

+

В Mac OS X, вы можете нажать правой кнопкой мыши на папке contents вашего Расширения и выбрать "Создать архив ..." для создания архива. Однако, Mac OS X добавляет скрытые файлы в папку. Поэтому следует использовать Terminal, для удаления скрытых файлов (чьи имена начинаются с периода), а затем ввести в командной строке zip команду для создания архива.

+

В Linux, вы аналогичным образом можете использовать в командной строке Zip инструменты.

+

Если у вас установлено Extension Builder вы можете использовать его для сборки .xpi файла (Tools -> Extension Developer -> Extension Builder). Просто выберите каталог, где находится ваше расширение (install.rdf т.д.), и нажмите кнопку Build Extension (Построить расширение). Это расширение имеет множество инструментов для облегчения процесса создания расширений.

+

Теперь загрузите ваш .XPI файл на сервер, и сделайте, так чтобы он определялся как application/x-xpinstall. Вы можете давать ссылку на него и позволить людям скачивать и установить его. Для тестирования нашего. XPI файла можно просто перетащить его в окно менеджера расширений, открыв его через меню Tools -> Extensions в Firefox 1.5.0.x, или Tools -> Add-ons в более поздних версиях.

+
Установка с web-страниц
+

Существует множество путей, которыми вы можете устанавливать ваши расширения прямо с web-страниц, в том числе использование прямых ссылок на файлы XPI и использование InstallTrigger method объекта. Разработчикам расширений и веб разработчикам, рекомендуется использовать для установки XPI методы InstallTrigger, которые дают больше возможностей их пользователям.

+
Использование addons.mozilla.org
+

С помощью сайта Mozilla Add-ons вы может распространять ваше Расширение для бесплатного пользования. Вше расширение будет иметь зеркала на Mozilla, что обеспечит доступность вашего расширения, если оно станет очень популярным. Сайт Mozilla также упрощает установку расширений для пользователей , и автоматически сделает доступными ваши новые версии для пользователей вашей текущей версии, после того как вы загрузите их. Кроме того Mozilla Add-ons позволяет пользователям оставлять комментарии и тем самым обеспечивает обратную связь с Вашим Расширением. Настоятельно рекомендуется использовать Mozilla Add-ons для распространения ваших расширений!

+

Зайдите на http://addons.mozilla.org/developers/ создайте учётную запись и начинайте распространение ваших расширений!

+

Примечание:Ваше Расширение будет скачиваться быстрее и чаще, если у вас будет хорошее описание и скриншоты с вашим расширением в действии.

+
Регистрация расширений в реестре Windows
+

В Windows, информация о расширениях может быть добавлена в реестр, откуда Расширение автоматически будет извлекаться в следующий раз, при загрузке приложения. This allows application installers to easily add integration hooks as extensions. Для получения более подробной информации смотри Adding Extensions using the Windows Registry.

+

Подробнее о XUL Оверлеях

+

Помимо добавления UI виджетов, вы также можете использовать XUL фрагменты для:

+ +
<statusbarpanel position="1" .../>
+
+<statusbarpanel insertbefore="other-id" .../>
+
+<statusbarpanel insertafter="other-id" .../>
+
+

Создание новых компонентов UI

+

Вы можете создавать ваши собственные окна и диалоговые окошки в отдельных .xul файлах, обеспечивая их функциональность с помощью описания действий пользователя в .js файлах, используя DOM для манипуляции UI “виджетами”. Вы можете использовать стили из .css файлов для присоединения изображений, установки цвета и т.д.

+

Смотрите документацию по XUL на крупных ресурсах для разработчиков XUL.

+

Файлы По умолчанию

+

Файлы по умолчанию, которые вы используете для профиля пользователя, должны быть помещены в defaults/ в корень в иерархии папок вашего Расширения. По умолчанию .js файлы с настройками должны храниться в defaults/preferences/ - после того как вы поместите их туда они будут автоматически загружаться в системные настройки Firefox при запуске, так что вы сможете получить к ним доступ использую Preferences API.

+

Пример файла настроек по умолчанию:

+
pref("extensions.sample.username", "Joe"); //строка
+pref("extensions.sample.sort", 2); //число
+pref("extensions.sample.showAdvanced", true); //булево
+
+

XPCOM Components

+

Firefox поддерживает XPCOM компоненты в расширениях. Вы можете легко создавать свои собственные компоненты на JavaScript или C + + (с использованием Gecko SDK).

+

Поместите все ваши. JS или. DLL файлы каталог components/ - после установки расширения , они автоматически будут зарегистрированы при первом запуске Firefox.

+

Для получения дополнительной информации см. Как создать XPCOM компонент на JavaScript, Как создать XPCOM компонент с использованием Visual Studio и Cкниги по созданию XPCOM Компонентов.

+
Командная строка приложения
+

Один из возможных вариантов использования пользовательских XPCOM компонентов добавить в командную строку указатель для Firefox или Thunderbird. Вы можете использовать этот метод для запуска ваших расширений, как приложений:

+
 firefox.exe -myapp
+
+

I should move the useful parts of this to the Command Line page. -Nickolay This is done by adding a component containing the function... function NSGetModule(comMgr, fileSpec) { return myAppHandlerModule; } This function is run by firefox each time firefox is started. Firefox registers the myAppHandlerModule's by calling its 'registerSelf()'. Then it obtains the myAppHandlerModule's handler factory via 'getClassObject()'. The handler factory is then used to create the handle using its 'createInstance(). Finally, the handle's 'handle(cmdline)' processes the command line cmdline's handleFlagWithParam() and handleFlag(). Смотрите Chrome: Command Line , а также обсуждения на форуме.

+

Локализация

+

Для поддержки более чем одного языка, вы должны вместо отдельных строк из вашего содержимого использовать "сущности" или a href="mks://localhost/en/XUL_Tutorial/Property_Files" title="en/XUL_Tutorial/Property_Files">"связки строк". Это лучше делать в самом начале разработки Вашего Расширения, а не возвращаться, к этому позже!

+

Информация о локализации хранится в каталоге локализации расширения. Например, чтобы добавить локализацию для нашего расширения, создайте директорию с именем "locale" в каталоге chrome (где находится каталог "content" ) и добавьте следующую строчку в файл chrome.manifest:

+
locale sample en-US chrome/locale/en-US/
+
+

Для создания локализации , значения атрибута в XUL, вы вставляете его значение в .ent (или .dtd) файле который, затем помещаете каталог локализации и который выглядит так:

+
<!ENTITY  button.label     "Click Me!">
+<!ENTITY  button.accesskey "C">
+
+

Затем, подключаете его в верхней части вашего XUL документа ( сразу под строкой ), вот так::

+
<!DOCTYPE window SYSTEM "chrome://packagename/locale/filename.ent">
+
+

где window это localName значение, которое является корневым элементом вашего XUL документа, и свойство SYSTEM значение которого chorm URI к файлу с сущностями. Для примера нашего расширения, мы используем корневой элемент overlay.

+

Для использования сущностей измените ваш XUL, что бы он выглядел так:

+
<button label="&button.label;" accesskey="&button.accesskey;"/>
+
+

Chrome реестр всегда будет загружать тот файл с сущностями, который соответствует текущей выбранной локализации.

+

Для строк которые вы используете в сценарии (скрипте), создайте файл .properties, текстовый файл который будет содержать строки в таком формате:

+
key=value
+
+

а, затем используйте nsIStringBundleService/nsIStringBundle или тег <stringbundle>, чтобы получить значения в сценарии (скрипте).

+

Understanding the Browser

+

Use the DOM Inspector to inspect the browser window or any other XUL window you want to extend.

+

Примечание: DOM Inspector не устанавливается в режиме стандартной установки Firefox. Начиная с версии Firefox 3 Beta 4, DOM Inspector доступен с сайта Firefox Add-ons, как автономное расширение. Для более ранних версий, вам необходимо переустановить FireFox в режиме Пользовательской установки и выбрать путь к DOM Inspector(или Developer Tools в Firefox 1.5), если DOM Inspector'a нет в меню Инструменты (Tools) в вашего браузера.

+

Используйте кнопку Point-and-click icon в верхнем правом углу панели инструментов DOM Inspector для визуального выбора интересующего элемента в окне XUL. После выбора элемента, в окне DOM inspector появится DOM иерархия интересующего Вас элемента.

+

Use the DOM Inspector's right side panel to discover merge points with ids that you can use to insert your elements from overlays. If you cannot discover an element with an id that you can merge into, you may need to attach a script in your overlay and insert your elements when the load event fires on the master XUL window.

+

Debugging Extensions

+

Analytical Tools for Debugging

+ +

printf debugging

+ +

Advanced debugging

+ +

Быстрый старт

+

Вы можете использовать Extension Wizard, инструмент для создания простых Расширений.

+

A Hello World extension similar to what you can generate with the Extension Wizard is explained line-by-line in another tutorial from MozillaZine Knowledge Base.

+

Further information

+ diff --git a/files/ru/conflicting/mozilla/firefox/releases/index.html b/files/ru/conflicting/mozilla/firefox/releases/index.html new file mode 100644 index 0000000000..ba7f7887f2 --- /dev/null +++ b/files/ru/conflicting/mozilla/firefox/releases/index.html @@ -0,0 +1,128 @@ +--- +title: Замечания к релизу +slug: Tools/Release_notes +translation_of: Mozilla/Firefox/Releases +translation_of_original: Tools/Release_notes +--- +
{{ToolsSidebar}}

Firefox 48

+ +

Главное:

+ + + +

Другие исправления багов

+ +

Firefox 32

+ +

Highlights:

+ + + +

More details:

+ + + +

All devtools bugs fixed between Firefox 31 and Firefox 32.

+ +

Firefox 31

+ +

Highlights:

+ + + +

More details:

+ + + +

All devtools bugs fixed between Firefox 30 and Firefox 31.

+ +

Firefox 30

+ +

Highlights:

+ + + +

More details:

+ + + +

All devtools bugs fixed between Firefox 29 and Firefox 30.

+ +

Firefox 29

+ +

Firefox 29 Hacks post. Highlights:

+ + + +

Firefox 28

+ +

Firefox 28 Hacks post. Highlights:

+ + + +

Firefox 27

+ +

Firefox 27 Hacks post. Highlights:

+ + diff --git a/files/ru/conflicting/tools/performance/index.html b/files/ru/conflicting/tools/performance/index.html new file mode 100644 index 0000000000..10e4254907 --- /dev/null +++ b/files/ru/conflicting/tools/performance/index.html @@ -0,0 +1,169 @@ +--- +title: Профилирование JavaScript +slug: Tools/Profiler +tags: + - Firefox + - Отладка + - Профайлер + - Профилирование + - Руководство + - инструменты +translation_of: Tools/Performance +translation_of_original: Tools/Profiler +--- +
{{ToolsSidebar}}

Используйте средства профилирования, чтобы находить узкие места в своём JavaScript коде.  Профайлер периодически проверяет состояние стека вызовов JavaScript и составляет статистику на основе полученных в результате измерения величин.

+ +

Вы можете запустить профайлер выбрав «Profiler»  из меню «Web Develeper». Для операционных систем Linux и OS X данное меню находится в меню «Tools», в Windows его можно вызвать из меню «Firefox».

+ +

В открывшемся меню уже будет выбран профайлер.

+ +

 

+ +

Семплирующие профайлеры

+ +

 

+ +

Профайлер JavaScript — сэмплирующий профайлер. Это означает, что он периодически собирает информацию о состоянии интерпретатора JavaScript, сохраняет стек выполняющегося на момент сэмплирования кода. Статистически, число образцов полученных во время выполнения какой-либо функции, соответствует количеству времени, которое браузер проводит выполняя её, таким образом вы можете находить узкие места в своём коде.

+ +

Рассмотрим следующую программу в качестве примера:

+ +
function doSomething() {
+  var x = getTheValue();
+  x = x + 1;                   // -> sample A
+  logTheValue(x);
+}
+
+function getTheValue() {
+  return 5;
+}
+
+function logTheValue(x) {
+ console.log(x);               // -> sample B, sample C
+}
+
+doSomething();
+ +

Допустим мы запустили данную программу с активным профайлером, и во время её выполнения, профайлер взял три сэмпла, в местах указанных комментариями.

+ +

Они все взяты внутри doSomething(), но вторые два внутри функции logTheValue() вызванной doSomething(). В результате получим профиль состоящий из трёх записей:

+ +
Sample A: doSomething()
+Sample B: doSomething() > logTheValue()
+Sample C: doSomething() > logTheValue()
+ +

Конечно этих данных недостаточно, чтобы сделать какие-то выводы, но с гораздо большим количеством сэмплов, мы поймём, что узким местом в нашей программе является logTheValue().

+ +

 

+ +

Создание профиля

+ +

Нажмите кнопку stopwatch в профайлере, чтобы начать сбор сэмплов. Кнопка stopwatch подсвечена, если профайлер активен. Кликните на ней ещё раз и сохраните новый профиль:

+ +

 

+ +

+ +

Новый профиль будет открыт автоматически при нажатии "Stop".

+ +

+ +

Панель разделена на две части:

+ + + +

 

+ +

Анализируем профиль

+ +

 

+ +

Профиль разделён на две части:

+ + + +

График профилирования

+ +

График профилирования располагается в верхней части экрана профиля.

+ +

+ +

Горизонтальная ось это время, а вертикальная — размер стека вызовов на текущий сэмпл. Стек вызовов представляет количество активных функций  на момент сэмплирования.
+ Красные сэмплы на графике говорят о том, что браузер был недоступен на тот момент и пользователь мог наблюдать паузы в анимации и отклике браузера. Если профиль содержит красные образцы,  их следует разбить на несколько событий и рассмотреть  используя requestAnimationFrame и Workers.

+ +

Подсветив определённый участок в профиле рамкой, можно исследовать его более детально:

+ +

+ +

В таком случае, над графиком появится новая кнопка с надписью вида: "Sample Range [AAA, BBB]". Нажав на неё, можно приблизить рассматриваемый участок и детально его рассмотреть.

+ +

+ +

Детали профилирования

+ +

Детали профилирования расположены в нижней части экрана профиля:

+ +

+ +

Когда вы впервые открываете новый сэмпл, панель сэмплов содержит единственную строку «(total)»,  как на скриншоте ниже. Если кликнуть на стрелке следующей за надписью «(total)», вы увидилте список всех функций верхнего уровня которые находятся в сэмпле.

+ +


+

+ +

Время выполнения (Running time) показывает число сэмплов в которых присутствует данная функция1 , далее следует процент появления функции в остальных сэмплах профиля.  Первая сверху строка показывает, что в профиле 2021 сэмпл, вторая строка показывает, что 1914 или 94.7% из них содержат в себе функцию detectImage().

+ +

Self показывает количество сэмплов полученное во время выполнения самой функции, а не функции её вызвавшей. В примере выше  doSomething() имеет время выполнения (Running time) равное 3 (сэмпл A, B и C), но значение Self равно единице (sample A).

+ +

Третий столбец содержит имена функций, а также имена файлов и номера строк (для локальных функций) или полное/доменное имя (для внешних). Функции серого цвета — встроенные функции браузера, чёрные — JavaScript загруженный страницей. Если вы переместите курсор мыши вдоль строк, то обнаружите справа от имён функций стрелочку: кликните по ней и увидите исходный код функции.

+ +

 

+ +

Раскрываем древо вызовов

+ +

 

+ +

В строке, если какие-либо сэмплы были взяты в функции вызванной другой функцией (т. е. Если время выполнения (Running time) больше чем Self для заданной строки) — появляется стрелочка слева от имени функции, дающая возможность раскрыть древо вызовов.

+ +

Для примера приведённого выше, полностью раскрытое древо вызовов будет выглядеть следующим образом:

+ + + + + + + + + + + + + + + + + + + +
Running TimeSelf 
3            100%1doSomething()
2              67%2logTheValue()
+ +

Более реалистичный пример: на скриншоте ниже,  на второй строке видно 1914 сэмпла взятых внутри функции detectImage(). Но все сэмплы были получены  внутри функции названной detectImage() (Self равно нулю). Мы можем развернуть древо вызовов чтобы определить какая из функций на самом деле выполнялась когда было взято большинство сэмплов:

+ +

+ +

Далее можно сделать вывод, что 6 сэмплов было взято во время выполнения detectAtScale(), 12 во время getRect() и так далее.

+ +

Примечания

+ +
    +
  1.   Если функция вызывается несколько раз из различных источников, в выводе профайлера представлена она будет так же несколько раз. Так структуры вроде forEach будут появляться несколько раз в древе вызовов. + +

     

    +
  2. +
+ +

 

diff --git a/files/ru/conflicting/web/accessibility/index.html b/files/ru/conflicting/web/accessibility/index.html new file mode 100644 index 0000000000..ce48a75de2 --- /dev/null +++ b/files/ru/conflicting/web/accessibility/index.html @@ -0,0 +1,51 @@ +--- +title: Веб-разработка +slug: Web/Accessibility/Веб-разработка +tags: + - ARIA + - Web Development + - XUL + - доступность +translation_of: Web/Accessibility +translation_of_original: Web/Accessibility/Web_Development +--- +

Здесь ссылки на более подробную информацию для разработчиков о доступности (accessibility) в Веб и в XUL.

+ + + + + + + + +
+

Доступность в Вебе

+ +
+
ARIA для разработчиков
+
ARIA позволяет делать доступным динамический HTML-контент. Examples are live content regions and JavaScript widgets.
+
Keyboard-navigable JavaScript widgets
+
До недавнего времени у веб-разработчиков, желавших сделать свои виджеты на основе <div>, <span> и стилей доступными с клавиатуры, не было the proper techniques. Управляемость с клавиатуры — одно из минимальных требований accessibility, о которых должен знать каждый разработчик.
+
+ +

Доступность XUL

+ +
+
 
+
Building accessible custom components in XUL
+
How to use DHTML Accessibility techniques to add accessibility to your custom XUL components.
+
Accessible XUL authoring guidelines
+
When authored according to these guidelines, XUL is capable of generating accessible user interfaces. Coders, reviewers, designers and QA engineers should be familiar with these guidelines.
+
+
+

Внешние ресурсы

+ +
+
Dive into Accessibility
+
Эта книга отвечает на два вопроса. Первый — «Зачем мне делать мой сайт более доступным?» Второй — «Как мне сделать мой сайт более доступным?»
+
Accessible Web Page Authoring
+
A handy web accessibility checklist, from IBM.
+
+
+ +

 

diff --git a/files/ru/conflicting/web/api/canvas_api/a_basic_ray-caster/index.html b/files/ru/conflicting/web/api/canvas_api/a_basic_ray-caster/index.html new file mode 100644 index 0000000000..23b14adb7c --- /dev/null +++ b/files/ru/conflicting/web/api/canvas_api/a_basic_ray-caster/index.html @@ -0,0 +1,50 @@ +--- +title: A Basic RayCaster +slug: A_Basic_RayCaster +tags: + - Canvas_examples +--- +

 

+ +

The raycaster in action

+ +

View the live demo.

+ +

Why?

+ +

After realizing, to my delight, that the nifty <canvas> element I'd been reading about was not only soon to be supported in Firefox, but wasalready supported in the current version of Safari, I had to try a little experiment.

+ +

The canvas overview and tutorial I found here at MDC are great, but nobody had written about animation yet, so I thought I'd try a port of a basic raycaster I'd worked on a while ago, and see what sort of performance we can expect from a javascript controlled pixel buffer.

+ +

How?

+ +

The basic idea is to use setInterval at some arbitrary delay that corresponds to a desired frame rate. After every interval an update function will repaint the canvas showing the current view. I know I could have started with a simpler example, but I'm sure the canvas tutorial will get to that, and I wanted to see if I could do this.

+ +

So every update, the raycaster looks to see if you've pressed any keys lately, to conserve calculations by not casting if you're idle. If you have, then the canvas is cleared, the ground and sky are drawn, the camera position and / or orientation are updated and the rays are cast out. As the rays intersect walls, then they render a vertical sliver of canvas in the color of the wall they've hit, blended with a darker version of the color according to the distance to the wall. The height of the sliver is also modulated by the distance from the camera to the wall, and is drawn centered over the horizon line.

+ +

The code I ended up with is a regurgitated amalgam of the raycaster chapters from an old André LaMotheTricks of the Game Programming Gurus book (ISBN: 0672305070), and a java raycaster I found online, filtered through my compulsion to rename everything so it makes sense to me, and all the tinkering that had to be done to make things work well.

+ +

Results

+ +

The canvas in Safari 2.0.1 performed suprisingly well. With the blockiness factor cranked up to render slivers 8 pixels wide, I can run a 320 x 240 window at 24 fps on my Apple mini. Firefox 1.5 Beta 1 is even faster; I can run 320 x 240 at 24 fps with 4 pixel slivers. Not exactly a new member of the ID software family, but pretty decent considering it's a fully interpreted environment, and I didn't have to worry about memory allocation or video modes or coding inner routines in assembler or anything. The code does attempt to be very efficient, using array look-ups of pre-computed values, but I'm no optimization guru, so things could probably be written faster.

+ +

Also, it leaves a lot to be desired in terms of trying to be any sort of game engine—there are no wall textures, no sprites, no doors, not even any teleporters to get to another level. But I'm pretty confident all those things could be added given enough time. The canvas API supports pixel copying of images, so textures seem feasible. I'll leave that for another article, probably from another person. =)

+ +

The RayCaster

+ +

The nice people here have manually copied my files up so you can take a look, and for your hacking enjoyment I've posted the individual file contents as code listings (see below).

+ +

So there you are, fire up Safari 1.3+ or Firefox 1.5+ or some other browser that supports the <canvas> element and enjoy!
+
+ input.js | Level.js | Player.js | RayCaster.html | RayCaster.js | trace.css | trace.js

+ +

See Also

+ + + +

{{ languages( { "fr": "fr/Un_raycaster_basique", "ja": "ja/A_Basic_RayCaster", "pl": "pl/Prosty_RayCaster" } ) }}

diff --git a/files/ru/conflicting/web/api/crypto/getrandomvalues/index.html b/files/ru/conflicting/web/api/crypto/getrandomvalues/index.html new file mode 100644 index 0000000000..d56506a90a --- /dev/null +++ b/files/ru/conflicting/web/api/crypto/getrandomvalues/index.html @@ -0,0 +1,111 @@ +--- +title: RandomSource +slug: Web/API/RandomSource +tags: + - API + - Interface + - NeedsTranslation + - RandomSource + - Reference + - TopicStub + - Web Crypto API +translation_of: Web/API/Crypto/getRandomValues +translation_of_original: Web/API/RandomSource +--- +

{{APIRef("Web Crypto API")}}

+ +

RandomSource представляет собой источник криптографически безопасных случайных чисел. Он доступен через {{domxref("Crypto")}} объект глобального объекта: {{domxref("Window.crypto")}} на веб страницах, {{domxref("WorkerGlobalScope.crypto")}} для воркеров.

+ +

RandomSource не является интерфейсом и объект этого типа не может быть создан.

+ +

Свойства

+ +

RandomSource не объявляет и не наследует никаких свойств.

+ +
+
+ +

Методы

+ +
+
{{ domxref("RandomSource.getRandomValues()") }}
+
Наполняет {{ domxref("ArrayBufferView") }} криптографически безопасными случайными числовыми значениями.
+
+ +

Спецификации

+ + + + + + + + + + + + + + +
СпецификацияСтатусКоммент
{{SpecName('Web Crypto API', '#dfn-RandomSource')}}{{Spec2('Web Crypto API')}}Изначальное определение
+ +

Совместимость с браузерами

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
ВозможностьChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка11.0 {{ webkitbug("22049") }}{{CompatGeckoDesktop(21)}} [1]11.015.03.1
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
ВозможностьAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{ CompatNo() }}23{{CompatGeckoMobile(21)}}{{ CompatNo() }}{{ CompatNo() }}6
+
+ +

[1] Although the transparent RandomSource is only available since Firefox 26, the feature was available in Firefox 21.

+ +

Смотрите также

+ + diff --git a/files/ru/conflicting/web/api/document_object_model/index.html b/files/ru/conflicting/web/api/document_object_model/index.html new file mode 100644 index 0000000000..3acab80018 --- /dev/null +++ b/files/ru/conflicting/web/api/document_object_model/index.html @@ -0,0 +1,62 @@ +--- +title: DOM +slug: DOM +tags: + - DOM +translation_of: Web/API/Document_Object_Model +translation_of_original: DOM +--- +
+

Объектная модель документа (DOM) — это API для HTML и XML документов. Она предоставляет структуру документа, что позволяет изменять его содержимое и внешний вид. По сути, она связывает веб-страницы со скриптами или языками программирования.

+
+ + + + + + + +
+

Документация

+
+
+ Справочная информация по Gecko DOM
+
+ Объектная модель документа движка Gecko.
+
+ Об объектной модели документа
+
+ Краткое введение в DOM.
+
+ Динамически изменяемый пользовательский интерфейс на XUL
+
+ Основы управления XUL UI с помощью методов DOM.
+
+ DOM и JavaScript
+
+ Что такое DOM? Что такое JavaScript? Как мне использовать их совместно на моей веб-странице? Этот документ отвечает на эти и другие вопросы.
+
+ Объектная модель документа Mozilla
+
+ Более старая документация по DOM, размещенная на mozilla.org.
+
+

Посмотреть все...

+
+

Сообщество

+
    +
  • Форумы Mozilla... {{ DiscussionList("dev-tech-dom", "mozilla.dev.tech.dom") }}
  • +
+

Инструменты

+ +

Посмотреть все...

+ + +
+

 

diff --git a/files/ru/conflicting/web/api/document_object_model_5521049528397035462607d58539e0cc/index.html b/files/ru/conflicting/web/api/document_object_model_5521049528397035462607d58539e0cc/index.html new file mode 100644 index 0000000000..ab6a5c0435 --- /dev/null +++ b/files/ru/conflicting/web/api/document_object_model_5521049528397035462607d58539e0cc/index.html @@ -0,0 +1,25 @@ +--- +title: Об объектной модели документа +slug: Об_объектной_модели_документа +tags: + - DOM +translation_of: Web/API/Document_Object_Model +translation_of_original: DOM/About_the_Document_Object_Model +--- +

Что такое DOM?

+ +

Document Object Model — это API для HTML и XML документов. Она предоставляет структурное представление документа, что позволяет изменять его содержимое и внешний вид. По сути, она связывает веб-страницы со скриптами или языками программирования.

+ +

Все свойства, методы и события, доступные веб-разработчику для манипулирования и создания веб-страниц организованы в объекты (например, объект document, который представляет сам документ, объект table, который представляет элементы HTML-таблицы, и т.д.). Эти объекты доступны через скриптовые языки в большинстве современных браузеров.

+ +

В основном DOM используется вместе с JavaScript. То есть код пишется на JavaScript, но он использует DOM для доступа к веб-странице и ее элементам. Тем не менее, DOM создавался, чтобы независимо от конкретных языков программирования имелась возможность доступа к структурному представлению документа через один API. Несмотря на то, что на этом сайте мы заострим внимание на JavaScript, реализации DOM могут быть созданы для любого языка.

+ +

World Wide Web Consortium установил стандарт для DOM, называемый W3C DOM. Сейчас, когда большинство браузеров поддерживают этот стандарт, появилась возможность создавать мощные кросс-браузерные приложения.

+ +

Почему так важна поддержка DOM в Mozilla?

+ +

"Динамический HTML" (DHTML) — это термин, под которым понимают совокупность HTML, CSS и скриптов, которые позволяют создавать анимированные веб-страницы. Поскольку Mozilla позиционирует свой продукт как "платформу для веб-приложений", поддержка DOM является очень важной и необходимой, чтобы Mozilla была достойной альтернативой другим браузерам.

+ +

Еще более важным фактом является то, что пользовательский интерфейс в Mozilla (а также в Firefox и Thunderbird) построен на XUL — языке разметки пользовательского интерфейса. Так что Mozilla использует DOM для изменения своего интерфейса.

+ +

{{ languages( { "es": "es/Acerca_del_Modelo_de_Objetos_del_Documento", "fr": "fr/\u00c0_propos_du_Document_Object_Model", "ja": "ja/About_the_Document_Object_Model", "ko": "ko/About_the_Document_Object_Model", "pl": "pl/O_modelu_obiektowym_dokumentu", "zh-cn": "cn/\u5173\u4e8e\u6587\u6863\u5bf9\u8c61\u6a21\u578b" } ) }}

diff --git a/files/ru/conflicting/web/api/document_object_model_dd00a71ceceac547ab464128db6bd8ef/index.html b/files/ru/conflicting/web/api/document_object_model_dd00a71ceceac547ab464128db6bd8ef/index.html new file mode 100644 index 0000000000..1671813170 --- /dev/null +++ b/files/ru/conflicting/web/api/document_object_model_dd00a71ceceac547ab464128db6bd8ef/index.html @@ -0,0 +1,38 @@ +--- +title: DOM developer guide +slug: Web/Guide/API/DOM +tags: + - API + - DOM + - Guide + - NeedsContent + - NeedsTranslation + - TopicStub +translation_of: Web/API/Document_Object_Model +translation_of_original: Web/Guide/API/DOM +--- +

{{draft}}

+ +

Объектная модель документа - это API для документов HTML и XML. Она обеспечивает структурное представление документа, позволяя разработчику изменять его содержание и визуальное представление. По сути, она соединяет веб-страницы со скриптами или языками программирования.

+ +

Все свойства, методы и события, доступные веб-разработчику для манипулирования и создания веб-страниц, организованы в объекты (например, объект документа, представляющий сам документ, объект таблицы, представляющий элемент таблицы HTML и т. Д.) , Эти объекты доступны через скриптовые языки в самых последних веб-браузерах.

+ +

DOM чаще всего используется в сочетании с JavaScript. Тем не менее, DOM был разработан, чтобы быть независимым от какого-либо конкретного языка программирования, делая структурное представление документа доступным из единого, согласованного API. Хотя мы,на этом сайте, сосредоточены на JavaScript реализации DOM могут быть построены для любого языка.

+ +

Консорциум World Wide Web устанавливает стандарт для DOM, называемый W3C DOM. Теперь, когда наиболее важные браузеры правильно его реализуют, следует включить мощные кросс-браузерные приложения.

+ +

Почему так важен DOM?

+ +

"Dynamic HTML" (DHTML) это термин, используемый некоторыми поставщиками для описания комбинации HTML, таблиц стилей и сценариев, позволяющих анимировать документы. Рабочая группа W3C DOM усердно работает над тем, чтобы согласовать совместимые и не зависящие от языка решения (см. также W3C FAQ).

+ +

Поскольку Mozilla претендует на звание «Платформа веб-приложений», поддержка DOM является одной из наиболее востребованных функций и необходимой, если Mozilla хочет стать жизнеспособной альтернативой другим браузерам. Пользовательский интерфейс Mozilla (также Firefox и Thunderbird) построен с использованием XUL, используя DOM для управления собственным пользовательским  интерфейсом UI.

+ +

More about the DOM

+ +

{{LandingPageListSubpages}}

+ + + +

«Динамический HTML» (DHTML) - это термин, используемый некоторыми поставщиками для описания комбинации HTML, таблиц стилей и сценариев, позволяющих анимировать документы. Рабочая группа W3C DOM усердно работает над тем, чтобы согласовать совместимые и не зависящие от языка решения (см. Также FAQ по W3C).

+ +

Поскольку Mozilla претендует на звание «Платформа веб-приложений», поддержка DOM является одной из наиболее востребованных функций и необходимой, если Mozilla хочет стать жизнеспособной альтернативой другим браузерам. Пользовательский интерфейс Mozilla (также Firefox и Thunderbird) построен с использованием XUL, используя DOM для управления собственным пользовательским интерфейсом.

diff --git a/files/ru/conflicting/web/api/element/index.html b/files/ru/conflicting/web/api/element/index.html new file mode 100644 index 0000000000..af6ec4765c --- /dev/null +++ b/files/ru/conflicting/web/api/element/index.html @@ -0,0 +1,45 @@ +--- +title: Slotable +slug: Web/API/Slotable +tags: + - миксины +translation_of: Web/API/Slottable +translation_of_original: Web/API/Slotable +--- +

{{APIRef("Shadow DOM")}}

+ +

Миксин Slotable определяет возможности, которые позволяют нодам становиться контентом элемента {{htmlelement("slot")}} — следующие возможности включены в  {{domxref("Element")}} и {{domxref("Text")}}.

+ +

Свойства

+ +
+
{{domxref("Slotable.assignedSlot")}} {{readonlyInline}}
+
Возвращает {{htmlelement("slot")}}, в который вставлена нода.
+
+ +

Методы

+ +

Нет.

+ +

Спецификации

+ + + + + + + + + + + + + + +
СпецификацияСтатусКомментарии
{{SpecName('DOM WHATWG','#slotable','Slotable')}}{{Spec2('DOM WHATWG')}}Первое определение.
+ +

Поддержка браузерами

+ + + +

{{Compat("api.Slotable")}}

diff --git a/files/ru/conflicting/web/api/eventtarget/addeventlistener/index.html b/files/ru/conflicting/web/api/eventtarget/addeventlistener/index.html new file mode 100644 index 0000000000..a428f9724c --- /dev/null +++ b/files/ru/conflicting/web/api/eventtarget/addeventlistener/index.html @@ -0,0 +1,9 @@ +--- +title: EventTarget.attachEvent() +slug: Web/API/EventTarget/attachEvent +tags: + - Junk +translation_of: Web/API/EventTarget/addEventListener +translation_of_original: Web/API/EventTarget/attachEvent +--- +

{{DOMxRef("EventTarget.addEventListener","EventTarget.addEventListener()")}}

diff --git a/files/ru/conflicting/web/api/eventtarget/removeeventlistener/index.html b/files/ru/conflicting/web/api/eventtarget/removeeventlistener/index.html new file mode 100644 index 0000000000..9a62ecb63c --- /dev/null +++ b/files/ru/conflicting/web/api/eventtarget/removeeventlistener/index.html @@ -0,0 +1,92 @@ +--- +title: EventTarget.detachEvent() +slug: Web/API/EventTarget/detachEvent +translation_of: Web/API/EventTarget/removeEventListener +translation_of_original: Web/API/EventTarget/detachEvent +--- +

{{APIRef("DOM Events")}}

+ +

{{ Non-standard_header() }}

+ +

Кратко

+ +

Это проприетарная альтернатива методу {{domxref("EventTarget.removeEventListener()")}}  в Microsoft Internet Explorer.

+ +

Синтаксис

+ +
target.detachEvent(eventNameWithOn, callback)
+
+ +
+
target
+
DOM елемент, для которого надо убрать обработчик.
+
eventNameWithOn
+
Название ивента, начинающийся на "on" (так если бы это был колбэк атрибут), чей обработчик должен быть убран. Например, вам следует использовать "onclick" для удаления обработчика для данного "click" ивента.
+
callback
+
Функция, которую стоит убрать.
+
+ +

Спецификация

+ +

Не является частью спецификации.

+ +

Microsoft содержит описание на MSDN.

+ +

Поддержка браузерами

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Базовая поддержка{{ CompatNo() }}{{ CompatNo() }}6 thru 10 [1]{{ CompatUnknown() }}{{ CompatNo() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Базовая поддержка{{ CompatNo() }}{{ CompatNo() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatNo() }}
+
+ +

[1]: detachEvent() больше не поддерживается в IE11+. {{domxref("EventTarget.removeEventListener()")}} поддерживается в IE9+.

+ +

Смотрите так-же

+ + diff --git a/files/ru/conflicting/web/api/geolocation/index.html b/files/ru/conflicting/web/api/geolocation/index.html new file mode 100644 index 0000000000..7287eee669 --- /dev/null +++ b/files/ru/conflicting/web/api/geolocation/index.html @@ -0,0 +1,103 @@ +--- +title: NavigatorGeolocation +slug: Web/API/NavigatorGeolocation +translation_of: Web/API/Geolocation +translation_of_original: Web/API/NavigatorGeolocation +--- +
{{APIRef("Geolocation API")}}
+ +

NavigatorGeolocation содержит метод, позволяющий объектам реализовывать его,, получая {{domxref("Geolocation")}} экземпляр объекта.

+ +

Здесь нет объектов типа NavigatorGeolocation, но некоторые интерфейсы, например, {{domxref("Navigator")}} реализуют его.

+ +

Свойства

+ +

Интерфейс NavigatorGeolocation не наследует каких-либо свойств.

+ +
+
{{domxref("NavigatorGeolocation.geolocation")}} {{readonlyInline}}
+
Возвращает объект {{domxref("Geolocation")}} позволяющий получить доступ к местоположению устройства.
+
+ +

Методы

+ +

Интерфейс NavigatorGeolocation ни реализует, ни наследует  никаких методов.

+ +

Спецификации

+ + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('Geolocation', '#navi-geo', 'NavigatorGeolocation')}}{{Spec2('Geolocation')}}Изначальное описание
+ +

Совместимость с браузерами

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
СвойствоChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка5{{CompatGeckoDesktop("1.9.1")}}910.60
+ {{CompatNo}} 15.0
+ 16.0
5
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
СвойствоAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("4")}}{{CompatUnknown}}10.60{{CompatUnknown}}
+
+ +

Смотрите также

+ + diff --git a/files/ru/conflicting/web/api/htmlmediaelement/abort_event/index.html b/files/ru/conflicting/web/api/htmlmediaelement/abort_event/index.html new file mode 100644 index 0000000000..d8029e2378 --- /dev/null +++ b/files/ru/conflicting/web/api/htmlmediaelement/abort_event/index.html @@ -0,0 +1,70 @@ +--- +title: abort +slug: Web/Events/abort +tags: + - Событие +translation_of: Web/API/HTMLMediaElement/abort_event +translation_of_original: Web/Events/abort +--- +

Событие "abort" вызывается когда загрузка какого-либо ресурса была прервана.

+ +

Общая информация

+ +
+
Спецификация
+
DOM L3
+
Интерфейс
+
{{domxref("UIEvent")}} если событие сгенерировано из пользовательского интерфейса, иначе {{domxref("Event")}}.
+
Всплывание
+
Нет
+
Отменяемость
+
Нет
+
Цель
+
{{domxref("window")}}, {{domxref("Element")}}
+
Действие по умолчанию
+
Нет
+
+ +

Свойства

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
СвойствоТипОписание
target {{readonlyInline}}EventTargetЦель события (самый вышележащий элемент в DOM дереве).
type {{readonlyInline}}DOMStringТип события.
bubbles {{readonlyInline}}BooleanПоднимается ли событие вверх как принято или нет.
cancelable {{readonlyInline}}BooleanЯвляется ли событие отменяемым или нет?
view {{readonlyInline}}WindowProxydocument.defaultView (свойство window  объекта document)
detail {{readonlyInline}}long (float)0.
diff --git a/files/ru/conflicting/web/api/index.html b/files/ru/conflicting/web/api/index.html new file mode 100644 index 0000000000..9ffb624bc7 --- /dev/null +++ b/files/ru/conflicting/web/api/index.html @@ -0,0 +1,131 @@ +--- +title: WebAPI +slug: Web/WebAPI +tags: + - API +translation_of: Web/API +translation_of_original: WebAPI +--- +

WebAPI is a term used to refer to a suite of device compatibility and access APIs that allow Web apps and content to access device hardware (such as battery status or the device vibration hardware), as well as access to data stored on the device (such as the calendar or contacts list). By adding these APIs, we hope to expand what the Web can do today to also include what only proprietary platforms were able to do in the past.

+ +
+

Note: For a brief explanation of each badge, please see the packaged apps documentation.

+
+ +

 

+ +
+
+

Communication APIs

+ +
+
Network Information API
+
Provides basic information about the current network connection, such as connection speed.
+
Bluetooth {{NonStandardBadge}}
+
The WebBluetooth API provides low-level access to the device's Bluetooth hardware.
+
Mobile Connection API {{NonStandardBadge}}
+
Exposes information about the device's cellular connectivity, such as signal strength, operator information, and so forth.
+
Network Stats API {{NonStandardBadge}}
+
Monitors data usage and exposes this data to privileged applications.
+
Telephony {{NonStandardBadge}}
+
Lets apps place and answer phone calls and use the built-in telephony user interface.
+
WebSMS {{NonStandardBadge}}
+
Lets apps send and receive SMS text messages, as well as to access and manage the messages stored on the device.
+
WiFi Information API {{NonStandardBadge}}
+
A privileged API which provides information about signal strength, the name of the current network, available WiFi networks, and so forth.
+
+ +

Hardware access APIs

+ +
+
Ambient Light Sensor API
+
Provides access to the ambient light sensor, which lets your app detect the ambient light level in the vicinity of the device.
+
Battery Status API
+
Provides information about the battery's charge level and whether or not the device is currently plugged in and charging.
+
Geolocation API
+
Provides information about the device's physical location.
+
Pointer Lock API
+
Lets apps lock access to the mouse and gain access to movement deltas rather than absolute coordinates; this is great for gaming.
+
Proximity API
+
Lets you detect proximity of the device to a nearby object, such as the user's face.
+
Device Orientation API
+
Provides notifications when the device's orientation changes.
+
Screen Orientation API
+
Provides notifications when the screen's orientation changes. You can also use this API to let your app indicate what orientation it prefers.
+
Vibration API
+
Lets apps control the device's vibration hardware for things such as haptic feedback in games. This is not intended for things such as notification vibrations. See the Alarm API for that.
+
Camera API {{NonStandardBadge}}
+
Allows apps to take photographs and/or record video using the device's built-in camera.
+
Power Management API {{NonStandardBadge}}
+
Lets apps turn on and off the screen, CPU, device power, and so forth. Also provides support for listening for and inspecting resource lock events.
+
+ +

View All...

+
+ +
+

Data management APIs

+ +
+
FileHandle API {{NonStandardBadge}}
+
Provides support for writable files with locking support.
+
IndexedDB
+
Client-side storage of structured data with support for high-performance searches.
+
Settings API {{NonStandardBadge}}
+
Lets apps examine and change system-wide configuration options that are permanently stored on the device.
+
+ +

Other APIs

+ +
+
Alarm API
+
Lets apps schedule notifications. Also provides support for automatically launching an app at a specific time.
+
Simple Push API
+
Lets the platform send notification messages to specific applications.
+
Push API
+
Gives web applications the ability to receive messages pushed to them from a server, whether or not the web app is in the foreground, or even currently loaded, on a user agent.
+
Web Notifications
+
Lets applications send notifications displayed at the system level.
+
Apps API {{NonStandardBadge}}
+
The Open WebApps API provides support for installing and managing Web apps. In addition, support is provided to let apps determine payment information.
+
Web Activities {{NonStandardBadge}}
+
Lets an app delegate an activity to another app; for example, an app might ask another app to select (or create) and return a photo. Typically the user is able to configure what apps are used for which activities.
+
WebPayment API {{NonStandardBadge}}
+
Lets Web content initiate payments and refunds for virtual goods.
+
Browser API {{NonStandardBadge}}
+
Provides support for building a Web browser completely using Web technologies (in essence, a browser within a browser).
+
+ +
+
Idle API
+
Lets apps receive notifications when the user is not actively using the device.
+
Permissions API {{NonStandardBadge}}
+
Manages app permissions in a centralized location. Used by the Settings app.
+
Time/Clock API {{NonStandardBadge}}
+
Provides support for setting the current time. The time zone is set using the Settings API.
+
+ +

WebAPI community

+ +

If you need help with these APIs, there are several ways you can talk to other developers making use of them.

+ +
    +
  • Consult the WebAPI forum: {{DiscussionList("dev-webapi", "mozilla.dev.webapi")}}
  • +
  • Visit the WebAPI IRC channel: #webapi
  • +
+ +

Don't forget about the netiquette...

+ + + + +
+
+ +

 

+ +

 

diff --git a/files/ru/conflicting/web/api/node/index.html b/files/ru/conflicting/web/api/node/index.html new file mode 100644 index 0000000000..7f7dbfb782 --- /dev/null +++ b/files/ru/conflicting/web/api/node/index.html @@ -0,0 +1,26 @@ +--- +title: Node.baseURIObject +slug: Web/API/Node/baseURIObject +translation_of: Web/API/Node +translation_of_original: Web/API/Node/baseURIObject +--- +
{{APIRef("DOM")}} {{Non-standard_header}}
+ +

Свойство Node.baseURIObject возвращает {{Interface("nsIURI")}} представляющий базовый URL узла (обычно документ или элемент). Это похоже на {{domxref("Node.baseURI")}}, за исключением того, что возвращает nsIURI вместо строки.

+ +

Это свойство существует на всех узлах (HTML, XUL, SVG, MathML, и т.д.), но только если скрипт пытается использовать его имея привилегии UniversalXPConnect.

+ +

Смотрите {{domxref("Node.baseURI")}} для уточнения деталей что такое базовый URL.

+ +

Синтаксис

+ +
uriObj = node.baseURIObject
+
+ +

Примечания

+ +

Это свойство только для чтения; попытка записать информацию в него, будет сбрасывать исключения. Кроме того, это свойство может быть доступно только для привилегированного кода.

+ +

Спецификация

+ +

Нет какой-либо спецификации.

diff --git a/files/ru/conflicting/web/api/node_378aed5ed6869e50853edbc988cf9556/index.html b/files/ru/conflicting/web/api/node_378aed5ed6869e50853edbc988cf9556/index.html new file mode 100644 index 0000000000..11b342e6c3 --- /dev/null +++ b/files/ru/conflicting/web/api/node_378aed5ed6869e50853edbc988cf9556/index.html @@ -0,0 +1,29 @@ +--- +title: Node.nodePrincipal +slug: Web/API/Node/nodePrincipal +translation_of: Web/API/Node +translation_of_original: Web/API/Node/nodePrincipal +--- +
+
{{APIRef("DOM")}}
+{{Non-standard_header}} + +

Свойство Node.nodePrincipal только для чтения, возвращающее объект {{Interface("nsIPrincipal")}}, представляющий текущий контекст безопасности узла.

+ +

{{Note("Это свойство существует во всех узлах (HTML, XUL, SVG, MathML, и т.д.), но только если скрипт пытается использовать chrome привилегии.")}}

+ +

Синтаксис

+ +
principalObj = element.nodePrincipal
+
+ +

Примечания

+ +

Это свойство только для чтения; пытаясь вводить информацию в него, будет сбрасывать исключение.Кроме того, это свойство может быть доступно только для привилегированного кода.

+ +

Спецификация

+ +

Нет никакой спецификации.

+
+ +

 

diff --git a/files/ru/conflicting/web/api/push_api/index.html b/files/ru/conflicting/web/api/push_api/index.html new file mode 100644 index 0000000000..40086e4e91 --- /dev/null +++ b/files/ru/conflicting/web/api/push_api/index.html @@ -0,0 +1,420 @@ +--- +title: Использование Push API +slug: Web/API/Push_API/Using_the_Push_API +translation_of: Web/API/Push_API +translation_of_original: Web/API/Push_API/Using_the_Push_API +--- +

W3C Push API предоставляет некоторый захватывающий новый функционал для разработчиков для использования в web-приложениях: эта статья предлагает вводную информацию о том, как настроить Push-уведомления и управлять ими, с помощью простого демо.

+ +

Возможность посылать сообщения или уведомления от сервера клиенту в любое время — независимо от того, активно приложение или нет — было прерогативой нативных приложений некоторое время, и наконец пришло в Web! Поддерживается большинства возможностей Push сейчас возможна в браузерах Firefox 43+ и Chrome 42+ на настольных компьютерах, мобильные платформы, возможно, скоро присоединятся. {{domxref("PushMessageData")}} на данный момент экспериментально поддерживаются только в Firefox Nightly (44+), и реализация может меняться.

+ +
+

Примечание: Ранние версии Firefox OS использовали проприетарную версию этого API вызывая Simple Push. Считается устаревшим по стандартам Push API.

+
+ +

Демо: основы простого сервера чат-приложения

+ +

Демо, котрые мы создали, представляет начальное описание простого чат-приложения. Оно представляет собой форму, в которую вводятся данные, и кнопку для подписки на push-сообщения . Как только кнопка будет нажата, вы подпишитесь на push-сообщения, ваши данные будут записаны на сервере, а отправленное push-сообщение сообщит всем текущим подписчикам, что кто-то подписался.

+ +

На данном этапе, имя нового подписчика появится в списке подписчиков, вместе с текстовым полем и кнопкой рассылки, чтобы позволить подписчику отправить сообщение.

+ +

+ +

Чтобы запустить демо, следуйте инструкциям на странице push-api-demo README. Заметте, что серверная компонента все еще нуждается в небольшой доработке для запуска в Chrome и в общем запусается более разумным путем. Но аспекты Push все еще могут быть полностью понятны; мы углубимся в это после того, как просмотрим технологии в процессе.

+ +

Обзор технологии

+ +

Эта секция предоставляет описание того, какие технологии учавствуют в примере.

+ +

Web Push-сообщения это часть семейства технологий сервис воркеров; в первую очередь, для получения push-сообщений сервис воркер должен быть активирован на странице. Сервис воркер получает push-сообщения, и затем вы сами решаете, как уведомить об этом страницу. Вы можете:

+ + + +

Обычно необходима комбинация этих двух решений; демо внизу включает пример обоих.

+ +
+

Примечание: Вам необходим некоторый код, запущенный на сервере, для управления конечной точкой/шифроманием данных и отправки запросов push-сообщений. В нашем демо мы собрали на скорую руку сервер, используя NodeJS.

+
+ +

Сервис воркер так же должен подписаться на сервис push-сообщений. Каждой сессии предоставляется собственная уникальная конечная точка, когда она подписывается на сервис push-сообщений. Эта конечная точка получается из свойства  ({{domxref("PushSubscription.endpoint")}}) объекта подписчика. Она может быть отправлена серверу и использоваться для пересылки сообщений активному сервис воркеру сессии. Каждый браузер имеет свой собсвтенный сервер push-сообщений для  управления отправкой push-сообщений.

+ +

Шифрование

+ +
+

Примечание: Для интерактивного краткого обзора, попробуйте JR Conlin's Web Push Data Encryption Test Page.

+
+ +

Для отправки данных с помошью push-сообщений необходимо шифрование. Для этого необходим публичный ключ, созданный с использованием метода  {{domxref("PushSubscription.getKey()")}}, который основывается на некотором комплексе механизмов шифрования, которые выполняются на стороне сервера; читайте Message Encryption for Web Push. Со временем появятся библиотеки для управления генерацией ключей и шифроманием/дешифрованием push-сообщений; для этого демо мы используем Marco Castelluccio's NodeJS web-push library.

+ +
+

Примечание: Есть так же другая библиотека для управления шифрованием с помошью Node и Python, смотри encrypted-content-encoding.

+
+ +

Обобщение рабочего процесса Push

+ +

Общие сведения ниже это то, что необходимо для реализации push-сообщений. Вы можете найти больше информации о некоторых частях демо в последующих частях.

+ +
    +
  1. Запрос на разрешение web-уведомлений или что-то другое, что вы используете и для чего необходимо разрешение.
  2. +
  3. Регистрация сервис воркера для контроля над страницей с помошью вызова {{domxref("ServiceWorkerContainer.register()")}}.
  4. +
  5. Подписка на сервис push-уведомлений с помошью {{domxref("PushManager.subscribe()")}}.
  6. +
  7. Запрашивание конечной точки, соответствующей подписчику, и генерация публичного ключа клиента ({{domxref("PushSubscription.endpoint")}} и {{domxref("PushSubscription.getKey()")}}. Заметте, что getKey() на данный момент эксперементальная технологий и доступна только в Firefox.)
  8. +
  9. Отправка данных на сервер, чтобы тот мог присылать push-сообщения, когда необходимо. Это демо использует {{domxref("XMLHttpRequest")}}, но вы можете использовать Fetch.
  10. +
  11. Если вы используете Channel Messaging API для связи с сервис воркером, установите новый канал связи ({{domxref("MessageChannel.MessageChannel()")}}) и отправте port2 сервис воркеру с помошью вызова {{domxref("Worker.postMessage()")}} для того, чтобы открыть канал связи. Вы так же должны настроить слушателя для ответов на сообщения, которые будут отправляться обратно с сервис воркера.
  12. +
  13. На стороне сервера сохраните конечную точку и все остальные необходимые данные, чтобы они были доступны, когда будет необходимо отправить push-сообщение добавленному подписчику (мы используем простой текстовый файл, но вы можете использовать базу данных или все что угодно на ваш вкус). В приложении на продакшене убедитесь, что скрываете эти данные, так что злоумышленники не смогут украсть конечную точку и разослать спам подписчикам в push-сообщениях.
  14. +
  15. Для отправки push-сообщений необходимо отослать HTTP POST конечному URL. Запрос должен включать TTL заголовок, который ограничивает время пребывания сообщения в очереди, если пользователь не в сети. Для добавления полезной информации в запросе, необходимо зашифровать ее (что включает публичнй ключ клиента). В нашем примере мы используем web-push модуль, который управляет всей тяжелой работой.
  16. +
  17. Поверх в сервис воркере настройте обработчик событий push для ответов на полученные push-сообщения. +
      +
    1. Если вы хотите отвечать отправкой сообщения канала обратно основному контексту (смотри шаг 6), необходимо сначала получить ссылку на port2, который был отправлен контексту сервис воркера ({{domxref("MessagePort")}}). Это доступно в объекте  {{domxref("MessageEvent")}}, передаваемого обработчику onmessage ({{domxref("ServiceWorkerGlobalScope.onmessage")}}). Конкретнее, он находится в свойстве ports, индекс 0. Когда это сделано, вы можете отправить сообщение обратно port1, используя {{domxref("MessagePort.postMessage()")}}.
    2. +
    3. Если вы хотитет ответить запуском системного уведомления, вы можете сделать это, вызвав {{domxref("ServiceWorkerRegistration.showNotification()")}}. Заметте, что в нашем коде мы вызываем его внутри метода {{domxref("ExtendableEvent.waitUntil()")}} — это растягивает время жизни события, пока уведомление не будет запущено, так что мы можем убедиться, что все, что мы хотели, чтобы произошло, действительно произошло.
    4. +
    +
  18. +
+ +

Сборка демо

+ +

Давайте пройдемся по коду для демо, чтобы понять, как все работает.

+ +

HTML и CSS

+ +

Нет ничего примечательного в HTML и CSS демо; HTML содержит простую форму для ввода данных для фхода в чат, кнопку для подписки на push-уведомления и двух списков, в которых перечислены подписчики и сообщения чата. После подписки появляются дополнительные средства для того, чтобы пользователь мог ввести сообщение в чат.

+ +

CSS был оставлен очень минимальным, чтобы не отвлекать от объяснения того, как функционируют Push API.

+ +

Основной файл JavaScript

+ +

 JavaScript очевидно намного более существенный. Давайте взглянем на основной файл JavaScript.

+ +

Переменные и начальные настройки

+ +

Для начала определим некоторые переменные, которые будем использовать в нашем приложении:

+ +
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';
+ +

Сначала нам необходимо создать две булевы переменные, для того чтобы отслеживать подписку на push-сообщения и подтверждение разрешения на рассылку уведомлений.

+ +

Далее, мы перехватываем ссылку на {{htmlelement("button")}} подписки/отписки и задаем переменные для сохранения ссылок на наши кнопку отправки сообщения/ввода (который создастся только после успешной подписки).
+
+ Следующие переменные перехватывают ссылки на три основные {{htmlelement("div")}} элемента, так что мы можем включить в них элементы (к примеру, когда появится кнопка Отправки Сообщения Чата или сообщение появится с писке Сообщений).

+ +

Finally we grab references to our name selection form and {{htmlelement("input")}} element, give the input a default value, and use preventDefault() to stop the form submitting when the form is submitted by pressing return.

+ +

Next, we request permission to send web notifications, using {{domxref("Notification.requestPermission","requestPermission()")}}:

+ +
Notification.requestPermission();
+ +

Now we run a section of code when onload is fired, to start up the process of inialising the app when it is first loaded. First of all we add a click event listener to the subscribe/unsubscribe button that runs our unsubscribe() function if we are already subscribed (isPushEnabled is true), and subscribe() otherwise:

+ +
window.addEventListener('load', function() {
+  subBtn.addEventListener('click', function() {
+    if (isPushEnabled) {
+      unsubscribe();
+    } else {
+      subscribe();
+    }
+  });
+ +

Next we check to see if service workers are supported. If so, we register a service worker using {{domxref("ServiceWorkerContainer.register()")}}, and run our initialiseState() function. If not, we deliver an error message to the console.

+ +
  // 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.');
+  }
+});
+
+ +

The next thing in the source code is the initialiseState() function — for the full commented code, look at the initialiseState() source on Github (we are not repeating it here for brevity's sake.)

+ +

initialiseState() first checks whether notifications are supported on service workers, then sets the useNotifications variable to true if so. Next, it checks whether said notifications are permitted by the user, and if push messages are supported, and reacts accordingly to each.

+ +

Finally, it uses {{domxref("ServiceWorkerContainer.ready()")}} to wait until the service worker is active and ready to start doing things. Once its promise resolves, we retrieve our subscription to push messaging using the {{domxref("ServiceWorkerRegistration.pushManager")}} property, which returns a {{domxref("PushManager")}} object that we then call {{domxref("PushManager.getSubscription()")}} on. Once this second inner promise resolves, we enable the subscribe/unsubscribe button (subBtn.disabled = false;), and check that we have a subscription object to work with.

+ +

If we do, then we are already subscribed. This is possible when the app is not open in the browser; the service worker can still be active in the background. If we're subscribed, we update the UI to show that we are subscribed by updating the button label, then we set isPushEnabled to true, grab the subscription endpoint from {{domxref("PushSubscription.endpoint")}}, generate a public key using {{domxref("PushSubscription.getKey()")}}, and run our updateStatus() function, which as you'll see later communicates with the server.

+ +

As an added bonus, we set up a new {{domxref("MessageChannel")}} using the {{domxref("MessageChannel.MessageChannel()")}} constructor, grab a reference to the active service worker using {{domxref("ServiceworkerRegistration.active")}}, then set up a channel betweeen the main browser context and the service worker context using {{domxref("Worker.postMessage()")}}. The browser context receives messages on {{domxref("MessageChannel.port1")}}; whenever that happens, we run the handleChannelMessage() function to decide what to do with that data (see the {{anch("Handling channel messages sent from the service worker")}} section).

+ +

Subscribing and unsubscribing

+ +

Let's now turn our attention to the subscribe() and unsubscribe() functions used to subscribe/unsubscribe to the push notification service.

+ +

In the case of subscription, we again check that our service worker is active and ready by calling {{domxref("ServiceWorkerContainer.ready()")}}. When the promise resolves, we subscribe to the service using {{domxref("PushManager.subscribe()")}}. If the subscription is successful, we get a {{domxref("PushSubscription")}} object, extract the subscription endpoint from this and generate a public key (again, {{domxref("PushSubscription.endpoint")}} and {{domxref("PushSubscription.getKey()")}}), and pass them to our updateStatus() function along with the update type (subscribe) to send the necessary details to the server.

+ +

We also make the necessary updates to the app state (set isPushEnabled to true) and UI (enable the subscribe/unsubscribe button and set its label text to show that the next time it is pressed it will unsubscribe.)

+ +

The unsubscribe() function is pretty similar in structure, but it basically does the opposite; the most notable difference is that it gets the current subscription using {{domxref("PushManager.getSubscription()")}}, and when that promise resolves it unsubscribes using {{domxref("PushSubscription.unsubscribe()")}}.

+ +

Appropriate error handling is also provided in both functions.  

+ +

We only show the subscribe() code below, for brevity; see the full subscribe/unsubscribe code on Github.

+ +
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';
+        }
+      });
+  });
+}
+ +

Updating the status in the app and server

+ +

The next function in our main JavaScript is updateStatus(), which updates the UI for sending chat messages when subscribing/unsubscribing and sends a request to update this information on the server.

+ +

The function does one of three different things, depending on the value of the statusType parameter passed into it:

+ + + +

Again, we have not included the entire function listing for brevity. Examine the full updateStatus() code on Github.

+ +

Handling channel messages sent from the service worker

+ +

As mentioned earlier, when a channel message is received from the service worker, our handleChannelMessage() function is called to handle it. This is done by our handler for the {{event("message")}} event, {{domxref("channel.port1.onmessage")}}:

+ +
channel.port1.onmessage = function(e) {
+  handleChannelMessage(e.data);
+}
+ +

This occurs when the service worker sends a channel message over.

+ +

The handleChannelMessage() function looks like this:

+ +
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 = '';
+  }
+}
+ +

What happens here depends on what the action property on the data object is set to:

+ + + +
+

Note: We have to pass the data back to the main context before we do DOM updates because service workers don't have access to the DOM. You should be aware of the limitations of service workers before attemping to ue them. Read Using Service Workers for more details.

+
+ +

Sending chat messages

+ +

When the Send Chat Message button is clicked, the content of the associated text field is sent as a chat message. This is handled by the sendChatMessage() function (again, not shown in full for brevity). This works in a similar way to the different parts of the updateStatus() function (see {{anch("Updating the status in the app and server")}}) — we retrieve an endpoint and public key via a {{domxref("PushSubscription")}} object, which is itself retrieved via {{domxref("ServiceWorkerContainer.ready()")}} and {{domxref("PushManager.subscribe()")}}. These are sent to the server via {{domxref("XMLHttpRequest")}} in a message object, along with the name of the subscribed user, the chat message to send, and a statusType of chatMsg.

+ +

The server

+ +

As mentioned above, we need a server-side component in our app, to handle storing subscription details, and send out push messages when updates occur. We've hacked together a quick-and-dirty server using NodeJS (server.js), which handles the XHR requests sent by our client-side JavaScript code.

+ +

It uses a text file (endpoint.txt) to store subscription details; this file starts out empty. There are four different types of request, marked by the statusType property of the object sent over in the request; these are the same as those understood client-side, and perform the required server actions for that same situation. Here's what each means in the context of the server:

+ + + +

A couple more things to note:

+ + + +

The service worker

+ +

Now let's have a look at the service worker code (sw.js), which responds to the push messages, represented by {{Event("push")}} events. These are handled on the service worker's scope by the ({{domxref("ServiceWorkerGlobalScope.onpush")}}) event handler; its job is to work out what to do in response to each received message. We first convert the received message back into an object by calling {{domxref("PushMessageData.json()")}}. Next, we check what type of push message it is, by looking at the object's action property:

+ + + +
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);
+  }
+});
+ +

Next, let's look at the fireNotification() function (which is blissfully pretty simple).

+ +
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
+  }));
+}
+ +

Here we assemble the assets needed by the notification box: the title, body, and icon. Then we send a notification via the {{domxref("ServiceWorkerRegistration.showNotification()")}} method, providing that information as well as the tag "push", which we can use to identify this notification among any other notifications we might be using. When the notification is successfully sent, it manifests as a system notification dialog on the users computers/devices in whatever style system notifications look like on those systems (the following image shows a Mac OSX system notification.)

+ +

+ +

Note that we do this from inside an {{domxref("ExtendableEvent.waitUntil()")}} method; this is to make sure the service worker remains active until the notification has been sent. waitUntil() will extend the life cycle of the service worker until everything inside this method has completed.

+ +
+

Note: Web notifications from service workers were introduced around Firefox version 42, but are likely to be removed again while the surrounding functionality (such as Clients.openWindow()) is properly implemented (see {{bug(1203324)}} for more details.)

+
+ +

Handling premature subscription expiration

+ +

Sometimes push subscriptions expire prematurely, without {{domxref("PushSubscription.unsubscribe()")}} being called. This can happen when the server gets overloaded, or if you are offline for a long time, for example.  This is highly server-dependent, so the exact behavior is difficult to predict. In any case, you can handle this problem by watching for the {{Event("pushsubscriptionchange")}} event, which you can listen for by providing a {{domxref("ServiceWorkerGlobalScope.onpushsubscriptionchange")}} event handler; this event is fired only in this specific case.

+ +
self.addEventListener('pushsubscriptionchange', function() {
+  // do something, usually resubscribe to push and
+  // send the new subscription details back to the
+  // server via XHR or Fetch
+});
+ +

Note that we don't cover this case in our demo, as a subscription ending is not a big deal for a simple chat server. But for a more complex example you'd probably want to resubscribe the user.

+ +

Extra steps for Chrome support

+ +

To get the app working on Chrome, we need a few extra steps, as Chrome currently relies on Google's Cloud Messaging service to work.

+ +

Setting up Google Cloud Messaging

+ +

To get this set up, follow these steps:

+ +
    +
  1. Navigate to the Google Developers Console  and set up a new project.
  2. +
  3. Go to your project's homepage (ours is at https://console.developers.google.com/project/push-project-978, for example), then +
      +
    1. Select the Enable Google APIs for use in your apps option.
    2. +
    3. In the next screen, click Cloud Messaging for Android under the Mobile APIs section.
    4. +
    5. Click the Enable API button.
    6. +
    +
  4. +
  5. Now you need to make a note of your project number and API key because you'll need them later. To find them: +
      +
    1. Project number: click Home on the left; the project number is clearly marked at the top of your project's home page.
    2. +
    3. API key: click Credentials on the left hand menu; the API key can be found on that screen.
    4. +
    +
  6. +
+ +

manifest.json

+ +

You need to include a Google app-style manifest.json file in your app, which references the project number you made a note of earlier in the gcm_sender_id parameter. Here is our simple example manifest.json:

+ +
{
+  "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"
+}
+ +

You also need to reference your manifest using a {{HTMLElement("link")}} element in your HTML:

+ +
<link rel="manifest" href="manifest.json">
+ +

userVisibleOnly

+ +

Chrome requires you to set the userVisibleOnly parameter to true when subscribing to the push service, which indicates that we are promising to show a notification whenever a push is received. This can be seen in action in our subscribe() function.

+ +

See also

+ + + +
+

Note: Some of the client-side code in our Push demo is heavily influenced by Matt Gaunt's excellent examples in Push Notifications on the Open Web. Thanks for the awesome work, Matt!

+
diff --git a/files/ru/conflicting/web/api/svgaelement/target/index.html b/files/ru/conflicting/web/api/svgaelement/target/index.html new file mode 100644 index 0000000000..dcd76310d4 --- /dev/null +++ b/files/ru/conflicting/web/api/svgaelement/target/index.html @@ -0,0 +1,107 @@ +--- +title: SVGAElement.target +slug: Web/API/SVGAElement/SVGAlement.target +translation_of: Web/API/SVGAElement/target +translation_of_original: Web/API/SVGAElement/SVGAlement.target +--- +

{{APIRef("SVGAElement")}}

+ +

 

+ +

Свойство SVGAElement.target для чтения только {{domxref ("SVGAElement")}} возвращает объект {{domxref ("SVGAnimatedString")}}, который указывает часть целевого окна, фрейма, панель, в которую открывается при активации ссылки.

+ +

Это свойство используется, когда существует множество возможных целей для конечного ресурса, например, когда родительский документ является документом HTML или HTML-документом mlti-frame.

+ +

 

+ +

Синтаксис

+ +
myLink.target = 'value';
+ +

Стоимость

+ +

{{Domxref ("SVGAnimatedString")}}, указывающий конечную цель ресурса, которая открывает документ при активации ссылки.

+ +

Значения для {{domxref ("target")}} можно увидеть here

+ +

Пример

+ +

Код  взят из "SVGAElement example code"

+ +
...
+var linkRef = document.querySelector('a');
+linkRef.target ='_blank';
+...
+ +

Характеристики

+ + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('SVG1.1', 'text.html#InterfaceSVGAElement', 'target')}}{{Spec2('SVG1.1')}} 
+ +

Совместимость с браузером

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}9.0{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{ CompatVersionUnknown() }}{{ CompatUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

Смотрите также

+ + diff --git a/files/ru/conflicting/web/api/web_storage_api/index.html b/files/ru/conflicting/web/api/web_storage_api/index.html new file mode 100644 index 0000000000..b63a374c8c --- /dev/null +++ b/files/ru/conflicting/web/api/web_storage_api/index.html @@ -0,0 +1,368 @@ +--- +title: DOM Storage guide +slug: Web/Guide/API/DOM/Storage +translation_of: Web/API/Web_Storage_API +translation_of_original: Web/Guide/API/DOM/Storage +--- +

 

+ +

DOM хранилище (DOM Storage) - это название для набора инструментов, относящихся к хранилищам, впервые представленных в спецификации Web Applications 1.0,  и выделенных теперь в отдельную специкацию W3C Web Storage. DOM хранилище было разработано с целью предоставления альтернативы хранению информации в кукисах. Предполагается, что DOM хранилище предоставляет больше объема, оно более защищено и легче в использовании. Впервые оно было представлено  в браузерах Firefox 2 и Safari 4.

+ +
Заметка: DOM хранилище - это не то же самое, что mozStorage (Mozilla's XPCOM interfaces to SQLite) или Session store API (утилита XPCOM - хранилище для использования в расширениях).
+ +
+

Заметка: Эта статья скоро будет сильно переработана. Вместо того, чтобы хранить всю информацию на одной странице, она будет разбита на несколько статей, каждая из которых будет описывать разные API хранилища. Отдельная статья, помогающая разобраться в разных API, будет также добавлена.

+
+ +

Описание

+ +

Механизм DOM хранилища - средство, благодаря которому можно безопасно хранить и позже извлекать пары "ключ / значение". Целью этого является обеспечение комплексного средства, с помощью которого можно разрабатывать интерактивные приложения(включая приложения с продвинутыми возможностями, такими как возможность работать "автономно"("offline") в течение длительных периодов времени).

+ +

Браузеры на основе Mozilla, Internet Explorer 8 +, Safari 4 + и Chrome обеспечивают рабочую реализацию спецификации DOM хранилища. (В случае, если нужна кросс-браузерная поддержка функциональности, включая более старые версии IE, будет полезно отметить, что IE также имеет подобную легаси функциональность под названием "USERDATA поведение", которая дополненяет DOM хранилище IE в IE8.)

+ +

DOM хранилище удобно, потому что нет других хороших способов хранения разумных объемов данных за любой период времени, встроенных в браузер. Кукисы ограничены в количестве хранимой информации и не обеспечивают поддержку для организации постоянных данных, а другие методы (например, флэш-локальное хранилище) требуют плагина.

+ +

Одним из первых известных приложений,  использующих новые функциональные возможности DOM хранилища(в дополнение к USERDATA поведения в Internet Explorer) было halfnote (приложение для заметок), написанное Аароном Будменом. В своем приложении, Аарон одновременно сохранял заметки на сервере (когда/если Интернет-подключение  был доступно) и локального хранилища данных(в обратном случае). Это дало возможность пользователю смело писать резервные копии заметок даже при нерегулярном подключении к Интернету.

+ +

Хотя идея и реализация halfnote были сравнительно простыми, создание halfnote показывает возможность для нового поколения веб-приложений, которые можно использовать как в онлайн-, так и оффлайн- режиме.

+ +

Связь

+ +

Ниже приведены глобальные объекты, которые существуют как свойства каждого объекта  window. Это означает, что они могут быть доступны как sessionStorage или window.sessionStorage. (Это важно, потому что вы можете использовать фреймы(IFrames) для хранения или доступа, дополнительные данные кроме того, что сразу же включено на странице.)

+ +

Storage

+ +

Это конструктор(Storageдля всех экземпляров Storage (sessionStorage и globalStorage[location.hostname]).

+ +

Сохранение Storage.prototype.removeKey = function(key){ this.removeItem(this.key(key)) } будет доступно через localStorage.removeKey и sessionStorage.removeKey.

+ +

Единицы globalStorage являются экземплярами StorageObsolete, а не Storage.

+ +

Storage определен в WhatWG Storage Interface следующим образом:

+ +
interface Storage {
+  readonly attribute unsigned long length;
+  [IndexGetter] DOMString key(in unsigned long index);
+  [NameGetter] DOMString getItem(in DOMString key);
+  [NameSetter] void setItem(in DOMString key, in DOMString data);
+  [NameDeleter] void removeItem(in DOMString key);
+  void clear();
+};
+
+ +
Заметка: Несмотря на то, что значения доступны для чтения и записи через стандартные способы Javascript, рекомендуется использование getItem и setItem.
+ +
Заметка: Обратите внимание, что любые данные, которые хранятся в любом из хранилищ, описанных на этой странице, преобразуются в строку, используя метод.toString. перед тем, как сохранить значение. Попытка сохранить объект приведет к сохранению строки "[object Object]"  вместо объекта или его JSON представления. Самым лучшим и распространенным способом сохранения объектов в формате строки является использование предоставляемых браузером методов JSON для парсинга и сериализации объектов.
+ +

sessionStorage

+ +

Это глобальный объект (sessionStorage), который сохраняет значения, которые доступны в течение периода текущей сессии. Сессия страницы длится, пока браузер открыт, и восстанавливает свои значения после перегрузки страницы. Открытие страницы в новой вкладке или окне приведет к созданию новой сессии для этой страницы.

+ +
// Сохранить данные в текущем хранилизе сессий
+sessionStorage.setItem("username", "John");
+
+// Получить значения сохраненного значения
+alert( "username = " + sessionStorage.getItem("username"));
+
+ +

Объект sessionStorage наиболее полезен для хранения временных данных, которые должны быть восстановлены, если страница браузер была случайно перегружена.

+ +

Примеры:

+ +

Автоматическое сохранение содержимого тестового поля, и если страница была случайно перегружена, то данные не будут потеряны.

+ +
 // Получить значение текстового поля, которое мы собираемся отслеживать
+ var field = document.getElementById("field");
+
+ // Проверяем, что значение поля autosave существует
+ // (это будет происходить при случайной перезагрузке страницы)
+ if (sessionStorage.getItem("autosave")) {
+    // Восстановить значение тестового поля
+    field.value = sessionStorage.getItem("autosave");
+ }
+
+ // Прослушивать изменения значения текстового поля
+ field.addEventListener("change", function() {
+    // И сохранить результаты в объект хранилища сессий
+    sessionStorage.setItem("autosave", field.value);
+ });
+
+ +

Больше информации:

+ + + +

localStorage

+ +

localStorage - это то же самое, что и {{ Anch("sessionStorage") }}, поддерживает правила единого происхождения(same-origin rules), но хранение данных постоянно. localStorage был представлен в Firefox 3.5.

+ +
Заметка: Когда браузер переходит в частный режим браузера(private browsing mode), то новая, временная база данных создается для хранения данных локального хранилища; эта база данных очищается и удаляется, как только частный режим браузера выключается.
+ +

Совместимость

+ +

Объекты Storage - относительно недавнее дополнение стандарта. Это означает, что они не обязательно должны быть реализованы во всех браузерах. Проблему можно решить с помощью включения следующего куска кода в начале вашего скрипта, позволяя использовать объект localStorage в реализациях, которые нативно не поддерживают его.

+ +

Следующий алгоритм - это точная имитация объекта localStorage, но использует куки.

+ +
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;
+  })());
+}
+
+ +
Note: The maximum size of data that can be saved is severely restricted by the use of cookies. With this algorithm, use the functions localStorage.setItem() and localStorage.removeItem() to add, change, or remove a key. The use of methods localStorage.yourKey = yourValue; and delete localStorage.yourKey; to set or delete a key is not a secure way with this code. You can also change its name and use it only to manage a document's cookies regardless of the localStorage object.
+ +
Note: By changing the string "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/" to: "; path=/" (and changing the object's name), this will become a sessionStorage polyfill rather than a localStorage polyfill. However, this implementation will share stored values across browser tabs and windows (and will only be cleared when all browser windows have been closed), while a fully-compliant sessionStorage implementation restricts stored values to the current browsing context only.
+ +

Here is another, less exact, imitation of the localStorage object. It is simpler than the previous one, but it is compatible with old browsers, like Internet Explorer < 8 (tested and working even in Internet Explorer 6). It also makes use of cookies.

+ +
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;
+}
+
+ +
Note: The maximum size of data that can be saved is severely restricted by the use of cookies. With this algorithm, use the functions localStorage.getItem(), localStorage.setItem(), and localStorage.removeItem() to get, add, change, or remove a key. The use of method localStorage.yourKey in order to get, set, or delete a key is not permitted with this code. You can also change its name and use it only to manage a document's cookies regardless of the localStorage object.
+ +
Note: By changing the string "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/" to: "; path=/" (and changing the object's name), this will become a sessionStorage polyfill rather than a localStorage polyfill. However, this implementation will share stored values across browser tabs and windows (and will only be cleared when all browser windows have been closed), while a fully-compliant sessionStorage implementation restricts stored values to the current browsing context only.
+ +

Compatibility and relation with globalStorage

+ +

localStorage is also the same as globalStorage[location.hostname], with the exception of being scoped to an HTML5 origin (scheme + hostname + non-standard port) and localStorage being an instance of Storage as opposed to globalStorage[location.hostname] being an instance of StorageObsolete which is covered below. For example, http://example.com is not able to access the same localStorage object as https://example.com but they can access the same globalStorage item. localStorage is a standard interface while globalStorage is non-standard so you shouldn't rely on these.

+ +

Please note that setting a property on globalStorage[location.hostname] does not set it on localStorage and extending Storage.prototype does not affect globalStorage items; only extending StorageObsolete.prototype does.

+ +

globalStorage

+ +
{{ Non-standard_header }}{{ obsolete_header("13.0") }}
+ +

globalStorage is obsolete since Gecko 1.9.1 (Firefox 3.5) and unsupported since Gecko 13 (Firefox 13). Just use {{ Anch("localStorage") }} instead. This proposed addition to HTML5 has been removed from the HTML5 specification in favor of {{ Anch("localStorage") }}, which is implemented in Firefox 3.5. This is a global object (globalStorage) 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).

+ +
Note: globalStorage is not a Storage instance, but a StorageList instance containing StorageObsolete instances.
+ +
// Save data that only scripts on the mozilla.org domain can access
+globalStorage['mozilla.org'].setItem("snippet", "<b>Hello</b>, how are you?");
+
+ +

Specifically, the globalStorage 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 globalStorage on this domain (developer.mozilla.org) we'd have the following storage object available to us:

+ + + +

Examples:

+ +

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.

+ +

Remember a user's username for the particular sub-domain that is being visited:

+ +
 globalStorage['developer.mozilla.org'].setItem("username", "John");
+
+ +

Keep track of the number of times that a user visits all pages of your domain:

+ +
 // 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);
+
+ +

Расположение хранилища и очищение данных

+ +

In Firefox the DOM storage data is stored in the webappsstore.sqlite file in the profile folder (there's also chromeappsstore.sqlite file used to store browser's own data, notably for the start page - about:home, but potentially for other internal pages with "about:" URLs).

+ + + +

See also clearing offline resources cache.

+ +

Больше информации

+ + + +

Примеры

+ + + +

Совместимость с браузерами

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
localStorage43.5810.504
sessionStorage52810.504
globalStorage{{ CompatNo }}2-13{{ CompatNo }}{{ CompatNo }}{{ CompatNo }}
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support2.1{{ CompatUnknown }}811iOS 3.2
+
+ +

All browsers have varying capacity levels for both localStorage and sessionStorage. Here is a detailed rundown of all the storage capacities for various browsers.

+ +
+

Note: since iOS 5.1, Safari Mobile stores localStorage data in the cache folder, which is subject to occasional clean up, at the behest of the OS, typically if space is short.

+
+ +

Полезные ссылки

+ + + +
{{ HTML5ArticleTOC }}
diff --git a/files/ru/conflicting/web/api/webrtc_api/index.html b/files/ru/conflicting/web/api/webrtc_api/index.html new file mode 100644 index 0000000000..d8fbf01983 --- /dev/null +++ b/files/ru/conflicting/web/api/webrtc_api/index.html @@ -0,0 +1,35 @@ +--- +title: WebRTC +slug: Web/Guide/API/WebRTC +translation_of: Web/API/WebRTC_API +translation_of_original: Web/Guide/API/WebRTC +--- +

WebRTC (где RTC расшифровывается как Real-Time Communications) - это технология, которая позволяет передавать данные и потоковое аудио/видео между браузерами. Как набор стандартов в целом, WebRTC предоставляет любым поддерживающим этот стандарт, браузерам обмениваться данными и устраивать сеансы телеконференций в режиме точка-точка, без необходимости устанавливать какие-либо плагины и стороннее програмное обеспечение.

+ +

Компоненты WebRTC доступны через API JavaScript: Network Stream API, который представляет собой поток аудио и видео данных, PeerConnection API, который позволяет двум и более пользователям общаться браузер-браузер напрямую, DataChannel API, который позволяет обмениваться данными других типов, например в играх в режиме реального времени, текстовые чаты, обмен файлами и так далее.

+ +
+

На заметку: Эта документация находится в процессе переезда в свой новый дом.

+
+ +

Руководства

+ +
+
Обмен данными в режиме точка-точка с WebRTC
+
О том, как наладить обмен данными в режиме точка-точка используя API WebRTC.
+
Введение в архитектуру WebRTC
+
(AKA "WebRTC and the Ocean of Acronyms") WebRTC состоит из множества частей и это может быть причиной сложностей для новичков. Эта статья рассказывает обо всех частях и объясняет то как они между собой связаны.
+
Основы WebRTC
+
Теперь, когда вы уже знаете архитектуру WebRTC, вы можете перейти к этой статье, которая проведет вас через путь создания кросс-браузерного RTC-приложения
+
+ +

Ссылки

+ +
+
MediaDevices.getUserMedia
+
API захвата медиа (видео/аудио)
+
RTCPeerConnection
+
Интерфейс обработки потоковых данных между двуми пирами.
+
RTCDataChannel
+
Интерфейс передачи произвольных данных через соединение точка-точка.
+
diff --git a/files/ru/conflicting/web/api/webrtc_api/signaling_and_video_calling/index.html b/files/ru/conflicting/web/api/webrtc_api/signaling_and_video_calling/index.html new file mode 100644 index 0000000000..863dde7e14 --- /dev/null +++ b/files/ru/conflicting/web/api/webrtc_api/signaling_and_video_calling/index.html @@ -0,0 +1,351 @@ +--- +title: Основы WebRTC +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 +--- +

{{WebRTCSidebar}}

+ +

{{Draft}}

+ +
+

После того, как вы понимаете WebRTC architecture, вы можете прочитать эту статью, которая сопроводит вас через создание кросс-браузерного RTC приложения. К концу этой документации, вы должны иметь рабочие каналы соединения равноправных узлов ЛВС и передачи данных средств массовой информации.

+
+ +

Полу-старое содержание, из

+ +

RTCPeerConnection

+ +

Материал здесь происходит от RTCPeerConnection; она может остаться здесь, или же  может переместится в другое место.

+ +

Основы использования
+ Базовое использование RTCPeerConnection предполагает переговоры связь между локальной машиной и удаленной машиной один генерируя Session Description Protocol для обмена между ними. Вызывающая программа начинает процесс, отправив предложение на удаленное устройство, которое реагирует либо принять или отклонить запрос на соединение.

+ +

Обе стороны (вызывающий и вызываемый абонент) необходимо настроить свои собственные экземпляры RTCPeerConnection, чтобы представить их конец соединения равноправных узлов ЛВС:

+ +
var pc = new RTCPeerConnection();
+pc.onaddstream = function(obj) {
+  var vid = document.createElement("video");
+  document.appendChild(vid);
+  vid.srcObject = obj.stream;
+}
+
+// функция помощник
+function endCall() {
+  var videos = document.getElementsByTagName("video");
+  for (var i = 0; i < videos.length; i++) {
+    videos[i].pause();
+  }
+
+  pc.close();
+
+
+function error(err) {
+  endCall();
+}
+
+ +

При инициализации вызова

+ +

Если вы один инициирующий вызов, вы будете использовать navigator.getUserMedia(), чтобы получить видеопоток, а затем добавить поток в RTCPeerConnection. Как только это было сделано, вызов RTCPeerConnection, чтобы создать предложение, настроить предложение, а затем отправить его на сервер, через  соединение которое было создано.

+ +
// Получить список людей с сервера
+// Пользователь выбирает список людей, чтобы установить соединение с нужным человеком
+navigator.getUserMedia({video: true}, function(stream) {
+  // Добавление локального потока не вызовет onaddstream обратного вызова,
+  // так называют его вручную.
+  pc.onaddstream = e => video.src = URL.createObjectURL(e.stream);
+  pc.addStream(stream);
+
+  pc.createOffer(function(offer) {
+    pc.setLocalDescription(offer, function() {
+      // send the offer to a server to be forwarded to the friend you're calling.
+    }, error);
+  }, error);
+});
+
+ +

Ответ на вызов

+ +

На противоположном конце, друг получит предложение от сервера, используя любой протокол используется для того чтобы сделать это. После того, как предложение прибывает, {{domxref ("navigator.getUserMedia ()")}} вновь используется для создания потока, который добавляется к RTCPeerConnection. {{Domxref ("RTCSessionDescription")}} объект создается и установить в качестве удаленного описания с помощью вызова {{domxref ("RTCPeerConnection.setRemoteDescription ()")}}.

+ +

Тогда ответ создается с помощью RTCPeerConnection.createAnswer () и отправляется обратно на сервер, который направляет его к вызывающему абоненту.

+ +
var offer = getOfferFromFriend();
+navigator.getUserMedia({video: true}, function(stream) {
+  pc.onaddstream = e => video.src = URL.createObjectURL(e.stream);
+  pc.addStream(stream);
+
+  pc.setRemoteDescription(new RTCSessionDescription(offer), function() {
+    pc.createAnswer(function(answer) {
+      pc.setLocalDescription(answer, function() {
+        // send the answer to a server to be forwarded back to the caller (you)
+      }, error);
+    }, error);
+  }, error);
+});
+
+ +

Ответ на вызов

+ +

На противоположном конце, человек получит предложение от сервера, используя любой протокол используется для того чтобы сделать это. После того, как предложение принято, navigator.getUserMedia () вновь используется для создания потока, который добавляется к RTCPeerConnection.  объект создается и установить в качестве удаленного описания с помощью вызова {{domxref ("RTCPeerConnection.setRemoteDescription ()")}}.

+ +

Тогда ответ создается с помощью RTCPeerConnection.createAnswer () и отправляется обратно на сервер, который направляет его к вызывающему абоненту.

+ +
// ПК был создан раньше, когда мы сделали первоначальное предложение
+var offer = getResponseFromFriend();
+pc.setRemoteDescription(new RTCSessionDescription(offer), function() { }, error);
+ +

Old content follows!

+ +

Все, что находится ниже этого пункта,  потенциально устарело. Это по-прежнему находится в стадии рассмотрения  и возможного включения в другие части документации, если они все еще актуальны.

+ +
+

Не используйте примеры на этой странице. Смотрите статью Signaling and video calling для работы, актуальный пример с использованием WebRTC media.

+
+ +

Note

+ +

Due to recent changes in the API there are many old examples that require fixing:

+ + + +

The currently working example is:

+ + + +

Implementation may be inferred from the specification.

+ +

This remainder of this page contains outdated information as noted on bugzilla.

+ +

Shims

+ +

As you can imagine, with such an early API, you must use the browser prefixes and shim it to a common variable.

+ +
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;
+ +

RTCPeerConnection

+ +

This is the starting point to creating a connection with a peer. It accepts configuration options about ICE servers to use to establish a connection.

+ +
var pc = new RTCPeerConnection(configuration);
+ +

RTCConfiguration

+ +

The {{domxref("RTCConfiguration")}} object contains information about which TURN and/or STUN servers to use for ICE. This is required to ensure most users can actually create a connection by avoiding restrictions in NAT and firewalls.

+ +
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"}
+    ]
+}
+ +

Google runs a public STUN server that we can use. I also created an account at http://numb.viagenie.ca/ for a free TURN server to access. You may want to do the same and replace with your own credentials.

+ +

ICECandidate

+ + + +

After creating the PeerConnection and passing in the available STUN and TURN servers, an event will be fired once the ICE framework has found some “candidates” that will allow you to connect with a peer. This is known as an ICE Candidate and will execute a callback function on PeerConnection#onicecandidate.

+ +
pc.onicecandidate = function (e) {
+    // candidate exists in e.candidate
+    if (!e.candidate) return;
+    send("icecandidate", JSON.stringify(e.candidate));
+};
+ +

When the callback is executed, we must use the signal channel to send the Candidate to the peer. On Chrome, multiple ICE candidates are usually found, we only need one so I typically send the first one then remove the handler. Firefox includes the Candidate in the Offer SDP.

+ +

Signal Channel

+ +

Now that we have an ICE candidate, we need to send that to our peer so they know how to connect with us. However this leaves us with a chicken and egg situation; we want PeerConnection to send data to a peer but before that we need to send them metadata…

+ +

This is where the signal channel comes in. It’s any method of data transport that allows two peers to exchange information. In this article, we’re going to use FireBase because it’s incredibly easy to setup and doesn't require any hosting or server-code.

+ +

For now just imagine two methods exist: send() will take a key and assign data to it and recv() will call a handler when a key has a value.

+ +

The structure of the database will look like this:

+ +
{
+    "": {
+        "candidate:": …
+        "offer": …
+        "answer": …
+    }
+}
+ +

Connections are divided by a roomId and will store 4 pieces of information, the ICE candidate from the offerer, the ICE candidate from the answerer, the offer SDP and the answer SDP.

+ +

Offer

+ +

An Offer SDP (Session Description Protocol) is metadata that describes to the other peer the format to expect (video, formats, codecs, encryption, resolution, size, etc etc).

+ +

An exchange requires an offer from a peer, then the other peer must receive the offer and provide back an answer.

+ +
pc.createOffer(function (offer) {
+    pc.setLocalDescription(offer, function() {
+        send("offer", JSON.stringify(pc.localDescription);
+    }, errorHandler);
+}, errorHandler, options);
+ +

errorHandler

+ +

If there was an issue generating an offer, this method will be executed with error details as the first argument.

+ +
var errorHandler = function (err) {
+    console.error(err);
+};
+ +
options
+ +

Options for the offer SDP.

+ +
var options = {
+    offerToReceiveAudio: true,
+    offerToReceiveVideo: true
+};
+ +

offerToReceiveAudio/Video tells the other peer that you would like to receive video or audio from them. This is not needed for DataChannels.

+ +

Once the offer has been generated we must set the local SDP to the new offer and send it through the signal channel to the other peer and await their Answer SDP.

+ +

Answer

+ +

An Answer SDP is just like an offer but a response; sort of like answering the phone. We can only generate an answer once we have received an offer.

+ +
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);
+});
+ +

DataChannel

+ +

I will first explain how to use PeerConnection for the DataChannels API and transferring arbitrary data between peers.

+ +

Note: At the time of this article, interoperability between Chrome and Firefox is not possible with DataChannels. Chrome supports a similar but private protocol and will be supporting the standard protocol soon.

+ +
var channel = pc.createDataChannel(channelName, channelOptions);
+ +

The offerer should be the peer who creates the channel. The answerer will receive the channel in the callback ondatachannel on PeerConnection. You must call createDataChannel() once before creating the offer.

+ +

channelName

+ +

This is a string that acts as a label for your channel name. Warning: Make sure your channel name has no spaces or Chrome will fail on createAnswer().

+ +

channelOptions

+ +
var channelOptions = {};
+ +

Currently these options are not well supported on Chrome so you can leave this empty for now. Check the RFC for more information about the options.

+ +

Channel Events and Methods

+ +
onopen
+ +

Executed when the connection is established.

+ +
onerror
+ +

Executed if there is an error creating the connection. First argument is an error object.

+ +
channel.onerror = function (err) {
+    console.error("Channel Error:", err);
+};
+ +
onmessage
+ +
channel.onmessage = function (e) {
+    console.log("Got message:", e.data);
+}
+ +

The heart of the connection. When you receive a message, this method will execute. The first argument is an event object which contains the data, time received and other information.

+ +
onclose
+ +

Executed if the other peer closes the connection.

+ +

Binding the Events

+ +

If you were the creator of the channel (meaning the offerer), you can bind events directly to the DataChannel you created with createChannel. If you are the answerer, you must use the ondatachannel callback on PeerConnection to access the same channel.

+ +
pc.ondatachannel = function (e) {
+    e.channel.onmessage = function () { … };
+};
+ +

The channel is available in the event object passed into the handler as e.channel.

+ +
send()
+ +
channel.send("Hi Peer!");
+ +

This method allows you to send data directly to the peer! Amazing. You must send either String, Blob, ArrayBuffer or ArrayBufferView, so be sure to stringify objects.

+ +
close()
+ +

Close the channel once the connection should end. It is recommended to do this on page unload.

+ +

Media

+ +

Now we will cover transmitting media such as audio and video. To display the video and audio you must include a <video> tag on the document with the attribute autoplay.

+ +

Get User Media

+ +
<video id="preview" autoplay></video>
+
+var video = document.getElementById("preview");
+navigator.getUserMedia(constraints, function (stream) {
+    video.src = URL.createObjectURL(stream);
+}, errorHandler);
+ +

constraints

+ +

Constraints on what media types you want to return from the user.

+ +
var constraints = {
+    video: true,
+    audio: true
+};
+ +

If you just want an audio chat, remove the video member.

+ +
errorHandler
+ +

Executed if there is an error returning the requested media.

+ +

Media Events and Methods

+ +
addStream
+ +

Add the stream from getUserMedia to the PeerConnection.

+ +
pc.addStream(stream);
+ +
onaddstream
+ +
<video id="otherPeer" autoplay></video>
+
+var otherPeer = document.getElementById("otherPeer");
+pc.onaddstream = function (e) {
+    otherPeer.src = URL.createObjectURL(e.stream);
+};
+ +

Executed when the connection has been setup and the other peer has added the stream to the peer connection with addStream. You need another <video> tag to display the other peer's media.

+ +

The first argument is an event object with the other peer's media stream.

diff --git a/files/ru/conflicting/web/api/window/localstorage/index.html b/files/ru/conflicting/web/api/window/localstorage/index.html new file mode 100644 index 0000000000..f0fab82609 --- /dev/null +++ b/files/ru/conflicting/web/api/window/localstorage/index.html @@ -0,0 +1,146 @@ +--- +title: LocalStorage +slug: Web/API/Storage/LocalStorage +translation_of: Web/API/Window/localStorage +translation_of_original: Web/API/Web_Storage_API/Local_storage +--- +

localStorage это аналог sessionStorage, с некоторыми same-origin правилами, но значения хранятся постоянно (в отличии от sessions). localStorage появился в Firefox 3.5.

+ +
Примечание: Когда браузер переходит в режим приватного просмотра, создается новое временное хранилище. Изначально оно пустое. После выхода из режима приватного просмотра временное хранилище очищается.
+ +
// Сохраняет данные в текущий local store
+localStorage.setItem("username", "John");
+
+// Извлекает ранее сохраненные данные
+alert( "username = " + localStorage.getItem("username"));
+ +

localStorage's позволяет постоянно хранить некоторую полезную информацию, включая счетчики посещения страницы, как показано в примере this tutorial on Codepen.

+ +

Совместимость

+ +

Storage objects недавно добавлен в стандарт. Он может отсутствовать в некоторых браузерах. Вы можете работать с этой технологией добавив в страницу один из двух скриптов, которые представлены ниже. localStorage object реализуется програмно, если нет встроенной реализации.

+ +

Этот алгоритм является точной имитацией localStorage object, но для хранения использует cookies.

+ +
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
+    });
+    Object.defineProperty(oStorage, "clear", {
+      value: function () {
+        if(!aKeys.length) { return; }
+        for (var sKey in aKeys) {
+          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;
+  })());
+}
+
+ +
Примечание: Максимальныйe размер данных, которые могут быть сохранены, ограничен возможностями cookies. Используйте functions localStorage.setItem() и localStorage.removeItem() для добавления, изменения, или удаления ключа. Использование прямого присвоения localStorage.yourKey = yourValue; и delete localStorage.yourKey; для установки и удаления ключа не безопасно с этим кодом. Вы также можете изменить это имя (вместо window.localStorage прописать другое имя) и использовать объект для управления document's cookies, не обращая внимания на localStorage object.
+ +
Примечание: Если изменить строку "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/" на: "; path=/" (и изменить имя объекта), он превратится в sessionStorage polyfill больше, чем в localStorage polyfill. Однако эта реализация будет хранить общие значения для всех вкладок и окон браузера (and will only be cleared when all browser windows have been closed), в то время как полностью совместимая sessionStorage реализация хранит значения to the current browsing context only.
+ +

Here is another, less exact, imitation of the localStorage object. It is simpler than the previous one, but it is compatible with old browsers, like Internet Explorer < 8 (tested and working even in Internet Explorer 6). It also makes use of cookies.

+ +
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;
+}
+
+ +
Note: The maximum size of data that can be saved is severely restricted by the use of cookies. With this algorithm, use the functions localStorage.getItem()localStorage.setItem(), and localStorage.removeItem() to get, add, change, or remove a key. The use of method localStorage.yourKey in order to get, set, or delete a key is not permitted with this code. You can also change its name and use it only to manage a document's cookies regardless of the localStorage object.
+ +
Note: By changing the string "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/" to: "; path=/" (and changing the object's name), this will become a sessionStorage polyfill rather than a localStorage polyfill. However, this implementation will share stored values across browser tabs and windows (and will only be cleared when all browser windows have been closed), while a fully-compliant sessionStorage implementation restricts stored values to the current browsing context only.
+ +

Compatibility and relation with globalStorage

+ +

localStorage is also the same as globalStorage[location.hostname], with the exception of being scoped to an HTML5 origin (scheme + hostname + non-standard port) and localStorage being an instance of Storage as opposed to globalStorage[location.hostname] being an instance of StorageObsolete which is covered below. For example, http://example.com is not able to access the same localStorage object as https://example.com but they can access the same globalStorage item. localStorage is a standard interface while globalStorage is non-standard so you shouldn't rely on these.

+ +

Please note that setting a property on globalStorage[location.hostname] does not set it on localStorage and extending Storage.prototype does not affect globalStorage items; only extending StorageObsolete.prototype does.

+ +

Storage format

+ +

Storage keys and values are both stored in the UTF-16 DOMString format, which uses 2 bytes per character.

+ +

 

diff --git a/files/ru/conflicting/web/api/windoworworkerglobalscope/index.html b/files/ru/conflicting/web/api/windoworworkerglobalscope/index.html new file mode 100644 index 0000000000..f51b72c102 --- /dev/null +++ b/files/ru/conflicting/web/api/windoworworkerglobalscope/index.html @@ -0,0 +1,121 @@ +--- +title: WindowBase64 +slug: Web/API/WindowBase64 +tags: + - API + - HTML-DOM + - Helper + - NeedsTranslation + - TopicStub + - WindowBase64 +translation_of: Web/API/WindowOrWorkerGlobalScope +translation_of_original: Web/API/WindowBase64 +--- +

{{APIRef("HTML DOM")}}

+ +

The WindowBase64 helper contains utility methods to convert data to and from base64, a binary-to-text encoding scheme. For example it is used in data URIs.

+ +

There is no object of this type, though the context object, either the {{domxref("Window")}} for regular browsing scope, or the {{domxref("WorkerGlobalScope")}}  for workers, implements it.

+ +

Properties

+ +

This helper neither defines nor inherits any properties.

+ +

Methods

+ +

This helper does not inherit any methods.

+ +
+
{{domxref("WindowBase64.atob()")}}
+
Decodes a string of data which has been encoded using base-64 encoding.
+
{{domxref("WindowBase64.btoa()")}}
+
Creates a base-64 encoded ASCII string from a string of binary data.
+
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#windowbase64', 'WindowBase64')}}{{Spec2('HTML WHATWG')}}No change since the latest snapshot, {{SpecName("HTML5.1")}}.
{{SpecName('HTML5.1', '#windowbase64', 'WindowBase64')}}{{Spec2('HTML5.1')}}Snapshot of {{SpecName("HTML WHATWG")}}. No change.
{{SpecName("HTML5 W3C", "#windowbase64", "WindowBase64")}}{{Spec2('HTML5 W3C')}}Snapshot of {{SpecName("HTML WHATWG")}}. Creation of WindowBase64 (properties where on the target before it).
+ +

Browser compatibility

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureFirefox (Gecko)ChromeInternet ExplorerOperaSafari
Basic support{{CompatGeckoDesktop(1)}} [1]{{CompatVersionUnknown}}10.0{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureFirefox Mobile (Gecko)AndroidIE MobileOpera MobileSafari Mobile
Basic support{{CompatGeckoMobile(1)}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

[1]  atob() is also available to XPCOM components implemented in JavaScript, even though {{domxref("Window")}} is not the global object in components.

+ +

See also

+ + diff --git a/files/ru/conflicting/web/api/windoworworkerglobalscope_e2691f7ad05781a30c5fc5bb3b3f633a/index.html b/files/ru/conflicting/web/api/windoworworkerglobalscope_e2691f7ad05781a30c5fc5bb3b3f633a/index.html new file mode 100644 index 0000000000..ac80f42b5f --- /dev/null +++ b/files/ru/conflicting/web/api/windoworworkerglobalscope_e2691f7ad05781a30c5fc5bb3b3f633a/index.html @@ -0,0 +1,120 @@ +--- +title: WindowTimers +slug: Web/API/WindowTimers +tags: + - API + - HTML DOM +translation_of: Web/API/WindowOrWorkerGlobalScope +translation_of_original: Web/API/WindowTimers +--- +
{{APIRef("HTML DOM")}}
+ +

WindowTimers contains utility methods to set and clear timers.

+ +

There is no object of this type, though the context object, either the {{domxref("Window")}} for regular browsing scope, or the {{domxref("WorkerGlobalScope")}}  for workers, implements it.

+ +

Properties

+ +

This interface do not define any property, nor inherit any.

+ +

Methods

+ +

This interface do not inherit any method.

+ +
+
{{domxref("WindowTimers.clearInterval()")}}
+
Cancels the repeated execution set using {{domxref("WindowTimers.setInterval()")}}.
+
{{domxref("WindowTimers.clearTimeout()")}}
+
Cancels the repeated execution set using {{domxref("WindowTimers.setTimeout()")}}.
+
{{domxref("WindowTimers.setInterval()")}}
+
Schedules the execution of a function each X milliseconds.
+
{{domxref("WindowTimers.setTimeout()")}}
+
Sets a delay for executing a function.
+
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#windowtimers', 'WindowTimers')}}{{Spec2('HTML WHATWG')}}No change since the latest snapshot, {{SpecName("HTML5.1")}}.
{{SpecName('HTML5.1', '#windowtimers', 'WindowTimers')}}{{Spec2('HTML5.1')}}Snapshot of {{SpecName("HTML WHATWG")}}. No change.
{{SpecName("HTML5 W3C", "#windowtimers", "WindowTimers")}}{{Spec2('HTML5 W3C')}}Snapshot of {{SpecName("HTML WHATWG")}}. Creation of WindowBase64 (properties where on the target before it).
+ +

Browser compatibility

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureFirefox (Gecko)ChromeInternet ExplorerOperaSafari
Basic support{{CompatGeckoDesktop(1)}}1.04.04.01.0
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureFirefox Mobile (Gecko)AndroidIE MobileOpera MobileSafari Mobile
Basic support{{CompatGeckoMobile(1)}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

 

+ +

See also

+ + diff --git a/files/ru/conflicting/web/api/xmlhttprequest/index.html b/files/ru/conflicting/web/api/xmlhttprequest/index.html new file mode 100644 index 0000000000..0de9dfed9d --- /dev/null +++ b/files/ru/conflicting/web/api/xmlhttprequest/index.html @@ -0,0 +1,282 @@ +--- +title: XMLHttpRequest +slug: XMLHttpRequest +tags: + - AJAX + - XMLHttpRequest +--- +

XMLHttpRequest — это объект JavaScript, созданный Microsoft и адаптированный Mozilla. Вы можете использовать его для простой передачи данных через HTTP. Несмотря на свое название, он может быть использован не только для XML документов, но и, например, для JSON.

+ +

Оставшаяся часть статьи может содержать информацию, специфичную для Gecko или привилегированного кода, такого как дополнения.

+ +

В Gecko этот объект реализует интерфейсы nsIJSXMLHttpRequest и nsIXMLHttpRequest. Недавние версии Gecko содержат некоторые изменения для этого объекта (см. XMLHttpRequest changes for Gecko1.8).

+ +

Основы использования

+ +

Использовать XMLHttpRequest очень просто. Вы создаёте экземпляр объекта, открываете URL и отправляете запрос. Статус HTTP-ответа, так же как и возвращаемый документ, доступны в свойствах объекта запроса.

+ +
Замечание: Версии Firefox до версии 3 постоянно отправляют запрос, используя кодировку UTF-8. Отправляя документ, Firefox 3 использует кодировку, определенную в data.inputEncoding (где data — ненулевой объект, переданный в send()). Если не определено, то используется UTF-8.
+ +

Пример

+ +
var req = new XMLHttpRequest();
+req.open('GET', 'http://www.mozilla.org/', false);
+req.send(null);
+if(req.status == 200)
+  dump(req.responseText);
+
+ +
Замечание: Этот пример работает синхронно, то есть он заблокирует интерфейс пользователя, если вы вызовете его из своего кода. Не рекомендуется использовать это на практике.
+ +

Пример без http протокола

+ +
var req = new XMLHttpRequest();
+req.open('GET', 'file:///home/user/file.json', false);
+req.send(null);
+if(req.status == 0)
+  dump(req.responseText);
+
+ +
Замечание: file:/// и ftp:// не возвращают HTTP статуса, вот почему они возвращают ноль в status и пустую строчку в statusText. См. {{ Bug(331610) }} для подробной информации.
+ +

Асинхронное использование

+ +

Если вы собираетесь использовать XMLHttpRequest из дополнения, вы должны позволить ему загружаться асинхронно. Во время асинхронного использования вы получаете отзыв после загрузки данных, что позволяет браузеру продолжать работу пока ваш запрос обрабатывается.

+ +

Пример

+ +
var req = new XMLHttpRequest();
+req.open('GET', 'http://www.mozilla.org/', true); /* Третий аргумент true означает асинхронность */
+req.onreadystatechange = function (aEvt) {
+  if (req.readyState == 4) {
+     if(req.status == 200)
+      dump(req.responseText);
+     else
+      dump("Error loading page\n");
+  }
+};
+req.send(null);
+
+ +

Наблюдение за прогрессом

+ +

XMLHttpRequest предоставляет возможность отлавливать некоторые события которые могут возникнуть во время обработки запроса. Включая периодические уведомления о прогрессе, сообщения об ошибках и так далее.

+ +

Если к примеру вы желаете предоставить информацию пользователю о прогрессе получения документа, вы можете использовать код вроде этого:

+ +
function onProgress(e) {
+  var percentComplete = (e.position / e.totalSize)*100;
+  ...
+}
+
+function onError(e) {
+  alert("Error " + e.target.status + " occurred while receiving the document.");
+}
+
+function onLoad(e) {
+  // ...
+}
+// ...
+var req = new XMLHttpRequest();
+req.onprogress = onProgress;
+req.open("GET", url, true);
+req.onload = onLoad;
+req.onerror = onError;
+req.send(null);
+
+ +

Атрибуты события onprogress: position и totalSize, отображают соотвественно текущие количество принятых байтов и количество ожидаемых байтов.

+ +

Все эти события имеют свои target атрибуты установленные в соответствии с XMLHttpRequest.

+ +
Замечание: Firefox 3 по сути обеспечивает установку значений-ссылок полей target, currentTarget и this у объекта события на правильные объекты во время вызова обработчика событий для XML документов представленных в XMLDocument. См. {{ Bug(198595) }} для деталей.
+ +

Другие Свойства и Методы

+ +

В дополнение к свойствам и методам описанным выше, ниже следуют другие полезные свойства и методы для объекта запроса.

+ +

responseXML

+ +

Если вы загрузили XML документ свойство responseXML будет содержать документ в виде XmlDocument объекта которым вы можете манипулировать используя DOM методы. Если сервер отправляет правильно сформированные XML документы но не устанавливает Content-Type заголовок для него, вы можете использовать overrideMimeType() для того чтобы документ был обработан как XML. Если сервер не отправляет правильно сформированного документа XML, responseXML вернет null независимо от любых перезаписей Content-Type заголовка.

+ +

overrideMimeType()

+ +

Этот метод может быть использован для обработки документа особенным образом. Обычно вы будете использовать его, когда запросите responseXML, и сервер отправит вам XML, но не отправит правильного Content-Type заголовка.

+ +
Замечание: Этот метод должен вызываться до вызова send().
+ +
var req = new XMLHttpRequest();
+req.open('GET', 'http://www.mozilla.org/', true);
+req.overrideMimeType('text/xml');
+req.send(null);
+
+ +

setRequestHeader()

+ +

Этот метод может быть использован чтобы установить HTTP заголовок в запросе до его отправки.

+ +
Замечание: Вы должны вызвать вначале open().
+ +
var req = new XMLHttpRequest();
+req.open('GET', 'http://www.mozilla.org/', true);
+req.setRequestHeader("X-Foo", "Bar");
+req.send(null);
+
+ +

getResponseHeader()

+ +

Этот метод может быть использован для получения HTTP заголовка из ответа сервера.

+ +
var req = new XMLHttpRequest();
+req.open('GET', 'http://www.mozilla.org/', false);
+req.send(null);
+dump("Content-Type: " + req.getResponseHeader("Content-Type") + "\n");
+
+ +

abort()

+ +

Этот метод может быть использован чтобы отменить обрабатываемый запрос.

+ +
var req = new XMLHttpRequest();
+req.open('GET', 'http://www.mozilla.org/', false);
+req.send(null);
+req.abort();
+
+ +

mozBackgroundRequest

+ +

Это свойство может быть использовано чтобы уберечь от всплытия аутентификации и неправильных диалогов сертификации в ответ на запрос. Также запрос не будет отменен при закрытии его окна, которому он принадлежит. Это свойство работает только для кода chrome. {{ Fx_minversion_inline(3) }}

+ +
var req = new XMLHttpRequest();
+req.mozBackgroundRequest = true;
+req.open('GET', 'http://www.mozilla.org/', true);
+req.send(null);
+
+ +

Using from XPCOM components

+ +
Note: Changes are required if you use XMLHttpRequest from a JavaScript XPCOM component.
+ +

XMLHttpRequest cannot be instantiated using the XMLHttpRequest() constructor from a JavaScript XPCOM component. The constructor is not defined inside components and the code results in an error. You'll need to create and use it using a different syntax.

+ +

Instead of this:

+ +
var req = new XMLHttpRequest();
+req.onprogress = onProgress;
+req.onload = onLoad;
+req.onerror = onError;
+req.open("GET", url, true);
+req.send(null);
+
+ +

Do this:

+ +
var req = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
+                    .createInstance(Components.interfaces.nsIXMLHttpRequest);
+req.onprogress = onProgress;
+req.onload = onLoad;
+req.onerror = onError;
+req.open("GET", url, true);
+req.send(null);
+
+ +

For C++ code you would need to QueryInterface the component to an nsIEventTarget in order to add event listeners, but chances are in C++ using a channel directly would be better.

+ +

Limited number of simultaneous XMLHttpRequest connections

+ +

The about:config preference: network.http.max-persistent-connections-per-server limits the number of connections. In Firefox 3 this value is 6 by default, previous versions use 2 as the default. Some interactive web pages using xmlHttpRequest may keep a connection open. Opening two or three of these pages in different tabs or on different windows may cause the browser to hang in such a way that the window no longer repaints and browser controls don't respond.

+ +

Binary Content

+ +

Although less typical than sending/receiving character-oriented content, XMLHttpRequest can be used to send and receive binary content.

+ +

Retrieving binary content

+ +
// Fetches BINARY FILES synchronously using XMLHttpRequest
+function load_binary_resource(url) {
+  var req = new XMLHttpRequest();
+  req.open('GET', url, false);
+  //XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com]
+  req.overrideMimeType('text/plain; charset=x-user-defined');
+  req.send(null);
+  if (req.status != 200) return '';
+  return req.responseText;
+}
+
+var filestream = load_binary_resource(url);
+// x is the offset (i.e. position) of the byte in the returned binary file stream. The valid range for x is from 0 up to filestream.length-1.
+var abyte = filestream.charCodeAt(x) & 0xff; // throw away high-order byte (f7)
+
+ +

See downloading binary streams with XMLHttpRequest for a detailed explanation. See also downloading files.

+ +

Sending binary content

+ +

This example POSTs binary content asynchronously. aBody is some data to send.

+ +
 var req = new XMLHttpRequest();
+ req.open("POST", url, true);
+ // set headers and mime-type appropriately
+ req.setRequestHeader("Content-Length", 741);
+ req.sendAsBinary(aBody);
+
+ +

You can also send binary content by passing an instance of interface nsIFileInputStream to req.send(). In that case, there is not need to set the Content-Length request header:

+ +
// Make a stream from a file. The file variable holds an nsIFile
+var stream = Components.classes["@mozilla.org/network/file-input-stream;1"]
+                       .createInstance(Components.interfaces.nsIFileInputStream);
+stream.init(file, 0x04 | 0x08, 0644, 0x04); // file is an nsIFile instance
+
+// Try to determine the MIME type of the file
+var mimeType = "text/plain";
+try {
+  var mimeService = Components.classes["@mozilla.org/mime;1"].getService(Components.interfaces.nsIMIMEService);
+  mimeType = mimeService.getTypeFromFile(file); // file is an nsIFile instance
+}
+catch(e) { /* eat it; just use text/plain */ }
+
+// Send
+var req = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
+                    .createInstance(Components.interfaces.nsIXMLHttpRequest);
+req.open('PUT', url, false); /* synchronous! */
+req.setRequestHeader('Content-Type', mimeType);
+req.send(stream);
+
+ +

Bypassing cache

+ +

Normally, XMLHttpRequest attempts to retrieve content from local cache. To bypass this attempt, do the following:

+ +
 var req = new XMLHttpRequest();
+ req.open('GET', url, false);
+ req.channel.loadFlags |= Components.interfaces.nsIRequest.LOAD_BYPASS_CACHE;
+ req.send(null);
+
+ +

An alternative approach to bypassing cache, as described here:

+ +
 var req = new XMLHttpRequest();
+ req.open("GET", url += (url.match(/\?/) == null ? "?" : "&") + (new Date()).getTime(), false);
+ req.send(null);
+
+ +

This appends a timestamp URL parameter to the URL, taking care to insert a ? or & as appropriate. For example, http://foo.com/bar.html becomes http://foo.com/bar.html?12345 and http://foo.com/bar.html?foobar=baz becomes http://foo.com/bar.html?foobar=baz&12345. Since local cache is indexed by URL, the idea is that every URL used by XMLHttpRequest is unique, bypassing the cache.

+ +

Downloading JSON and JavaScript in extensions

+ +

Extensions shouldn't use eval() on JSON or JavaScript downloaded from the web. See Downloading JSON and JavaScript in extensions for details.

+ +

References

+ +
    +
  1. MDC AJAX introduction
  2. +
  3. XMLHttpRequest - REST and the Rich User Experience
  4. +
  5. XULPlanet documentation
  6. +
  7. Microsoft documentation
  8. +
  9. Apple developers' reference
  10. +
  11. "Using the XMLHttpRequest Object" (jibbering.com)
  12. +
  13. The XMLHttpRequest Object: W3C Working Draft
  14. +
+ +

{{ languages( { "es": "es/XMLHttpRequest", "fr": "fr/XMLHttpRequest", "it": "it/XMLHttpRequest", "ja": "ja/XMLHttpRequest", "ko": "ko/XMLHttpRequest", "pl": "pl/XMLHttpRequest", "zh-cn": "cn/XMLHttpRequest" } ) }}

diff --git a/files/ru/conflicting/web/css/@viewport/index.html b/files/ru/conflicting/web/css/@viewport/index.html new file mode 100644 index 0000000000..3cb5768532 --- /dev/null +++ b/files/ru/conflicting/web/css/@viewport/index.html @@ -0,0 +1,106 @@ +--- +title: user-zoom +slug: Web/CSS/@viewport/user-zoom +translation_of: Web/CSS/@viewport +translation_of_original: Web/CSS/@viewport/user-zoom +--- +
{{ CSSRef }}
+ +

Введение

+ +

The user-zoom CSS descriptor controls whether or not the user should be able to change the zoom factor of a document defined by {{cssxref("@viewport")}}.

+ +

{{cssinfo}}

+ +

Синтаксис

+ +
/* Keyword values */
+user-zoom: zoom;
+user-zoom: fixed;
+
+ +

Значения

+ +
+
zoom
+
The user can zoom in or out.
+
fixed
+
The user cannot zoom in or out.
+
+ +

Формальный синтаксис

+ +
{{csssyntax}}
+ +

Спецфикации

+ + + + + + + + + + + + + + + + +
СпецфикацииСтатусКомментарий
{{SpecName('CSS3 Device', '#the-lsquouser-zoomrsquo-descriptor', '"user-zoom" descriptor')}}{{Spec2('CSS3 Device')}}Initial definition
+ +

Совместимость с браузерами

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
+
+ +

 

diff --git a/files/ru/conflicting/web/css/_colon_is/index.html b/files/ru/conflicting/web/css/_colon_is/index.html new file mode 100644 index 0000000000..6a9dab56ac --- /dev/null +++ b/files/ru/conflicting/web/css/_colon_is/index.html @@ -0,0 +1,190 @@ +--- +title: ':any' +slug: 'Web/CSS/:any' +tags: + - CSS + - Experimental + - Псевдоклассы + - Руководство + - Экспериментальное +translation_of: 'Web/CSS/:is' +translation_of_original: 'Web/CSS/:any' +--- +
{{CSSRef}}{{SeeCompatTable}}
+ +

Описание

+ +

Псевдокласс :any() дает возможность быстрого конструирования наборов похожих селекторов путем составления групп, в которых каждый из входящих элементов будет комбинироваться с элементами из других групп. Это альтернатива для прописывания комбинаций селекторов для одного элемента, который может находится в разных родителях.

+ +
Замечание: Этот псевдо-класс все еще находится в процессе стандартизации в CSS селекторах уровня 4 под именем :matches(). Вполне вероятно, что синтаксис и имя :-vendor-any() будут изменены в ближайшем будущем, чтобы соответствовать спецификации.
+ +

Синтаксис

+ +
:-moz-any( selector[, selector]* ) :-webkit-any( selector[, selector]* )
+ +

Параметры

+ +
+
selector
+
Селектор. Это может быть просто селектор или несколько селекторов, состоящих из CSS 3 простых селекторов и может включать комбинацию потомков.
+
+ +
Замечание: Селекторы не могут содержать псевдо-элементы, допускается только комбинирование потомков.
+ +

Примеры

+ +

Например, следующий CSS:

+ +
/* на глубине 3 (или больше) неупорядоченные списки используют square */
+ol ol ul,     ol ul ul,     ol menu ul,     ol dir ul,
+ol ol menu,   ol ul menu,   ol menu menu,   ol dir menu,
+ol ol dir,    ol ul dir,    ol menu dir,    ol dir dir,
+ul ol ul,     ul ul ul,     ul menu ul,     ul dir ul,
+ul ol menu,   ul ul menu,   ul menu menu,   ul dir menu,
+ul ol dir,    ul ul dir,    ul menu dir,    ul dir dir,
+menu ol ul,   menu ul ul,   menu menu ul,   menu dir ul,
+menu ol menu, menu ul menu, menu menu menu, menu dir menu,
+menu ol dir,  menu ul dir,  menu menu dir,  menu dir dir,
+dir ol ul,    dir ul ul,    dir menu ul,    dir dir ul,
+dir ol menu,  dir ul menu,  dir menu menu,  dir dir menu,
+dir ol dir,   dir ul dir,   dir menu dir,   dir dir dir {
+  list-style-type: square;
+}
+
+ +

Может быть записано, как:

+ +
/* на глубине 3 (или больше) неупорядоченные списки используют square */
+:-moz-any(ol, ul, menu, dir) :-moz-any(ol, ul, menu, dir) ul,
+:-moz-any(ol, ul, menu, dir) :-moz-any(ol, ul, menu, dir) menu,
+:-moz-any(ol, ul, menu, dir) :-moz-any(ol, ul, menu, dir) dir {
+  list-style-type: square;
+}
+ +

Однако, не нужно использовать это так: (Смотрите раздел о производительности ниже.)

+ +
:-moz-any(ol, ul, menu, dir) :-moz-any(ol, ul, menu, dir) :-moz-any(ul, menu, dir) {
+  list-style-type: square;
+}
+ +

Примечания

+ +

Особенно полезен при работе с разделами и заголовками в HTML5 . Теги {{HTMLElement("section")}}, {{HTMLElement("article")}}, {{HTMLElement("aside")}}, и {{HTMLElement("nav")}} могут быть вложенными, без :any() стилизация их соответствия друг другу может быть сложной.

+ +

Например, без :any(), стилизация всех элементов {{HTMLElement("h1")}} на разной глубине будет очень сложна:

+ +
/* Уровень 0 */
+h1 {
+  font-size: 30px;
+}
+/* Уровень 1 */
+section h1, article h1, aside h1, nav h1 {
+  font-size: 25px;
+}
+/* Уровень 2 */
+section section h1, section article h1, section aside h1, section nav h1,
+article section h1, article article h1, article aside h1, article nav h1,
+aside section h1, aside article h1, aside aside h1, aside nav h1,
+nav section h1, nav article h1, nav aside h1, nav nav h1, {
+  font-size: 20px;
+}
+/* Уровень 3 */
+/* ... даже не думайте о нём*/
+
+ +

При использовании :-any(), это становится намного проще:

+ +
/* Уровень 0 */
+h1 {
+  font-size: 30px;
+}
+/* Уровень 1 */
+:-moz-any(section, article, aside, nav) h1 {
+  font-size: 25px;
+}
+/* Уровень 2 */
+:-moz-any(section, article, aside, nav)
+:-moz-any(section, article, aside, nav) h1 {
+  font-size: 20px;
+}
+/* Уровень 3 */
+:-moz-any(section, article, aside, nav)
+:-moz-any(section, article, aside, nav)
+:-moz-any(section, article, aside, nav) h1 {
+  font-size: 15px;
+}
+ +

Проблемы с производительностью и особенности

+ +

{{ bug("561154") }} в Gecko, где специфика :-moz-any() не корректна. Текущая реализация (как в Firefox 12) ставит :-moz-any() в категорию универсальных правил, что означает, что использование его в качестве селектора справа будет медленнее, чем использование селекторов по ID, классу, или тегу.

+ +

Например:

+ +
.a > :-moz-any(.b, .c)
+
+ +

медленнее, чем:

+ +
.a > .b, .a > .c
+
+ +

а следующее быстрее:

+ +
:-moz-any(.a, .d) > .b, :-moz-any(.a, .d) > .c
+
+ +

Поддержка браузерами

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
ВозможностьFirefox (Gecko)ChromeInternet ExplorerOperaSafari
Базовая поддержка{{CompatGeckoDesktop("2")}}{{property_prefix("-moz")}}12.0 (534.30){{property_prefix("-webkit")}}   +

5
+ {{property_prefix("-webkit")}}

+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
ВозможностьAndroidChrome for AndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Базовая поддержка{{CompatUnknown}}{{CompatVersionUnknown}}{{property_prefix("-webkit")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}5
+ {{property_prefix("-webkit")}}
+
diff --git a/files/ru/conflicting/web/css/css_basic_user_interface/index.html b/files/ru/conflicting/web/css/css_basic_user_interface/index.html new file mode 100644 index 0000000000..2a4028644d --- /dev/null +++ b/files/ru/conflicting/web/css/css_basic_user_interface/index.html @@ -0,0 +1,119 @@ +--- +title: CSS Basic User Interface +slug: Web/CSS/CSS_User_Interface +tags: + - CSS + - CSS Basic User Interface + - NeedsTranslation + - Overview + - Reference + - TopicStub +translation_of: Web/CSS/CSS_Basic_User_Interface +translation_of_original: Web/CSS/CSS_User_Interface +--- +
{{CSSRef}}
+ +

CSS User Interface is a CSS module that lets you define the rendering and functionality of features related to the user interface.

+ +

Reference

+ +

Preferences

+ +
+ +
+ +

Guides

+ +
+
Using URL values for the cursor property
+
Explains how a URL can be used with the {{cssxref("cursor")}} property to produce custom cursors.
+
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('CSS3 Basic UI')}}{{Spec2('CSS3 Basic UI')}} 
{{SpecName('CSS2.1', 'ui.html')}}{{Spec2('CSS2.1')}}Initial definition
+ +

Browser compatibility

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support1.01.5 (1.8)8.07.01.2 (125)
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support1.0{{CompatGeckoMobile(1.8)}}8.06.03.1
+
diff --git a/files/ru/conflicting/web/css/css_flexible_box_layout/basic_concepts_of_flexbox/index.html b/files/ru/conflicting/web/css/css_flexible_box_layout/basic_concepts_of_flexbox/index.html new file mode 100644 index 0000000000..3f0b229d20 --- /dev/null +++ b/files/ru/conflicting/web/css/css_flexible_box_layout/basic_concepts_of_flexbox/index.html @@ -0,0 +1,379 @@ +--- +title: Используем CSS Flexible Boxes +slug: Web/CSS/CSS_Flexible_Box_Layout/Using_CSS_flexible_boxes +translation_of: Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox +translation_of_original: Web/CSS/CSS_Flexible_Box_Layout/Using_CSS_flexible_boxes +--- +
Эта статья устарела и удалена из английской версии. Вместо неё идёт перенаправление на статью: +

Основные понятия Flexbox

+ + + +

У меня не поднялась рука удалить эту статью окончательно, но я рекомендую Вам вместо неё, всё-таки, прочитать ту.

+
+ +
{{CSSRef}}
+ +

CSS3 Flexible Box, или просто flexbox — это режим разметки, созданный для упорядочения элементов на странице таким образом, чтобы они вели себя предсказуемо в случаях, когда разметка страницы адаптирована под различные размеры экрана и устройства. Во многих случаях флексбоксы лучше блочной модели разметки, поскольку не использует обтекания (floats) и не выполняет схлопывание отступлений flex-контейнера и его содержимого (margin collapse).

+ +

Для многих дизайнеров модель использования флексбоксов будет более простой для применения. Дочерние элементы внутри флексбокса могут размещаться в любом направлении и могут менять размер, чтобы адаптироваться к различным размерам дисплея. Позиционирование элементов в таком случае является простым и комплексная разметка достигается значительно легче и с более чистым кодом, поскольку порядок отображения элементов не связан с их порядком в коде. Эта независимость умышленно касается только визуального рендеринга, оставляя порядок интерпретации и навигацию зависимыми от порядка в исходниках.

+ +
Внимание: некоторые браузеры все еще могут частично или полностью не поддерживать флексбоксы. Ознакомьтесь с таблицей совместимости.
+ +

Концепция Flexbox

+ +

Главной концепцией Flexbox есть возможность изменения высоты и/или ширины его элементов, чтобы лучше заполнять пространство любого дисплея. Flex-контейнер увеличивает элементы, чтобы заполнить доступное пространство или уменьшает чтобы предотвратить перекрытие.

+ +

Алгоритм разметки флексбоксами агностичено направлен в противовес блочной разметке, которая ориентирована строго вертикально, или горизонтально-ориентированной инлайн-разметке. Несмотря на то что разметка блоками хорошо подходит для страницы, ей не хватает объективного механизма для поддержки компонентов, которые должны менять ориентацию, размеры а также растягиваться или сжиматься при изменениях размера экрана, изменении ориентации с вертикальной на горизонтальную и так далее. Разметка флексбоксами наиболее желательна для компонентов приложения и шаблонов, которые мало масштабируются, тогда как grid-разметка создана для больших шаблонов. Обе технологии являются частью разработки CSS Working Group которая должна способствовать совместимости web-приложений с различными браузерами, режимами а также большей гибкости.

+ +

Терминология

+ +

Поскольку описание флексбоксов не включает таких словосочетаний, как горизонтальная / inline и вертикальная / block оси, объяснение модели предусматривает новую терминологию. Используйте следующую диаграмму при просмотре словаря терминов. Она изображает flex-контейнер, имеющий flex-направление ряда, что означает, что каждый flex item расположен горизонтально, друг за другом по главной оси (main axis) в соответствии с установленным направлением написания текста элемента. Слева направо в данном случае.

+ +

flex_terms.png

+ +
+
Flex-контейнер
+
Родительский элемент, в котором содержатся flex-элементы. Flex-контейнер определяется установкой свойства {{Cssxref("display")}} в flex или inline-flex.
+
Flex-элемент, flex item
+
+

Каждый дочерний элемент flex-контейнера становится flex-элементом. Текст, который напрямую содержится в flex-контейнере, оборачивается анонимным flex-элементом.

+
+
Оси
+
+

Каждый flexible-бокс шаблон строится по двум осям. Главная ось (main axis) — это ось, вдоль которой flex-элементы следуют один за другим, а перекрёстная ось (cross axis) перпендикулярна ей.

+ +
    +
  • Свойство {{Cssxref("flex-direction")}} устанавливает главную ось.
  • +
  • Свойство {{Cssxref("justify-content")}} определяет расположение элементов вдоль главной оси в текущем ряду.
  • +
  • Свойство align-items расположение элементов вдоль перекрёстной оси в текущем ряду.
  • +
  • Свойство align-self устанавливает, как отдельный flex-элемент выровнен по перекрёстной оси, переопределяя значения, установленные с помощью align-items.
  • +
+
+
Направления
+
+

Главное начало и конец (main) и перекрёстное начало и конец (cross start/end) — это стороны контейнера, определяющие начало и окончание потока flex-элемментов. Они следуют по главной и перекрестной осями flex-контейнера в векторе, установленном режимом написания ({{Cssxref("writing-mode")}}) (слева направо, справа налево и т. д.).

+ +
    +
  • Свойство {{Cssxref("order")}} присваивает элементы порядковым группам и определяет, в каком порядке их показывать.
  • +
  • Свойство {{Cssxref("flex-flow")}} — это короткая форма, состоящая из свойств {{Cssxref("flex-direction")}} и {{Cssxref("flex-wrap")}}, определяющих расплолжение элементов.
  • +
+
+
Линии
+
+

Flex-элементы могут размещаться на одной или нескольких линиях в зависимости от значения свойства {{Cssxref("flex-wrap")}}, которое контролирует направление перекрестных линий и направление в котором складываются новые линии.

+
+
Размеры
+
+

Флекс элементы агностически эквивалентны высоте и ширине главного размера и поперечного размера, которые равны, соответственно,  главной оси (main axis) и поперечной оси (cross axis) флекс-контейнера.

+ + +
+
+ +

Делаем элемент флексбоксом

+ +

Чтобы сделать элемент flexible-боксом, укажите значение {{cssxref("display")}} следующим образом:

+ +
display: flex
+ +

или

+ +
display: inline-flex
+ +

Таким образом мы определяем элемент как флексбокс, а его дочерниие элементы — как flex-элементы. Значение flex делает контейнер блочным элементом, а inline-flex значение превращает его в инлайн-элемент.

+ +
Внимание: для указания префикса вендора, добавьте строку в значение атрибута, а не к самому атрибуту. Например, display: -webkit-flex.
+ +

Рассмотрим flex-элементы

+ +

Текст, который содержится непосредственно внутри flex-контейнера, автоматически оборачивается анонимным flex-элементом. Однако, анонимный flex-элемент, содержащий только пробелы, не отображается (как будто было указано значение display: none).

+ +

Абсолютно позиционированные дочерние элементы flex-контейнера позиционируются так, что их статическое положение определяется относительно главного начального угла содержащего их flex-контейнера.

+ +

Отступы (margin) соседних flex-контейнеров не схлопываются. Установка значений margin: auto поглощает дополнительное место в вертикальном или горизонтальном направлении и может быть использовано для выравнивания или для разделения соседних flex-элементов. См. Выравнивание при помощи 'автоматических' отступов в разделе "Модель расположения при помощи flex-контейнеров" спецификации W3C.

+ +

Свойства выравнивания flexbox выполняют "истинное" центрирование в отличие от других способов центрирования в CSS. Это означает, что flex-элементы будут оставаться отцентрированными даже если они переполняют flex-контейнер. Впрочем, это может иногда быть проблематичным, если они вылезают за верхний или левый край страницы (в языках с написанием слева направо; в языках с написанием справа налево, таких как арабский, возникает проблема с правой границей), так как вы не можете прокрутить страницу в данную область даже если там есть содержимое! В будущем релизе свойства выравнивания будут также дополнены "безопасной" опцией. На данный момент, если это проблема, вы можете использовать отступы (margin) для достижения центрирования, так как они сработают "безопасно" и центрирование будет прекращено при переполнении. Вместо использования свойства align- просто установите автоматические отступы (margin: auto) для flex-элементов, которые вы хотите отцентрировать. Вместо свойств justify- установите margin: auto на внешние края первого и последнего элемента в flex-контейнере. Автоматические отступы будут "подстраиваться" и занимать оставшееся место, центрируя flex-элементы при наличии свободного места и используя стандартное выравнивание при его отсутствии. Тем не менее, если вы пытаетесь заменить justify-content центрированием, основанным на отступах (margin-based) в многострочном flexbox, вам, видимо, не повезло, так как вам необходимо установить отступы для первого и последнего элемента на каждой строке. Если вы не можете предугадать заранее на какой строке окажется каждый элемент, вы не сможете надежно использовать центрирование, основанное на отступах, на основной оси для замены свойства justify-content.

+ +

Помните, что, несмотря на то, что порядок отображения элементов не зависит от их положения в исходном коде, эта независимость затрагивает только визуальное отображение, оставляя навигацию и голосовую помощь в исходном порядке. Даже свойство {{cssxref("order")}} не влияет на очередность голосовой помощи и навигации. Таким образом, разработчики должны уделять внимание правильному порядку элементов в исходном коде, чтобы не навредить доступности документа.

+ +

Свойства Flexbox

+ +

Свойства, не влияющие на Flexbox

+ +

Так как flexbox используют другой алгоритм расположения, некоторые свойства не имеют смысла для flex-контейнера:

+ + + +

Пример

+ +

Типичный пример flex

+ +

Типичный пример показывает как применять "flex-эффект" к элементам и как соседние элементы ведут себя в состоянии flex.

+ +
​<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <style>
+    .flex {
+        /* basic styling */
+        width: 350px;
+        height: 200px;
+        border: 1px solid #555;
+        font: 14px Arial;
+
+        /* flexbox setup */
+        display: flex;
+        flex-direction: row;
+    }
+
+    .flex > div {
+        flex: 1 1 auto;
+        width: 30px; /* To make the transition work nicely. (Transitions to/from
+                        "width:auto" are buggy in Gecko and Webkit, at least.
+                        See http://bugzil.la/731886 for more info.) */
+        transition: width 0.7s ease-out;
+    }
+
+    /* colors */
+    .flex > div:nth-child(1){ background: #009246; }
+    .flex > div:nth-child(2){ background: #F1F2F1; }
+    .flex > div:nth-child(3){ background: #CE2B37; }
+
+    .flex > div:hover {
+        width: 200px;
+    }
+
+    </style>
+  </head>
+  <body>
+    <p>Flexbox nuovo</p>
+    <div class="flex">
+      <div>uno</div>
+      <div>due</div>
+      <div>tre</div>
+    </div>
+  </body>
+</html>
+ +

Пример расположения "Священный Грааль"

+ +

Данный пример показывает как flexbox предоставляет возможность динамически изменять расположение для различных разрешений экрана. Следующая схема иллюстрирует преобразование.

+ +

HolyGrailLayout.png

+ +

Здесь изображен случай, когда расположение, подходящее для окна браузера должно быть оптимизировано для экрана смартфона. Не только элементы должны уменьшиться в размере, но и порядок, в котором они отображаются, должен измениться. Flexbox сильно упрощает это.

+ +
​<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <style>
+    body {
+        font: 24px Helvetica;
+        background: #999999;
+    }
+
+    #main {
+        min-height: 800px;
+        margin: 0px;
+        padding: 0px;
+        display: flex;
+        flex-flow: row;
+    }
+
+    #main > article {
+        margin: 4px;
+        padding: 5px;
+        border: 1px solid #cccc33;
+        border-radius: 7pt;
+        background: #dddd88;
+        flex: 3 1 60%;
+        order: 2;
+    }
+
+    #main > nav {
+        margin: 4px;
+        padding: 5px;
+        border: 1px solid #8888bb;
+        border-radius: 7pt;
+        background: #ccccff;
+        flex: 1 6 20%;
+        order: 1;
+    }
+
+    #main > aside {
+        margin: 4px;
+        padding: 5px;
+        border: 1px solid #8888bb;
+        border-radius: 7pt;
+        background: #ccccff;
+        flex: 1 6 20%;
+        order: 3;
+    }
+
+    header, footer {
+        display: block;
+        margin: 4px;
+        padding: 5px;
+        min-height: 100px;
+        border: 1px solid #eebb55;
+        border-radius: 7pt;
+        background: #ffeebb;
+    }
+
+    /* Too narrow to support three columns */
+    @media all and (max-width: 640px) {
+        #main, #page {
+            flex-direction: column;
+        }
+
+        #main > article, #main > nav, #main > aside {
+        /* Return them to document order */
+            order: 0;
+        }
+
+        #main > nav, #main > aside, header, footer {
+            min-height: 50px;
+            max-height: 50px;
+        }
+    }
+    </style>
+  </head>
+  <body>
+    <header>header</header>
+    <div id='main'>
+      <article>article</article>
+      <nav>nav</nav>
+      <aside>aside</aside>
+    </div>
+    <footer>footer</footer>
+  </body>
+</html>
+ +

Песочница

+ +

Существует несколько песочниц с flexbox, доступных онлайн для экспериментов:

+ + + +

О чем нужно помнить

+ +

Алгоритм, описывающий как flex-элементы располагаются, иногда может быть довольно запутанным. Вот несколько правильных решений, которые позволят избежать неприятных сюрпризов при верстке с использованием flexbox.

+ +

Flexbox располагаются в соответствие с направлением письма, что означает, что главное начало и главный конец располагаются в зависимости от положения начала и конца (строки - прим.).

+ +

Перекрестное начало и перекрестный конец полагаются на определение позиции начала и конца, которое зависит от значения свойства {{cssxref("direction")}}.

+ +

Разрывы страницы допустимы в расположении flex-контейнеров, когда это позволяет свойство break-. Свойства CSS3 break-after, break-before и break-inside, а также свойства CSS 2.1 page-break-before, page-break-after и page-break-inside работают на flex-контейнере, flex-элементах, а также внутри flex-элементов.

+ +

Совместимость с браузерами

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureFirefox (Gecko)ChromeInternet ExplorerOperaSafari
Basic support (single-line flexbox){{CompatGeckoDesktop("18.0")}}[6]{{property_prefix("-moz")}}[2]
+ {{CompatGeckoDesktop("22.0")}}
21.0{{property_prefix("-webkit")}}
+ 29.0
11[3]12.10{{property_prefix("-webkit")}}[5]6.1{{property_prefix("-webkit")}}[1]
Multi-line flexbox{{CompatGeckoDesktop("28.0")}}21.0{{property_prefix("-webkit")}}
+ 29.0
11[3]12.10[5]
+ 15 {{property_prefix("-webkit")}}
6.1{{property_prefix("-webkit")}}[1]
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureFirefox Mobile (Gecko)Firefox OSAndroidIE PhoneOpera MobileSafari Mobile
Basic support (single-line flexbox){{CompatGeckoMobile("18.0")}}{{property_prefix("-moz")}}[2]
+ {{CompatGeckoMobile("22.0")}}
+

1.0{{property_prefix("-moz")}}[2]
+ 1.1

+
2.1{{property_prefix("-webkit")}}[4]
+ 4.4
1112.10[5]
+ 15{{property_prefix("-webkit")}}
7{{property_prefix("-webkit")}}[1]
Multi-line flexbox{{CompatGeckoMobile("28.0")}}1.32.1{{property_prefix("-webkit")}}[4]
+ 4.4
1112.10[5]
+ 15{{property_prefix("-webkit")}}
7{{property_prefix("-webkit")}}[1]
+
+ +

[1] Safari до версии 6.0 (iOS.1) поддерживал старую несовместимую черновую версию спецификации. Safari 6.1 (и Safari на iOS 7) был обновлен для поддержки финальной версии.

+ +

[2] До Firefox 22, чтобы активировать поддержку flexbox, пользователь должен установить параметр about:config layout.css.flexbox.enabled в значение true. Начиная с Firefox 22 по Firefox 27, параметр установлен в true по умолчанию, и полностью исключен в Firefox 28.

+ +

[3] Internet Explorer 10 поддерживает старую несовместимую черновую версию спецификации; Internet Explorer 11 был обновлен для поддержки финальной версии.

+ +

[4] Android browser до версии 4.3 поддерживал старую несовместимую черновую версию спецификации. Android 4.4 был обновлен для поддержки финальной версии.

+ +

[5] Хотя изначальная реализация в Opera 12.10 flexbox была без приставки, она получила приставку {{property_prefix("-webkit")}} в версиях с 15 по 16 Opera и с 15 по 19 Opera Mobile. Приставка была снова убрана в Opera 17 и Opera Mobile 24.

+ +

[6] До Firefox 29, установка visibility: collapse для flex-элемента заставляет его обрабатываться как display: none вместо предполагаемого поведения, обрабатывающего его как visibility: hidden. Предложенное решение - использовать visibility:hidden для flex-элементов, которые должны вести себя как при установленном visibility:collapse. Для большей информации, см {{bug(783470)}}.

+ +

См. также

+ + diff --git a/files/ru/conflicting/web/css/gap/index.html b/files/ru/conflicting/web/css/gap/index.html new file mode 100644 index 0000000000..90daa7c0ea --- /dev/null +++ b/files/ru/conflicting/web/css/gap/index.html @@ -0,0 +1,194 @@ +--- +title: grid-gap +slug: Web/CSS/grid-gap +translation_of: Web/CSS/gap +translation_of_original: Web/CSS/grid-gap +--- +

{{Deprecated_Header}}

+ +
+

Примечание. Свойство CSS с разделительной сеткой было переименовано в свойство prefix-less {{cssxref('gap')}}.

+
+ +

Свойство CSS grid-gap является сокращенным свойством для {{cssxref("grid-row-gap")}} и {{cssxref("grid-column-gap")}}, определяющего желоба между строками и столбцами сетки.

+ +
{{EmbedInteractiveExample("pages/css/grid-gap.html")}}
+ + + +

Syntax

+ +
/* Одно <length> значение */
+grid-gap: 20px;
+grid-gap: 1em;
+grid-gap: 3vmin;
+grid-gap: 0.5cm;
+
+/* Одно <percentage> значение */
+grid-gap: 16%;
+grid-gap: 100%;
+
+/* Два <length> значения */
+grid-gap: 20px 10px;
+grid-gap: 1em 0.5em;
+grid-gap: 3vmin 2vmax;
+grid-gap: 0.5cm 2mm;
+
+/* Один или два <percentage> значения */
+grid-gap: 16% 100%;
+grid-gap: 21px 82%;
+
+/* calc() значения */
+grid-gap: calc(10% + 20px);
+grid-gap: calc(20px + 10%) calc(10% - 5px);
+
+/* Глобальные значения */
+grid-gap: inherit;
+grid-gap: initial;
+grid-gap: unset;
+
+ +

Это свойство указывается как значение для <'grid-row-gap'> , за которым необязательно следует значение для <'grid-column-gap'>. Если <'grid-column-gap'> опущено, для него устанавливается то же значение, что и <'grid-row-gap'>.

+ +

Каждое из свойств <'grid-row-gap'> и <'grid-column-gap'> указываются как <length> или <percentage>.

+ +

Значения

+ +
+
<length>
+
Ширина отступа, разделяющего линии сетки.
+
<percentage>
+
Ширина отступа, разделяющего линии сетки относительно размеров элемента.
+
+ +

Формальный синтаксис

+ +
{{csssyntax}}
+ +

Примеры

+ +

HTML Контент

+ +
<div id="grid">
+  <div></div>
+  <div></div>
+  <div></div>
+  <div></div>
+  <div></div>
+  <div></div>
+  <div></div>
+  <div></div>
+  <div></div>
+</div>
+ +

CSS Контент

+ +
#grid {
+  display: grid;
+  height: 200px;
+  grid-template: repeat(3, 1fr) / repeat(3, 1fr);
+  grid-gap: 20px 5px;
+}
+
+#grid > div {
+  background-color: lime;
+}
+
+ +

{{EmbedLiveSample("Example", "100%", "200px")}}

+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName("CSS3 Box Alignment", "#propdef-grid-gap", "grid-gap")}}{{Spec2("CSS3 Box Alignment")}}Устарело в пользу gap
{{SpecName("CSS3 Grid", "#gutters", "grid-gap")}}{{Spec2("CSS3 Grid")}}Начальное определение
+ +

{{cssinfo}}

+ +

Совместимость с браузерами

+ + + +

{{Compat("css.properties.grid-gap")}}

+ +

Смотрите также

+ + + + diff --git a/files/ru/conflicting/web/css/url()/index.html b/files/ru/conflicting/web/css/url()/index.html new file mode 100644 index 0000000000..755d1adfe4 --- /dev/null +++ b/files/ru/conflicting/web/css/url()/index.html @@ -0,0 +1,35 @@ +--- +title: url() +slug: Web/CSS/filter-function/url +tags: + - CSS + - Начинающий + - Ссылка + - Функция +translation_of: Web/CSS/url() +translation_of_original: Web/CSS/filter-function/url +--- +
{{cssref}}
+ +

url() - это CSS функция, использующая SVG filter для измения внешнего вида у выводимого изображения.

+ +

Синтаксис

+ +
url(расположение)
+ +

Параметры

+ +
+
расположение
+
В {{cssxref("<URL-адрес>")}} из {{glossary("XML")}} указывается файл, который задает фильтр SVG, а также может включать в себя привязки к конкретному фильтрующему элементу.
+
+ +

Пример

+ +
url(resources.svg#c1)
+ +

Изучите также

+ + diff --git a/files/ru/conflicting/web/css/url()_168028c4e5edd9e19c061adb4b604d4f/index.html b/files/ru/conflicting/web/css/url()_168028c4e5edd9e19c061adb4b604d4f/index.html new file mode 100644 index 0000000000..82965bf827 --- /dev/null +++ b/files/ru/conflicting/web/css/url()_168028c4e5edd9e19c061adb4b604d4f/index.html @@ -0,0 +1,94 @@ +--- +title: +slug: Web/CSS/url +tags: + - Адрес + - Типы данных + - относительный адрес +translation_of: Web/CSS/url() +translation_of_original: Web/CSS/url +--- +
{{CssRef}}
+ +

Тип данных CSS <url> обозначает указатели на ресурсы, такие как изображения или шрифты. URL-адреса могут быть использованы в многочисленных свойствах CSS, таких как {{Cssxref("background-image")}}, {{Cssxref("cursor")}} или {{cssxref("list-style")}}.

+ +
+

URI или URL? Существует разница между {{Glossary("URI")}} и {{Glossary("URL")}}. URI просто идентифицирует ресурс. URL является типом URI, и описывает месторасположение ресурса.URI может быть либо URL-адресом, либо именем ресурса ({{Glossary("URN")}}).

+ +

В CSS Уровень 1, фунциональная нотация url()описывала только истинные URL-адреса. В CSS Уровень 2, определение url() было расширено для описания любого URI, будь то URL или URN. Неожиданно, что  url() может быть использовано для создания типа данных CSS <uri>. Это изменение было не только неожиданным, но и ненужным, так как URN почти не используется в реальном CSS. Для избежания путанницы, CSS Уровень 3 вернулся к более узкому, первоначальному определению. Сейчас url() означает только истинное значение <url>.

+
+ +

Синтаксис

+ +

Тип данных <url> является указанием к использованию функциональной нотации url(). Он  может быть задан без кавычек или с использованием одинарных или двойных кавычек. Допускаются относительные URL-адреса, относящиеся к URL-адресу страницы стилей (а не к URL-адресу веб-страницы).

+ +
<a_css_property>: url("http://mysite.example.com/mycursor.png")
+<a_css_property>: url('http://mysite.example.com/mycursor.png')
+<a_css_property>: url(http://mysite.example.com/mycursor.png)
+
+ +
+

Примечание: Контрольные символы выше 0x7e не допустимы в URL-адресах без кавычек, начиная с Firefox 15. Смотри {{Bug(752230)}} для более детальной информации.

+
+ +

Примеры

+ +
.topbanner {
+  background: url("topbanner.png") #00D no-repeat fixed;
+}
+
+ +
ul {
+  list-style: square url(http://www.example.com/redball.png);
+}
+
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('CSS4 Values', '#urls', '<url>')}}{{Spec2('CSS4 Values')}} 
{{SpecName('CSS3 Values', '#urls', '<url>')}}{{Spec2('CSS3 Values')}}Нет значительных изменений по сравнению с CSS Уровень 2 (Revision 1).
{{Specname('CSS2.1', 'syndata.html#uri', '<uri>')}}{{Spec2('CSS2.1')}}Нет значительных изменений по сравнению с CSS Уровень 1.
{{SpecName('CSS1', '#url', '<url>')}}{{Spec2('CSS1')}}первое определение.
+ +

Поддержка браузерами

+ + + +
{{Compat("css.types.url")}}
+ +

Смотрите также

+ + diff --git a/files/ru/conflicting/web/guide/index.html b/files/ru/conflicting/web/guide/index.html new file mode 100644 index 0000000000..3dd0b4cbcc --- /dev/null +++ b/files/ru/conflicting/web/guide/index.html @@ -0,0 +1,10 @@ +--- +title: Веб-разработка +slug: Веб-разработка +translation_of: Web/Guide +translation_of_original: Web_Development +--- +

Веб-разработка включает в себя все аспекты разработки веб-сайта или веб-приложения. Статьи этого раздела освещают создание как простых веб-сайтов, так и сложных, интерактивных веб-приложений с использованием новейших технологий разработки для веб.

+ +

Разделы документации

Введение в веб-разработку
Руководство, обучающее разработке для веб.
HTML
HyperText Markup Language — основной язык, используемый для создания веб-страниц и других документов, пригодных для просмотра в браузере.
JavaScript
JavaScript — наиболее широко используемый для разработки веб-приложений скриптовый язык; он также используется и при разработке программного обеспечения основанного на Mozilla.
CSS
Cascading Style Sheets — таблицы стилей позволяющие создать make it possible to do advanced layout and page design on the Web.
AJAX
Asynchronous JavaScript and XML — не столько технология, сколько подход к сочетанию имеющихся технологий; JavaScript и другие современные веб-технологии используются совместно при создании динамических веб-приложений.
Веб-стандарты
Learn how to make your Web site or application reach the largest number of users through compatibility with the open Web.
DOM
Document Object Model — API для HTML- и XML-документов, providing a structural representation of the document that you can modify in order to alter its visual presentation.
XHTML
Extensible HyperText Markup Language is an XML-based HTML-like language that offers a stricter syntax than HTML.
SVG
Scalable Vector Graphics — язык разметки, основанный на XML, для описания двухмерной векторной графики.
Mozilla Web developer FAQ
Наиболее часто задаваемые веб-разработчиками вопросы. С ответами!

View All...

Сообщество

Инструменты

+

{{ languages( { "de": "de/Webentwicklung", "en": "en/Web_Development", "es": "es/Desarrollo_Web", "fr": "fr/D\u00e9veloppement_Web", "it": "it/Sviluppo_Web", "ja": "ja/Web_Development", "pl": "pl/Programowanie_WWW", "zh-cn": "cn/Web_Development" } ) }}

diff --git a/files/ru/conflicting/web/guide/mobile/index.html b/files/ru/conflicting/web/guide/mobile/index.html new file mode 100644 index 0000000000..cc288a9c45 --- /dev/null +++ b/files/ru/conflicting/web/guide/mobile/index.html @@ -0,0 +1,18 @@ +--- +title: Mobile Web development +slug: Web_Development/Mobile +tags: + - Mobile + - NeedsTranslation + - TopicStub + - Web Development +translation_of: Web/Guide/Mobile +translation_of_original: Web_Development/Mobile +--- +

Developing web sites to be viewed on mobile devices requires approaches that ensure a web site works as well on mobile devices as it does on desktop browsers. The following articles describe some of these approaches.

+ diff --git a/files/ru/conflicting/web/http/cors/index.html b/files/ru/conflicting/web/http/cors/index.html new file mode 100644 index 0000000000..c3d53cb730 --- /dev/null +++ b/files/ru/conflicting/web/http/cors/index.html @@ -0,0 +1,213 @@ +--- +title: Server-Side Access Control (CORS) +slug: Web/HTTP/Server-Side_Access_Control +translation_of: Web/HTTP/CORS +translation_of_original: Web/HTTP/Server-Side_Access_Control +--- +

Системы контроля доступа производят идентификацию авторизацииаутентификацию, подтверждение доступа и подотчетность сущностей с помощью учетных данных для входа, включая пароль, личный идентификационный номер (PINs), биометрическое сканирование и физический или электронный ключ.

+ +

Контроль доступа --- это техника безопасности, которую можно использовать для регулирования процессом того, кто или что может видеть или использовать ресурсы в вычислительном окружении.

+ +

{{HTTPSidebar}}

+ +

Для меж-сайтовых запросов, произведенных с помощью {{domxref("XMLHttpRequest")}} или Fetch API, браузеры передают специальные HTTP заголовки. Так же ожидаемо увидеть определенные HTTP заголовки, переданные обратно внутри меж-сайтового ответа. Обзор этих заголовков, включая примеры JavaScript кода, создающего запросы и обрабатывающего ответы от сервера, как и описание каждого из заголовков, может быть найден в статье HTTP Access Control (CORS) и должен быть прочитан вместе с данной. Эта статья покрывает обработку Запросов контроля доступа и формулировку Ответов контроля доступа в PHP. Целевая аудитория для этой статьи ---  разработчики серверов и администраторы. Хотя примеры кода, приведенные тут, на PHP, подобная концепция применяется в ASP.net, Perl, Python, Java, etc.; в общем, эти концепции могут быть применены в любом сервером окружении, который обрабатывает HTTP запросы и динамически формирует HTTP ответы.

+ +

Discussion of HTTP headers

+ +

The article covering the HTTP headers used by both clients and servers is here, and should be considered prerequisite reading.

+ +

Working code samples

+ +

The PHP snippets (and the JavaScript invocations to the server) in subsequent sections are taken from the working code samples posted here. These will work in browsers that implement cross-site {{domxref("XMLHttpRequest")}}.

+ +

Simple cross-site requests

+ +

Simple Access Control Requests are initiated when:

+ + + +

In this case, responses can be sent back based on some considerations.

+ + + +

The section on Simple Access Control Requests shows you the header exchanges between client and server. Here is a PHP code segment that handles a Simple Request:

+ +
<?php
+
+// We'll be granting access to only the arunranga.com domain
+// which we think is safe to access this resource as application/xml
+
+if($_SERVER['HTTP_ORIGIN'] == "http://arunranga.com") {
+    header('Access-Control-Allow-Origin: http://arunranga.com');
+    header('Content-type: application/xml');
+    readfile('arunerDotNetResource.xml');
+} else {
+  header('Content-Type: text/html');
+  echo "<html>";
+  echo "<head>";
+  echo "   <title>Another Resource</title>";
+  echo "</head>";
+  echo "<body>",
+       "<p>This resource behaves two-fold:";
+  echo "<ul>",
+         "<li>If accessed from <code>http://arunranga.com</code> it returns an XML document</li>";
+  echo   "<li>If accessed from any other origin including from simply typing in the URL into the browser's address bar,";
+  echo   "you get this HTML document</li>",
+       "</ul>",
+     "</body>",
+   "</html>";
+}
+?>
+
+ +

The above checks to see if the {{HTTPHeader("Origin")}} header sent by the browser (obtained through $_SERVER['HTTP_ORIGIN']) matches 'http://arunranga.com'. If yes, it returns {{HTTPHeader("Access-Control-Allow-Origin")}}: http://arunranga.com. This example can be seen running here.

+ +

Preflighted requests

+ +

Preflighted Access Control Requests occur when:

+ + + +

The section on Preflighted Access Control Requests shows a header exchange between client and server. A server resource responding to a preflight requests needs to be able to make the following determinations:

+ + + +

Here is an example in PHP of handling a preflighted request:

+ +
<?php
+
+if($_SERVER['REQUEST_METHOD'] == "GET") {
+
+  header('Content-Type: text/plain');
+  echo "This HTTP resource is designed to handle POSTed XML input";
+  echo "from arunranga.com and not be retrieved with GET";
+
+} elseif($_SERVER['REQUEST_METHOD'] == "OPTIONS") {
+  // Tell the Client we support invocations from arunranga.com and
+  // that this preflight holds good for only 20 days
+
+  if($_SERVER['HTTP_ORIGIN'] == "http://arunranga.com") {
+    header('Access-Control-Allow-Origin: http://arunranga.com');
+    header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
+    header('Access-Control-Allow-Headers: X-PINGARUNER');
+    header('Access-Control-Max-Age: 1728000');
+    header("Content-Length: 0");
+    header("Content-Type: text/plain");
+    //exit(0);
+  } else {
+    header("HTTP/1.1 403 Access Forbidden");
+    header("Content-Type: text/plain");
+    echo "You cannot repeat this request";
+  }
+
+} elseif($_SERVER['REQUEST_METHOD'] == "POST") {
+  // Handle POST by first getting the XML POST blob,
+  // and then doing something to it, and then sending results to the client
+
+  if($_SERVER['HTTP_ORIGIN'] == "http://arunranga.com") {
+    $postData = file_get_contents('php://input');
+    $document = simplexml_load_string($postData);
+
+    // do something with POST data
+
+    $ping = $_SERVER['HTTP_X_PINGARUNER'];
+
+    header('Access-Control-Allow-Origin: http://arunranga.com');
+    header('Content-Type: text/plain');
+    echo // some string response after processing
+  } else {
+    die("POSTing Only Allowed from arunranga.com");
+  }
+} else {
+    die("No Other Methods Allowed");
+}
+?>
+
+ +

Note the appropriate headers being sent back in response to the {{HTTPMethod("OPTIONS")}} preflight as well as to the {{HTTPMethod("POST")}} data. One resource thus handles the preflight as well as the actual request. In the response to the OPTIONS request, the server notifies the client that the actual request can indeed be made with the POST method, and header fields such as X-PINGARUNER can be sent with the actual request. This example can be seen running here.

+ +

Credentialed requests

+ +

Credentialed Access Control Requests – that is, requests that are accompanied by Cookies or HTTP Authentication information (and which expect Cookies to be sent with responses) – can be either Simple or Preflighted, depending on the request methods used.

+ +

In a Simple Request scenario, the request will be sent with Cookies (e.g. if the withCredentials flag is set on {{domxref("XMLHttpRequest")}}). If the server responds with {{HTTPHeader("Access-Control-Allow-Credentials")}}: true attached to the credentialed response, then the response is accepted by the client and exposed to web content. In a Preflighted Request, the server can respond with Access-Control-Allow-Credentials: true to the OPTIONS request.

+ +

Here is some PHP that handles credentialed requests:

+ +
<?php
+
+if($_SERVER['REQUEST_METHOD'] == "GET") {
+  header('Access-Control-Allow-Origin: http://arunranga.com');
+  header('Access-Control-Allow-Credentials: true');
+  header('Cache-Control: no-cache');
+  header('Pragma: no-cache');
+  header('Content-Type: text/plain');
+
+  // First See if There Is a Cookie
+  if (!isset($_COOKIE["pageAccess"])) {
+    setcookie("pageAccess", 1, time()+2592000);
+    echo 'I do not know you or anyone like you so I am going to';
+    echo 'mark you with a Cookie :-)';
+  } else {
+    $accesses = $_COOKIE['pageAccess'];
+    setcookie('pageAccess', ++$accesses, time()+2592000);
+    echo 'Hello -- I know you or something a lot like you!';
+    echo 'You have been to ', $_SERVER['SERVER_NAME'], ';
+    echo 'at least ', $accesses-1, ' time(s) before!';
+  }
+} elseif($_SERVER['REQUEST_METHOD'] == "OPTIONS") {
+  // Tell the Client this preflight holds good for only 20 days
+  if($_SERVER['HTTP_ORIGIN'] == "http://arunranga.com") {
+    header('Access-Control-Allow-Origin: http://arunranga.com');
+    header('Access-Control-Allow-Methods: GET, OPTIONS');
+    header('Access-Control-Allow-Credentials: true');
+    header('Access-Control-Max-Age: 1728000');
+    header("Content-Length: 0");
+    header("Content-Type: text/plain");
+  } else {
+    header("HTTP/1.1 403 Access Forbidden");
+    header("Content-Type: text/plain");
+    echo "You cannot repeat this request";
+  }
+} else {
+  die("This HTTP Resource can ONLY be accessed with GET or OPTIONS");
+}
+?>
+
+ +

Note that in the case of credentialed requests, the Access-Control-Allow-Origin: header must not have a wildcard value of "*".  It must mention a valid origin domain. The example above can be seen running here.

+ +

Apache examples

+ +

Restrict access to certain URIs

+ +

One helpful trick is to use an Apache rewrite, environment variable, and headers to apply Access-Control-Allow-* to certain URIs. This is useful, for example, to constrain cross-origin requests to GET /api(.*).json requests without credentials:

+ +
RewriteRule ^/api(.*)\.json$ /api$1.json [CORS=True]
+Header set Access-Control-Allow-Origin "*" env=CORS
+Header set Access-Control-Allow-Methods "GET" env=CORS
+Header set Access-Control-Allow-Credentials "false" env=CORS
+
+ +

See also

+ + diff --git a/files/ru/conflicting/web/http/csp/index.html b/files/ru/conflicting/web/http/csp/index.html new file mode 100644 index 0000000000..5a3bfeae33 --- /dev/null +++ b/files/ru/conflicting/web/http/csp/index.html @@ -0,0 +1,43 @@ +--- +title: CSP (Политика Защиты Контента) +slug: Web/Security/CSP +tags: + - CSP + - Landing +translation_of: Web/HTTP/CSP +translation_of_original: Web/Security/CSP +--- +
{{gecko_minversion_header("2.0")}}
+ +

Политика защиты контента (CSP) — это дополнительный уровень безопасности, который помогает обнаружить и смягчить некоторые виды атак, в том числе межсайтовый скриптинг (XSS) и инъекцию данных. Эти атаки используются для всего, от кражи данных до порчи сайтов и распространения вредоносного ПО.

+ +

Хотя CSP выпустила первую в Firefox 4, с использованием X-Content-Security-Policy предварительно из-за наличия формальной спецификации для CSP.  Firefox 23 содержит обновленную реализацию CSP, которая используется без префикса заголовка Content-Security-Policy и директив, как описано в W3C CSP 1.0 spec.

+ +

Разделы CSP

+ +
+
Introducing Content Security Policy
+
Обзор того, что такое CSP и как это может сделать ваш сайт более безопасным.
+
CSP policy directives
+
Ссылка на CSP директивы политик.
+
Using Content Security Policy
+
Вы можете настроить поведение CSP при настройке наборов правил политик. Это позволяет ослабить или усилить меры безопасности для отдельных видов ресурсов, исходя из потребностей вашего сайта. Эта статья описывает, как настроить CSP, а также о том, как включить его для вашего сайта.
+
Using CSP violation reports
+
Как использовать сообщения CSP  о нарушениях, чтобы контролировать попытки атаковать ваш сайт и его пользователей.
+
Default CSP restrictions {{obsolete_inline("15.0")}}
+
Подробности об ограничениях внедренных по умолчанию в CSP.
+
+ +

См. также

+ + + + + + diff --git a/files/ru/conflicting/web/javascript/guide/index.html b/files/ru/conflicting/web/javascript/guide/index.html new file mode 100644 index 0000000000..a0f5770315 --- /dev/null +++ b/files/ru/conflicting/web/javascript/guide/index.html @@ -0,0 +1,923 @@ +--- +title: Predefined Core Objects +slug: Web/JavaScript/Guide/Predefined_Core_Objects +translation_of: Web/JavaScript/Guide +translation_of_original: Web/JavaScript/Guide/Predefined_Core_Objects +--- +

Эта глава описывает предопределённые объекты в стандартном JavaScript: Array, Boolean, Date, Function, Math, Number, RegExp, и String.

+ +

Объект Array

+ +

В JavaScript массив как тип данных отсутствует. Тем не менее, вы можете использовать предопределённый объект Array и его методы, чтобы работать с массивами в ваших приложениях. Объект Array содержит различные методы для манипуляций с массивами, такими как объединение, обращение и сортировка. У него есть свойство для определения длины массива и другие свойства для работы с регулярными выражениями.

+ +

Массив - это упорядоченный набор значений, обращаться к которым можно с помощью имени и индекса. Например, можно создать массив emp, который содержит имена сотрудников фирмы, проиндексированные номерами. Тогда emp[1] будет соответствовать сотруднику номер один, emp[2] сотруднику номер два и так далее.

+ +

Создание объекта Array

+ +

Следующие инструкции создают эквивалентные массивы:

+ +
+
var arr = new Array(element0, element1, ..., elementN);
+var arr = Array(element0, element1, ..., elementN);
+var arr = [element0, element1, ..., elementN];
+
+
+ +

element0, element1, ..., elementN это список значений во вновь создаваемом массиве. Когда эти значения заданы, массив инициализирует ими свои эелементы. Длина массива определяется по числу аргументов и сохраняется в свойстве length (длина).

+ +

Синтаксис с квадратными скобками называется "литералом массива" (array literal) или "инициализатором массива" (array initializer). Такая запись короче других и используется чаще. Подробности смотрите в Array Literals.

+ +

Создать массив ненулевой длины, но без элементов, можно одним из следующих способов:

+ +
var arr = new Array(arrayLength);
+var arr = Array(arrayLength);
+
+// This has exactly the same effect
+var arr = [];
+arr.length = arrayLength;
+
+ +

Обратите внимание: в приведённом выше коде arrayLength должен быть значением типа Number, то есть числом, иначе будет создан массив с одним элементом (переданным конструктору значением). Вызов arr.length возвратит arrayLength, хотя на самом деле элемент содержит пустые (неопределённые, undefined) элементы. Итерация по массиву циклом for...in не возвратит никаких элементов.

+ +

Массивы можно не только определить как и переменные, но и присвоить существующему объекту как свойство:

+ +
var obj = {};
+// ...
+obj.prop = [element0, element1, ..., elementN];
+
+// OR
+var obj = {prop: [element0, element1, ...., elementN]}
+
+ +

Если же вы хотите создать одноэлементный массив, содержащий число, придётся использовать запись с квадратными скобками, так как когда конструктору Array() передаётся одно-единственное число, оно трактуется как длина массива, а не как хранимвый элемент.

+ +
var arr = [42];
+var arr = Array(42); // Creates an array with no element, but with arr.length set to 42
+
+// The above code is equivalent to
+var arr = [];
+arr.length = 42;
+
+
+ +

Вызов Array(N) приводит к RangeError, если N не является целым числом, чья дробная часть не равна нулю. Следующий пример иллюстрирует это поведение.

+ +
var arr = Array(9.3);  // RangeError: Invalid array length
+
+ +

Если ваш код должен создавать массивы с отдельными элементами произвольного типа, безопаснее использовать литералы массива. Или, создайте пустой массив, прежде чем добавлять элементы к нему.

+ +

Заполнение массива

+ +

You can populate an array by assigning values to its elements. For example,

+ +
var emp = [];
+emp[0] = "Casey Jones";
+emp[1] = "Phil Lesh";
+emp[2] = "August West";
+
+ +

Note: if you supply a non-integer value to the array operator in the code above, a property will be created in the object representing the array, instead of an array element.

+ +
 var arr = [];
+arr[3.4] = "Oranges";
+console.log(arr.length);                // 0
+console.log(arr.hasOwnProperty(3.4));   // true
+
+ +

You can also populate an array when you create it:

+ +
var myArray = new Array("Hello", myVar, 3.14159);
+var myArray = ["Mango", "Apple", "Orange"]
+
+ +

Referring to Array Elements

+ +

You refer to an array's elements by using the element's ordinal number. For example, suppose you define the following array:

+ +
var myArray = ["Wind", "Rain", "Fire"];
+
+ +

You then refer to the first element of the array as myArray[0] and the second element of the array as myArray[1]. The index of the elements begins with zero.

+ +

Note: the array operator (square brackets) is also used for accessing the array's properties (arrays are also objects in JavaScript). For example,

+ +
 var arr = ["one", "two", "three"];
+arr[2];  // three
+arr["length"];  // 3
+
+ +

Understanding length

+ +

At the implementation level, JavaScript's arrays actually store their elements as standard object properties, using the array index as the property name. The length property is special; it always returns the index of the last element plus one (in following example Dusty is indexed at 30 so cats.length returns 30 + 1). Remember, Javascript Array indexes are 0-based: they start at 0, not 1. This means that the length property will be one more than the highest index stored in the array:

+ +
var cats = [];
+cats[30] = ['Dusty'];
+print(cats.length); // 31
+
+ +

You can also assign to the length property. Writing a value that is shorter than the number of stored items truncates the array; writing 0 empties it entirely:

+ +
var cats = ['Dusty', 'Misty', 'Twiggy'];
+console.log(cats.length); // 3
+
+cats.length = 2;
+console.log(cats); // prints "Dusty,Misty" - Twiggy has been removed
+
+cats.length = 0;
+console.log(cats); // prints nothing; the cats array is empty
+
+cats.length = 3;
+console.log(cats); // [undefined, undefined, undefined]
+
+ +

Iterating over arrays

+ +

A common operation is to iterate over the values of an array, processing each one in some way. The simplest way to do this is as follows:

+ +
var colors = ['red', 'green', 'blue'];
+for (var i = 0; i < colors.length; i++) {
+  console.log(colors[i]);
+}
+
+ +

If you know that none of the elements in your array evaluate to false in a boolean context — if your array consists only of DOM nodes, for example, you can use a more efficient idiom:

+ +
var divs = document.getElementsByTagName('div');
+for (var i = 0, div; div = divs[i]; i++) {
+  /* Process div in some way */
+}
+
+ +

This avoids the overhead of checking the length of the array, and ensures that the div variable is reassigned to the current item each time around the loop for added convenience.

+ +

The forEach() method, introduced in JavaScript 1.6, provides another way of iterating over an array:

+ +
var colors = ['red', 'green', 'blue'];
+colors.forEach(function(color) {
+  console.log(color);
+});
+
+ +

The function passed to forEach is executed once for every item in the array, with the array item passed as the argument to the function. Unassigned values are not iterated in a forEach loop.

+ +

Note that the elements of array omitted when the array is defined are not listed when iterating by forEach, but are listed when undefined has been manually assigned to the element:

+ +
var array = ['first', 'second', , 'fourth'];
+
+// returns ['first', 'second', 'fourth'];
+array.forEach(function(element) {
+  console.log(element);
+})
+
+if(array[2] === undefined) { console.log('array[2] is undefined'); } // true
+
+var array = ['first', 'second', undefined, 'fourth'];
+
+// returns ['first', 'second', undefined, 'fourth'];
+array.forEach(function(element) {
+  console.log(element);
+})
+ +

Since JavaScript elements are saved as standard object properties, it is not advisable to iterate through JavaScript arrays using for...in loops because normal elements and all enumerable properties will be listed.

+ +

Array Methods

+ +

The Array object has the following methods:

+ + + +

Compatibility code for older browsers can be found for each of these functions on the individual pages. Native browser support for these features in various browsers can be found here.

+ + + +

The methods above that take a callback are known as iterative methods, because they iterate over the entire array in some fashion. Each one takes an optional second argument called thisObject. If provided, thisObject becomes the value of the this keyword inside the body of the callback function. If not provided, as with other cases where a function is invoked outside of an explicit object context, this will refer to the global object (window).

+ +

The callback function is actually called with three arguments. The first is the value of the current item, the second is its array index, and the third is a reference to the array itself. JavaScript functions ignore any arguments that are not named in the parameter list so it is safe to provide a callback function that only takes a single argument, such as alert.

+ + + +

reduce and reduceRight are the least obvious of the iterative array methods. They should be used for algorithms that combine two values recursively in order to reduce a sequence down to a single value.

+ +

Multi-Dimensional Arrays

+ +

Arrays can be nested, meaning that an array can contain another array as an element. Using this characteristic of JavaScript arrays, multi-dimensional arrays can be created.

+ +

The following code creates a two-dimensional array.

+ +
var a = new Array(4);
+for (i = 0; i < 4; i++) {
+  a[i] = new Array(4);
+  for (j = 0; j < 4; j++) {
+    a[i][j] = "[" + i + "," + j + "]";
+  }
+}
+
+ +

This example creates an array with the following rows:

+ +
Row 0: [0,0] [0,1] [0,2] [0,3]
+Row 1: [1,0] [1,1] [1,2] [1,3]
+Row 2: [2,0] [2,1] [2,2] [2,3]
+Row 3: [3,0] [3,1] [3,2] [3,3]
+
+ +

Arrays and Regular Expressions

+ +

When an array is the result of a match between a regular expression and a string, the array returns properties and elements that provide information about the match. An array is the return value of RegExp.exec(), String.match(), and String.split(). For information on using arrays with regular expressions, see Regular Expressions.

+ +

Working with Array-like objects

+ +

Some JavaScript objects, such as the NodeList returned by document.getElementsByTagName() or the arguments object made available within the body of a function, look and behave like arrays on the surface but do not share all of their methods. The arguments object provides a length attribute but does not implement the forEach() method, for example.

+ +

Array generics, introduced in JavaScript 1.6, provide a way of running Array methods against other array-like objects. Each standard array method has a corresponding method on the Array object itself; for example:

+ +
 function alertArguments() {
+   Array.forEach(arguments, function(item) {
+     alert(item);
+   });
+ }
+
+ +

These generic methods can be emulated more verbosely in older versions of JavaScript using the call method provided by JavaScript function objects:

+ +
 Array.prototype.forEach.call(arguments, function(item) {
+   alert(item);
+ });
+
+ +

Array generic methods can be used on strings as well, since they provide sequential access to their characters in a similar way to arrays:

+ +
Array.forEach("a string", function(chr) {
+   alert(chr);
+});
+ +

Here are some further examples of applying array methods to strings, also taking advantage of JavaScript 1.8 expression closures:

+ +
var str = 'abcdef';
+var consonantsOnlyStr = Array.filter(str, function (c) !(/[aeiou]/i).test(c)).join(''); // 'bcdf'
+var vowelsPresent = Array.some(str, function (c) (/[aeiou]/i).test(c)); // true
+var allVowels = Array.every(str, function (c) (/[aeiou]/i).test(c)); // false
+var interpolatedZeros = Array.map(str, function (c) c+'0').join(''); // 'a0b0c0d0e0f0'
+var numerologicalValue = Array.reduce(str, function (c, c2) c+c2.toLowerCase().charCodeAt()-96, 0);
+// 21 (reduce() since JS v1.8)
+
+ +

Note that filter and map do not automatically return the characters back into being members of a string in the return result; an array is returned, so we must use join to return back to a string.

+ +

Array comprehensions

+ +

Introduced in JavaScript 1.7, array comprehensions provide a useful shortcut for constructing a new array based on the contents of another. Comprehensions can often be used in place of calls to map() and filter(), or as a way of combining the two.

+ +

The following comprehension takes an array of numbers and creates a new array of the double of each of those numbers.

+ +
var numbers = [1, 2, 3, 4];
+var doubled = [i * 2 for (i of numbers)];
+alert(doubled); // Alerts 2,4,6,8
+
+ +

This is equivalent to the following map() operation:

+ +
var doubled = numbers.map(function(i){return i * 2;});
+
+ +

Comprehensions can also be used to select items that match a particular expression. Here is a comprehension which selects only even numbers:

+ +
var numbers = [1, 2, 3, 21, 22, 30];
+var evens = [i for (i of numbers) if (i % 2 === 0)];
+alert(evens); // Alerts 2,22,30
+
+ +

filter() can be used for the same purpose:

+ +
var evens = numbers.filter(function(i){return i % 2 === 0;});
+
+ +

map() and filter() style operations can be combined into a single array comprehension. Here is one that filters just the even numbers, then creates an array containing their doubles:

+ +
var numbers = [1, 2, 3, 21, 22, 30];
+var doubledEvens = [i * 2 for (i of numbers) if (i % 2 === 0)];
+alert(doubledEvens); // Alerts 4,44,60
+
+ +

The square brackets of an array comprehension introduce an implicit block for scoping purposes. New variables (such as i in the example) are treated as if they had been declared using let. This means that they will not be available outside of the comprehension.

+ +

The input to an array comprehension does not itself need to be an array; iterators and generators can also be used.

+ +

Even strings may be used as input; to achieve the filter and map actions (under Array-like objects) above:

+ +
var str = 'abcdef';
+var consonantsOnlyStr = [c for (c of str) if (!(/[aeiouAEIOU]/).test(c))  ].join(''); // 'bcdf'
+var interpolatedZeros = [c+'0' for (c of str) ].join(''); // 'a0b0c0d0e0f0'
+
+ +

Again, the input form is not preserved, so we have to use join() to revert back to a string.

+ +

Boolean Object

+ +

The Boolean object is a wrapper around the primitive Boolean data type. Use the following syntax to create a Boolean object:

+ +
var booleanObjectName = new Boolean(value);
+
+ +

Do not confuse the primitive Boolean values true and false with the true and false values of the Boolean object. Any object whose value is not undefined , null, 0, NaN, or the empty string, including a Boolean object whose value is false, evaluates to true when passed to a conditional statement. See if...else Statement for more information.

+ +

Date Object

+ +

JavaScript does not have a date data type. However, you can use the Date object and its methods to work with dates and times in your applications. The Date object has a large number of methods for setting, getting, and manipulating dates. It does not have any properties.

+ +

JavaScript handles dates similarly to Java. The two languages have many of the same date methods, and both languages store dates as the number of milliseconds since January 1, 1970, 00:00:00.

+ +

The Date object range is -100,000,000 days to 100,000,000 days relative to 01 January, 1970 UTC.

+ +

To create a Date object:

+ +
var dateObjectName = new Date([parameters]);
+
+ +

where dateObjectName is the name of the Date object being created; it can be a new object or a property of an existing object.

+ +

Calling Date without the new keyword simply converts the provided date to a string representation.

+ +

The parameters in the preceding syntax can be any of the following:

+ + + +

JavaScript 1.2 and earlier
+ The Date object behaves as follows:

+ + + +

Methods of the Date Object

+ +

The Date object methods for handling dates and times fall into these broad categories:

+ + + +

With the "get" and "set" methods you can get and set seconds, minutes, hours, day of the month, day of the week, months, and years separately. There is a getDay method that returns the day of the week, but no corresponding setDay method, because the day of the week is set automatically. These methods use integers to represent these values as follows:

+ + + +

For example, suppose you define the following date:

+ +
var Xmas95 = new Date("December 25, 1995");
+
+ +

Then Xmas95.getMonth() returns 11, and Xmas95.getFullYear() returns 1995.

+ +

The getTime and setTime methods are useful for comparing dates. The getTime method returns the number of milliseconds since January 1, 1970, 00:00:00 for a Date object.

+ +

For example, the following code displays the number of days left in the current year:

+ +
var today = new Date();
+var endYear = new Date(1995, 11, 31, 23, 59, 59, 999); // Set day and month
+endYear.setFullYear(today.getFullYear()); // Set year to this year
+var msPerDay = 24 * 60 * 60 * 1000; // Number of milliseconds per day
+var daysLeft = (endYear.getTime() - today.getTime()) / msPerDay;
+var daysLeft = Math.round(daysLeft); //returns days left in the year
+
+ +

This example creates a Date object named today that contains today's date. It then creates a Date object named endYear and sets the year to the current year. Then, using the number of milliseconds per day, it computes the number of days between today and endYear, using getTime and rounding to a whole number of days.

+ +

The parse method is useful for assigning values from date strings to existing Date objects. For example, the following code uses parse and setTime to assign a date value to the IPOdate object:

+ +
var IPOdate = new Date();
+IPOdate.setTime(Date.parse("Aug 9, 1995"));
+
+ +

Using the Date Object: an Example

+ +

In the following example, the function JSClock() returns the time in the format of a digital clock.

+ +
function JSClock() {
+  var time = new Date();
+  var hour = time.getHours();
+  var minute = time.getMinutes();
+  var second = time.getSeconds();
+  var temp = "" + ((hour > 12) ? hour - 12 : hour);
+  if (hour == 0)
+    temp = "12";
+  temp += ((minute < 10) ? ":0" : ":") + minute;
+  temp += ((second < 10) ? ":0" : ":") + second;
+  temp += (hour >= 12) ? " P.M." : " A.M.";
+  return temp;
+}
+
+ +

The JSClock function first creates a new Date object called time; since no arguments are given, time is created with the current date and time. Then calls to the getHours, getMinutes, and getSeconds methods assign the value of the current hour, minute, and second to hour, minute, and second.

+ +

The next four statements build a string value based on the time. The first statement creates a variable temp, assigning it a value using a conditional expression; if hour is greater than 12, (hour - 12), otherwise simply hour, unless hour is 0, in which case it becomes 12.

+ +

The next statement appends a minute value to temp. If the value of minute is less than 10, the conditional expression adds a string with a preceding zero; otherwise it adds a string with a demarcating colon. Then a statement appends a seconds value to temp in the same way.

+ +

Finally, a conditional expression appends "P.M." to temp if hour is 12 or greater; otherwise, it appends "A.M." to temp.

+ +

Function Object

+ +

The predefined Function object specifies a string of JavaScript code to be compiled as a function.

+ +

To create a Function object:

+ +
var functionObjectName = new Function ([arg1, arg2, ... argn], functionBody);
+
+ +

functionObjectName is the name of a variable or a property of an existing object. It can also be an object followed by a lowercase event handler name, such as window.onerror.

+ +

arg1, arg2, ... argn are arguments to be used by the function as formal argument names. Each must be a string that corresponds to a valid JavaScript identifier; for example "x" or "theForm".

+ +

functionBody is a string specifying the JavaScript code to be compiled as the function body.

+ +

Function objects are evaluated each time they are used. This is less efficient than declaring a function and calling it within your code, because declared functions are compiled.

+ +

In addition to defining functions as described here, you can also use the function statement and the function expression. See the JavaScript Reference for more information.

+ +

The following code assigns a function to the variable setBGColor. This function sets the current document's background color.

+ +
var setBGColor = new Function("document.bgColor = 'antiquewhite'");
+
+ +

To call the Function object, you can specify the variable name as if it were a function. The following code executes the function specified by the setBGColor variable:

+ +
var colorChoice="antiquewhite";
+if (colorChoice=="antiquewhite") {setBGColor()}
+
+ +

You can assign the function to an event handler in either of the following ways:

+ +
    +
  1. +
    document.form1.colorButton.onclick = setBGColor;
    +
    +
  2. +
  3. +
    <INPUT NAME="colorButton" TYPE="button"
    +  VALUE="Change background color"
    +  onClick="setBGColor()">
    +
    +
  4. +
+ +

Creating the variable setBGColor shown above is similar to declaring the following function:

+ +
function setBGColor() {
+  document.bgColor = 'antiquewhite';
+}
+
+ +

Assigning a function to a variable is similar to declaring a function, but there are differences:

+ + + +

You can nest a function within a function. The nested (inner) function is private to its containing (outer) function:

+ + + +

Math Object

+ +

The predefined Math object has properties and methods for mathematical constants and functions. For example, the Math object's PI property has the value of pi (3.141...), which you would use in an application as

+ +
Math.PI
+
+ +

Similarly, standard mathematical functions are methods of Math. These include trigonometric, logarithmic, exponential, and other functions. For example, if you want to use the trigonometric function sine, you would write

+ +
Math.sin(1.56)
+
+ +

Note that all trigonometric methods of Math take arguments in radians.

+ +

The following table summarizes the Math object's methods.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 7.1 Methods of Math
MethodDescription
absAbsolute value
sin, cos, tanStandard trigonometric functions; argument in radians
acos, asin, atan, atan2Inverse trigonometric functions; return values in radians
exp, logExponential and natural logarithm, base e
ceilReturns least integer greater than or equal to argument
floorReturns greatest integer less than or equal to argument
min, maxReturns greater or lesser (respectively) of two arguments
powExponential; first argument is base, second is exponent
randomReturns a random number between 0 and 1.
roundRounds argument to nearest integer
sqrtSquare root
+ +

Unlike many other objects, you never create a Math object of your own. You always use the predefined Math object.

+ +

Number Object

+ +

The Number object has properties for numerical constants, such as maximum value, not-a-number, and infinity. You cannot change the values of these properties and you use them as follows:

+ +
var biggestNum = Number.MAX_VALUE;
+var smallestNum = Number.MIN_VALUE;
+var infiniteNum = Number.POSITIVE_INFINITY;
+var negInfiniteNum = Number.NEGATIVE_INFINITY;
+var notANum = Number.NaN;
+
+ +

You always refer to a property of the predefined Number object as shown above, and not as a property of a Number object you create yourself.

+ +

The following table summarizes the Number object's properties.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 7.2 Properties of Number
PropertyDescription
MAX_VALUEThe largest representable number
MIN_VALUEThe smallest representable number
NaNSpecial "not a number" value
NEGATIVE_INFINITYSpecial negative infinite value; returned on overflow
POSITIVE_INFINITYSpecial positive infinite value; returned on overflow
+ +

The Number prototype provides methods for retrieving information from Number objects in various formats. The following table summarizes the methods of Number.prototype.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 7.3 Methods of Number.prototype
MethodDescription
toExponentialReturns a string representing the number in exponential notation.
toFixedReturns a string representing the number in fixed-point notation.
toPrecisionReturns a string representing the number to a specified precision in fixed-point notation.
toSourceReturns an object literal representing the specified Number object; you can use this value to create a new object. Overrides the Object.toSource method.
toStringReturns a string representing the specified object. Overrides the Object.toString method.
valueOfReturns the primitive value of the specified object. Overrides the Object.valueOf method.
+ +

RegExp Object

+ +

The RegExp object lets you work with regular expressions. It is described in Regular Expressions.

+ +

String Object

+ +

The String object is a wrapper around the string primitive data type. Do not confuse a string literal with the String object. For example, the following code creates the string literal s1 and also the String object s2:

+ +
var s1 = "foo"; //creates a string literal value
+var s2 = new String("foo"); //creates a String object
+
+ +

You can call any of the methods of the String object on a string literal value—JavaScript automatically converts the string literal to a temporary String object, calls the method, then discards the temporary String object. You can also use the String.length property with a string literal.

+ +

You should use string literals unless you specifically need to use a String object, because String objects can have counterintuitive behavior. For example:

+ +
var s1 = "2 + 2"; //creates a string literal value
+var s2 = new String("2 + 2"); //creates a String object
+eval(s1); //returns the number 4
+eval(s2); //returns the string "2 + 2"
+ +

A String object has one property, length, that indicates the number of characters in the string. For example, the following code assigns x the value 13, because "Hello, World!" has 13 characters:

+ +
var mystring = "Hello, World!";
+var x = mystring.length;
+
+ +

A String object has two types of methods: those that return a variation on the string itself, such as substring and toUpperCase, and those that return an HTML-formatted version of the string, such as bold and link.

+ +

For example, using the previous example, both mystring.toUpperCase() and "hello, world!".toUpperCase() return the string "HELLO, WORLD!"

+ +

The substring method takes two arguments and returns a subset of the string between the two arguments. Using the previous example, mystring.substring(4, 9) returns the string "o, Wo". See the substring method of the String object in the JavaScript Reference for more information.

+ +

The String object also has a number of methods for automatic HTML formatting, such as bold to create boldface text and link to create a hyperlink. For example, you could create a hyperlink to a hypothetical URL with the link method as follows:

+ +
mystring.link("http://www.helloworld.com")
+
+ +

The following table summarizes the methods of String objects.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 7.4 Methods of String Instances
MethodDescription
anchorCreates HTML named anchor.
big, blink, bold, fixed, italics, small, strike, sub, supCreate HTML formatted string.
charAt, charCodeAtReturn the character or character code at the specified position in string.
indexOf, lastIndexOfReturn the position of specified substring in the string or last position of specified substring, respectively.
linkCreates HTML hyperlink.
concatCombines the text of two strings and returns a new string.
fromCharCodeConstructs a string from the specified sequence of Unicode values. This is a method of the String class, not a String instance.
splitSplits a String object into an array of strings by separating the string into substrings.
sliceExtracts a section of an string and returns a new string.
substring, substrReturn the specified subset of the string, either by specifying the start and end indexes or the start index and a length.
match, replace, searchWork with regular expressions.
toLowerCase, toUpperCase +

Return the string in all lowercase or all uppercase, respectively.

+
+ +

autoPreviousNext("JSGChapters")

diff --git a/files/ru/conflicting/web/javascript/guide/introduction/index.html b/files/ru/conflicting/web/javascript/guide/introduction/index.html new file mode 100644 index 0000000000..6d58fafb80 --- /dev/null +++ b/files/ru/conflicting/web/javascript/guide/introduction/index.html @@ -0,0 +1,159 @@ +--- +title: Об этом учебнике +slug: Web/JavaScript/Guide/About +translation_of: Web/JavaScript/Guide/Introduction +translation_of_original: Web/JavaScript/Guide/About +--- +

JavaScript это кросс-платформенный, объектно-ориентированный интерпретируемый язык программирования. В этом учебнике описано все, что вам нужно знать для того, чтобы начать ипользовать JavaScript.

+ +

Особенности разных версий JavaScript

+ +

 

+ + + +

 

+ +

Что вы уже должны знать

+ +

Этот учебник предполагает, что у вас уже имеются некоторые знания и опыт:

+ +

Общее понимание, что такое Интернет и всемирная сеть WWW. Знание языка разметки гипертекста (HTML) также привествуется.

+ +

Некоторый опыт программирования на C или Visual Basic будет полезен, но не является обязательным.

+ +

Версии JavaScript

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Таблица 1. Версии JavaScript и Navigator
Версия JavaScriptВерсия Navigator
JavaScript 1.0Navigator 2.0
JavaScript 1.1Navigator 3.0
JavaScript 1.2Navigator 4.0-4.05
JavaScript 1.3Navigator 4.06-4.7x
JavaScript 1.4 
JavaScript 1.5Navigator 6.0
+ Mozilla (браузер с открытым исходным кодом)
JavaScript 1.6Firefox 1.5, другие, основанные на Mozilla 1.8 продукты
JavaScript 1.7Firefox 2, другие, основанные на Mozilla 1.8.1 продукты
JavaScript 1.8Firefox 3, другие, основанные на Mozilla 1.9 продукты
+ +

Каждая версия Netscape Enterprise Server также поддерживает разные версии JavaScript. Чтобы помочь вам писать скрипты совместимые с разными версиями Enterprise Server, это руководство пользуется аббревиатурой, которая однозначно идентифицирует версию сервера, в которой реализована каждая функциональность.

+ +


+  Таблица 2. Аббревиатуры версий Netscape Enterprise Server

+ + + + + + + + + + + + + + + + + + +
AbbreviationEnterprise Server version
NES 2.0Netscape Enterprise Server 2.0
NES 3.0Netscape Enterprise Server 3.0
+ +

Где найти информацию по JavaScript

+ +

Документация JavaScript включает в себя следующие материалы:

+ + + +

Если вы новичок в JavaScript, то начните с Учебника JavaScript. Как только вы усвоили фундаментальные основы, вы можете начать пользоваться Справочником JavaScript, чтобы получить больше информации об определенных объектах, выражениях и операторах.

+ +

Советы изучающим JavaScript

+ +

Начать изучать JavaScript очень легко: все что вам нужно - это современный веб браузер. Этот учебник включает описание некоторых особенностей JavaScript, которые доступны только в самых последних версиях Firefox (и других браузерах основанных на движке Gecko), так что лучше всего воспользоваться самой последней версией Firefox.

+ +

Интерактивный интерпретатор.

+ +

Интерактивная строка ввода JavaScript окажет бесценную услугу в изучении языка, так как позволит пробовать все вещи сразу же, вам не потребуется сохранять изменения в файле и обновлять страницу каждый раз. Консоль ошибок Firefox, доступна через меню Инструменты, предлагает простой способ попробовать выполнить JavaScript выражения: просто введите строку с кодом и нажмите кнопку "Evaluate".

+ +

Image:ErrorConsole.png

+ +

Firebug

+ +

Более продвинутое средство доступно в Firebug. Firebug это расширение Firefox. Хотя в последних версиях Firefox средства отладки становятся более совершенными и такой нужды Firebug уже нет. Выражения которые вы вводите интерпретируются как объекты и связываются c другими частями в Firebug. Например, вы можете сложить 5 плюс 5, заменить буквы в строке со строчных на прописные, получить кликабельную ссылку на документ, или получить ссылку на элемент в документе:

+ +

+ +

Нажав на кнопке со стрелкой в нижнем правом углу вы можете открыть многострочный редактор скриптов.

+ +

Firebug также имеет в составе продвинутый инспектор DOM, дебаггер JavaScript, инструменты профилирования и многие другие полезные утилиты. JavaScript код выполняемый на веб странице может вызвать функцию console.log(), которая выведет свой аргумент на консоль Firebug.

+ +

Множество примеров в этом учебнике используют функцию alert(), чтобы вывести сообщение во время выполнения скрипта.

+ +

Принятые соглашения в документе

+ +

JavaScript приложения выполняются на разных операционных системах; информация в этом учебнике актуальна в любом случае. Пути к директориям или файлам даны в формате Windows (обратный слеш как разделитель). Для версии Юникс, пути точно такие же, за исключением того, что используеся обычный слеш вместо обратного, а также соотвественно корневая директория начинается с '/' а не 'c:/' как это в Windows.

+ +

Этот учебник использует единый локатор ресурсов (URL-ы) следующей формы:

+ +

http://server.domain/path/file.html

+ +

В этих URL-ах, server - это имя сервера на котором запущено ваше приложение, например research1 или www; domain - это имя Internet домена, например netscape.com или uiuc.edu; path - структура директорий на сервере; и file.html - имя файла, который расположен на вашем сервере. В общем, элементы выделенные курсивом в URL-ах это метки-заполнители, а элементы выделенные нормальным моноширинным шрифтом точные неизменные значения (например, конфиругацию сервера вы можете изменить, как и сменить доменное имя, структура каталогов может поменяться, а вот протокол всегда один, и расширение файла для  вебстраниц тоже постоянно). Если ваш вебсервер поддерживает Secure Sockets Layer (SSL), то вы можете пользоваться  https вместо http в URL.

+ +

Этот учебник пользуется следующим соглашением об использовании шрифтов:

+ + diff --git a/files/ru/conflicting/web/javascript/guide/introduction_6f341ba6db4b060ccbd8dce4a0d5214b/index.html b/files/ru/conflicting/web/javascript/guide/introduction_6f341ba6db4b060ccbd8dce4a0d5214b/index.html new file mode 100644 index 0000000000..5db1f95ca4 --- /dev/null +++ b/files/ru/conflicting/web/javascript/guide/introduction_6f341ba6db4b060ccbd8dce4a0d5214b/index.html @@ -0,0 +1,142 @@ +--- +title: Обзор JavaScript +slug: Web/JavaScript/Guide/JavaScript_Overview +translation_of: Web/JavaScript/Guide/Introduction +translation_of_original: Web/JavaScript/Guide/JavaScript_Overview +--- +

Эта глава является введением в JavaScript и описывает некоторые из базовых понятий.

+ +

Что такое JavaScript?

+ +

JavaScript это кросс-платформенный, объектно-ориентированный, скриптовый язык. JavaScript - это маленький и легковесный язык; он спроектирован не для создания законченных, полноценных приложений,  а для легкого встраивания в другие продукты и приложения, например, в веб браузеры. Внутри основного приложения, JavaScript может соединяться с объектами этого приложения и осуществлять программный контроль над ними.

+ +

Ядро JavaScript содержит набор базовых объектов, например Array, Date и Math, и набор элементов языка: операторов, управляющих структур, и выражений. Ядро JavaScript может быть расширено для различных целей с помощью дополнений, например:

+ + + +

Используя функции JavaScript LiveConnect, Вы можете позволить коду на Java и JavaScript общаться между собой. Вы можете создать экземпляр объекта Java из JavaScript и получить доступ к его публичным методам и свойствам. Из Java, Вы можете получить доступ к объектам, свойствам и методам JavaScript.

+ +

Впервые JavaScript был использован в браузерах Netscape.

+ +

JavaScript и Java

+ +

JavaScript и Java схожи в некоторых отношениях, но принципиально отличаются в других. Язык JavaScript напоминает Java, но не имеет статической типизации и строгой проверки типов. В основном, JavaScript следует большей части синтакса Java в выражениях, именованиях и основного потока управления конструкциями, что стало причиной, почему он был переименован из LiveScript в JavaScript.

+ +

В отличии от системы компилированных классов в Java, построенной на объявлениях, JavaScript поддерживает систему исполнения, основанную на небольшом количестве типов данных, представляющих числовые, логические и строковые значения. JavaScript обладает моделью объектов на базе прототипов вместо более общей модели объектов на базе классов. Модель объектов на базе прототипов делает возможным динамическое наследование; то есть, то, что унаследовано, может различаться для отдельных объектов. JavaScript также поддерживает функции без каких-либо специальных декларативных требований. Функции могут быть свойствами объектов, выполняться как слабо типизированные методы.

+ +

По сравнению с Java, JavaScript - это язык с очень свободной формой языка. Вам не надо объявлять переменные, классы или методы. Вы не должны беспокоиться, является ли метод public, private или protected, Вам не надо реализовывать интерфейсы. Переменные, параметры и возвращаемые функциями типы не являются явно типизированными.

+ +

Java - язык программирования на основе классов, предназначенный для быстрого выполнения и безопасности типов. Безопасность типов означает, например, что Вы не можете взять тип Java integer и привести его к типу object reference или получить доступ к закрытой памяти изменяя байт-код Java. Ориентированная на классы модель Java означает, что программы состоят исключительно из классов и их методов. Наследование классов и строгая типизация в Java обычно тербуют тесно связанную иерархию объектов. Эти требования делают программирование на Java более сложным чем на JavaScript.

+ +

По духу JavaScript происходит от нескольких небольших, динамически типизированных языков программирования, таких как HyperTalk и dBASE. Эти скриптовые языки предлагают инструменты программирования для гораздо более широкой аудитории благодаря более простому синтаксису, специальной встроенной функциональности и минимальным требованиям для создания объектов.

+ + + + + + + + + + + + + + + + + + + + + + + +
Таблица 1.1 Сравнение JavaScript и Java
JavaScriptJava
Объектно-ориентированный. Нет различий между типами объектов. Наследование реализовано через механизм прототипов, свойства и методы могут быть динамически добавлены к любому объекту.На базе классов. Объекты делятся на классы и экземпляры с наследованием через иерархию классов. Классы и экземпляры не могут иметь динамически добавленные свойства и методы.
Типы данных переменных не объявлены (динамическая типизация).Типы данных переменных должны быть объявлены (статическая типизация).
Не может автоматически записывать на жесткий диск.Может автоматически записывать на жесткий диск.
+ +

Для получения дополнительной информации о различиях между JavaScript и Java, см. раздел Details of the Object Model.

+ +

JavaScript and the ECMAScript Specification

+ +

Netscape invented JavaScript, and JavaScript was first used in Netscape browsers. However, Netscape is working with Ecma International — the European association for standardizing information and communication systems (ECMA was formerly an acronym for the European Computer Manufacturers Association) to deliver a standardized, international programming language based on core JavaScript. This standardized version of JavaScript, called ECMAScript, behaves the same way in all applications that support the standard. Companies can use the open standard language to develop their implementation of JavaScript. The ECMAScript standard is documented in the ECMA-262 specification.

+ +

The ECMA-262 standard is also approved by the ISO (International Organization for Standardization) as ISO-16262. You can find a PDF version of ECMA-262 (outdated version) at the Mozilla website. You can also find the specification on the Ecma International website. The ECMAScript specification does not describe the Document Object Model (DOM), which is standardized by the World Wide Web Consortium (W3C). The DOM defines the way in which HTML document objects are exposed to your script.

+ +

Relationship between JavaScript Versions and ECMAScript Editions

+ +

Netscape worked closely with Ecma International to produce the ECMAScript Specification (ECMA-262). The following table describes the relationship between JavaScript versions and ECMAScript editions.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 1.2 JavaScript versions and ECMAScript editions
JavaScript versionRelationship to ECMAScript edition
JavaScript 1.1ECMA-262, Edition 1 is based on JavaScript 1.1.
JavaScript 1.2ECMA-262 was not complete when JavaScript 1.2 was released. JavaScript 1.2 is not fully compatible with ECMA-262, Edition 1, for the following reasons: +
    +
  • Netscape developed additional features in JavaScript 1.2 that were not considered for ECMA-262.
  • +
  • ECMA-262 adds two new features: internationalization using Unicode, and uniform behavior across all platforms. Several features of JavaScript 1.2, such as the Date object, were platform-dependent and used platform-specific behavior.
  • +
+
+

JavaScript 1.3

+
+

JavaScript 1.3 is fully compatible with ECMA-262, Edition 1.

+ +

JavaScript 1.3 resolved the inconsistencies that JavaScript 1.2 had with ECMA-262, while keeping all the additional features of JavaScript 1.2 except == and !=, which were changed to conform with ECMA-262.

+
+

JavaScript 1.4

+
+

JavaScript 1.4 is fully compatible with ECMA-262, Edition 1.

+ +

The third version of the ECMAScript specification was not finalized when JavaScript 1.4 was released.

+
JavaScript 1.5JavaScript 1.5 is fully compatible with ECMA-262, Edition 3.
+ +
Note: ECMA-262, Edition 2 consisted of minor editorial changes and bug fixes to the Edition 1 specification. The  current release by the TC39 working group of Ecma International is ECMAScript Edition 5.1
+ +

The JavaScript Reference indicates which features of the language are ECMAScript-compliant.

+ +

JavaScript will always include features that are not part of the ECMAScript Specification; JavaScript is compatible with ECMAScript, while providing additional features.

+ +

JavaScript Documentation versus the ECMAScript Specification

+ +

The ECMAScript specification is a set of requirements for implementing ECMAScript; it is useful if you want to determine whether a JavaScript feature is supported in other ECMAScript implementations. If you plan to write JavaScript code that uses only features supported by ECMAScript, then you may need to review the ECMAScript specification.

+ +

The ECMAScript document is not intended to help script programmers; use the JavaScript documentation for information on writing scripts.

+ +

JavaScript and ECMAScript Terminology

+ +

The ECMAScript specification uses terminology and syntax that may be unfamiliar to a JavaScript programmer. Although the description of the language may differ in ECMAScript, the language itself remains the same. JavaScript supports all functionality outlined in the ECMAScript specification.

+ +

The JavaScript documentation describes aspects of the language that are appropriate for a JavaScript programmer. For example:

+ + diff --git a/files/ru/conflicting/web/javascript/reference/global_objects/boolean/index.html b/files/ru/conflicting/web/javascript/reference/global_objects/boolean/index.html new file mode 100644 index 0000000000..f0188080f1 --- /dev/null +++ b/files/ru/conflicting/web/javascript/reference/global_objects/boolean/index.html @@ -0,0 +1,113 @@ +--- +title: Boolean.prototype +slug: Web/JavaScript/Reference/Global_Objects/Boolean/prototype +tags: + - Boolean + - JavaScript + - Property + - Prototype +translation_of: Web/JavaScript/Reference/Global_Objects/Boolean +translation_of_original: Web/JavaScript/Reference/Global_Objects/Boolean/prototype +--- +
{{JSRef("Global_Objects", "Boolean")}}
+ +

Сводка

+

Свойство Boolean.prototype представляет прототип конструктора объекта {{jsxref("Global_Objects/Boolean", "Boolean")}}.

+ +
{{js_property_attributes(0, 0, 0)}}
+ +

Описание

+

Экземпляры объекта {{jsxref("Global_Objects/Boolean", "Boolean")}} наследуются от Boolean.prototype. Вы можете использовать протитип конструктора объекта для добавления свойств или методов ко всем экземплярам объекта {{jsxref("Global_Objects/Boolean", "Boolean")}}.

+ +

Свойства

+
+
Boolean.prototype.constructor
+
Возвращает функцию, создающую экземпляр прототипа. По умолчанию, это функция {{jsxref("Global_Objects/Boolean", "Boolean")}}.
+
+
{{jsOverrides("Object", "properties", "constructor")}}
+ +

Методы

+
+
{{jsxref("Boolean.prototype.toSource()")}} {{non-standard_inline}}
+
Возвращает строку, содержащую исходный код объекта {{jsxref("Global_Objects/Boolean", "Boolean")}}; вы можете использовать эту строку для создания эквивалентного объекта. Переопределяет метод {{jsxref("Object.prototype.toSource()")}}.
+
{{jsxref("Boolean.prototype.toString()")}}
+
Возвращает строку "true" или "false", в зависимости от значения объекта. Переопределяет метод {{jsxref("Object.prototype.toString()")}}.
+
{{jsxref("Boolean.prototype.valueOf()")}}
+
Возвращает примитивное значение объекта {{jsxref("Global_Objects/Boolean", "Boolean")}}. Переопределяет метод {{jsxref("Object.prototype.valueOf()")}}.
+
+
{{jsOverrides("Object", "methods", "toSource", "toString", "valueOf")}}
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарии
ECMAScript 1-е издание.СтандартИзначальное определение. Реализована в JavaScript 1.0.
{{SpecName('ES5.1', '#sec-15.6.3.1', 'Boolean.prototype')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-boolean.prototype', 'Boolean.prototype')}}{{Spec2('ES6')}} 
+ +

Совместимость с браузерами

+
{{CompatibilityTable}}
+
+ + + + + + + + + + + + + + + + + + + +
ВозможностьChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
ВозможностьAndroidChrome для AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
diff --git a/files/ru/conflicting/web/javascript/reference/global_objects/date/index.html b/files/ru/conflicting/web/javascript/reference/global_objects/date/index.html new file mode 100644 index 0000000000..956a7555a1 --- /dev/null +++ b/files/ru/conflicting/web/javascript/reference/global_objects/date/index.html @@ -0,0 +1,229 @@ +--- +title: Date.prototype +slug: Web/JavaScript/Reference/Global_Objects/Date/prototype +tags: + - Date + - JavaScript + - Property + - Prototype + - Reference + - Référence(2) +translation_of: Web/JavaScript/Reference/Global_Objects/Date +translation_of_original: Web/JavaScript/Reference/Global_Objects/Date/prototype +--- +
{{JSRef("Global_Objects", "Date")}}
+ +

Сводка

+ +

Свойство Date.prototype представляет прототип конструктора {{jsxref("Global_Objects/Date", "Date")}}.

+ +
{{js_property_attributes(0, 0, 1)}}
+ +

Описание

+ +

Все экземпляры {{jsxref("Global_Objects/Date", "Date")}} наследуются от Date.prototype. Объект прототипа конструктора {{jsxref("Global_Objects/Date", "Date")}} может быть изменён для затрагивания всех экземпляров объекта {{jsxref("Global_Objects/Date", "Date")}}.

+ +

Для совместимости с вычислениями тысячелетия (другими словами, для учёта 2000 года), вы всегда должны указывать полный год; например, использовать число 1998, а не 98. Чтобы помочь вам определить полный год, JavaScript включает методы {{jsxref("Date.prototype.getFullYear()", "getFullYear()")}}, {{jsxref("Date.prototype.setFullYear()", "setFullYear()")}}, {{jsxref("Date.prototype.getUTCFullYear()", "getUTCFullYear()")}} и {{jsxref("Date.prototype.setUTCFullYear()", "setUTCFullYear()")}}.

+ +

Свойства

+ +
+
Date.prototype.constructor
+
Возвращает функцию, создавшую этот экземпляр объекта. По умолчанию ей является объект {{jsxref("Global_Objects/Date", "Date")}}.
+
+ +
{{jsOverrides("Object", "properties", "constructor")}}
+ +

Методы

+ +

Получения значения

+ +
+
{{jsxref("Date.prototype.getDate()")}}
+
Возвращает день месяца (1-31) указанной даты по местному времени.
+
{{jsxref("Date.prototype.getDay()")}}
+
Возвращает день недели (0-6) указанной даты по местному времени.
+
{{jsxref("Date.prototype.getFullYear()")}}
+
Возвращает год (4 цифры для 4-х значного года) указанной даты по местному времени.
+
{{jsxref("Date.prototype.getHours()")}}
+
Возвращает часы (0-23) указанной даты по местному времени.
+
{{jsxref("Date.prototype.getMilliseconds()")}}
+
Возвращает миллисекунды (0-999) указанной даты по местному времени.
+
{{jsxref("Date.prototype.getMinutes()")}}
+
Возвращает минуты (0-59) указанной даты по местному времени.
+
{{jsxref("Date.prototype.getMonth()")}}
+
Возвращает месяц (0-11) указанной даты по местному времени.
+
{{jsxref("Date.prototype.getSeconds()")}}
+
Возвращает секунды (0-59) указанной даты по местному времени.
+
{{jsxref("Date.prototype.getTime()")}}
+
Возвращает числовое значение указанной даты как количество миллисекунд, прошедших с 1 января 1970 года 00:00:00 по UTC (отрицательное значение для даты до этого момента).
+
{{jsxref("Date.prototype.getTimezoneOffset()")}}
+
Возвращает смещение часового пояса в минутах для текущей локали.
+
{{jsxref("Date.prototype.getUTCDate()")}}
+
Возвращает день месяца (1-31) указанной даты по всемирному координированному времени.
+
{{jsxref("Date.prototype.getUTCDay()")}}
+
Возвращает день недели (0-6) указанной даты по всемирному координированному времени.
+
{{jsxref("Date.prototype.getUTCFullYear()")}}
+
Возвращает год (4 цифры для 4-х значного года) указанной даты по всемирному координированному времени.
+
{{jsxref("Date.prototype.getUTCHours()")}}
+
Возвращает часы (0-23) указанной даты по всемирному координированному времени.
+
{{jsxref("Date.prototype.getUTCMilliseconds()")}}
+
Возвращает миллисекунды (0-999) указанной даты по всемирному координированному времени.
+
{{jsxref("Date.prototype.getUTCMinutes()")}}
+
Возвращает минуты (0-59) указанной даты по всемирному координированному времени.
+
{{jsxref("Date.prototype.getUTCMonth()")}}
+
Возвращает месяц (0-11) указанной даты по всемирному координированному времени.
+
{{jsxref("Date.prototype.getUTCSeconds()")}}
+
Возвращает секунды (0-59) указанной даты по всемирному координированному времени.
+
{{jsxref("Date.prototype.getYear()")}} {{deprecated_inline}}
+
Возвращает год (обычно 2-3 цифры) указанной даты по всемирному координированному времени. Вместо него используйте метод {{jsxref("Date.prototype.getFullYear()", "getFullYear()")}}.
+
+ +

Установки значения

+ +
+
{{jsxref("Date.prototype.setDate()")}}
+
Устанавливает день месяца указанной даты по местному времени.
+
{{jsxref("Date.prototype.setFullYear()")}}
+
Устанавливает полный год (4 цифры для 4-х значного года) указанной даты по местному времени.
+
{{jsxref("Date.prototype.setHours()")}}
+
Устанавливает часы указанной даты по местному времени.
+
{{jsxref("Date.prototype.setMilliseconds()")}}
+
Устанавливает миллисекунды указанной даты по местному времени.
+
{{jsxref("Date.prototype.setMinutes()")}}
+
Устанавливает минуты указанной даты по местному времени.
+
{{jsxref("Date.prototype.setMonth()")}}
+
Устанавливает месяц указанной даты по местному времени.
+
{{jsxref("Date.prototype.setSeconds()")}}
+
Устанавливает секунды указанной даты по местному времени.
+
{{jsxref("Date.prototype.setTime()")}}
+
Устанавливает объект {{jsxref("Global_Objects/Date", "Date")}} во время, представляемое количеством миллисекунд, прошедших с 1 января 1970 года 00:00:00 по UTC (отрицательное значение устанавливает даты до этого момента).
+
{{jsxref("Date.prototype.setUTCDate()")}}
+
Устанавливает день месяца указанной даты по всемирному координированному времени.
+
{{jsxref("Date.prototype.setUTCFullYear()")}}
+
Устанавливает полный год (4 цифры для 4-х значного года) указанной даты по всемирному координированному времени.
+
{{jsxref("Date.prototype.setUTCHours()")}}
+
Устанавливает часы указанной даты по всемирному координированному времени.
+
{{jsxref("Date.prototype.setUTCMilliseconds()")}}
+
Устанавливает миллисекунды указанной даты по всемирному координированному времени.
+
{{jsxref("Date.prototype.setUTCMinutes()")}}
+
Устанавливает минуты указанной даты по всемирному координированному времени.
+
{{jsxref("Date.prototype.setUTCMonth()")}}
+
Устанавливает месяц указанной даты по всемирному координированному времени.
+
{{jsxref("Date.prototype.setUTCSeconds()")}}
+
Устанавливает секунды указанной даты по всемирному координированному времени.
+
{{jsxref("Date.prototype.setYear()")}} {{deprecated_inline}}
+
Устанавливает год (обычно 2-3 цифры) указанной даты по всемирному координированному времени. Вместо него используйте метод {{jsxref("Date.prototype.setFullYear()", "setFullYear()")}}.
+
+ +

Получения преобразованного значения

+ +
+
{{jsxref("Date.prototype.toDateString()")}}
+
Возвращает часть, содержащую только дату объекта {{jsxref("Global_Objects/Date", "Date")}} в качестве человеко-читаемой строки.
+
{{jsxref("Date.prototype.toISOString()")}}
+
Преобразует дату в строку, следуя расширенному формату ISO 8601.
+
{{jsxref("Date.prototype.toJSON()")}}
+
Возвращает строку, представляющую объект {{jsxref("Global_Objects/Date", "Date")}}, используя метод {{jsxref("Date.prototype.toISOString()", "toISOString()")}}. Предназначен для использования методом {{jsxref("JSON.stringify()")}}.
+
{{jsxref("Date.prototype.toGMTString()")}} {{deprecated_inline}}
+
Возвращает строку, представляющую объект {{jsxref("Global_Objects/Date", "Date")}}, на основе часового пояса GMT (всемирное время). Вместо него используйте метод {{jsxref("Date.prototype.toUTCString()", "toUTCString()")}}.
+
{{jsxref("Date.prototype.toLocaleDateString()")}}
+
Возвращает строку с датой, чьё представление зависит от системных настроек локали.
+
{{jsxref("Date.prototype.toLocaleFormat()")}} {{non-standard_inline}}
+
Преобразует дату в строку, используя строку форматирования.
+
{{jsxref("Date.prototype.toLocaleString()")}}
+
Возвращает строку, чьё представление зависит от настроек локали. Переопределяет метод {{jsxref("Object.prototype.toLocaleString()")}}.
+
{{jsxref("Date.prototype.toLocaleTimeString()")}}
+
Возвращает строку со временем, чьё представление зависит от системных настроек локали.
+
{{jsxref("Date.prototype.toSource()")}} {{non-standard_inline}}
+
Возвращает строковое представление исходного кода эквивалентного объекта {{jsxref("Global_Objects/Date", "Date")}}; вы можете использовать это значение для создания нового объекта. Переопределяет метод {{jsxref("Object.prototype.toSource()")}}.
+
{{jsxref("Date.prototype.toString()")}}
+
Возвращает строковое представление указанного объекта {{jsxref("Global_Objects/Date", "Date")}}. Переопределяет метод {{jsxref("Object.prototype.toString()")}}.
+
{{jsxref("Date.prototype.toTimeString()")}}
+
Возвращает часть, содержащую только время объекта {{jsxref("Global_Objects/Date", "Date")}} в качестве человеко-читаемой строки.
+
{{jsxref("Date.prototype.toUTCString()")}}
+
Преобразует дату в строку, используя часовой пояс UTC.
+
{{jsxref("Date.prototype.valueOf()")}}
+
Возвращает примитивное значение объекта {{jsxref("Global_Objects/Date", "Date")}}. Переопределяет метод {{jsxref("Object.prototype.valueOf()")}}.
+
+ +
{{jsOverrides("Object", "methods", "getDate", "getDay", "getFullYear", "getHours", "getMilliseconds", "getMinutes", "getMonth", "getSeconds", "getTime", "getTimezoneOffset", "getUTCDate", "getUTCDay", "getUTCFullYear", "getUTCHours", "getUTCMilliseconds", "getUTCMinutes", "getUTCMonth", "getUTCSeconds", "getYear", "setdate", "setFullYear", "setHours", "setMilliseconds", "setMinutes", "setMontth", "setSeconds", "setTime", "setUTCDate", "setUTCFullYear", "setUTCHours", "setUTCMilliseconds", "setUTCMinutes", "setUTCMonth", "setUTCSeconds", "setYear", "toDateString", "toGMTString", "toLocaleDateString", "toLocaleFormat", "toLocaleString", "toLocaleTimeString", "toSource", "toString", "toTimeString", "toUTCString", "valueOf")}}
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарии
ECMAScript 1-е издание.СтандартИзначальное определение. Реализована в JavaScript 1.1.
{{SpecName('ES5.1', '#sec-15.9.5', 'Date.prototype')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-properties-of-the-date-prototype-object', 'Date.prototype')}}{{Spec2('ES6')}}
+ +

Совместимость с браузерами

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
ВозможностьChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
ВозможностьAndroidChrome для AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
diff --git a/files/ru/conflicting/web/javascript/reference/global_objects/error/index.html b/files/ru/conflicting/web/javascript/reference/global_objects/error/index.html new file mode 100644 index 0000000000..668277c4e0 --- /dev/null +++ b/files/ru/conflicting/web/javascript/reference/global_objects/error/index.html @@ -0,0 +1,155 @@ +--- +title: Error.prototype +slug: Web/JavaScript/Reference/Global_Objects/Error/prototype +tags: + - Error + - JavaScript + - Property +translation_of: Web/JavaScript/Reference/Global_Objects/Error +translation_of_original: Web/JavaScript/Reference/Global_Objects/Error/prototype +--- +
{{JSRef("Global_Objects", "Error", "EvalError,InternalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError")}}
+ +

Сводка

+ +

Свойство Error.prototype представляет прототип конструктора объекта {{jsxref("Global_Objects/Error", "Error")}}.

+ +
{{js_property_attributes(0, 0, 0)}}
+ +

Описание

+ +

Все экземпляры {{jsxref("Global_Objects/Error", "Error")}} и экземпляры {{jsxref("Global_Objects/Error", "неуниверсальных ошибок", "#Error_types", 1)}} наследуются от Error.prototype. Как и со всеми функциями-конструкторами, вы можете использовать прототип конструктора для добавления свойств и методов ко всем экземплярам, создаваемым этим конструктором.

+ +

Свойства

+ +

Стандартные свойства

+ +
+
Error.prototype.constructor
+
Определяет функцию, создающую прототип экземпляра ошибки.
+
{{jsxref("Error.prototype.message")}}
+
Сообщение ошибки.
+
{{jsxref("Error.prototype.name")}}
+
Название ошибки.
+
+ +

Расширения вендоров

+ +
{{non-standard_header}}
+ +

Microsoft

+ +
+
{{jsxref("Error.prototype.description")}}
+
Описание ошибки. Аналогично свойству {{jsxref("Error.prototype.message", "message")}}.
+
{{jsxref("Error.prototype.number")}}
+
Номер ошибки.
+
+ +

Mozilla

+ +
+
{{jsxref("Error.prototype.fileName")}}
+
Путь к файлу, в котором возникла эта ошибка.
+
{{jsxref("Error.prototype.lineNumber")}}
+
Номер строки в файле, в котором возникла эта ошибка.
+
{{jsxref("Error.prototype.columnNumber")}}
+
Номер колонки в строке, на которой возникла эта ошибка.
+
{{jsxref("Error.prototype.stack")}}
+
Стек вызовов.
+
+ +

Методы

+ +
+
{{jsxref("Error.prototype.toSource()")}} {{non-standard_inline}}
+
Возвращает строку, содержащую исходный код указанного объекта {{jsxref("Global_Objects/Error", "Error")}}; вы можете использовать это значение для создания нового объекта. Переопределяет метод {{jsxref("Object.prototype.toSource()")}}.
+
{{jsxref("Error.prototype.toString()")}}
+
Возвращает строку, представляющую указанный объект. Переопределяет метод {{jsxref("Object.prototype.toString()")}}.
+
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарии
ECMAScript 1-е издание.СтандартИзначальное определение. Реализована в JavaScript 1.1.
{{SpecName('ES5.1', '#sec-15.11.3.1', 'Error')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-error.prototype', 'Error')}}{{Spec2('ES6')}} 
+ +

Совместимость с браузерами

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
ВозможностьChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
ВозможностьAndroidChrome для AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

Смотрите также

+ + diff --git a/files/ru/conflicting/web/javascript/reference/global_objects/evalerror/index.html b/files/ru/conflicting/web/javascript/reference/global_objects/evalerror/index.html new file mode 100644 index 0000000000..e7de1a018e --- /dev/null +++ b/files/ru/conflicting/web/javascript/reference/global_objects/evalerror/index.html @@ -0,0 +1,122 @@ +--- +title: EvalError.prototype +slug: Web/JavaScript/Reference/Global_Objects/EvalError/prototype +tags: + - Error + - EvalError + - JavaScript + - Property +translation_of: Web/JavaScript/Reference/Global_Objects/EvalError +translation_of_original: Web/JavaScript/Reference/Global_Objects/EvalError/prototype +--- +
{{JSRef("Global_Objects", "Error", "EvalError,InternalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError")}}
+ +

Сводка

+

Свойство EvalError.prototype представляет прототип конструктора объекта {{jsxref("EvalError")}}.

+ +
{{js_property_attributes(0, 0, 0)}}
+ +

Описание

+

Все экземпляры {{jsxref("EvalError")}} наследуются от объекта EvalError.prototype. Вы можете использовать прототип для добавления свойств или методов ко всем экземплярам.

+ +

Свойства

+
+
EvalError.prototype.constructor
+
Определяет функцию, создающую прототип экземпляра.
+
{{jsxref("Error.prototype.message", "EvalError.prototype.message")}}
+
Сообщение ошибки. Хотя стандарт ECMA-262 определяет, что {{jsxref("EvalError")}} должен предоставлять своё собственное свойство message, в SpiderMonkey он наследует свойство {{jsxref("Error.prototype.message")}}.
+
{{jsxref("Error.prototype.name", "EvalError.prototype.name")}}
+
Название ошибки. Унаследовано от {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.fileName", "EvalError.prototype.fileName")}}
+
Путь к файлу, в котором возникла эта ошибка. Унаследовано от {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.lineNumber", "EvalError.prototype.lineNumber")}}
+
Номер строки в файле, в котором возникла эта ошибка. Унаследовано от {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.columnNumber", "EvalError.prototype.columnNumber")}}
+
Номер колонки в строке, на которой возникла эта ошибка. Унаследовано от {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.stack", "EvalError.prototype.stack")}}
+
Стек вызовов. Унаследовано от {{jsxref("Error")}}.
+
+ +

Методы

+

Хотя объект прототипа {{jsxref("EvalError")}} не содержит собственных методов, экземпляры {{jsxref("EvalError")}} наследуют некоторые методы из цепочки прототипов.

+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарии
ECMAScript 3-е издание.СтандартИзначальное определение.
{{SpecName('ES5.1', '#sec-15.11.7.6', 'NativeError.prototype')}}{{Spec2('ES5.1')}}Определено как NativeError.prototype.
{{SpecName('ES6', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ES6')}}Определено как NativeError.prototype.
+ +

Совместимость с браузерами

+
{{CompatibilityTable}}
+
+ + + + + + + + + + + + + + + + + + + +
ВозможностьChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
ВозможностьAndroidChrome для AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

Смотрите также

+ diff --git a/files/ru/conflicting/web/javascript/reference/global_objects/function/index.html b/files/ru/conflicting/web/javascript/reference/global_objects/function/index.html new file mode 100644 index 0000000000..acf9fc5c6e --- /dev/null +++ b/files/ru/conflicting/web/javascript/reference/global_objects/function/index.html @@ -0,0 +1,152 @@ +--- +title: Function.prototype +slug: Web/JavaScript/Reference/Global_Objects/Function/prototype +tags: + - Function + - JavaScript + - Property + - Prototype + - Reference + - Référence(2) +translation_of: Web/JavaScript/Reference/Global_Objects/Function +translation_of_original: Web/JavaScript/Reference/Global_Objects/Function/prototype +--- +
{{JSRef("Global_Objects", "Function")}}
+ +

Сводка

+ +

Свойство Function.prototype представляет прототип объекта {{jsxref("Global_Objects/Function", "Function")}}.

+ +

Описание

+ +

Объекты {{jsxref("Global_Objects/Function", "Function")}} наследуются от Function.prototype. Объект Function.prototype не может быть изменён.

+ +

Свойства

+ +
+
{{jsxref("Function.arguments")}} {{deprecated_inline}}
+
Массив, соответствующий аргументам, переданным в функцию. Это устаревшее свойство {{jsxref("Global_Objects/Function", "Function")}}, используйте вместо него объект {{jsxref("Functions_and_function_scope/arguments", "arguments")}}, доступный внутри функции.
+
{{jsxref("Function.arity")}} {{obsolete_inline}}
+
Использовалось для определения количества аргументов, ожидаемых функцией, но было удалено. Вместо него используйте свойство {{jsxref("Function.length", "length")}}.
+
{{jsxref("Function.caller")}} {{non-standard_inline}}
+
Определяет функцию, вызвавшую текущую выполняющуюся функцию.
+
{{jsxref("Function.length")}}
+
Определяет количество аргументов, ожидаемых функцией.
+
{{jsxref("Function.name")}} {{non-standard_inline}}
+
Имя функции.
+
{{jsxref("Function.displayName")}} {{non-standard_inline}}
+
Отображаемое имя функции.
+
Function.prototype.constructor
+
Определяет функцию, создающую прототип объекта. Смотрите документацию по {{jsxref("Object.prototype.constructor")}}.
+
+ +

Методы

+ +
+
{{jsxref("Function.prototype.apply()")}}
+
Вызывает функцию и устанавливает this в контекст предоставленного значения; аргументы передаются объектом {{jsxref("Global_Objects/Array", "Array")}}.
+
{{jsxref("Function.prototype.bind()")}}
+
Создаёт новую функцию, которая, при вызове, самостоятельно вызывает эту функцию в контексте предоставленного значения, с данной последовательностью аргументов, предшествующих любым аргументам, переданным в новую функцию при её вызове. Устанавливает this в контекст предоставленного значения.
+
{{jsxref("Function.prototype.call()")}}
+
Вызывает (выполняет) функцию и устанавливает this в контекст предоставленного значения; аргументы передаются как есть.
+
{{jsxref("Function.prototype.isGenerator()")}} {{non-standard_inline}}
+
Возвращает true, если функция является генератором; в противном случае возвращает false.
+
{{jsxref("Function.prototype.toSource()")}} {{non-standard_inline}}
+
Возвращает строку, представляющую исходный код функции. Переопределяет метод {{jsxref("Object.prototype.toSource")}}.
+
{{jsxref("Function.prototype.toString()")}}
+
Возвращает строку, представляющую исходный код функции. Переопределяет метод {{jsxref("Object.prototype.toString")}}.
+
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарии
{{SpecName('ES1')}}{{Spec2('ES1')}}Изначальное определение. Реализована в JavaScript 1.1.
{{SpecName('ES5.1', '#sec-15.3.3.1', 'Function.prototype')}}
+ Для экземпляров объекта {{jsxref("Global_Objects/Function", "Function")}}:
+ {{SpecName('ES5.1', '#sec-15.3.5.2', 'Function.prototype')}}
{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-function.prototype', 'Function.prototype')}}
+ Для экземпляров объекта {{jsxref("Global_Objects/Function", "Function")}}:
+ {{SpecName('ES6', '#sec-function-instances-prototype', 'Function.prototype')}}
{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-function-instances-prototype', 'Function.prototype')}}{{Spec2('ESDraft')}} 
+ +

Совместимость с браузерами

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
ВозможностьChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
ВозможностьAndroidChrome для AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

Смотрите также

+ + diff --git a/files/ru/conflicting/web/javascript/reference/global_objects/generatorfunction/index.html b/files/ru/conflicting/web/javascript/reference/global_objects/generatorfunction/index.html new file mode 100644 index 0000000000..b9974a46a3 --- /dev/null +++ b/files/ru/conflicting/web/javascript/reference/global_objects/generatorfunction/index.html @@ -0,0 +1,59 @@ +--- +title: GeneratorFunction.prototype +slug: Web/JavaScript/Reference/Global_Objects/GeneratorFunction/prototype +translation_of: Web/JavaScript/Reference/Global_Objects/GeneratorFunction +translation_of_original: Web/JavaScript/Reference/Global_Objects/GeneratorFunction/prototype +--- +
{{JSRef}}
+ +

Свойство GeneratorFunction.prototype представляет собой прототип объекта {{jsxref("GeneratorFunction")}} .

+ +

Описание

+ +

Объект {{jsxref("GeneratorFunction")}} наследуется из GeneratorFunction.prototype. GeneratorFunction.prototype не может быть изменён.

+ +

Свойства

+ +
+
GeneratorFunction.constructor
+
Изначальное значение {{jsxref("GeneratorFunction")}}.
+
GeneratorFunction.prototype.prototype
+
Значение %GeneratorPrototype%.
+
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('ES2015', '#sec-generatorfunction.prototype', 'GeneratorFunction.prototype')}}{{Spec2('ES2015')}}Изначальное определение.
{{SpecName('ESDraft', '#sec-generatorfunction.prototype', 'GeneratorFunction.prototype')}}{{Spec2('ESDraft')}}
+ +

Совместимость с браузерами

+ +
+ + +

{{Compat("javascript.builtins.GeneratorFunction.prototype")}}

+
+ +

Смотрите также

+ + diff --git a/files/ru/conflicting/web/javascript/reference/global_objects/internalerror/index.html b/files/ru/conflicting/web/javascript/reference/global_objects/internalerror/index.html new file mode 100644 index 0000000000..633ffbf9fb --- /dev/null +++ b/files/ru/conflicting/web/javascript/reference/global_objects/internalerror/index.html @@ -0,0 +1,100 @@ +--- +title: InternalError.prototype +slug: Web/JavaScript/Reference/Global_Objects/InternalError/prototype +tags: + - Error + - InternalError + - JavaScript + - Non-standard + - Property +translation_of: Web/JavaScript/Reference/Global_Objects/InternalError +translation_of_original: Web/JavaScript/Reference/Global_Objects/InternalError/prototype +--- +
{{JSRef("Global_Objects", "Error", "EvalError,InternalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError")}} {{non-standard_header}}
+ +

Сводка

+

Свойство InternalError.prototype представляет прототип конструктора объекта {{jsxref("InternalError")}}.

+ +
{{js_property_attributes(0, 0, 0)}}
+ +

Описание

+

Все экземпляры {{jsxref("InternalError")}} наследуются от объекта InternalError.prototype. Вы можете использовать прототип для добавления свойств или методов ко всем экземплярам.

+ +

Свойства

+
+
InternalError.prototype.constructor
+
Определяет функцию, создающую прототип экземпляра.
+
{{jsxref("Error.prototype.message", "InternalError.prototype.message")}}
+
Сообщение ошибки. Унаследовано от {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.name", "InternalError.prototype.name")}}
+
Название ошибки. Унаследовано от {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.fileName", "InternalError.prototype.fileName")}}
+
Путь к файлу, в котором возникла эта ошибка. Унаследовано от {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.lineNumber", "InternalError.prototype.lineNumber")}}
+
Номер строки в файле, в котором возникла эта ошибка. Унаследовано от {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.columnNumber", "InternalError.prototype.columnNumber")}}
+
Номер колонки в строке, на которой возникла эта ошибка. Унаследовано от {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.stack", "InternalError.prototype.stack")}}
+
Стек вызовов. Унаследовано от {{jsxref("Error")}}.
+
+ +

Методы

+

Хотя объект прототипа {{jsxref("InternalError")}} не содержит собственных методов, экземпляры {{jsxref("InternalError")}} наследуют некоторые методы из цепочки прототипов.

+ +

Спецификации

+

Не является частью какой-либо спецификации.

+ +

Совместимость с браузерами

+
{{CompatibilityTable}}
+
+ + + + + + + + + + + + + + + + + + + +
ВозможностьChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
ВозможностьAndroidChrome для AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{CompatNo}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

Смотрите также

+ diff --git a/files/ru/conflicting/web/javascript/reference/global_objects/intl/collator/index.html b/files/ru/conflicting/web/javascript/reference/global_objects/intl/collator/index.html new file mode 100644 index 0000000000..eb708cca36 --- /dev/null +++ b/files/ru/conflicting/web/javascript/reference/global_objects/intl/collator/index.html @@ -0,0 +1,109 @@ +--- +title: Intl.Collator.prototype +slug: Web/JavaScript/Reference/Global_Objects/Intl/Collator/prototype +tags: + - Collator + - Internationalization + - JavaScript + - Property + - Prototype +translation_of: Web/JavaScript/Reference/Global_Objects/Intl/Collator +translation_of_original: Web/JavaScript/Reference/Global_Objects/Intl/Collator/prototype +--- +
{{JSRef("Global_Objects", "Collator", "Intl,DateTimeFormat,NumberFormat")}}
+ +

Сводка

+

Свойство Intl.Collator.prototype представляет объект прототипа конструктора {{jsxref("Global_Objects/Collator", "Intl.Collator")}}.

+ +
{{js_property_attributes(0, 0, 0)}}
+ +

Описание

+

Смотрите {{jsxref("Global_Objects/Collator", "Collator")}} для описания экземпляров Intl.NumberFormat.

+

Экземпляры {{jsxref("Global_Objects/Collator", "Intl.Collator")}} наследуются от Intl.NumberFormat.prototype. Изменения объекта прототипа наследуются всеми экземплярами {{jsxref("Global_Objects/Collator", "Intl.Collator")}}.

+ +

Свойства

+
+
Intl.Collator.prototype.constructor
+
Ссылка на {{jsxref("Global_Objects/Collator", "Intl.Collator")}}.
+
{{jsxref("Collator.compare", "Intl.Collator.prototype.compare")}}
+
Геттер; возвращает функцию, сравнивающую две строки согласно порядку сортировки этого объекта {{jsxref("Global_Objects/Collator", "Collator")}}.
+
+ +

Методы

+
+
{{jsxref("Collator.resolvedOptions", "Intl.Collator.prototype.resolvedOptions()")}}
+
Возвращает новый объект со свойствами, отражающими локаль и опции сравнения строк, вычисленные при инициализации объекта.
+
+ +

Спецификации

+ + + + + + + + + + + + + +
СпецификацияСтатусКомментарии
{{SpecName('ES Int 1.0', '#sec-10.2.1', 'Intl.Collator.prototype')}}{{Spec2('ES Int 1.0')}}Изначальное определение.
+ +

Совместимость с браузерами

+
{{CompatibilityTable}}
+
+ + + + + + + + + + + + + + + + + + + +
ВозможностьChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Базовая поддержка{{CompatChrome("24")}}{{CompatGeckoDesktop("29")}}{{CompatIE("11")}}{{CompatOpera("15")}}{{CompatNo}}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
ВозможностьAndroidChrome для AndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Базовая поддержка{{CompatNo}}{{CompatChrome("26")}} + {{CompatNo}}
+ {{bug("864843")}} +
{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

Смотрите также

+ diff --git a/files/ru/conflicting/web/javascript/reference/global_objects/intl/datetimeformat/index.html b/files/ru/conflicting/web/javascript/reference/global_objects/intl/datetimeformat/index.html new file mode 100644 index 0000000000..a22ec7aeaa --- /dev/null +++ b/files/ru/conflicting/web/javascript/reference/global_objects/intl/datetimeformat/index.html @@ -0,0 +1,109 @@ +--- +title: Intl.DateTimeFormat.prototype +slug: Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/prototype +tags: + - DateTimeFormat + - Internationalization + - JavaScript + - Property + - Prototype +translation_of: Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat +translation_of_original: Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/prototype +--- +
{{JSRef("Global_Objects", "DateTimeFormat", "Intl,Collator,NumberFormat")}}
+ +

Сводка

+

Свойство Intl.DateTimeFormat.prototype представляет объект прототипа конструктора {{jsxref("Global_Objects/DateTimeFormat", "Intl.DateTimeFormat")}}.

+ +
{{js_property_attributes(0, 0, 0)}}
+ +

Описание

+

Смотрите {{jsxref("Global_Objects/DateTimeFormat", "DateTimeFormat")}} для описания экземпляров Intl.NumberFormat.

+

Экземпляры {{jsxref("Global_Objects/DateTimeFormat", "Intl.DateTimeFormat")}} наследуются от Intl.NumberFormat.prototype. Изменения объекта прототипа наследуются всеми экземплярами {{jsxref("Global_Objects/DateTimeFormat", "Intl.DateTimeFormat")}}.

+ +

Свойства

+
+
Intl.DateTimeFormat.prototype.constructor
+
Ссылка на {{jsxref("Global_Objects/DateTimeFormat", "Intl.DateTimeFormat")}}.
+
{{jsxref("DateTimeFormat.format", "Intl.DateTimeFormat.prototype.format")}}
+
Геттер; возвращает функцию, форматирующую дату согласно локали и опциям форматирования этого объекта {{jsxref("Global_Objects/DateTimeFormat", "DateTimeFormat")}}.
+
+ +

Методы

+
+
{{jsxref("DateTimeFormat.resolvedOptions", "Intl.DateTimeFormat.prototype.resolvedOptions()")}}
+
Возвращает новый объект со свойствами, отражающими локаль и опции форматирования, вычисленные при инициализации объекта.
+
+ +

Спецификации

+ + + + + + + + + + + + + +
СпецификацияСтатусКомментарии
{{SpecName('ES Int 1.0', '#sec-12.2.1', 'Intl.DateTimeFormat.prototype')}}{{Spec2('ES Int 1.0')}}Изначальное определение.
+ +

Совместимость с браузерами

+
{{CompatibilityTable}}
+
+ + + + + + + + + + + + + + + + + + + +
ВозможностьChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Базовая поддержка{{CompatChrome("24")}}{{CompatGeckoDesktop("29")}}{{CompatIE("11")}}{{CompatOpera("15")}}{{CompatNo}}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
ВозможностьAndroidChrome для AndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Базовая поддержка{{CompatNo}}{{CompatChrome("26")}} + {{CompatNo}}
+ {{bug("864843")}} +
{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

Смотрите также

+ diff --git a/files/ru/conflicting/web/javascript/reference/global_objects/intl/numberformat/index.html b/files/ru/conflicting/web/javascript/reference/global_objects/intl/numberformat/index.html new file mode 100644 index 0000000000..fd9fbeeac8 --- /dev/null +++ b/files/ru/conflicting/web/javascript/reference/global_objects/intl/numberformat/index.html @@ -0,0 +1,109 @@ +--- +title: Intl.NumberFormat.prototype +slug: Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/prototype +tags: + - Internationalization + - JavaScript + - NumberFormat + - Property + - Prototype +translation_of: Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat +translation_of_original: Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/prototype +--- +
{{JSRef("Global_Objects", "NumberFormat", "Intl,Collator,DateTimeFormat")}}
+ +

Сводка

+

Свойство Intl.NumberFormat.prototype представляет объект прототипа конструктора {{jsxref("Global_Objects/NumberFormat", "Intl.NumberFormat")}}.

+ +
{{js_property_attributes(0, 0, 0)}}
+ +

Описание

+

Смотрите {{jsxref("NumberFormat")}} для описания экземпляров Intl.NumberFormat.

+

Экземпляры {{jsxref("Global_Objects/NumberFormat", "Intl.NumberFormat")}} наследуются от Intl.NumberFormat.prototype. Изменения объекта прототипа наследуются всеми экземплярами {{jsxref("Global_Objects/NumberFormat", "Intl.NumberFormat")}}.

+ +

Свойства

+
+
Intl.NumberFormat.prototype.constructor
+
Ссылка на {{jsxref("Global_Objects/NumberFormat", "Intl.NumberFormat")}}.
+
{{jsxref("NumberFormat.format", "Intl.NumberFormat.prototype.format")}}
+
Геттер; возвращает функцию, форматирующую число согласно локали и опциям форматирования этого объекта {{jsxref("Global_Objects/NumberFormat", "NumberFormat")}}.
+
+ +

Методы

+
+
{{jsxref("NumberFormat.resolvedOptions", "Intl.NumberFormat.prototype.resolvedOptions()")}}
+
Возвращает новый объект со свойствами, отражающими локаль и опции сравнения, вычисленные при инициализации объекта.
+
+ +

Спецификации

+ + + + + + + + + + + + + +
СпецификацияСтатусКомментарии
{{SpecName('ES Int 1.0', '#sec-11.2.1', 'Intl.NumberFormat.prototype')}}{{Spec2('ES Int 1.0')}}Изначальное определение.
+ +

Совместимость с браузерами

+
{{CompatibilityTable}}
+
+ + + + + + + + + + + + + + + + + + + +
ВозможностьChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Базовая поддержка{{CompatChrome("24")}}{{CompatGeckoDesktop("29")}}{{CompatIE("11")}}{{CompatOpera("15")}}{{CompatNo}}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
ВозможностьAndroidChrome для AndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Базовая поддержка{{CompatNo}}{{CompatChrome("26")}} + {{CompatNo}}
+ {{bug("864843")}} +
{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

Смотрите также

+ diff --git a/files/ru/conflicting/web/javascript/reference/global_objects/map/index.html b/files/ru/conflicting/web/javascript/reference/global_objects/map/index.html new file mode 100644 index 0000000000..a3af6a0c61 --- /dev/null +++ b/files/ru/conflicting/web/javascript/reference/global_objects/map/index.html @@ -0,0 +1,126 @@ +--- +title: Map.prototype +slug: Web/JavaScript/Reference/Global_Objects/Map/prototype +translation_of: Web/JavaScript/Reference/Global_Objects/Map +translation_of_original: Web/JavaScript/Reference/Global_Objects/Map/prototype +--- +
{{JSRef}}
+ +

Свойство Map.prototype представляет собой прототип конструктора {{jsxref("Map")}}.

+ +
{{js_property_attributes(0,0,0)}}
+ +

Описание

+ +

Экземпляры {{jsxref("Map")}} наследуются от {{jsxref("Map.prototype")}}. Вы можете использовать объект конструктора прототипа для добавления свойств и методов ко всем экземплярам Map.

+ +

Свойства

+ +
+
Map.prototype.constructor
+
Возвращает функцию, создающую экземпляр прототипа. Это функция {{jsxref("Map")}} по умолчанию. 
+
{{jsxref("Map.prototype.size")}}
+
Возвращает количество пар key/value, содержащихся в объекте Map.
+
+ +

Методы

+ +
+
{{jsxref("Map.prototype.clear()")}}
+
Удаляет все пары key/value из объекта Map.
+
{{jsxref("Map.delete", "Map.prototype.delete(key)")}}
+
Возвращает true, если элемент присутствовал в объекте Map и был удалён, или false, если элемент отсутствует. После вызова этого метода Map.prototype.has(key) вернёт false.
+
{{jsxref("Map.prototype.entries()")}}
+
Возвращает новый объект итератора - new Iterator, который содержит массив из [key, value] для каждого элемента в объекте Map в порядке добавления.
+
{{jsxref("Map.forEach", "Map.prototype.forEach(callbackFn[, thisArg])")}}
+
Вызывает callbackFn для каждой пары key/value, находящейся в объекте Map, в порядке добавления. Если указан параметр thisArg, он будет использоваться в качестве значения this при каждом вызове callbackFn. 
+
{{jsxref("Map.get", "Map.prototype.get(key)")}}
+
Возвращает значение по указанному ключу key или undefined, если значение отсутствует. 
+
{{jsxref("Map.has", "Map.prototype.has(key)")}}
+
Возвращает true или false в зависимости от того, было ли значение связано с key в объекте Map или нет.
+
{{jsxref("Map.prototype.keys()")}}
+
Возвращает новый объект итератора - new Iterator, который содержит keys для каждого элемента в объекте Map в порядке добавления.
+
{{jsxref("Map.set", "Map.prototype.set(key, value)")}}
+
Устанавлиевает value для key в объекте Map. Возвращает объект Map.
+
{{jsxref("Map.prototype.values()")}}
+
Возвращает новый объект итератора - new Iterator, который содержит values для каждого элемента в объекте Map в порядке добавления.
+
{{jsxref("Map.@@iterator", "Map.prototype[@@iterator]()")}}
+
Возвращает новый объект итератора - new Iterator, который содержит массив из [key, value] для каждого элемента в объекте Map в порядке добавления. 
+
+ +

Спецификации

+ + + + + + + + + + + + + + +
СпецификацияСтатусКомментарии
{{SpecName('ES6', '#sec-map.prototype', 'Map.prototype')}}{{Spec2('ES6')}}Initial definition.
+ +

Совместимость с браузерами

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
ВозможностьChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка38{{ CompatGeckoDesktop("13") }}11257.1
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
ВозможностьAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{CompatNo}}38{{CompatGeckoMobile("13")}}{{CompatNo}}{{CompatNo}} +

8

+
+
+ +

Смотрите также

+ + diff --git a/files/ru/conflicting/web/javascript/reference/global_objects/number/index.html b/files/ru/conflicting/web/javascript/reference/global_objects/number/index.html new file mode 100644 index 0000000000..259d8a3fb3 --- /dev/null +++ b/files/ru/conflicting/web/javascript/reference/global_objects/number/index.html @@ -0,0 +1,124 @@ +--- +title: Number.prototype +slug: Web/JavaScript/Reference/Global_Objects/Number/prototype +tags: + - JavaScript + - Number + - Property + - Prototype + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Number +translation_of_original: Web/JavaScript/Reference/Global_Objects/Number/prototype +--- +
{{JSRef("Global_Objects", "Number")}}
+ +

Сводка

+

Свойство Number.prototype представляет прототип конструктора {{jsxref("Global_Objects/Number", "Number")}}.

+ +
{{js_property_attributes(0, 0, 0)}}
+ +

Описание

+

Все экземпляры {{jsxref("Global_Objects/Number", "Number")}} наследуются от Number.prototype. Объект прототипа конструктора {{jsxref("Global_Objects/Number", "Number")}} может быть изменён для затрагивания всех экземпляров объекта {{jsxref("Global_Objects/Number", "Number")}}.

+ +

Свойства

+
+
Number.prototype.constructor
+
Возвращает функцию, создавшую этот экземпляр объекта. По умолчанию ей является объект {{jsxref("Global_Objects/Number", "Number")}}.
+
+ +
{{jsOverrides("Object", "properties", "constructor")}}
+ +

Методы

+
+
{{jsxref("Number.prototype.toExponential()")}}
+
Возвращает строку, представляющую число в экспоненциальной записи.
+
{{jsxref("Number.prototype.toFixed()")}}
+
Возвращает строку, представляющую число в записи с фиксированной запятой.
+
{{jsxref("Number.prototype.toLocaleString()")}}
+
Возвращает строку с языко-зависимым представлением числа. Переопределяет метод {{jsxref("Object.prototype.toLocaleString()")}}.
+
{{jsxref("Number.prototype.toPrecision()")}}
+
Возвращает строку, представляющую число с указанной точностью в экспоненциальной записи, либо записи с фиксированной запятой.
+
{{jsxref("Number.prototype.toSource()")}} {{non-standard_inline}}
+
Возвращает объектный литерал, представляющий объект {{jsxref("Global_Objects/Number", "Number")}}; вы можете использовать это значение для создания нового объекта. Переопределяет метод {{jsxref("Object.prototype.toSource()")}}.
+
{{jsxref("Number.prototype.toString()")}}
+
Возвращает строку, представляющую указанный объект по указанному основанию системы счисления. Переопределяет метод {{jsxref("Object.prototype.toString()")}}.
+
{{jsxref("Number.prototype.valueOf()")}}
+
Возвращает примитивное значение указанного объекта. Переопределяет метод {{jsxref("Object.prototype.valueOf()")}}.
+
+ +
{{jsOverrides("Object", "methods", "toExponential", "toFixed", "toLocaleString", "toPrecision", "toSource", "toString", "valueOf")}}
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарии
ECMAScript 1-е издание.СтандартИзначальное определение. Реализована в JavaScript 1.1.
{{SpecName('ES5.1', '#sec-15.7.4', 'Number')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-properties-of-the-number-prototype-object', 'Number')}}{{Spec2('ES6')}} 
+ +

Совместимость с браузерами

+
{{CompatibilityTable}}
+
+ + + + + + + + + + + + + + + + + + + +
ВозможностьChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
ВозможностьAndroidChrome для AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
diff --git a/files/ru/conflicting/web/javascript/reference/global_objects/object/index.html b/files/ru/conflicting/web/javascript/reference/global_objects/object/index.html new file mode 100644 index 0000000000..aaa398171d --- /dev/null +++ b/files/ru/conflicting/web/javascript/reference/global_objects/object/index.html @@ -0,0 +1,205 @@ +--- +title: Object.prototype +slug: Web/JavaScript/Reference/Global_Objects/Object/prototype +tags: + - JavaScript + - Object + - Property + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Object +translation_of_original: Web/JavaScript/Reference/Global_Objects/Object/prototype +--- +
{{JSRef("Global_Objects", "Object")}}
+ +

Сводка

+ +

Свойство Object.prototype представляет объект прототипа {{jsxref("Global_Objects/Object", "Object")}}.

+ +
{{js_property_attributes(0, 0, 0)}}
+ +

Описание

+ +

Все объекты в JavaScript являются потомками {{jsxref("Global_Objects/Object", "Object")}}; все объекты наследуют методы и свойства из прототипа объекта Object.prototype, хотя они и могут быть переопределены (за исключением объекта Object с прототипом null, то есть, созданным вызовом Object.create(null)). Например, прототипы других конструкторов переопределяют свойство constructor и предоставляют свои собственные методы {{jsxref("Object.prototype.toString()", "toString()")}}. Изменения в объекте прототипа {{jsxref("Global_Objects/Object", "Object")}} распространяются на все объекты до тех пор, пока свойства и методы, учитывающие эти изменения, не переопределяются дальше по цепочке прототипов.

+ +

Свойства

+ +
+
{{jsxref("Object.prototype.constructor")}}
+
Определяет функцию, создающую прототип объекта.
+
{{jsxref("Object.proto", "Object.prototype.__proto__")}} {{non-standard_inline}}
+
Указывает на объект, который использовался в качестве прототипа при инстанцировании объекта.
+
{{jsxref("Object.noSuchMethod", "Object.prototype.__noSuchMethod__")}} {{non-standard_inline}}
+
Позволяет определить функцию, выполняющуюся при вызове в качестве метода неопределённого члена объекта.
+
{{jsxref("Object.count", "Object.prototype.__count__")}} {{obsolete_inline}}
+
Использовалось для возврата количества перечисляемых свойств, определённых напрямую на пользовательском объекте, но было удалено.
+
{{jsxref("Object.parent", "Object.prototype.__parent__")}} {{obsolete_inline}}
+
Использовалось для указания контекста объекта, но было удалено.
+
+ +

Методы

+ +
+
{{jsxref("Object.defineGetter", "Object.prototype.__defineGetter__()")}} {{non-standard_inline}} {{deprecated_inline}}
+
Ассоциирует функцию со свойством, которое, при доступе к нему, выполняет эту функцию и возвращает её возвращаемое значение.
+
{{jsxref("Object.defineSetter", "Object.prototype.__defineSetter__()")}} {{non-standard_inline}} {{deprecated_inline}}
+
Ассоциирует функцию со свойством, которое, при его установке, выполняет эту функцию, изменяющую свойство.
+
{{jsxref("Object.lookupGetter", "Object.prototype.__lookupGetter__()")}} {{non-standard_inline}} {{deprecated_inline}}
+
Возвращает функцию, ассоциированную с указанным свойством методом {{jsxref("Object.defineGetter", "__defineGetter__")}}.
+
{{jsxref("Object.lookupSetter", "Object.prototype.__lookupSetter__()")}} {{non-standard_inline}} {{deprecated_inline}}
+
Возвращает функцию, ассоциированную с указанным свойством методом {{jsxref("Object.defineSetter", "__defineSetter__")}}.
+
{{jsxref("Object.prototype.hasOwnProperty()")}}
+
Возвращает логическое значение, указывающее, содержит ли указанное свойство непосредственно объект, или он унаследовал его по цепочке прототипов.
+
{{jsxref("Object.prototype.isPrototypeOf()")}}
+
Возвращает логическое значение, указывающее, состоит ли указанный объект в цепочке прототипов объекта, на котором был вызван данный метод.
+
{{jsxref("Object.prototype.propertyIsEnumerable()")}}
+
Возвращает логическое значение, указывающее, установлен ли внутренний атрибут ECMAScript DontEnum.
+
{{jsxref("Object.prototype.toSource()")}} {{non-standard_inline}}
+
Возвращает строку, содержащую исходный код объекта в литеральной форме, представляющего объект, на котором был вызван данный метод; вы можете использовать это значение для создания нового объекта.
+
{{jsxref("Object.prototype.toLocaleString()")}}
+
Вызывает {{jsxref("Object.toString", "toString()")}}.
+
{{jsxref("Object.prototype.toString()")}}
+
Возвращает строковое представление объекта.
+
{{jsxref("Object.prototype.unwatch()")}} {{non-standard_inline}}
+
Удаляет точку наблюдения (watchpoint) со свойства объекта.
+
{{jsxref("Object.prototype.valueOf()")}}
+
Возвращает значение примитива указанного объекта.
+
{{jsxref("Object.prototype.watch()")}} {{non-standard_inline}}
+
Добавляет точку наблюдения (watchpoint) к свойству объекта.
+
{{jsxref("Object.prototype.eval()")}} {{obsolete_inline}}
+
Использовался для вычисления строки с JavaScript-кодом в контексте указанного объекта, но был удалён.
+
+ +

Примеры

+ +

Поскольку Javascript, строго говоря, не имеет объекты подклассов, прототип является полезным обходным путём создания объекта «базового класса» из определённых функций, которые выступают в роли объектов. Например:

+ +
var Person = function(name) {
+    this.name = name;
+    this.canTalk = true;
+    this.greet = function() {
+        if (this.canTalk) {
+            console.log('Привет, я ' + this.name);
+        }
+    };
+};
+
+var Employee = function(name, title) {
+    this.name = name;
+    this.title = title;
+    this.greet = function() {
+        if (this.canTalk) {
+            console.log('Привет, я ' + this.name + ', ' + this.title);
+        }
+    };
+};
+Employee.prototype = new Person();
+
+var Customer = function(name) {
+    this.name = name;
+};
+Customer.prototype = new Person();
+
+var Mime = function(name) {
+    this.name = name;
+    this.canTalk = false;
+};
+Mime.prototype = new Person();
+
+var bob = new Employee('Боб', 'Строитель');
+var joe = new Customer('Джо');
+var rg = new Employee('Ред Грин', 'Разнорабочий');
+var mike = new Customer('Майк');
+var mime = new Mime('Мим');
+bob.greet();
+joe.greet();
+rg.greet();
+mike.greet();
+mime.greet();
+
+ +

Вывод будет следующим:

+ +
Привет, я Боб, Строитель
+Привет, я Джо
+Привет, я Ред Грин, Разнорабочий
+Привет, я Майк
+
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарии
ECMAScript 1-е издание.СтандартИзначальное определение. Реализована в JavaScript 1.0.
{{SpecName('ES5.1', '#sec-15.2.3.1', 'Object.prototype')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-object.prototype', 'Object.prototype')}}{{Spec2('ES6')}}
+ +

Совместимость с браузерами

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
ВозможностьChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
ВозможностьAndroidChrome для AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
diff --git a/files/ru/conflicting/web/javascript/reference/global_objects/promise/index.html b/files/ru/conflicting/web/javascript/reference/global_objects/promise/index.html new file mode 100644 index 0000000000..65384e8346 --- /dev/null +++ b/files/ru/conflicting/web/javascript/reference/global_objects/promise/index.html @@ -0,0 +1,67 @@ +--- +title: Promise.prototype +slug: Web/JavaScript/Reference/Global_Objects/Promise/prototype +tags: + - JavaScript + - Обещание + - Свойство +translation_of: Web/JavaScript/Reference/Global_Objects/Promise +translation_of_original: Web/JavaScript/Reference/Global_Objects/Promise/prototype +--- +
{{JSRef}}
+ +

Cвойство Promise.prototype представляет собой прототип конструктора {{jsxref("Promise")}}.

+ +
{{js_property_attributes(0,0,0)}}
+ +

Описание

+ +

{{jsxref("Promise")}} обьект наследованный от {{jsxref("Promise.prototype")}}. Вы можете использовать прототип конструктора  чтобы добавлять свойства или методы во все объекты обещаний.

+ +

Свойства

+ +
+
Promise.prototype.constructor
+
Возвращает функцию, которая создала прототип экземпляра. Это функция всех обещаний по умолчанию.
+
+ +

Методы

+ +
+
{{jsxref("Promise.catch", "Promise.prototype.catch(onRejected)")}}
+
Добавляет функцию обратного вызова для обработки отклонения обещания, которая возвращает новое обещание выполненное с переданным значением, если она вызвана, или оригинальное значение resolve, если обещание выполнено.
+
{{jsxref("Promise.then", "Promise.prototype.then(onFulfilled, onRejected)")}}
+
Добавляет обработчик выполнения и отклонения обещания, и возвращает новое обещание выполненное со значением вызванного обработчика, или оригинальное значение, если обещание не было обработано (т.е. если соответствующий обработчик onFulfilled или onRejected не является функцией).
+
+ +

Спецификация

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-promise.prototype', 'Promise.prototype')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-promise.prototype', 'Promise.prototype')}}{{Spec2('ESDraft')}}
+ +

Совместимость с браузерами

+ + + +

Смотри также

+ + diff --git a/files/ru/conflicting/web/javascript/reference/global_objects/proxy/proxy/index.html b/files/ru/conflicting/web/javascript/reference/global_objects/proxy/proxy/index.html new file mode 100644 index 0000000000..472e9d4735 --- /dev/null +++ b/files/ru/conflicting/web/javascript/reference/global_objects/proxy/proxy/index.html @@ -0,0 +1,135 @@ +--- +title: Proxy handler +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler +tags: + - ECMAScript 2015 + - JavaScript + - NeedsTranslation + - Proxy + - TopicStub + - Прокси + - Русский + - ловушки +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy +translation_of_original: Web/JavaScript/Reference/Global_Objects/Proxy/handler +--- +
{{JSRef}}
+ +

Объект-обработчик прокси - это объект, который содержит ловушки для {{jsxref("Proxy", "proxies", "", 1)}}.

+ +

Методы

+ +

Все ловушки ставятся по желанию разработчика. Если ловушка не была определена, то, по умолчанию, операция перенаправляется на исходный объект (target).

+ +
+
{{jsxref("Global_Objects/Proxy/handler/getPrototypeOf", "handler.getPrototypeOf()")}}
+
Ловушка для {{jsxref("Object.getPrototypeOf")}}.
+
{{jsxref("Global_Objects/Proxy/handler/setPrototypeOf", "handler.setPrototypeOf()")}}
+
Ловушка для {{jsxref("Object.setPrototypeOf")}}.
+
{{jsxref("Global_Objects/Proxy/handler/isExtensible", "handler.isExtensible()")}}
+
Ловушка для {{jsxref("Object.isExtensible")}}.
+
{{jsxref("Global_Objects/Proxy/handler/preventExtensions", "handler.preventExtensions()")}}
+
Ловушка для {{jsxref("Object.preventExtensions")}}.
+
{{jsxref("Global_Objects/Proxy/handler/getOwnPropertyDescriptor", "handler.getOwnPropertyDescriptor()")}}
+
Ловушка для {{jsxref("Object.getOwnPropertyDescriptor")}}.
+
{{jsxref("Global_Objects/Proxy/handler/defineProperty", "handler.defineProperty()")}}
+
Ловушка для {{jsxref("Object.defineProperty")}}.
+
{{jsxref("Global_Objects/Proxy/handler/has", "handler.has()")}}
+
Ловушка для оператора {{jsxref("Operators/in", "in")}}.
+
{{jsxref("Global_Objects/Proxy/handler/get", "handler.get()")}}
+
Ловушка для получения значений из свойств.
+
{{jsxref("Global_Objects/Proxy/handler/set", "handler.set()")}}
+
Ловушка для установки значений в свойства.
+
{{jsxref("Global_Objects/Proxy/handler/deleteProperty", "handler.deleteProperty()")}}
+
Ловушка для оператора {{jsxref("Operators/delete", "delete")}}.
+
{{jsxref("Global_Objects/Proxy/handler/ownKeys", "handler.ownKeys()")}}
+
Ловушка для {{jsxref("Object.getOwnPropertyNames")}} и {{jsxref("Object.getOwnPropertySymbols")}}.
+
{{jsxref("Global_Objects/Proxy/handler/apply", "handler.apply()")}}
+
Ловушка для вызова функции.
+
{{jsxref("Global_Objects/Proxy/handler/construct", "handler.construct()")}}
+
Ловушка для оператора {{jsxref("Operators/new", "new")}}.
+
+ +

Некоторые нестандартные ловушки устарели и были удалены.

+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots', 'Proxy Object Internal Methods and Internal Slots')}}{{Spec2('ES2015')}}Определении при инициализации.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots', 'Proxy Object Internal Methods and Internal Slots')}}{{Spec2('ESDraft')}}Обработчик enumerate был удален.
+ +

Совместимость с браузерами

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support49 [1]{{ CompatGeckoDesktop("18") }}12{{CompatOpera(36)}}{{CompatSafari(10)}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{ CompatGeckoDesktop("18") }}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

[1] Разрешен по умолчанию.

+ +

Смотрите также

+ + diff --git a/files/ru/conflicting/web/javascript/reference/global_objects/rangeerror/index.html b/files/ru/conflicting/web/javascript/reference/global_objects/rangeerror/index.html new file mode 100644 index 0000000000..0e1df7fb7c --- /dev/null +++ b/files/ru/conflicting/web/javascript/reference/global_objects/rangeerror/index.html @@ -0,0 +1,123 @@ +--- +title: RangeError.prototype +slug: Web/JavaScript/Reference/Global_Objects/RangeError/prototype +tags: + - Error + - JavaScript + - Property + - Prototype + - RangeError +translation_of: Web/JavaScript/Reference/Global_Objects/RangeError +translation_of_original: Web/JavaScript/Reference/Global_Objects/RangeError/prototype +--- +
{{JSRef("Global_Objects", "Error", "EvalError,InternalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError")}}
+ +

Сводка

+

Свойство RangeError.prototype представляет прототип конструктора объекта {{jsxref("RangeError")}}.

+ +
{{js_property_attributes(0, 0, 0)}}
+ +

Описание

+

Все экземпляры {{jsxref("RangeError")}} наследуются от объекта RangeError.prototype. Вы можете использовать прототип для добавления свойств или методов ко всем экземплярам.

+ +

Свойства

+
+
RangeError.prototype.constructor
+
Определяет функцию, создающую прототип экземпляра.
+
{{jsxref("Error.prototype.message", "RangeError.prototype.message")}}
+
Сообщение ошибки. Хотя стандарт ECMA-262 определяет, что {{jsxref("RangeError")}} должен предоставлять своё собственное свойство message, в SpiderMonkey он наследует свойство {{jsxref("Error.prototype.message")}}.
+
{{jsxref("Error.prototype.name", "RangeError.prototype.name")}}
+
Название ошибки. Унаследовано от {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.fileName", "RangeError.prototype.fileName")}}
+
Путь к файлу, в котором возникла эта ошибка. Унаследовано от {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.lineNumber", "RangeError.prototype.lineNumber")}}
+
Номер строки в файле, в котором возникла эта ошибка. Унаследовано от {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.columnNumber", "RangeError.prototype.columnNumber")}}
+
Номер колонки в строке, на которой возникла эта ошибка. Унаследовано от {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.stack", "RangeError.prototype.stack")}}
+
Стек вызовов. Унаследовано от {{jsxref("Error")}}.
+
+ +

Методы

+

Хотя объект прототипа {{jsxref("RangeError")}} не содержит собственных методов, экземпляры {{jsxref("RangeError")}} наследуют некоторые методы из цепочки прототипов.

+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарии
ECMAScript 3-е издание.СтандартИзначальное определение.
{{SpecName('ES5.1', '#sec-15.11.7.6', 'NativeError.prototype')}}{{Spec2('ES5.1')}}Определено как NativeError.prototype.
{{SpecName('ES6', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ES6')}}Определено как NativeError.prototype.
+ +

Совместимость с браузерами

+
{{CompatibilityTable}}
+
+ + + + + + + + + + + + + + + + + + + +
ВозможностьChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
ВозможностьAndroidChrome для AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

Смотрите также

+ diff --git a/files/ru/conflicting/web/javascript/reference/global_objects/referenceerror/index.html b/files/ru/conflicting/web/javascript/reference/global_objects/referenceerror/index.html new file mode 100644 index 0000000000..1c73b6cb4e --- /dev/null +++ b/files/ru/conflicting/web/javascript/reference/global_objects/referenceerror/index.html @@ -0,0 +1,123 @@ +--- +title: ReferenceError.prototype +slug: Web/JavaScript/Reference/Global_Objects/ReferenceError/prototype +tags: + - Error + - JavaScript + - Property + - Prototype + - ReferenceError +translation_of: Web/JavaScript/Reference/Global_Objects/ReferenceError +translation_of_original: Web/JavaScript/Reference/Global_Objects/ReferenceError/prototype +--- +
{{JSRef("Global_Objects", "Error", "EvalError,InternalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError")}}
+ +

Сводка

+

Свойство ReferenceError.prototype представляет прототип конструктора объекта {{jsxref("ReferenceError")}}.

+ +
{{js_property_attributes(0, 0, 0)}}
+ +

Описание

+

Все экземпляры {{jsxref("ReferenceError")}} наследуются от объекта ReferenceError.prototype. Вы можете использовать прототип для добавления свойств или методов ко всем экземплярам.

+ +

Свойства

+
+
ReferenceError.prototype.constructor
+
Определяет функцию, создающую прототип экземпляра.
+
{{jsxref("Error.prototype.message", "ReferenceError.prototype.message")}}
+
Сообщение ошибки. Хотя стандарт ECMA-262 определяет, что {{jsxref("ReferenceError")}} должен предоставлять своё собственное свойство message, в SpiderMonkey он наследует свойство {{jsxref("Error.prototype.message")}}.
+
{{jsxref("Error.prototype.name", "ReferenceError.prototype.name")}}
+
Название ошибки. Унаследовано от {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.fileName", "ReferenceError.prototype.fileName")}}
+
Путь к файлу, в котором возникла эта ошибка. Унаследовано от {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.lineNumber", "ReferenceError.prototype.lineNumber")}}
+
Номер строки в файле, в котором возникла эта ошибка. Унаследовано от {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.columnNumber", "ReferenceError.prototype.columnNumber")}}
+
Номер колонки в строке, на которой возникла эта ошибка. Унаследовано от {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.stack", "ReferenceError.prototype.stack")}}
+
Стек вызовов. Унаследовано от {{jsxref("Error")}}.
+
+ +

Методы

+

Хотя объект прототипа {{jsxref("ReferenceError")}} не содержит собственных методов, экземпляры {{jsxref("ReferenceError")}} наследуют некоторые методы из цепочки прототипов.

+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарии
ECMAScript 3-е издание.СтандартИзначальное определение.
{{SpecName('ES5.1', '#sec-15.11.7.6', 'NativeError.prototype')}}{{Spec2('ES5.1')}}Определено как NativeError.prototype.
{{SpecName('ES6', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ES6')}}Определено как NativeError.prototype.
+ +

Совместимость с браузерами

+
{{CompatibilityTable}}
+
+ + + + + + + + + + + + + + + + + + + +
ВозможностьChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
ВозможностьAndroidChrome для AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

Смотрите также

+ diff --git a/files/ru/conflicting/web/javascript/reference/global_objects/regexp/index.html b/files/ru/conflicting/web/javascript/reference/global_objects/regexp/index.html new file mode 100644 index 0000000000..b0a655760c --- /dev/null +++ b/files/ru/conflicting/web/javascript/reference/global_objects/regexp/index.html @@ -0,0 +1,141 @@ +--- +title: RegExp.prototype +slug: Web/JavaScript/Reference/Global_Objects/RegExp/prototype +tags: + - JavaScript + - Property + - Prototype + - Reference + - RegExp + - регулярные выражения +translation_of: Web/JavaScript/Reference/Global_Objects/RegExp +translation_of_original: Web/JavaScript/Reference/Global_Objects/RegExp/prototype +--- +
{{JSRef("Global_Objects", "RegExp")}}
+ +

Сводка

+

Свойство RegExp.prototype представляет объект прототипа для констуктора {{jsxref("Global_Objects/RegExp", "RegExp")}}.

+ +
{{js_property_attributes(0, 0, 0)}}
+ +

Описание

+

Описание экземпляров регулярных выражений смотрите на странице документации, посвящёной объекту {{jsxref("Global_Objects/RegExp", "RegExp")}}. Экземпляры регулярных выражений наследуются от RegExp.prototype. Изменение объекта прототипа распространяется на все экземпляры регулярных выражений.

+ +

Свойства

+

Также смотрите устаревшие свойства объекта RegExp

+

Обратите внимание, что некоторые свойста объекта {{jsxref("Global_Objects/RegExp", "RegExp")}} имеют как длинные, так и короткие (Perl-подобные) имена. Оба имени всегда ссылаются на одно и тоже значение. Perl — это язык программирования, откуда JavaScript взял свои регулярные выражения.

+
+
RegExp.prototype.constructor
+
Определяет функцию, создающую прототип объекта.
+
{{jsxref("RegExp.prototype.global")}}
+
Определяет, надо ли проверять регулярное выражение на все возможные сопоставления со строкой, или достаточно только первый раз.
+
{{jsxref("RegExp.prototype.ignoreCase")}}
+
Определяет, надо ли игнорировать регистр символов при попытке сопоставления со строкой.
+
{{jsxref("RegExp.prototype.lastIndex")}}
+
Индекс, по которому начинается следующее сопоставление.
+
{{jsxref("RegExp.prototype.multiline")}}
+
Определяет, надо ли искать по нескольким строкам.
+
{{jsxref("RegExp.prototype.source")}}
+
Текст шаблона.
+
{{jsxref("RegExp.prototype.sticky")}} {{experimental_inline}}
+
Определяет, включён ли режим «липкого» поиска.
+
{{jsxref("RegExp.prototype.flags")}} {{experimental_inline}}
+
Строка, состоящая из флагов объекта регулярного выражения.
+
+
{{jsOverrides("Object", "properties", "constructor", "global", "ignoreCase", "lastIndex", "multiline", "source", "sticky")}}
+ +

Методы

+

Также смотрите устаревшие методы объекта RegExp

+
+
{{jsxref("RegExp.prototype.exec()")}}
+
Выполняет поиск сопоставлений регулярного выражения в своём строковом параметре.
+
{{jsxref("RegExp.prototype.test()")}}
+
Пытается сопоставить регулярное выражение своему строковому параметру.
+
{{jsxref("RegExp.prototype.toSource()")}} {{non-standard_inline}}
+
Возвращает объектный литерал, представляющий указаный объект; вы можете использовать это значение для создания нового объекта. Переопределяет метод {{jsxref("Object.prototype.toSource()")}}.
+
{{jsxref("RegExp.prototype.toString()")}}
+
Возвращает строку, представляющую указаннный объект. Переопределяет метод {{jsxref("Object.prototype.toString()")}}.
+
+
{{jsOverrides("Object", "Methods", "exec", "test", "toSource", "toString")}}
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарии
ECMAScript 1-е издание.СтандартИзначальное определение. Реализована в JavaScript 1.1.
{{SpecName('ES5.1', '#sec-15.10.5.1', 'RegExp')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-regexp.prototype', 'RegExp.prototype')}}{{Spec2('ES6')}} 
+ +

Совместимость с браузерами

+
{{CompatibilityTable}}
+
+ + + + + + + + + + + + + + + + + + + +
ВозможностьChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
ВозможностьAndroidChrome для AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

Смотрите также

+ diff --git a/files/ru/conflicting/web/javascript/reference/global_objects/set/index.html b/files/ru/conflicting/web/javascript/reference/global_objects/set/index.html new file mode 100644 index 0000000000..a09b758046 --- /dev/null +++ b/files/ru/conflicting/web/javascript/reference/global_objects/set/index.html @@ -0,0 +1,81 @@ +--- +title: Set.prototype +slug: Web/JavaScript/Reference/Global_Objects/Set/prototype +translation_of: Web/JavaScript/Reference/Global_Objects/Set +translation_of_original: Web/JavaScript/Reference/Global_Objects/Set/prototype +--- +
{{JSRef}}
+ +

The Set.prototype property represents the prototype for the {{jsxref("Set")}} constructor.

+ +
{{js_property_attributes(0,0,0)}}
+ +

Description

+ +

{{jsxref("Set")}} instances inherit from {{jsxref("Set.prototype")}}. You can use the constructor's prototype object to add properties or methods to all Set instances.

+ +

Свойства

+ +
+
Set.prototype.constructor
+
Возвращает функцию, которая создала прототип экземпляра. Это функция {{jsxref("Set")}} по умолчанию.
+
{{jsxref("Set.prototype.size")}}
+
Возвращает количество элементов в объекте Set.
+
+ +

Методы

+ +
+
{{jsxref("Set.add", "Set.prototype.add(value)")}}
+
Добавляет новый элемент с переданным значением в Set объект. Возвращает Set объект.
+
{{jsxref("Set.prototype.clear()")}}
+
Removes all elements from the Set object.
+
{{jsxref("Set.delete", "Set.prototype.delete(value)")}}
+
Removes the element associated to the value and returns the value that Set.prototype.has(value) would have previously returned. Set.prototype.has(value) will return false afterwards.
+
{{jsxref("Set.prototype.entries()")}}
+
Returns a new Iterator object that contains an array of [value, value] for each element in the Set object, in insertion order. This is kept similar to the Map object, so that each entry has the same value for its key and value here.
+
{{jsxref("Set.forEach", "Set.prototype.forEach(callbackFn[, thisArg])")}}
+
Calls callbackFn once for each value present in the Set object, in insertion order. If a thisArg parameter is provided to forEach, it will be used as the this value for each callback.
+
{{jsxref("Set.has", "Set.prototype.has(value)")}}
+
Returns a boolean asserting whether an element is present with the given value in the Set object or not.
+
{{jsxref("Set.prototype.keys()")}}
+
Is the same function as the values() function and returns a new Iterator object that contains the values for each element in the Set object in insertion order.
+
{{jsxref("Set.prototype.values()")}}
+
Returns a new Iterator object that contains the values for each element in the Set object in insertion order.
+
{{jsxref("Set.prototype.@@iterator()", "Set.prototype[@@iterator]()")}}
+
Returns a new Iterator object that contains the values for each element in the Set object in insertion order.
+
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-set.prototype', 'Set.prototype')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-set.prototype', 'Set.prototype')}}{{Spec2('ESDraft')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.builtins.Set.prototype")}}

+ +

See also

+ + diff --git a/files/ru/conflicting/web/javascript/reference/global_objects/string/index.html b/files/ru/conflicting/web/javascript/reference/global_objects/string/index.html new file mode 100644 index 0000000000..66537d9ae8 --- /dev/null +++ b/files/ru/conflicting/web/javascript/reference/global_objects/string/index.html @@ -0,0 +1,230 @@ +--- +title: String.prototype +slug: Web/JavaScript/Reference/Global_Objects/String/prototype +tags: + - JavaScript + - Property + - Prototype + - Reference + - String +translation_of: Web/JavaScript/Reference/Global_Objects/String +translation_of_original: Web/JavaScript/Reference/Global_Objects/String/prototype +--- +
{{JSRef("Global_Objects", "String")}}
+ +

Сводка

+ +

Свойство String.prototype представляет прототип объекта {{jsxref("Global_Objects/String", "String")}}.

+ +
{{js_property_attributes(0, 0, 0)}}
+ +

Описание

+ +

Все объекты {{jsxref("Global_Objects/String", "String")}} наследуются от String.prototype. Изменения в прототипе объекта {{jsxref("Global_Objects/String", "String")}} распространяются на все его экземпляры.

+ +

Свойства

+ +
+
String.prototype.constructor
+
Определяет функцию, создающую прототип этого объекта.
+
{{jsxref("String.prototype.length")}}
+
Отражает длину строки.
+
N
+
Используется для доступа к символу в позиции N, где N — это целое число между 0 и длиной строки {{jsxref("String.length", "length")}} минус один. Эти свойства доступны только для чтения.
+
+ +

Методы

+ +

Методы, не относящиеся к HTML

+ +
+
{{jsxref("String.prototype.charAt()")}}
+
Возвращает символ по указанному индексу.
+
{{jsxref("String.prototype.charCodeAt()")}}
+
Возвращает число, представляющее значение символа в Юникоде по указанному индексу.
+
{{jsxref("String.prototype.codePointAt()")}} {{experimental_inline}}
+
Возвращает неотрицательное целое число, представляющее закодированную в UTF-16 кодовую точку значения по указанной позиции.
+
{{jsxref("String.prototype.concat()")}}
+
Объединяет текст двух строк и возвращает новую строку.
+
{{jsxref("String.prototype.includes()")}} {{experimental_inline}}
+
Определяет, находится ли строка внутри другой строки.
+
{{jsxref("String.prototype.endsWith()")}} {{experimental_inline}}
+
Определяет, заканчивается ли строка символами другой строки.
+
{{jsxref("String.prototype.indexOf()")}}
+
Возвращает индекс первого вхождения указанного значения в объекте {{jsxref("Global_Objects/String", "String")}}, на котором был вызван этот метод, или -1, если вхождений нет.
+
{{jsxref("String.prototype.lastIndexOf()")}}
+
Возвращает индекс последнего вхождения указанного значения в объекте {{jsxref("Global_Objects/String", "String")}}, на котором был вызван этот метод, или -1, если вхождений нет.
+
{{jsxref("String.prototype.localeCompare()")}}
+
Возвращает число, указывающее, находится ли образцовая строка до, после или на том же самом месте, что и указанная строка в порядке сортировки.
+
{{jsxref("String.prototype.match()")}}
+
Используется для сопоставления строке регулярного выражения.
+
+ +
+
{{jsxref("String.prototype.matchAll()")}}
+
Возвращает итератор по всем результатам при сопоставлении строки с регулярным выражением.
+
+ +
+
{{jsxref("String.prototype.normalize()")}} {{experimental_inline}}
+
Возвращает форму нормализации Юникода для строкового значения.
+
{{jsxref("String.prototype.quote()")}} {{obsolete_inline}}
+
Оборачивает строку в двойные кавычки (""").
+
{{jsxref("String.prototype.repeat()")}} {{experimental_inline}}
+
Возвращает строку. состоящую из элементов объекта, повторённых указанное количество раз.
+
{{jsxref("String.prototype.replace()")}}
+
Используется для сопоставления строке регулярного выражения и для замены совпавшей подстроки на новую подстроку.
+
{{jsxref("String.prototype.search()")}}
+
Выполняет поиск совпадения регулярного выражения со строкой.
+
{{jsxref("String.prototype.slice()")}}
+
Извлекает часть строки и возвращает новую строку.
+
{{jsxref("String.prototype.split()")}}
+
Разбивает объект {{jsxref("Global_Objects/String", "String")}} на массив строк, разделёных указанной строкой на подстроки.
+
{{jsxref("String.prototype.startsWith()")}} {{experimental_inline}}
+
Определяет, начинается ли строка символами другой строки.
+
{{jsxref("String.prototype.substr()")}}
+
Возвращает указанное количество символов в строке, начинающихся с указанной позиции.
+
{{jsxref("String.prototype.substring()")}}
+
Возвращает символы в строке между двумя индексами.
+
{{jsxref("String.prototype.toLocaleLowerCase()")}}
+
Приводит символы в строке к нижнему регистру согласно текущей локали. Для большинства языков, метод делает то же самое, что и метод {{jsxref("String.prototype.toLowerCase()", "toLowerCase()")}}.
+
{{jsxref("String.prototype.toLocaleUpperCase()")}}
+
Приводит символы в строке к верхнему регистру согласно текущей локали. Для большинства языков, метод делает то же самое, что и метод {{jsxref("String.prototype.toUpperCase()", "toUpperCase()")}}.
+
{{jsxref("String.prototype.toLowerCase()")}}
+
Возвращает строковое значение с символами в нижнем регистре.
+
{{jsxref("String.prototype.toSource()")}} {{non-standard_inline}}
+
Возвращает литерал объекта, представляющий указанный объект; вы можете использовать это значениедля создания нового объекта. Переопределяет метод {{jsxref("Object.prototype.toSource()")}}.
+
{{jsxref("String.prototype.toString()")}}
+
Возвращает строковое представление указаного объекта. Переопределяет метод {{jsxref("Object.prototype.toString()")}}.
+
{{jsxref("String.prototype.toUpperCase()")}}
+
Возвращает строковое значение с символами в верхнем регистре.
+
{{jsxref("String.prototype.trim()")}}
+
Обрезает пробельные символы в начале и в конце строки. Часть стандарта ECMAScript 5.
+
{{jsxref("String.prototype.trimLeft()")}} {{non-standard_inline}}
+
Обрезает пробельные символы с левой стороны строки.
+
{{jsxref("String.prototype.trimRight()")}} {{non-standard_inline}}
+
Обрезает пробельные символы с правой стороны строки.
+
{{jsxref("String.prototype.valueOf()")}}
+
Возвращает примитивное значение указанного объекта. Переопределяет метод {{jsxref("Object.prototype.valueOf()")}}.
+
{{jsxref("String.prototype.@@iterator()", "String.prototype[@@iterator]()")}} {{experimental_inline}}
+
Возвращает новый объект итератора Iterator, который итерируется по кодовым точкам строки и возвращает каждую кодовую точку в виде строкового значения.
+
+ +

Методы-обёртки HTML

+ +

Эти методы имеют ограниченное применение, поскольку они представляют только ограниченное подмножество доступных тегов и атрибутов HTML.

+ +
+
{{jsxref("String.prototype.anchor()")}} {{deprecated_inline}}
+
<a name="имя"> (цель гипертекста)
+
{{jsxref("String.prototype.big()")}} {{deprecated_inline}}
+
{{HTMLElement("big")}}
+
{{jsxref("String.prototype.blink()")}} {{deprecated_inline}}
+
{{HTMLElement("blink")}}
+
{{jsxref("String.prototype.bold()")}} {{deprecated_inline}}
+
{{HTMLElement("b")}}
+
{{jsxref("String.prototype.fixed()")}} {{deprecated_inline}}
+
{{HTMLElement("tt")}}
+
{{jsxref("String.prototype.fontcolor()")}} {{deprecated_inline}}
+
<font color="цвет">
+
{{jsxref("String.prototype.fontsize()")}} {{deprecated_inline}}
+
<font size="размер">
+
{{jsxref("String.prototype.italics()")}} {{deprecated_inline}}
+
{{HTMLElement("i")}}
+
{{jsxref("String.prototype.link()")}} {{deprecated_inline}}
+
<a href="url"> (ссылка на URL)
+
{{jsxref("String.prototype.small()")}} {{deprecated_inline}}
+
{{HTMLElement("small")}}
+
{{jsxref("String.prototype.strike()")}} {{deprecated_inline}}
+
{{HTMLElement("strike")}}
+
{{jsxref("String.prototype.sub()")}} {{deprecated_inline}}}
+
{{HTMLElement("sub")}}
+
{{jsxref("String.prototype.sup()")}} {{deprecated_inline}}
+
{{HTMLElement("sup")}}
+
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарии
ECMAScript 1-е издание.СтандартИзначальное определение.
{{SpecName('ES5.1', '#sec-15.5.3.1', 'String.prototype')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-string.prototype', 'String.prototype')}}{{Spec2('ES6')}}
+ +

Совместимость с браузерами

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
ВозможностьChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
ВозможностьAndroidChrome для AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

Смотрите также

+ + diff --git a/files/ru/conflicting/web/javascript/reference/global_objects/symbol/index.html b/files/ru/conflicting/web/javascript/reference/global_objects/symbol/index.html new file mode 100644 index 0000000000..b9ce5254e6 --- /dev/null +++ b/files/ru/conflicting/web/javascript/reference/global_objects/symbol/index.html @@ -0,0 +1,107 @@ +--- +title: Symbol.prototype +slug: Web/JavaScript/Reference/Global_Objects/Symbol/prototype +tags: + - ECMAScript6 + - JavaScript + - Свойство + - Символы +translation_of: Web/JavaScript/Reference/Global_Objects/Symbol +translation_of_original: Web/JavaScript/Reference/Global_Objects/Symbol/prototype +--- +
{{JSRef}}
+ +

Свойство Symbol.prototype указывает на прототип конструктора {{jsxref("Symbol")}}.

+ +
{{js_property_attributes(0,0,0)}}
+ +

Описание

+ +

Экземпляры типа {{jsxref("Symbol")}} наследуют {{jsxref("Symbol.prototype")}}. Вы можете использовать прототип конструктора, чтобы добавить свойства и методы ко всем экземплярам типа Symbol.

+ +

Свойства

+ +
+
Symbol.prototype.constructor
+
Указывает на функцию, создавшую прототип экземпляра. По умолчанию это функция {{jsxref("Symbol")}}.
+
+ +

Методы

+ +
+
{{jsxref("Symbol.prototype.toSource()")}} {{Non-standard_inline}}
+
Возвращает строку, содержащую исходный код объекта {{jsxref("Global_Objects/Symbol", "Symbol")}}. Перегружает метод {{jsxref("Object.prototype.toSource()")}}.
+
{{jsxref("Symbol.prototype.toString()")}}
+
Возвращает строку, содержащую описание символа. Перегружает метод {{jsxref("Object.prototype.toString()")}}.
+
{{jsxref("Symbol.prototype.valueOf()")}}
+
Возвращает примитивное значение объекта {{jsxref("Symbol")}}. Перегружает метод {{jsxref("Object.prototype.valueOf()")}}.
+
+ +

Спецификации

+ + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('ES6', '#sec-symbol.prototype', 'Symbol.prototype')}}{{Spec2('ES6')}}Изначальное определение.
+ +

Поддержка браузерами

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
ВозможностьChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка{{CompatVersionUnknown}}{{ CompatGeckoDesktop("36.0") }}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
ВозможностьAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{ CompatGeckoMobile("36.0") }}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
diff --git a/files/ru/conflicting/web/javascript/reference/global_objects/syntaxerror/index.html b/files/ru/conflicting/web/javascript/reference/global_objects/syntaxerror/index.html new file mode 100644 index 0000000000..840ac61f2b --- /dev/null +++ b/files/ru/conflicting/web/javascript/reference/global_objects/syntaxerror/index.html @@ -0,0 +1,123 @@ +--- +title: SyntaxError.prototype +slug: Web/JavaScript/Reference/Global_Objects/SyntaxError/prototype +tags: + - Error + - JavaScript + - Property + - Prototype + - SyntaxError +translation_of: Web/JavaScript/Reference/Global_Objects/SyntaxError +translation_of_original: Web/JavaScript/Reference/Global_Objects/SyntaxError/prototype +--- +
{{JSRef("Global_Objects", "Error", "EvalError,InternalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError")}}
+ +

Сводка

+

Свойство SyntaxError.prototype представляет прототип конструктора объекта {{jsxref("SyntaxError")}}.

+ +
{{js_property_attributes(0, 0, 0)}}
+ +

Описание

+

Все экземпляры {{jsxref("SyntaxError")}} наследуются от объекта SyntaxError.prototype. Вы можете использовать прототип для добавления свойств или методов ко всем экземплярам.

+ +

Свойства

+
+
SyntaxError.prototype.constructor
+
Определяет функцию, создающую прототип экземпляра.
+
{{jsxref("Error.prototype.message", "SyntaxError.prototype.message")}}
+
Сообщение ошибки. Хотя стандарт ECMA-262 определяет, что {{jsxref("SyntaxError")}} должен предоставлять своё собственное свойство message, в SpiderMonkey он наследует свойство {{jsxref("Error.prototype.message")}}.
+
{{jsxref("Error.prototype.name", "SyntaxError.prototype.name")}}
+
Название ошибки. Унаследовано от {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.fileName", "SyntaxError.prototype.fileName")}}
+
Путь к файлу, в котором возникла эта ошибка. Унаследовано от {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.lineNumber", "SyntaxError.prototype.lineNumber")}}
+
Номер строки в файле, в котором возникла эта ошибка. Унаследовано от {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.columnNumber", "SyntaxError.prototype.columnNumber")}}
+
Номер колонки в строке, на которой возникла эта ошибка. Унаследовано от {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.stack", "SyntaxError.prototype.stack")}}
+
Стек вызовов. Унаследовано от {{jsxref("Error")}}.
+
+ +

Методы

+

Хотя объект прототипа {{jsxref("SyntaxError")}} не содержит собственных методов, экземпляры {{jsxref("SyntaxError")}} наследуют некоторые методы из цепочки прототипов.

+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарии
ECMAScript 3-е издание.СтандартИзначальное определение.
{{SpecName('ES5.1', '#sec-15.11.7.6', 'NativeError.prototype')}}{{Spec2('ES5.1')}}Определено как NativeError.prototype.
{{SpecName('ES6', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ES6')}}Определено как NativeError.prototype.
+ +

Совместимость с браузерами

+
{{CompatibilityTable}}
+
+ + + + + + + + + + + + + + + + + + + +
ВозможностьChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
ВозможностьAndroidChrome для AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

Смотрите также

+ diff --git a/files/ru/conflicting/web/javascript/reference/global_objects/typedarray/index.html b/files/ru/conflicting/web/javascript/reference/global_objects/typedarray/index.html new file mode 100644 index 0000000000..1b79a06ad9 --- /dev/null +++ b/files/ru/conflicting/web/javascript/reference/global_objects/typedarray/index.html @@ -0,0 +1,129 @@ +--- +title: TypedArray.prototype +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/prototype +tags: + - TypedArray + - Типизированный массив +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray +translation_of_original: Web/JavaScript/Reference/Global_Objects/TypedArray/prototype +--- +
{{JSRef}}
+ +

Свойство TypedArray.prototype является прототипом для {{jsxref("TypedArray")}}-конструкторов.

+ +
{{js_property_attributes(0,0,0)}}
+ +

Описание

+ +

Экземпляры {{jsxref("TypedArray")}} наследуются от {{jsxref("TypedArray.prototype")}}. Вы можете использовать объект прототипа конструктора для добавления в свойств и методов во все экземпляры TypedArray, где TypedArray это один из типизированных массивов.

+ +

Также смотрите описание TypedArray для детальной информации о наследниках.

+ +

Свойства

+ +
+
TypedArray.prototype.constructor
+
Возвращает функцию, которая создала прототип экземпляра. Это единственное, что для объектов типизированных массивов функционирует по умолчанию.
+
{{jsxref("TypedArray.prototype.buffer")}} {{readonlyInline}}
+
Возвращает {{jsxref("ArrayBuffer")}}, на который ссылается типизированный массив. Значение фиксировано с времени создания и доступно только для чтения.
+
{{jsxref("TypedArray.prototype.byteLength")}} {{readonlyInline}}
+
Возвращает длину (в байтах) типизированного массива (с начала {{jsxref("ArrayBuffer")}}). Значение фиксировано с времени создания и доступно только для чтения.
+
{{jsxref("TypedArray.prototype.byteOffset")}} {{readonlyInline}}
+
Возвращает смещение (в байтах) типизированного массива от его {{jsxref("ArrayBuffer")}}. Значение фиксировано с времени создания и доступно только для чтения.
+
{{jsxref("TypedArray.prototype.length")}} {{readonlyInline}}
+
Возвращает число элементов типизированного массива. Значение фиксировано с времени создания и доступно только для чтения.
+
+ +

Методы

+ +
+
{{jsxref("TypedArray.prototype.copyWithin()")}}
+
Копирует последовательность элементов массива внутри него. Подробнее {{jsxref("Array.prototype.copyWithin()")}}.
+
{{jsxref("TypedArray.prototype.entries()")}}
+
Возвращает новый объект итератора Array Iterator, содержащий пары ключ / значение для каждого индекса массива. Подробнее {{jsxref("Array.prototype.entries()")}}.
+
{{jsxref("TypedArray.prototype.every()")}}
+
Проверяет, удовлетворяют ли все элементы массива условию, заданному в передаваемой функции. Подробнее {{jsxref("Array.prototype.every()")}}.
+
{{jsxref("TypedArray.prototype.fill()")}}
+
Заполняет все элементы массива от начального индекта до конечного индекса указанным значением. Подробнее {{jsxref("Array.prototype.fill()")}}.
+
{{jsxref("TypedArray.prototype.filter()")}}
+
Создаёт новый массив с теми элементами текущего массива, с которыми фильтрующая функция вернёт true. Подробнее {{jsxref("Array.prototype.filter()")}}.
+
{{jsxref("TypedArray.prototype.find()")}}
+
Возвращает значение элемента массива, если элемент удовлетворяет условию проверяющей функции, иначе возвращается undefined. Подробнее {{jsxref("Array.prototype.find()")}}.
+
{{jsxref("TypedArray.prototype.findIndex()")}}
+
Возвращает индекс элемента массива, если элемент удовлетворяет условию проверяющей функции, иначе возвращается -1. Подробнее {{jsxref("Array.prototype.findIndex()")}}.
+
{{jsxref("TypedArray.prototype.forEach()")}}
+
Выполняет указанную функцию один раз для каждого элемента в массиве. Подробнее {{jsxref("Array.prototype.forEach()")}}.
+
{{jsxref("TypedArray.prototype.includes()")}} {{experimental_inline}}
+
Определяет, содержит ли массив определённый элемент, возвращая в зависимости от этого true или false. Подробнее {{jsxref("Array.prototype.includes()")}}.
+
{{jsxref("TypedArray.prototype.indexOf()")}}
+
Возвращает первый (меньший) индекс элемента, значение которого равно указанному значению или -1, если такого индекса нет. Подробнее {{jsxref("Array.prototype.indexOf()")}}.
+
{{jsxref("TypedArray.prototype.join()")}}
+
Объединяет все элементы массива в строку . Подробнее {{jsxref("Array.prototype.join()")}}.
+
{{jsxref("TypedArray.prototype.keys()")}}
+
Возвращает новый итератор массива Array Iterator, содержащий ключи каждого индекса в массиве. Подробнее {{jsxref("Array.prototype.keys()")}}.
+
{{jsxref("TypedArray.prototype.lastIndexOf()")}}
+
Возвращает последний (больший) индекс элемента, значение которого равно заданному значению или -1, если такого индекса нет. Подробнее {{jsxref("Array.prototype.lastIndexOf()")}}.
+
{{jsxref("TypedArray.prototype.map()")}}
+
Создаёт новый массив с результатом вызова указанной функции для каждого элемента массива. Подробнее {{jsxref("Array.prototype.map()")}}.
+
{{jsxref("TypedArray.prototype.move()")}} {{non-standard_inline}} {{unimplemented_inline}}
+
Ранний нестандартный вариант от {{jsxref("TypedArray.prototype.copyWithin()")}}.
+
{{jsxref("TypedArray.prototype.reduce()")}}
+
Применяет функцию к аккумулятору и каждому значению массива (слева-направо), сводя его к одному значению. Подробнее {{jsxref("Array.prototype.reduce()")}}.
+
{{jsxref("TypedArray.prototype.reduceRight()")}}
+
Применяет функцию к аккумулятору и каждому значению массива (справа-налево), сводя его к одному значению. Подробнее {{jsxref("Array.prototype.reduceRight()")}}.
+
{{jsxref("TypedArray.prototype.reverse()")}}
+
Обращает порядок следования элементов массива. Первый элемент массива становится последним, а последний — первым. Подробнее {{jsxref("Array.prototype.reverse()")}}.
+
{{jsxref("TypedArray.prototype.set()")}}
+
Сохраняет несколько значений в типизированном массиве, получая входные значения из указанного массива.
+
{{jsxref("TypedArray.prototype.slice()")}}
+
Возвращает часть массива в новый объект массива. Подробнее {{jsxref("Array.prototype.slice()")}}.
+
{{jsxref("TypedArray.prototype.some()")}}
+
Возвращает true, если хоть какой-нибудь элемент массива удовлетворяет условию, заданному в передаваемой функции. Подробнее {{jsxref("Array.prototype.some()")}}.
+
{{jsxref("TypedArray.prototype.sort()")}}
+
На месте сортирует элементы массива и возвращает отсортированный массив. Подробнее {{jsxref("Array.prototype.sort()")}}.
+
{{jsxref("TypedArray.prototype.subarray()")}}
+
Возвращает новый TypedArray-объект, начиная с указанного стартового и кончая указанным конечным индексом элемента массива.
+
{{jsxref("TypedArray.prototype.values()")}}
+
Возвращает новый объект итератора массива Array Iterator, содержащий значения для каждого индекса в массиве. Подробнее {{jsxref("Array.prototype.values()")}}.
+
{{jsxref("TypedArray.prototype.toLocaleString()")}}
+
Возвращает локализованное строковое представление элементов массива. Подробнее {{jsxref("Array.prototype.toLocaleString()")}}.
+
{{jsxref("TypedArray.prototype.toString()")}}
+
Возвращает строковое представление указанного массива и его элементов . Подробнее {{jsxref("Array.prototype.toString()")}}.
+
{{jsxref("TypedArray.prototype.@@iterator()", "TypedArray.prototype[@@iterator]()")}}
+
Возвращает новый объект итератора массива Array Iterator, содержащий значения для каждого индекса массива.
+
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусОписание
{{SpecName('ES6', '#sec-properties-of-the-%typedarrayprototype%-object', 'TypedArray prototype')}}{{Spec2('ES6')}}Первоначальное определение
{{SpecName('ESDraft', '#sec-properties-of-the-%typedarrayprototype%-object', 'TypedArray prototype')}}{{Spec2('ESDraft')}} 
+ +

Совместимость браузеров

+ + + +

{{Compat("javascript.builtins.TypedArray.prototype")}}

+ +

Смотрите также

+ + diff --git a/files/ru/conflicting/web/javascript/reference/global_objects/typeerror/index.html b/files/ru/conflicting/web/javascript/reference/global_objects/typeerror/index.html new file mode 100644 index 0000000000..87a22a4a94 --- /dev/null +++ b/files/ru/conflicting/web/javascript/reference/global_objects/typeerror/index.html @@ -0,0 +1,123 @@ +--- +title: TypeError.prototype +slug: Web/JavaScript/Reference/Global_Objects/TypeError/prototype +tags: + - Error + - JavaScript + - Property + - Prototype + - TypeError +translation_of: Web/JavaScript/Reference/Global_Objects/TypeError +translation_of_original: Web/JavaScript/Reference/Global_Objects/TypeError/prototype +--- +
{{JSRef("Global_Objects", "Error", "EvalError,InternalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError")}}
+ +

Сводка

+

Свойство TypeError.prototype представляет прототип конструктора объекта {{jsxref("TypeError")}}.

+ +
{{js_property_attributes(0, 0, 0)}}
+ +

Описание

+

Все экземпляры {{jsxref("TypeError")}} наследуются от объекта TypeError.prototype. Вы можете использовать прототип для добавления свойств или методов ко всем экземплярам.

+ +

Свойства

+
+
TypeError.prototype.constructor
+
Определяет функцию, создающую прототип экземпляра.
+
{{jsxref("Error.prototype.message", "TypeError.prototype.message")}}
+
Сообщение ошибки. Хотя стандарт ECMA-262 определяет, что {{jsxref("TypeError")}} должен предоставлять своё собственное свойство message, в SpiderMonkey он наследует свойство {{jsxref("Error.prototype.message")}}.
+
{{jsxref("Error.prototype.name", "TypeError.prototype.name")}}
+
Название ошибки. Унаследовано от {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.fileName", "TypeError.prototype.fileName")}}
+
Путь к файлу, в котором возникла эта ошибка. Унаследовано от {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.lineNumber", "TypeError.prototype.lineNumber")}}
+
Номер строки в файле, в котором возникла эта ошибка. Унаследовано от {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.columnNumber", "TypeError.prototype.columnNumber")}}
+
Номер колонки в строке, на которой возникла эта ошибка. Унаследовано от {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.stack", "TypeError.prototype.stack")}}
+
Стек вызовов. Унаследовано от {{jsxref("Error")}}.
+
+ +

Методы

+

Хотя объект прототипа {{jsxref("TypeError")}} не содержит собственных методов, экземпляры {{jsxref("TypeError")}} наследуют некоторые методы из цепочки прототипов.

+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарии
ECMAScript 3-е издание.СтандартИзначальное определение.
{{SpecName('ES5.1', '#sec-15.11.7.6', 'NativeError.prototype')}}{{Spec2('ES5.1')}}Определено как NativeError.prototype.
{{SpecName('ES6', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ES6')}}Определено как NativeError.prototype.
+ +

Совместимость с браузерами

+
{{CompatibilityTable}}
+
+ + + + + + + + + + + + + + + + + + + +
ВозможностьChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
ВозможностьAndroidChrome для AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

Смотрите также

+ diff --git a/files/ru/conflicting/web/javascript/reference/global_objects/urierror/index.html b/files/ru/conflicting/web/javascript/reference/global_objects/urierror/index.html new file mode 100644 index 0000000000..9998443521 --- /dev/null +++ b/files/ru/conflicting/web/javascript/reference/global_objects/urierror/index.html @@ -0,0 +1,123 @@ +--- +title: URIError.prototype +slug: Web/JavaScript/Reference/Global_Objects/URIError/prototype +tags: + - Error + - JavaScript + - Property + - Prototype + - URIError +translation_of: Web/JavaScript/Reference/Global_Objects/URIError +translation_of_original: Web/JavaScript/Reference/Global_Objects/URIError/prototype +--- +
{{JSRef("Global_Objects", "Error", "EvalError,InternalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError")}}
+ +

Сводка

+

Свойство URIError.prototype представляет прототип конструктора объекта {{jsxref("URIError")}}.

+ +
{{js_property_attributes(0, 0, 0)}}
+ +

Описание

+

Все экземпляры {{jsxref("URIError")}} наследуются от объекта URIError.prototype. Вы можете использовать прототип для добавления свойств или методов ко всем экземплярам.

+ +

Свойства

+
+
URIError.prototype.constructor
+
Определяет функцию, создающую прототип экземпляра.
+
{{jsxref("Error.prototype.message", "URIError.prototype.message")}}
+
Сообщение ошибки. Хотя стандарт ECMA-262 определяет, что {{jsxref("URIError")}} должен предоставлять своё собственное свойство message, в SpiderMonkey он наследует свойство {{jsxref("Error.prototype.message")}}.
+
{{jsxref("Error.prototype.name", "URIError.prototype.name")}}
+
Название ошибки. Унаследовано от {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.fileName", "URIError.prototype.fileName")}}
+
Путь к файлу, в котором возникла эта ошибка. Унаследовано от {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.lineNumber", "URIError.prototype.lineNumber")}}
+
Номер строки в файле, в котором возникла эта ошибка. Унаследовано от {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.columnNumber", "URIError.prototype.columnNumber")}}
+
Номер колонки в строке, на которой возникла эта ошибка. Унаследовано от {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.stack", "URIError.prototype.stack")}}
+
Стек вызовов. Унаследовано от {{jsxref("Error")}}.
+
+ +

Методы

+

Хотя объект прототипа {{jsxref("URIError")}} не содержит собственных методов, экземпляры {{jsxref("URIError")}} наследуют некоторые методы из цепочки прототипов.

+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарии
ECMAScript 3-е издание.СтандартИзначальное определение.
{{SpecName('ES5.1', '#sec-15.11.7.6', 'NativeError.prototype')}}{{Spec2('ES5.1')}}Определено как NativeError.prototype.
{{SpecName('ES6', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ES6')}}Определено как NativeError.prototype.
+ +

Совместимость с браузерами

+
{{CompatibilityTable}}
+
+ + + + + + + + + + + + + + + + + + + +
ВозможностьChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
ВозможностьAndroidChrome для AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

Смотрите также

+ diff --git a/files/ru/conflicting/web/javascript/reference/global_objects/weakmap/index.html b/files/ru/conflicting/web/javascript/reference/global_objects/weakmap/index.html new file mode 100644 index 0000000000..56e1cf2fd8 --- /dev/null +++ b/files/ru/conflicting/web/javascript/reference/global_objects/weakmap/index.html @@ -0,0 +1,75 @@ +--- +title: WeakMap.prototype +slug: Web/JavaScript/Reference/Global_Objects/WeakMap/prototype +translation_of: Web/JavaScript/Reference/Global_Objects/WeakMap +translation_of_original: Web/JavaScript/Reference/Global_Objects/WeakMap/prototype +--- +
{{JSRef}}
+ +

WeakMap.prototype свойство указыкает на прототип {{jsxref("WeakMap")}} конструктора.

+ +
{{js_property_attributes(0,0,0)}}
+ +

Описание

+ +

{{jsxref("WeakMap")}} экзепляры унаследывают {{jsxref("WeakMap.prototype")}}. Вы можите использовать прототип конструктора объекта для добавления нових свойств и/или методов всем экзепляра класса WeakMap.

+ +

WeakMap.prototype является простым объектом:

+ +
Object.prototype.toString.call(WeakMap.prototype); // "[object Object]"
+ +

Свойства

+ +
+
WeakMap.prototype.constructor
+
Возвращает функцию, создавшую экземпляр. {{jsxref("WeakMap")}} function by default.
+
+ +

Методы

+ +
+
{{jsxref("WeakMap.delete", "WeakMap.prototype.delete(key)")}}
+
Удаление значение по ключу. WeakMap.prototype.has(key) вернет false после.
+
{{jsxref("WeakMap.get", "WeakMap.prototype.get(key)")}}
+
Возвращает значение по ключу, or undefined такового нет.
+
{{jsxref("WeakMap.has", "WeakMap.prototype.has(key)")}}
+
Вернет логическое значение, связанное с существованием ключа.
+
{{jsxref("WeakMap.set", "WeakMap.prototype.set(key, value)")}}
+
Устанавливает значение по ключу, после возвращает самого себя.
+
{{jsxref("WeakMap.prototype.clear()")}} {{obsolete_inline}}
+
Удаляет все ключи-значения из WeakMap объекта. Заметьте, что это возможно, только есть WeakMap-like объект имеет.clear() метод путем инкапсулирования WeakMap объекта, раннее неимевшего его (смотри пример на странице {{jsxref("WeakMap")}})
+
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-weakmap.prototype', 'WeakMap.prototype')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-weakmap.prototype', 'WeakMap.prototype')}}{{Spec2('ESDraft')}} 
+ +

Совместимость

+ + + +

{{Compat("javascript.builtins.WeakMap.prototype")}}

+ +

Рекомендуем

+ + diff --git a/files/ru/conflicting/web/javascript/reference/global_objects/weakset/index.html b/files/ru/conflicting/web/javascript/reference/global_objects/weakset/index.html new file mode 100644 index 0000000000..00725e2331 --- /dev/null +++ b/files/ru/conflicting/web/javascript/reference/global_objects/weakset/index.html @@ -0,0 +1,142 @@ +--- +title: WeakSet.prototype +slug: Web/JavaScript/Reference/Global_Objects/WeakSet/prototype +tags: + - ECMAScript6 + - JavaScript + - Property + - WeakSet +translation_of: Web/JavaScript/Reference/Global_Objects/WeakSet +translation_of_original: Web/JavaScript/Reference/Global_Objects/WeakSet/prototype +--- +
{{JSRef("Global_Objects", "WeakSet")}}
+ +

Свойство WeakSet.prototype представляет прототип для конструктора {{jsxref("WeakSet")}}.

+ +
{{js_property_attributes(0,0,0)}}
+ +

Описание

+ +

Экземпляры {{jsxref("WeakSet")}} наследуются от {{jsxref("WeakSet.prototype")}}. Вы можете изменять прототип конструктора объекта для применения изменений ко всем экземплярам класса WeakSet.

+ +

WeakSet.prototype сам по себе является обычным объектом:

+ +
Object.prototype.toString.call(WeakSet.prototype); // "[object Object]"
+ +

Свойства

+ +
+
WeakSet.prototype.constructor
+
Возвращает функцию, создающую экземпляр прототипа. По умолчанию, это функция {{jsxref("WeakSet")}}.
+
+ +

Методы

+ +
+
{{jsxref("WeakSet.add", "WeakSet.prototype.add(value)")}}
+
Добавляет объект value в WeakSet. 
+
{{jsxref("WeakSet.delete", "WeakSet.prototype.delete(value)")}}
+
Удаляет из WeakSet элемент value. После удаления вызов WeakSet.prototype.has(value) возвращает false. 
+
{{jsxref("WeakSet.has", "WeakSet.prototype.has(value)")}}
+
Определяет, содержит WeakSet объект value или нет, возвращая, соответственно, true или false. 
+
{{jsxref("WeakSet.prototype.clear()")}} {{obsolete_inline}}
+
Удаляет все элементы из объекта WeakSet.
+
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-weakset.prototype', 'WeakSet.prototype')}}{{Spec2('ES6')}}Изначальное определение.
{{SpecName('ESDraft', '#sec-weakset.prototype', 'WeakSet.prototype')}}{{Spec2('ESDraft')}} 
+ +

Совместимость с браузерами

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support36{{ CompatGeckoDesktop(34) }}{{CompatNo}}23{{CompatNo}}
Ordinary object{{CompatUnknown}}{{CompatGeckoDesktop("40")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChrome for AndroidAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{ CompatGeckoMobile(34) }}{{CompatNo}}{{CompatNo}}{{CompatNo}}
Ordinary object{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("40")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

Смотрите также

+ + diff --git a/files/ru/conflicting/web/javascript/reference/operators/index.html b/files/ru/conflicting/web/javascript/reference/operators/index.html new file mode 100644 index 0000000000..f1091e3706 --- /dev/null +++ b/files/ru/conflicting/web/javascript/reference/operators/index.html @@ -0,0 +1,291 @@ +--- +title: Арифметические операции +slug: Web/JavaScript/Reference/Operators/Arithmetic_Operators +tags: + - JavaScript + - Операторы +translation_of: Web/JavaScript/Reference/Operators +translation_of_original: Web/JavaScript/Reference/Operators/Arithmetic_Operators +--- +
+
{{jsSidebar("Operators")}}
+
+ +

Арифметические операции принимают в качестве операндов числовые значения (это может быть и литерал и переменная) и возвращают результат в виде одного числового значения. Стандартными арифметическими операциями являются сложение (+), вычитание (-), умножение (*) и деление (/).

+ +

Сложение (+)

+ +

Оператор сложения возвращает сумму числовых операндов или объединяет строки.

+ +

Синтаксис

+ +
Operator: x + y
+
+ +

Примеры

+ +
// Number + Number -> сложение
+1 + 2 // 3
+
+// Boolean + Number -> сложение
+true + 1 // 2
+
+// Boolean + Boolean -> сложение
+false + false // 0
+
+// Number + String -> конкатенация
+5 + "foo" // "5foo"
+
+// String + Boolean -> конкатенация
+"foo" + false // "foofalse"
+
+// String + String -> конкатенация
+"foo" + "bar" // "foobar"
+
+ +

Вычитание (-)

+ +

Оператор вычитания вычитает один операнд из другого и возвращает разницу.

+ +

Синтаксис

+ +
Operator: x - y
+
+ +

Примеры

+ +
5 - 3 // 2
+3 - 5 // -2
+"foo" - 3 // NaN
+ +

Деление (/)

+ +

Оператор деления производит деление его операндов, где левый операнд - делимый, а правый - делитель.

+ +

Синтаксис

+ +
Operator: x / y
+
+ +

Примеры

+ +
1 / 2      // возвращает 0.5 в JavaScript
+1 / 2      // возвращает 0 в Java
+// (так числа не с плавающими точками)
+
+1.0 / 2.0  // возвращает 0.5 и в JavaScript и в Java
+
+2.0 / 0    // возвращает Infinity в JavaScript
+2.0 / 0.0  // тоже возвращает Infinity
+2.0 / -0.0 // возвращает -Infinity в JavaScript
+ +

Умножение (*)

+ +

Оператор умножения возвращает произведение операндов.

+ +

Синтаксис

+ +
Operator: x * y
+
+ +

Примеры

+ +
2 * 2 // 4
+-2 * 2 // -4
+Infinity * 0 // NaN
+Infinity * Infinity // Infinity
+"foo" * 2 // NaN
+
+ +

Остаток от деления (%)

+ +

Оператор возвращает целый остаток от деления левого операнда на правый. Возвращаемое значение всегда получает знак делимого, а не делителя.  Он использует встроенную функцию modulo, для получения результата, которая является целочисленным остатком деления var1 на var2 — например— var1 modulo var2Есть предложение добавить оператор modulo в будущие версии ECMAScript, с той разницей, что оператор будет брать знак делителя, а не делимого.

+ +

Синтаксис

+ +
Оператор: var1 % var2
+
+ +

Примеры

+ +
12 % 5 // 2
+-1 % 2 // -1
+NaN % 2 // NaN
+1 % 2 // 1
+2 % 3 // 2
+-4 % 2 // -0
+5.5 % 2 // 1.5
+ +

Возведение в степень (**)

+ +

Оператор возведения в степень возвращает результат первого операнда в степень. это, var1var2, в предыдущем выражении, где var1 и var2 - переменные. Он право ассоциативен. a ** b ** c равно a ** (b ** c).

+ +

Синтаксис

+ +
Оператор: var1 ** var2
+ +

Замечания

+ +

Во многих языках, таких как PHP и Python и других, есть оператор возведения возведения в степень (обычно ^ или **), оператор определён имеющим приоритет выше, чем у унарных операторов, таких как унарный + и унарный -, но есть несколько исключений. Например, в Bash оператор ** создан имеющим приоритет ниже, чем у унарных операторов. В JavaScript невозможно написать двухсмысленное выражение, т.е. вы не можете ставить унарный оператор (+/-/~/!/delete/void/typeof) непосредственно перед базовым числом.

+ +
-2 ** 2;
+// 4 в Bash, -4 в других языках.
+// Это некорректно в JavaScript, т.е. операция двухсмыслена.
+
+
+-(2 ** 2);
+// -4 в JavaScript, намерения автора однозначны.
+ +

Примеры

+ +
2 ** 3 // 8
+3 ** 2 // 9
+3 ** 2.5 // 15.588457268119896
+10 ** -1 // 0.1
+NaN ** 2 // NaN
+
+2 ** 3 ** 2 // 512
+2 ** (3 ** 2) // 512
+(2 ** 3) ** 2 // 64
+ +

Изменим знак результата возведения в степень:

+ +
-(2 ** 2) // -4
+ +

Насильная установка основания как отрицательного числа:

+ +
(-2) ** 2 // 4
+ +

Инкремент (++)

+ +

Оператор инкремента увеличивает на единицу(инкрементирует) операнд и возвращает значение.

+ + + +

Синтаксис

+ +
Оператор: x++ или ++x
+
+ +

Примеры

+ +
// Постфиксный
+var x = 3;
+y = x++; // y = 3, x = 4
+
+// Префиксный
+var a = 2;
+b = ++a; // a = 3, b = 3
+
+ +

+ +

Декремент (--)

+ +

Операция декремента уменьшает на 1 (отнимает единицу) свой операнд и возвращает значение.

+ + + +

Синтаксис

+ +
Оператор: x-- или --x
+
+ +

Примеры

+ +
// Постфиксный
+var x = 3;
+y = x--; // y = 3, x = 2
+
+// Префиксный
+var a = 2;
+b = --a; // a = 1, b = 1
+
+ +

Унарный минус (-)

+ +

Унарный минус ставится перед своим операндом и возвращает его математическое отрицание.

+ +

Синтаксис

+ +
Оператор: -x
+
+ +

Примеры

+ +
var x = 3;
+y = -x; // y = -3, x = 3
+
+ +

Унарный плюс (+)

+ +

Оператор унарный плюс предшедствует своему операнду и оценивает его, пытается преобразовать его в число, если он им не является. Хотя, унарное отрицание (-) также конвертирует не числа, унарный плюс - быстрейший и предпочитаемый способ конвертирования чего-либо в число потому, что он не выполняет каких-либо операций с числом. Он может конвертировать строковые представления целых и чисел с плавающей точкой, а также нестроковые значения true, false и null. Поддерживаются числа в десятичном и шестнадцатиричном (с префиксом "0x") формате. Отрицательные числа тоже поддерживаются (но не 16-ричные). Если он не может вычислить конкретное значение, выполнится как NaN.

+ +

Синтаксис

+ +
Оператор: +x
+
+ +

Примеры

+ +
+3     // 3
++"3"   // 3
++true  // 1
++false // 0
++null  // 0
+
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусПримечание
{{SpecName('ES1')}}{{Spec2('ES1')}}Изначальное определение
{{SpecName('ES5.1', '#sec-11.3')}}{{Spec2('ES5.1')}}Определено в нескольких секциях специфии: Additive operators, Multiplicative operators, Postfix expressions, Unary operators.
{{SpecName('ES6', '#sec-postfix-expressions')}}{{Spec2('ES6')}}Определено в нескольких секциях специфии: Additive operators, Multiplicative operators, Postfix expressions, Unary operators.
{{SpecName('ES7', '#sec-postfix-expressions')}}{{Spec2('ES7')}}Добавлен Оператор возведения в степень.
{{SpecName('ESDraft', '#sec-postfix-expressions')}}{{Spec2('ESDraft')}}
+ +

Поддержка браузерами

+ + + +

{{Compat("javascript.operators.arithmetic")}}

+ +

Смотрите также

+ + diff --git a/files/ru/conflicting/web/javascript/reference/operators_69135a8d5772f8b6e45265523df05d89/index.html b/files/ru/conflicting/web/javascript/reference/operators_69135a8d5772f8b6e45265523df05d89/index.html new file mode 100644 index 0000000000..ee0565dc94 --- /dev/null +++ b/files/ru/conflicting/web/javascript/reference/operators_69135a8d5772f8b6e45265523df05d89/index.html @@ -0,0 +1,286 @@ +--- +title: Операторы сравнения +slug: Web/JavaScript/Reference/Operators/Операторы_сравнения +tags: + - JavaScript + - Операторы +translation_of: Web/JavaScript/Reference/Operators +translation_of_original: Web/JavaScript/Reference/Operators/Comparison_Operators +--- +
{{jsSidebar("Operators")}}
+ +

В JavaScript имеются как строгие сравнения, так и сравнения с преобразованием типа операндов. Строгие сравнения (к примеру, ===) истинны только в том случае, если типы сравниваемых значений являются одинаковыми (к примеру: string-string, number-number). Однако, чаще используются сравнения с преобразованием типов (к примеру, ==). Такой тип сравнения, перед тем как непосредственно выполнить сравнение, приводит операнды к одному типу. В случае же абстрактного реляционного сравнения, операнды сперва преобразуются в примитивы, затем приводятся к одному типу, и только после этого сравниваются.

+ +

Строки сравниваются на основе стандартного лексикографического упорядочения, используя значения Unicode.

+ +

Особенности сравнений:

+ + + +

При использовании сравнения с преобразованием типов, следует быть крайне осторожным, так как это может привести к непредвиденным проблемам, связанным с особенностями конвертации различных типов (см. параграф "Использование операторов равенства").

+ +

Операторы равенства

+ +

Равно (==)

+ +

Оператор равно сначала приводит операнды к одному типу, и затем применяет строгое сравнение. Если оба операнда являются объектами, то JavaScript сравнивает внутренние ссылки, которые равны в том случае, если они ссылаются на один и тот же объект в памяти.

+ +

Синтаксис

+ +
x == y
+
+ +

Примеры

+ +
 1  ==  1      // истина
+"1" ==  1      // истина
+ 1  == '1'     // истина
+ 3  ==  5      // ложь
+ 0  == false   // истина
+"foo" == "bar" // ложь
+
+ +

Не равно (!=)

+ +

Оператор не равно возвращает true в том случае, если операнды не равны.Он аналогичен оператору равенства, перед сравнением приводит операнды к одному типу. В случае если оба операнда являются объектами,  JavaScript сравнивает внутренние ссылки, которые не равны в том случае, если относятся к разным объектам в памяти.

+ +

Синтаксис

+ +
x != y
+ +

Примеры

+ +
1 !=   2       // истина
+1 !=  "1"      // ложь
+1 !=  '1'      // ложь
+1 !=  true     // ложь
+0 !=  false    // ложь
+"foo" != "bar" // истина
+
+ +

Строго равно (===)

+ +

Оператор возвращает истину в том случае, если операнды строго равны (см. выше). В отличие от оператора равно, данный оператор не приводит операнды к одному типу.

+ +

Синтаксис

+ +
x === y
+ +

Примеры

+ +
3 === 3   // истина
+3 === '3' // ложь
+'foo' === 'foo' // истина
+
+ +

Строго не равно (!==)

+ +

Оператор строго не равно возвращает истину в том случае, если операнды не равны, или их типы отличаются друг от друга.

+ +

Синтаксис

+ +
x !== y
+ +

Примеры

+ +
3 !== '3' // истина
+4 !== 3   // истина
+
+ +

Операторы сравнения

+ +

Больше (>)

+ +

Оператор больше возвращает истину в том случае, если значение левого операнда больше, чем правого.

+ +

Синтаксис

+ +
x > y
+ +

Примеры

+ +
4 > 3 // истина
+1 > 5 // ложь
+
+ +

Больше или равно (>=)

+ +

Оператор больше или равно, возвращает истину в том случае, если значение операнда слева больше или равно значению операнда справа.

+ +

Синтаксис

+ +
 x >= y
+ +

Примеры

+ +
4 >= 3 // истина
+3 >= 3 // истина
+
+ +

Меньше(<)

+ +

Оператор меньше, возвращает истину в том случае, если значение операнда слева меньше, чем значение операнда справа.

+ +

Синтаксис

+ +
 x < y
+ +

Примеры

+ +
3 < 4 // истина
+5 < 2 // ложь
+
+ +

Меньше или равно (<=)

+ +

Оператор меньше или равно, возвращает истину в том случае, если значение операнда слева меньше, или равно значению операнда справа.

+ +

Синтаксис

+ +
 x <= y
+ +

Примеры

+ +
3 <= 4 // истина
+3 <= 3 // истина
+
+ +

Использование операторов равенства

+ +

Стандартные операции равенства с преобразованием типов (== и !=) используют Абстрактный Алгоритм Эквивалентного Сравнения для сравнения двух операндов. Если у операндов различные типы, то JavaScript пытается привести их к одному типу, перед тем как сравнивать их. К примеру, в выражении 5 == '5', строка справа конвертируется в число, и только потом сравнивается.

+ +

Операторы строгого равентсва (=== и !==) используют Строгий Алгоритм Эквивалентного Сравнения, и предназначены для сравнения операндов одного типа. Если операнды имеют разные типы, то результат операции сравнения всегда будет ложью. К примеру, выражение 5 !== '5' будет истинным.

+ +

Используйте операторы строгого равенства в тех случаях, когда необходимо проверять не только значения операндов, но так же и их типы. Во противном случае, используйте операторы стандартного равенства, которые позволяют сравнить два операнда вне зависимости от их типов.

+ +

Когда происходит преобразование типов (т.е в случаях использования нестрогого сравнения), JavaScript преобразует типы String, Number, Boolean и Object, следующим образом:

+ + + +
Внимание: Объекты String имеют тип Object, а не String. Такие объекты используются редко, так что следующий код может вас сильно удивить.
+ +
// Истина, так как оба операнда имеют тип String
+'foo' === 'foo'
+
+var a = new String('foo');
+var b = new String('foo');
+
+// Ложь, так как операнды являются объектами, внутренние ссылки которых, ссылаются на разные объекты в памяти
+a == b
+
+// Ложь, так как операнды являются объектами, внутренние ссылки которых, ссылаются на разные объекты в памяти
+a === b
+
+// Истина, так как объект a (String) будет преобразован в строку 'foo', перед сопоставлением
+a == 'foo' 
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('ES1')}}{{Spec2('ES1')}}Появление в спецификации. Выполняется в JavaScript 1.0
{{SpecName('ES3')}}{{Spec2('ES3')}}Добавлены операторы === и !==. Выполняется в JavaScript 1.3
{{SpecName('ES5.1', '#sec-11.8')}}{{Spec2('ES5.1')}}Определено в нескольких секциях спецификации: Относительные операторыОператоры равенства
{{SpecName('ES6', '#sec-relational-operators')}}{{Spec2('ES6')}}Определено в нескольких секциях спецификации: Относительные операторыОператоры равенства
{{SpecName('ESDraft', '#sec-relational-operators')}}{{Spec2('ESDraft')}}Определено в нескольких секциях спецификации: Относительные операторыОператоры равенства
+ +

Поддержка браузерами

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
ChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}} +

{{CompatVersionUnknown}}

+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
AndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +


+ Смотрите также

+ + diff --git a/files/ru/conflicting/web/javascript/reference/operators_7c8eb9475d97a4a734c5991857698560/index.html b/files/ru/conflicting/web/javascript/reference/operators_7c8eb9475d97a4a734c5991857698560/index.html new file mode 100644 index 0000000000..ba4703c2c3 --- /dev/null +++ b/files/ru/conflicting/web/javascript/reference/operators_7c8eb9475d97a4a734c5991857698560/index.html @@ -0,0 +1,626 @@ +--- +title: Битовые операции +slug: Web/JavaScript/Reference/Operators/Bitwise_Operators +tags: + - JavaScript + - Оператор +translation_of: Web/JavaScript/Reference/Operators +translation_of_original: Web/JavaScript/Reference/Operators/Bitwise_Operators +--- +
{{jsSidebar("Operators")}}
+ +

Сводка

+ +

Битовые операции обращаются со своими операндами как с 32-х разрядными последовательностями нулей и единиц, а не как с десятичными, восьмеричными или шестнадцатиричными числами. К примеру десятичное число 9 в двоичном представлении будет выглядеть как 1001. Битовые операции производят свои преобразования именно с двоичным представлением числа, но возвращают стандартные числовые значения языка JavaScript.

+ + + + + + + + + + + + + + + +
Операторы
Реализованы в:JavaScript 1.0
Версия ECMA:ECMA-262
+ +

Следующая таблица содержит сводные данные о битовых операциях в JavaScript:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ОператорИспользованиеОписание
Побитовое Иa & bВозвращает 1 в тех разрядах, которые у обоих операндов были равны 1.
Побитовое ИЛИa | bВозвращает 1 в тех разрядах, которые хотя бы у одного из операндов были равны 1.
Побитовое исключающее ИЛИa ^ bВозвращает 1 в тех позициях, которые только у одного из операндов были равны 1.
Побитовое НЕ~ aИнвертирует биты операнда.
Сдвиг влевоa << bСдвигает двоичное представление числа a на b разрядов влево заполняя освободившиеся справа разряды нулями.
Арифметический сдвиг вправоa >> bСдвигает двоичное представление числа a на b разрядов вправо. Освобождающиеся разряды заполняются  знаковым битом.
Логический сдвиг вправоa >>> bСдвигает двоичное представление числа a на b разрядов вправо. Освобождающиеся разряды заполняются нулями.
+ +

Представление чисел (Signed 32-bit integers)

+ +

Операнды всех битовых операций конвертируются в 32-х битовые целые со знаком представленные в дополнительном коде и с использованием порядка битов от "старшего к младшему". Порядок битов "от старшего к младшему" означает, что наиболее значимый бит (бит с наибольшим значением) находится слева если 32-х разрядное число представлено в виде горизонтальной линии (шкалы). Представление в дополнительном коде  означает, что отрицательное значение числа (например 5 и -5) получается путем инвертирования числа (операция "побитовое НЕ", также известное как "обратный код") и прибавления к нему единицы.

+ +

Возьмем, к примеру, число 314. Представим его в двоичном коде:

+ +
00000000000000000000000100111010
+
+ +

Следующая строка представляет собой его обратный код или ~314:

+ +
11111111111111111111111011000101
+
+ +

Прибавив к нему единицу, мы получаем двоичное представление числа  -314, оно же 314 в дополнительном коде:

+ +
11111111111111111111111011000110
+ +

Дополнение до 2-х гарантирует нам, что у положительного числа самый левый бит равен 0, в то время как у отрицательного он равен 1. Он зовется знаковым битом.

+ +


+ Число 0 есть число, у которого во ввсех битовых позициях записаны нули.

+ +
0 (base 10) = 00000000000000000000000000000000 
+ +

Число -1 есть число, у которого во всех битовых позициях записаны единицы.

+ +
-1 (base 10) = 11111111111111111111111111111111 
+ +

Число -2147483648 (в шестнадцатиричной системе счисления: -0x80000000) - это вещественное число, которое состоит только из 0, заисключением самого первого слева, который есть 1 (отвечает за знак числа).

+ +
-2147483648 (base 10) = 10000000000000000000000000000000
+ +

Число 2147483648 (в шестнадцатиричной системе счисления: 0x80000000) - это вещественное число, которое состоит только из 1, заисключением самого первого слева, который есть 0 (отвечает за знак числа).

+ +
2147483647 (base 10) = 01111111111111111111111111111111
+ +

-2147483648 и 2147483647 - это самое минимальное и самое максимальное числа, которые можно представить в 32 разрядной ячейке памяти.

+ +

Побитовые логические операции

+ +

Побитовые логические операции работают следующим образом:

+ + + +
До:         11100110111110100000000000000110000000000001
+После:      10100000000000000110000000000001
+
+ + + +

& (Побитовое AND)

+ +

Производит побитовое И над каждой парой битов. Операция a AND b веренет 1 если только и a и b равны 1. Таблица истинности для этой операции выглядит так:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
aba AND b
000
010
100
111
+ +

Пример:

+ +
     9 (основание 10) = 00000000000000000000000000001001 (основание 2)
+    14 (основание 10) = 00000000000000000000000000001110 (основание 2)
+                   --------------------------------
+14 & 9 (основание 10) = 00000000000000000000000000001000 (осн. 2) = 8 (осн. 10)
+
+ +

Побитовое  AND любого числа x с нулем вернет 0.

+ +

Побитовое  AND любого числа x с числом -1 вернет х.

+ +

| (Побитовое OR)

+ +

Производит побитовое ИЛИ над каждой парой битов. Операция a OR b веренет 1 если a или b равны 1. Таблица истинности для этой операции выглядит так:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
aba OR b
000
011
101
111
+ +
Пример:
+
+9 (осн. 10) = 00000000000000000000000000001001 (осн. 2)
+14 (осн. 10) = 00000000000000000000000000001110 (осн. 2)
+                   --------------------------------
+14 | 9 (осн. 10) = 00000000000000000000000000001111 (осн. 2) = 15 (осн. 10)
+
+ +

Побитовое OR любого числа x c нулем вернет x.

+ +

Побитовое OR любого числа x с числом -1 вернет -1.

+ +

^ (Побитовое XOR)

+ +

Производит побитовое XOR над каждой парой битов. Операция a XOR b вернет 1 если a  и b различны. Таблица истинности для этой операции выглядит так:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
aba XOR b
000
011
101
110
+ +

Пример:

+ +
     9 (осн. 10) = 00000000000000000000000000001001 (осн. 2)
+    14 (осн. 10) = 00000000000000000000000000001110 (осн. 2)
+                   --------------------------------
+14 ^ 9 (осн. 10) = 00000000000000000000000000000111 (осн. 2) = 7 (осн. 10)
+
+ +

Побитовое XOR любого числа x c нулем вернет x.

+ +

Побитовое XOR любого числа x c числом -1 вернет ~x.

+ +

~ (Побитовое NOT)

+ +

Производит операцию NOT над каждым битом. NOT a вернет побитово инвертированное значение (обратный код) операнда. Таблица истинности для этой операции выглядит так:

+ + + + + + + + + + + + + + + + +
aNOT a
01
10
+ +

Пример:

+ +
 9 (осн. 10) = 00000000000000000000000000001001 (осн. 2)
+               --------------------------------
+~9 (осн. 10) = 11111111111111111111111111110110 (осн. 2) = -10 (осн. 10)
+
+ +

Побитовое NOT любого числа x вернет -(x + 1). Например, ~5 вернет -6.

+ +

Побитовые операции сдвига

+ +

Оператор побитового сдвига принимает в себя два операнда: первый - величина, которую сдвигают, второй - число позиций, на которое сдвигаются биты первого операнда. Направление сдвига зависит от используемого оператора.

+ +

Операторы сдвига конвертируют операнды в 32-ух разрядные числа с порядком байтов от старшего к младшему, а результат возвращает того же типа, что и левый операнд.

+ +

<< (Сдвиг влево)

+ +

Оператор побитового сдвига влево сдвигает первый операнд на заданное число битов влево. Лишние биты отбрасываются.

+ +

Например, 9 << 2 в результате даст 36:

+ +
     9 (осн. 10): 00000000000000000000000000001001 (осн. 2)
+                  --------------------------------
+9 << 2 (осн. 10): 00000000000000000000000000100100 (осн. 2) = 36 (осн. 10)
+
+
+
+ +

Побитовй сдвиг любого числа x влево на y бит в результате дает  x * 2 ** y.

+ +

>> (Сдвиг вправо с сохранением знака)

+ +

Оператор побитового сдвига вправо сдвигает первый операнд на заданное число битов вправо. Лишние биты отбрасываются. Слева добавляется заданное число битов равных первому биту исходного числа. Поскольку значение первого бита, определяющего знак числа, останется неизменным, знак получившегося результата будет таким же как у первого аргумента. Отсюда "с сохранением знака" в названи.

+ +

Например, 9 >> 2 в результате даст 2:

+ +
     9 (осн. 10): 00000000000000000000000000001001 (осн. 2)
+                  --------------------------------
+9 >> 2 (осн. 10): 00000000000000000000000000000010 (осн. 2) = 2 (осн. 10)
+
+ +

Аналогично, -9 >> 2 даст в результате  -3, так как знак сохранен:

+ +
     -9 (осн. 10): 11111111111111111111111111110111 (осн. 2)
+                   --------------------------------
+-9 >> 2 (осн. 10): 11111111111111111111111111111101 (осн. 2) = -3 (осн. 10)
+
+ +

>>> (Сдвиг вправо с заполнением нулями)

+ +

Оператор побитового сдвига вправо сдвигает первый операнд на заданное число битов вправо. Лишние биты отбрасываются. Слева добавляется заданное число нулевых битов. Поскольку значение первого бита, определяющего знак числа, становится нулевым, результатом операции всегда будет положительное число.

+ +

Для положительных чисел, сдвиг вправо с сохранением знака и сдвиг вправо с заполнением нулями эквивалентны.

+ +

Например, 9 >>> 2 дает в результате 2, как и 9 >> 2:

+ +
      9 (осн. 10): 00000000000000000000000000001001 (осн. 2)
+                   --------------------------------
+9 >>> 2 (осн. 10): 00000000000000000000000000000010 (осн. 2) = 2 (осн. 10)
+
+ +

Важно отметить, что для отрицательных результаты будут разными. Например, -9 >>> 2 дает в результате 1073741821, что отличается от результата -9 >> 2 (равно -3):

+ +
      -9 (осн. 10): 11111111111111111111111111110111 (осн. 2)
+                    --------------------------------
+-9 >>> 2 (осн. 10): 00111111111111111111111111111101 (осн. 2) = 1073741821 (осн. 10)
+
+ +

Примеры

+ +

Пример: флаги и битовые маски

+ +

Побитовые логические операторы часто используются для создания, обработки и чтения последовательности флагов, которые осуществляются также, как и двоичные переменные. Переменные могут быть использованы вместо этих последовательностей, но двоичные флаги занимают гораздо меньше памяти (в 32 разрядной ячейке памяти).

+ +

Предположим, существует 4 флага:

+ + + +

Эти флаги представлены последовательностью битов: DCBA. Считается, что флаг установлен (the flag is set), если его значение равно 1. Флаг сброшен (the flag is cleared), если его значение равно 0. Предположим, что переменная flags содержит двоичное значение 0101:

+ +
var flags = 0x5;   // двоичное 0101
+
+ +

Из этого значения следует:

+ + + +

Так как битовые операторы 32-битные, то 0101 в действительности представлено значением 00000000000000000000000000000101, но ведущие нули могут быть опущены, потому, что не содержат значимой информации.

+ +

Битовая маска, это последовательность битов, которая позволяет манипулировать и/или считывать значения флагов. Обычно для каждого флага задаётся "примитивная" битовая маска:

+ +
var FLAG_A = 0x1; // 0001
+var FLAG_B = 0x2; // 0010
+var FLAG_C = 0x4; // 0100
+var FLAG_D = 0x8; // 1000
+
+ +

New bitmasks can be created by using the bitwise logical operators on these primitive bitmasks. For example, the bitmask 1011 can be created by ORing FLAG_A, FLAG_B, and FLAG_D:

+ +
var mask = FLAG_A | FLAG_B | FLAG_D; // 0001 | 0010 | 1000 => 1011
+
+ +

Individual flag values can be extracted by ANDing them with a bitmask, where each bit with the value of one will "extract" the corresponding flag. The bitmask masks out the non-relevant flags by ANDing with zeros (hence the term "bitmask"). For example, the bitmask 0100 can be used to see if flag C is set:

+ +
// if we own a cat
+if (flags & FLAG_C) { // 0101 & 0100 => 0100 => true
+   // do stuff
+}
+
+ +

A bitmask with multiple set flags acts like an "either/or". For example, the following two are equivalent:

+ +
// if we own a bat or we own a cat
+if ((flags & FLAG_B) || (flags & FLAG_C)) { // (0101 & 0010) || (0101 & 0100) => 0000 || 0100 => true
+   // do stuff
+}
+
+ +
// if we own a bat or cat
+var mask = FLAG_B | FLAG_C; // 0010 | 0100 => 0110
+if (flags & mask) { // 0101 & 0110 => 0100 => true
+   // do stuff
+}
+
+ +

Flags can be set by ORing them with a bitmask, where each bit with the value one will set the corresponding flag, if that flag isn't already set. For example, the bitmask 1010 can be used to set flags C and D:

+ +
// yes, we own a cat and a duck
+var mask = FLAG_C | FLAG_D; // 0100 | 1000 => 1100
+flags |= mask;   // 0101 | 1100 => 1101
+
+ +

Flags can be cleared by ANDing them with a bitmask, where each bit with the value zero will clear the corresponding flag, if it isn't already cleared. This bitmask can be created by NOTing primitive bitmasks. For example, the bitmask 1010 can be used to clear flags A and C:

+ +
// no, we don't neither have an ant problem nor own a cat
+var mask = ~(FLAG_A | FLAG_C); // ~0101 => 1010
+flags &= mask;   // 1101 & 1010 => 1000
+
+ +

The mask could also have been created with ~FLAG_A & ~FLAG_C (De Morgan's law):

+ +
// no, we don't have an ant problem, and we don't own a cat
+var mask = ~FLAG_A & ~FLAG_C;
+flags &= mask;   // 1101 & 1010 => 1000
+
+ +

Flags can be toggled by XORing them with a bitmask, where each bit with the value one will toggle the corresponding flag. For example, the bitmask 0110 can be used to toggle flags B and C:

+ +
// if we didn't have a bat, we have one now, and if we did have one, bye-bye bat
+// same thing for cats
+var mask = FLAG_B | FLAG_C;
+flags = flags ^ mask;   // 1100 ^ 0110 => 1010
+
+ +

Finally, the flags can all be flipped with the NOT operator:

+ +
// entering parallel universe...
+flags = ~flags;    // ~1010 => 0101
+
+
+ +

Совместимость с браузерами

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ВозможностьChromeFirefox (Gecko)Internet ExplorerOperaSafari
Битовый NOT (~){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Битовый AND (&){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Битовый OR (|){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Битовый XOR (^){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Сдвиг влево (<<){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Сдвиг вправо (>>){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Беззнаковый сдвиг вправо (>>>){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ВозможностьAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Битовый NOT (~){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Битовый AND (&){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Битовый OR (|){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Битовый XOR (^){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Сдвиг влево (<<){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Сдвиг вправо (>>){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Беззнаковый сдвиг вправо (>>>){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

Смотрите также

+ + diff --git a/files/ru/conflicting/web/javascript/reference/operators_843c998343f0cdaa5699874c806d4cea/index.html b/files/ru/conflicting/web/javascript/reference/operators_843c998343f0cdaa5699874c806d4cea/index.html new file mode 100644 index 0000000000..b840f1e584 --- /dev/null +++ b/files/ru/conflicting/web/javascript/reference/operators_843c998343f0cdaa5699874c806d4cea/index.html @@ -0,0 +1,300 @@ +--- +title: Логические операторы +slug: Web/JavaScript/Reference/Operators/Логические_операторы +translation_of: Web/JavaScript/Reference/Operators +translation_of_original: Web/JavaScript/Reference/Operators/Logical_Operators +--- +
{{jsSidebar("Operators")}}
+ +
Логические операторы используются, как правило, с примитивами {{jsxref("Boolean")}} (логического) типа. В этом случае результатом работы оператора является значение типа Boolean. Между тем операторы && и || возвращают, вообще говоря, значение одного из операнда, потому при использовании в качестве аргументов этих операторов величин, тип которых отличен от Boolean, тип возвращаемого значения может быть отличным от Boolean.
+ +
+ +

Описание

+ +

В таблице приведены описания логических операторов:

+ + + + + + + + + + + + + + + + + + + + + + + + +
ОператорИспользованиеОписание
Логическое И (&&)expr1 && expr2Возвращает значение expr1, если оно может быть преобразовано в false; иначе возвращает значение expr2. Таким образом, при использовании с величинами типа Boolean оператор && вернет true, если оба операнда могут быть преобразованы в true; иначе оператор && вернет false. 
Логическое ИЛИ (||)expr1 || expr2 +

Возвращает значение expr1, если оно может быть преобразовано в true; иначе возвращает значение expr2. Таким образом, при использовании с величинами типа Boolean оператор || вернет true если хоть один из них равен true; в других случаях вернет false.

+
Логическое НЕ (!)!exprВозвращает false если значение expr можно привести к true;  в противоположном случае возвращает true.
+ +

Примеры значений выражений, которые могут быть преобразованы в false:

+ + + +

Хоть операторы && и || могут использовать операнды с не булевыми значениями, но они всёравно рассматриваются, как булевы операторы, т.к. их возвращаемые ими значения всегда могут быть сконвертированы в булевы значения.

+ +

Короткая схема вычислений

+ +

Так как логические операторы выполняются слева направо, они проверяются на "короткие вычисления" по следующим правилам:

+ + + +

Часть выражения (anything) не вычисляется. Если в ней есть вызов функции, то эта функция не будет вызвана.

+ +

Например, следующие две функции делают одно и тоже:

+ +
function shortCircuitEvaluation() {
+  doSomething() || doSomethingElse()
+}
+
+function equivalentEvaluation() {
+  var flag = doSomething();
+  if (!flag) {
+    doSomethingElse();
+  }
+}
+
+ +

Однако, следующие выражения дают разный результат в связи с приоритетом операторов.

+ +
false && true  || true      // вернёт true
+false && (true || true)     // вернёт false
+ +

Логическое И (&&)

+ +

Следующий код показывает пример оператора && (логическое И).

+ +
a1 = true  && true      // t && t вернёт true
+a2 = true  && false     // t && f вернёт false
+a3 = false && true      // f && t вернёт false
+a4 = false && (3 == 4)  // f && f вернёт false
+a5 = "Cat" && "Dog"     // t && t вернёт "Dog"
+a6 = false && "Cat"     // f && t вернёт false
+a7 = "Cat" && false     // t && f вернёт false
+
+ +

Логическое ИЛИ (||)

+ +

Это код представляет собой пример оператора || (логическое ИЛИ).

+ +
o1 = true  || true       // t || t вернёт true
+o2 = false || true       // f || t вернёт true
+o3 = true  || false      // t || f вернёт true
+o4 = false || (3 == 4)   // f || f вернёт false
+o5 = "Cat" || "Dog"      // t || t вернёт "Cat"
+o6 = false || "Cat"      // f || t вернёт "Cat"
+o7 = "Cat" || false      // t || f вернёт "Cat"
+
+ +

Логическое НЕ (!)

+ +

Следующий код является примером оператора ! (логическое НЕ).

+ +
n1 = !true              // !t вернёт false
+n2 = !false             // !f вернёт true
+n3 = !"Cat"             // !t вернёт false
+
+ +

Правила преобразования

+ +

Конвертирование И в ИЛИ

+ +

следующая операция использует булев тип:

+ +
bCondition1 && bCondition2
+ +

это всегда равно:

+ +
!(!bCondition1 || !bCondition2)
+ +

Конвертирование ИЛИ в И

+ +

эта операция использует булев тип:

+ +
bCondition1 || bCondition2
+ +

что эквивалентно:

+ +
!(!bCondition1 && !bCondition2)
+ +

Конвертирование многих НЕ

+ +

следующая операция использует булев тип:

+ +
!!bCondition
+ +

что равно:

+ +
bCondition
+ +

Удаление вложенных скобок

+ +

Так как логические выражения выполняются слева направо, становится возможным удалить круглые скобки из комплексного выражения, следуя следующим правилам.

+ +

Удаление вложенных И

+ +

Это составное выражение использует булев тип:

+ +
bCondition1 || (bCondition2 && bCondition3)
+ +

что будет равным:

+ +
bCondition1 || bCondition2 && bCondition3
+ +

Удаление вложенного ИЛИ

+ +

Следующее составное выражение использует булев тип:

+ +
bCondition1 && (bCondition2 || bCondition3)
+ +

всегда равно:

+ +
!(!bCondition1 || !bCondition2 && !bCondition3)
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('ES5.1')}}{{Spec2('ES1')}}Изначальное определение
{{SpecName('ES5.1', '#sec-11.11')}}{{Spec2('ES5.1')}}Определено в нескольких секциях спецификации: Логический оператор НЕ, Бинарные логические операторы
{{SpecName('ES6', '#sec-binary-logical-operators')}}{{Spec2('ES6')}}Определено в нескольких секциях спецификации: Логический оператор НЕ, Бинарные логические операторы
{{SpecName('ESDraft', '#sec-binary-logical-operators')}}{{Spec2('ESDraft')}}Определено в нескольких секциях спецификации: Логический оператор НЕ, Бинарные логические операторы
+ +

Поддержка браузерами

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ВозможностьChromeFirefox (Gecko)Internet ExplorerOperaSafari
Логическое И (&&){{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
Логическое ИЛИ (||){{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
Логическое НЕ (!){{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ВозможностьAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Логическое И (&&){{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
Логическое ИЛИ (||){{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
Логическое НЕ (!){{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

Смотрите также

+ + diff --git a/files/ru/conflicting/web/javascript/reference/operators_8d54701de06af40a7c984517cbe87b3e/index.html b/files/ru/conflicting/web/javascript/reference/operators_8d54701de06af40a7c984517cbe87b3e/index.html new file mode 100644 index 0000000000..5399324df0 --- /dev/null +++ b/files/ru/conflicting/web/javascript/reference/operators_8d54701de06af40a7c984517cbe87b3e/index.html @@ -0,0 +1,431 @@ +--- +title: Операторы присваивания +slug: Web/JavaScript/Reference/Operators/Assignment_Operators +tags: + - JavaScript + - Оператор +translation_of: Web/JavaScript/Reference/Operators#Assignment_operators +translation_of_original: Web/JavaScript/Reference/Operators/Assignment_Operators +--- +
{{jsSidebar("Operators")}}
+ +

Оператор присваивания присваивает левому операнду значение, основанное на значении правого операнда.

+ +

Описание

+ +

Основной оператор присваивания - это знак равно (=), он и присваивает значение правого операнда, левому. То есть - x = y присваивает значение переменной y, переменной x. Другие операторы присваивания, как следует из приведенной ниже таблицы с определениями и примерами, являются сокращениями стандартных операций.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ИмяСокращенный операторСмысл
Присваиваниеx = yx = y
Присваивание со сложениемx += yx = x + y
Присваивание с вычитаниемx -= yx = x - y
Присваивание с умножениемx *= yx = x * y
Присваивание с делениемx /= yx = x / y
Присваивание по модулюx %= yx = x % y
Присваивание с левым сдвигомx <<= yx = x << y
Присваивание с правым сдвигомx >>= yx = x >> y
Присваивание с беззнаковым сдвигом вправоx >>>= yx = x >>> y
Присваивание с побитовым ANDx &= yx = x & y
Присваивание с побитовым XORx ^= yx = x ^ y
Присваивание с побитовым ORx |= yx = x | y
+ +

Присваивание

+ +

Простой оператор присваивания, который задает значение переменной. Цепочка операторов присваивания может быть использована для назначения нескольким переменным одного и того же значения. Смотрите пример.

+ +

Синтаксис

+ +
Оператор: x = y
+
+ +

Примеры

+ +
// Например, следующие переменные:
+//  x = 5
+//  y = 10
+//  z = 25
+
+x = y     // x - 10
+x = y = z // x, y и z все равны 25
+
+ +

Присваивание со сложением

+ +

Оператор добавочного присваивания, добавляет значение правого операнда к значению левого, и сохраняет результат в переменную левого операнда. Типы значений обоих операндов, определяют поведение оператора добавочного присваивания. Возможны сложение и конкатенация. Смотрите {{jsxref("Operators/Arithmetic_Operators", "addition operator", "#Addition", 1)}} для подробностей.

+ +

Синтаксис

+ +
Оператор: x += y
+Значение: x = x + y
+
+ +

Примеры

+ +
// Например, следующие переменные:
+//  foo = "foo"
+//  bar = 5
+//  baz = true
+
+// Результат исполнения каждого нижеприведенного примера
+// представлен в изоляции от предыдущих примеров (как если
+// бы значения переменных foo, bar, baz возвращались на
+// первоначальные)
+
+// Number + Number -> сложение
+bar += 2 // 7
+
+// Boolean + Number -> сложение
+baz += 1 // 2
+
+// Boolean + Boolean -> сложение
+baz += false // 1
+
+// Number + String -> конкатенация
+bar += "foo" // "5foo"
+
+// String + Boolean -> конкатенация
+foo += false // "foofalse"
+
+// String + String -> конкатенация
+foo += "bar" // "foobar"
+
+ +

Присваивание с вычитанием

+ +

Оператор вычитаемого присваивания вычитает значение правого операнда из значения левого, и присваивает результат переменной левого операнда. Смотрите {{jsxref("Operators/Arithmetic_Operators", "subtraction operator", "#Subtraction", 1)}} для подробностей.

+ +

Синтаксис

+ +
Оператор: x -= y
+Значение:  x  = x - y
+
+ +

Примеры

+ +
// Например, следующие переменные:
+//  bar = 5
+
+bar -= 2     // 3
+bar -= "foo" // NaN
+
+ +

Присваивание с умножением

+ +

The multiplication assignment operator multiplies a variable by the value of the right operand and assigns the result to the variable. See the {{jsxref("Operators/Arithmetic_Operators", "multiplication operator", "#Multiplication", 1)}} for more details.

+ +

Синтаксис

+ +
Оператор: x *= y
+Значение:  x  = x * y
+
+ +

Примеры

+ +
// Assuming the following variable
+//  bar = 5
+
+bar *= 2     // 10
+bar *= "foo" // NaN
+
+ +

Присваивание с делением

+ +

The division assignment operator divides a variable by the value of the right operand and assigns the result to the variable. See the {{jsxref("Operators/Arithmetic_Operators", "division operator", "#Division", 1)}} for more details.

+ +

Синтаксис

+ +
Оператор: x /= y
+Значение:  x  = x / y
+
+ +

Примеры

+ +
// Assuming the following variable
+//  bar = 5
+
+bar /= 2     // 2.5
+bar /= "foo" // NaN
+bar /= 0     // Infinity
+
+ +

Присваивание по модулю

+ +

The remainder assignment operator divides a variable by the value of the right operand and assigns the remainder to the variable. See the {{jsxref("Operators/Arithmetic_Operators", "remainder operator", "#Remainder", 1)}} for more details.

+ +

Синтаксис

+ +
Оператор: x %= y
+Значение:  x  = x % y
+
+ +

Примеры

+ +
// Assuming the following variable
+// bar = 5
+
+bar %= 2     // 1
+bar %= "foo" // NaN
+bar %= 0     // NaN
+
+ +

Присваивание с левым сдвигом

+ +

The left shift assignment operator moves the specified amount of bits to the left and assigns the result to the variable. See the {{jsxref("Operators/Bitwise_Operators", "left shift operator", "#Left_shift", 1)}} for more details.

+ +

Синтаксис

+ +
Оператор: x <<= y
+Значение:  x   = x << y
+
+ +

Примеры

+ +
var bar = 5; //  (00000000000000000000000000000101)
+bar <<= 2; // 20 (00000000000000000000000000010100)
+
+ +

Присваивание с правым сдвигом

+ +

The right shift assignment operator moves the specified amount of bits to the right and assigns the result to the variable. See the {{jsxref("Operators/Bitwise_Operators", "right shift operator", "#Right_shift", 1)}} for more details.

+ +

Синтаксис

+ +
Оператор: x >>= y
+Значение:  x   = x >> y
+
+ +

Примеры

+ +
var bar = 5; //   (00000000000000000000000000000101)
+bar >>= 2;   // 1 (00000000000000000000000000000001)
+
+var bar -5; //    (-00000000000000000000000000000101)
+bar >>= 2;  // -2 (-00000000000000000000000000000010)
+
+ +

Присваивание с беззнаковым сдвигом вправо

+ +

The unsigned right shift assignment operator moves the specified amount of bits to the right and assigns the result to the variable. See the {{jsxref("Operators/Bitwise_Operators", " unsigned right shift operator", "#Unsigned_right_shift", 1)}} for more details.

+ +

Синтаксис

+ +
Оператор: x >>>= y
+Значение:  x    = x >>> y
+
+ +

Примеры

+ +
var bar = 5; //   (00000000000000000000000000000101)
+bar >>>= 2;  // 1 (00000000000000000000000000000001)
+
+var bar = -5; // (-00000000000000000000000000000101)
+bar >>>= 2; // 1073741822 (00111111111111111111111111111110)
+ +

Присваивание с побитовым AND

+ +

The bitwise AND assignment operator uses the binary representation of both operands, does a bitwise AND operation on them and assigns the result to the variable. See the {{jsxref("Operators/Bitwise_Operators", "bitwise AND operator", "#Bitwise_AND", 1)}} for more details.

+ +

Синтаксис

+ +
Оператор: x &= y
+Значение:  x  = x & y
+
+ +

Примеры

+ +
var bar = 5;
+// 5:     00000000000000000000000000000101
+// 2:     00000000000000000000000000000010
+bar &= 2; // 0
+
+ +

Присваивание с побитовым XOR

+ +

Побитовый оператор присваивания XOR использует двоичное представление обоих операндов, выполняет побитовую XOR-операцию и присваивает результат переменной. Для получения более подробной информации см. {{jsxref("Operators/Bitwise_Operators", "Побитовый оператор XOR", "#Bitwise_XOR", 1)}}.

+ +

Синтаксис

+ +
Оператор: x ^= y
+Значение:  x  = x ^ y
+
+ +

Примеры

+ +
var bar = 5;
+bar ^= 2; // 7
+// 5: 00000000000000000000000000000101
+// 2: 00000000000000000000000000000010
+// -----------------------------------
+// 7: 00000000000000000000000000000111
+
+ +

Присваиванием с побитовым OR

+ +

Побитовый оператор присваивания OR использует двоичное (бинарное) представление обоих операндов, выполняет побитовое ИЛИ для них и присваивает результат переменной. Дополнительную информацию см. {{jsxref("Operators/Bitwise_Operators", "Побитовый оператор OR", "#Bitwise_OR", 1)}}.

+ +

Синтаксис

+ +
Оператор: x |= y
+Значение:  x  = x | y
+
+ +

Примеры

+ +
var bar = 5;
+bar |= 2; // 7
+// 5: 00000000000000000000000000000101
+// 2: 00000000000000000000000000000010
+// -----------------------------------
+// 7: 00000000000000000000000000000111
+
+ +

Примеры

+ +

Левый операнд с другим оператором присваивания

+ +

В необычных ситуациях оператор присваивания, например, x += y не идентичен выражению, x = x + y. Когда левый операнд оператора присваивания содержит оператор присваивания, левый операнд оценивается только один раз. Например:

+ +
a[i++] += 5         // i оценивается только один раз
+a[i++] = a[i++] + 5 // i оценивается дважды
+
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
ECMAScript 1-е издание.СтандартИзначальное определение.
{{SpecName('ES5.1', '#sec-11.13', 'Операторы присваивания')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-assignment-operators', 'Операторы присваивания')}}{{Spec2('ES6')}} 
+ +

Совместимость с браузерами

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
ВозможностьChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
ВозможностьAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

Смотрите также

+ + diff --git a/files/ru/conflicting/web/javascript/reference/statements/switch/index.html b/files/ru/conflicting/web/javascript/reference/statements/switch/index.html new file mode 100644 index 0000000000..c1f3f6b923 --- /dev/null +++ b/files/ru/conflicting/web/javascript/reference/statements/switch/index.html @@ -0,0 +1,117 @@ +--- +title: default +slug: Web/JavaScript/Reference/Statements/default +tags: + - JavaScript + - Keyword + - Switch + - export +translation_of: Web/JavaScript/Reference/Statements/switch +translation_of_original: Web/JavaScript/Reference/Statements/default +--- +
{{jsSidebar("Statements")}}
+ +

В JavaScript ключевое слово default используется в двух случаях: внутри конструкции {{jsxref("Statements/switch", "switch")}} или с конструкцией {{jsxref("Statements/export", "export")}}.

+ +

Синтаксис

+ +

В конструкции {{jsxref("Statements/switch", "switch")}}:

+ +
switch (expression) {
+  case value1:
+    // Выражение выполнится, когда значение expression соответствует value1
+    [break;]
+  default:
+    // Выражение выполнится, когда ни одно из значений не будет соответствовать значению expression
+    [break;]
+}
+ +

С конструкцией {{jsxref("Statements/export", "export")}}:

+ +
export default nameN 
+ +

Описание

+ +

Для получения дополнительной информации смотрите:

+ + + +

Примеры

+ +

Использование default в  switch

+ +

В следующем примере, если expr имеет значение  "Апельсины" или "Яблоки", то программа сопоставит это значение с "Апельсины" или с "Яблоки", а затем выполнит соответствующее выражение. В других случаях поможет ключевое слово default,  выполня связанное выражение.

+ +
switch (expr) {
+  case 'Апельсины':
+    console.log('Апельсины стоят $0.59 за фунт.');
+    break;
+  case 'Яблоки':
+    console.log('Яблоки стоят $0.32 за фунт.');
+    break;
+  default:
+    console.log(`Извините, у нас закончились ${expr}.`);
+}
+ +

Использование default с export

+ +

При необходимости экспорта единственного значения или резервирования (fallback) значения для модуля, можно воспользоваться экспортом по-умолчанию: 

+ +
// модуль "my-module.js"
+let cube = function cube(x) {
+  return x * x * x;
+};
+export default cube;
+ +

Тогда, в другом файле JavaScript, становится возможным просто импортировать экспортируемое по-умолчанию значение:

+ +
// модуль "my-module.js"
+import myFunction from 'my-module';
+console.log(myFunction(3)); // 27
+
+ +

Спецификация

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('ES6', '#sec-switch-statement', 'switch statement')}}{{Spec2('ES6')}}
{{SpecName('ES6', '#sec-exports', 'Exports')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-switch-statement', 'switch statement')}}{{Spec2('ESDraft')}}
{{SpecName('ESDraft', '#sec-exports', 'Exports')}}{{Spec2('ESDraft')}}
+ +

Совместимость с браузерами

+ +

{{Compat("javascript.statements.default")}}

+ +

Смотрите также

+ + diff --git a/files/ru/conflicting/web/media/formats/index.html b/files/ru/conflicting/web/media/formats/index.html new file mode 100644 index 0000000000..9f86b15ff2 --- /dev/null +++ b/files/ru/conflicting/web/media/formats/index.html @@ -0,0 +1,517 @@ +--- +title: Форматы медиа поддерживаемые HTML audio и video элементами +slug: Web/HTML/Поддерживаемые_медиа_форматы +translation_of: Web/Media/Formats +translation_of_original: Web/HTML/Supported_media_formats +--- +

{{ HTMLElement("audio") }} и {{ HTMLElement("video") }} элементы предоставляют поддержку для проигрывания аудио и видео медиа без нужды в плагинах. Формат медиафайла состоит из контейнера, содержащего один или несколько потоков данных, закодированных с использованием формата сжатия, называемого кодеком. Контейнер идентифицируется по расширению файла. Потоки внутри контейнера имеют несколько типов, которые могут включать в себя видео, аудио, данные или титры. Один контейнер (т. е. медиафайл) может содержать несколько потоков одного типа. В аудио- и видео- потоках находятся кодеки. Кодек — сокращенние слов "кодера-декодер" — является алгоритмом сжатия данных в файле. Каждый тип контейнера имеет только определенные кодеки, которые он поддерживает.

+ +

Важно понять, почему в Интернете нужны разные медиаформаты. По разным причинам, выходящим за рамки данной статьи, различные браузеры поддерживают разные медиаформаты. Кроме того, область медиаформатов в Интернете сильно пострадала от патентного права во многих странах, включая США и страны ЕС. (Примечания к патентам в этой статье предоставляются как есть, так и без каких-либо гарантий.) В этой статье рассматриваются наиболее важные для Интернета форматы, включая поддержку в браузерах как мобильных, так и десктопных .

+ +

 

+ +

Отображение медиа

+ +

 

+ +

Ниже краткий обзор того, как медиа-элементы отображаются в HTML. Более подробную информацию смотрите в статьях для каждого элемента.

+ +

HTML5 поддерживает несколько элементов мультимедиа. Элементы {{HTMLElement ("video")}} и {{HTMLElement ("audio")}} могут использоваться отдельно или в сочетании с элементом {{HTMLElement ("source")}}. Наш краткий пример отображает это. Хотя элементы <video> и <audio> содержат атрибуты src, этот пример использует  элемент <source> для предоставления видеофайлов в нескольких форматах, позволяя каждому браузеру выбирать элемент, который он поддерживает.

+ +
<video controls>
+  <source src="somevideo.webm" type="video/webm">
+  <source src="somevideo.mp4" type="video/mp4">
+  Сожалею; ваш браузер не поддерживает HTML5 видео в WebM с VP8 или MP4 с H.264.
+  <!-- Ты можешь встроить флеш плеер сюда, для воспроизведения твоего mp4 видео в старых браузерах -->
+</video>
+
+ +

WebM

+ +

Формат WebM основан на ограниченной версии формата контейнера Matroska. Формат всегда использует видео кодек VP8 или VP9 и аудио кодек Vorbis или Opus. WebM нативно поддерживается в десктопной и мобильной версиях Gecko (Firefox), Chrome и Opera. Поддержка формата может быть добавлена в Internet Explorer и Safari (но не на iOS) установкой плагина. Нативная поддержка VP9 WebM в Edge сейчас в стадии разработки.

+ +

Формат WebM, а точнее видеокодек VP8, подвергся претензиям в нарушениях патентов от ряда компаний, отвечающих на требования, MPEG LA о фомировании списка патентов, но при этом MPEG LA дала согласие на лицензирование этих патентов для Google под лицензией "perpetual, transferable, royalty free license".  Это фактически означает, что все известные патенты, относящиеся к формату WebM лицензированы для свободного использования всеми.

+ +

Движок Gecko распознаёт следующие типы MIME как файлы WebM:

+ +
+
video/webm
+
файл WebM, содержащий видео (а возможно, также и аудио).
+
audio/webm
+
Файл WebM, содержащий только аудиоданные.
+
+ +

Ogg Theora Vorbis

+ +

The Ogg container format with the Theora video codec and the Vorbis audio codec is supported in desktop/mobile Gecko (Firefox), Chrome, and Opera, and support for the format can be added to Safari (but not on iOS) by installing an add-on. The format is not supported in Internet Explorer in any way.

+ +

WebM is generally preferred over Ogg Theora Vorbis when available, because it provides a better compression to quality ratio and is supported in more browsers. The Ogg format can however be used to support older browser versions (for example Firefox 3.5/3.6 don't support WebM, but do support Ogg.)

+ +

The patent situation of Theora is similar to that of WebM.

+ +

You can learn more about creating Ogg media by reading the Theora Cookbook.

+ +

Gecko recognizes the following MIME types as Ogg files:

+ +
+
audio/ogg
+
An Ogg file containing only audio.
+
video/ogg
+
An ogg file containing video (and possibly also audio).
+
application/ogg
+
An Ogg file with unspecified content. Using one of the other two MIME types is preferred, but you can use this if you don't know what the contents of the file are.
+
+ +

Ogg Opus

+ +

The Ogg container can also contain audio encoded using the Opus codec. Support for this is available in Gecko 15.0 {{ geckoRelease("15.0") }} and later, on desktop and mobile browsers.

+ +

MP4 H.264 (AAC or MP3)

+ +

The MP4 container format with the H.264 video codec and the AAC audio codec is natively supported by desktop/mobile Internet Explorer, Safari and Chrome, but Chromium and Opera do not support the format. IE and Chrome also support the MP3 audio codec in the MP4 container, but Safari does not. Firefox/Firefox for Android/Firefox OS supports the format in some cases, but only when a third-party decoder is available, and the device hardware can handle the profile used to encode the MP4.

+ +
+

Note: MP4s encoded with a high profile will not run on lower end hardware, such as low end Firefox OS phones.

+
+ +

The MPEG media formats are covered by patents, which are not freely licensed. All the necessary licenses can be bought from MPEG LA. Since H.264 is currently not a royalty free format, it is unfit for the open web platform, according to Mozilla [1, 2], Google [1, 2] and Opera. However, since royalty free formats are not supported by Internet Explorer and Safari, Mozilla has decided to support the format anyway, and Google never fulfilled their promise to remove support for it in Chrome.

+ +

MP3

+ +

MP3 аудио формат (.mp3, audio/mpeg; в отличии от выше MP3 аудио в случае MP4 контейнера) поддерживается в <audio> Firefox/Firefox для Android/Firefox OS когда операционая система обеспечивает MP3 декодер, и Internet Explorer, Chrome и Safari.

+ +

WAVE PCM

+ +

The WAVE container format, with the PCM audio codec (WAVE codec "1") is supported by desktop/mobile Gecko (Firefox) and Safari. Files in the WAVE container format typically end with the ".wav" extension.

+ +
Note: See RFC 2361 for the WAVE codec registry.
+ +

Gecko recognizes the following MIME types as WAVE audio files:

+ + + +

Media Source Extensions (MSE)

+ +

Media Source Extensions is a W3C working draft that plans to extend {{ domxref("HTMLMediaElement") }} to allow JavaScript to generate media streams for playback. Allowing JavaScript to generate streams facilitates a variety of use cases like adaptive streaming and time shifting live streams. This currently has experimental support in Firefox desktop, and other browsers too.
+
+ For example,  you could implement MPEG-DASH using JavaScript while offloading the decoding to MSE.

+ +
+

Note: Time Shifting is the process of consuming a live stream some time after it happened.

+
+ +

Browser compatibility

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support3.0{{ CompatGeckoDesktop("1.9.1") }}9.010.503.1
<audio>: PCM in WAVE{{ CompatVersionUnknown() }}{{ CompatGeckoDesktop("1.9.1") }}{{ CompatNo() }}10.503.1
<audio>: Vorbis in WebM{{ CompatVersionUnknown() }}{{ CompatGeckoDesktop("2.0") }}{{ CompatNo() }}10.603.1 (must be installed separately)
<audio>: Streaming Vorbis in WebM via Media Source Extensions (MSE){{ CompatUnknown() }}{{ CompatGeckoDesktop("36.0") }} in Nightly/Dev edition only{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
<audio>: Vorbis in Ogg{{ CompatVersionUnknown() }}{{ CompatGeckoDesktop("1.9.1") }}{{ CompatNo() }}10.503.1 (must be installed separately, e.g. XiphQT)
<audio>: MP3{{ CompatVersionUnknown() }} (Not in Chromium)Partial (see below)9.0{{ CompatVersionUnknown() }}3.1
<audio>: MP3 in MP4 +

{{ CompatUnknown() }}

+
{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatVersionUnknown() }}
<audio>: AAC in MP4 +

{{ CompatVersionUnknown() }} (Main only) (Not in Chromium)

+
+

Partial (see below)

+
9.0{{ CompatVersionUnknown() }}3.1
<audio>: Opus in Ogg27.0{{ CompatGeckoDesktop("15.0") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
<video>: VP8 and Vorbis in WebM6.0{{ CompatGeckoDesktop("2.0") }}9.0 (must be installed separately, e.g. WebM MF)10.603.1 (must be installed separately, e.g. Perian)
<video>: VP9 and Opus in WebM29.0{{ CompatGeckoDesktop("28.0") }}{{ CompatUnknown() }}{{ CompatVersionUnknown() }}{{ CompatUnknown() }}
<video>: Streaming VP9 and Opus/VP8 and Opus in WebM via Media Source Extensions (MSE){{ CompatUnknown() }}{{ CompatGeckoDesktop("36.0") }} in Nightly/Dev edition only{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
<video>:  Theora and Vorbis in Ogg{{ CompatVersionUnknown() }}{{ CompatGeckoDesktop("1.9.1") }}{{ CompatNo() }}10.503.1 (must be installed separately, e.g. XiphQT)
<video>:  H.264 and MP3 in MP4 +

{{ CompatVersionUnknown() }} (Not in Chromium)

+
Partial (see below)9.0{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
<video>: H.264 and AAC in MP4 +

{{ CompatVersionUnknown() }} (Not in Chromium)

+
Partial (see below)9.0{{ CompatVersionUnknown() }}3.1
any other format{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}3.1 (plays all formats available via QuickTime)
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)Firefox OS (Gecko)IE MobileOpera MobileOpera MiniSafari MobileChrome for Android
Basic support2.324.01.0.110.011.0Partial (see below)3.229.0
<audio>: PCM in WAVE{{ CompatUnknown() }}24.01.0.1{{ CompatNo() }}{{ CompatNo() }}Partial (see below)3.2{{ CompatUnknown() }}
<audio>: Vorbis in WebM{{ CompatUnknown() }}24.01.0.1{{ CompatNo() }}11.0Partial (see below){{ CompatNo() }}{{ CompatUnknown() }}
<audio>: Streaming Vorbis in WebM via Media Source Extensions (MSE){{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
<audio>: Vorbis in Ogg{{ CompatUnknown() }}24.01.0.1{{ CompatNo() }}11.0Partial (see below){{ CompatNo() }}{{ CompatUnknown() }}
<audio>: MP3{{ CompatUnknown() }}Partial (see below)Partial (see below)10.0{{ CompatUnknown() }}Partial (see below)3.2{{ CompatUnknown() }}
<audio>: MP3 in MP4{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatVersionUnknown() }}{{ CompatUnknown() }}
<audio>: AAC in MP4{{ CompatUnknown() }}Partial (see below)Partial (see below)10.0{{ CompatUnknown() }}Partial (see below){{ CompatVersionUnknown() }}{{ CompatUnknown() }}
<audio>: Opus in Ogg{{ CompatNo() }}24.0{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}Partial (see below){{ CompatNo() }}{{ CompatNo() }}
<video>:  VP8 and Vorbis in WebM2.324.01.0.1{{ CompatNo() }}16.0Partial (see below){{ CompatNo() }}29.0
<video>: VP9 and Opus in WebM{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
<video>: Streaming VP9 and Opus/VP8 and Opus in WebM via Media Source Extensions (MSE){{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
<video>: Theora and Vorbis in Ogg{{ CompatNo() }}24.01.0.1{{ CompatNo() }}{{ CompatNo() }}Partial (see below){{ CompatNo() }}{{ CompatNo() }}
<video>:  H.264 and MP3 in MP4Partial (see below)24.0Partial (see below)10.0Partial since 11.0, full since 16.0Partial (see below){{ CompatVersionUnknown() }}29.0
<video>: H.264 and AAC in MP4Partial (see below)24.0Partial (see below)10.0Partial since 11.0, full since 16.0Partial (see below)3.229.0
any other format{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
+
+ +

Notes:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PlatformFirefox version
Windows Vista+22.0+
Android20.0+
Firefox OS15.0+
Linux +

26.0+ (relies on GStreamer codecs)

+
OS X 10.7+35.0+
+ + + +

See also

+ + diff --git a/files/ru/conflicting/web/progressive_web_apps/index.html b/files/ru/conflicting/web/progressive_web_apps/index.html new file mode 100644 index 0000000000..8d8c8ba678 --- /dev/null +++ b/files/ru/conflicting/web/progressive_web_apps/index.html @@ -0,0 +1,48 @@ +--- +title: Адаптивный дизайн +slug: Web_Development/Mobile/Responsive_design +translation_of: Web/Progressive_web_apps +translation_of_original: Web/Guide/Responsive_design +--- +

As a reaction to the problems associated with the separate sites approach to developing Web sites for both mobile and desktop, a relatively new idea (which is actually quite old) is growing in popularity: ditch user-agent detection, and instead make your page respond on the client-side to the browser’s capabilities. This approach, introduced by Ethan Marcotte in his article for A List Apart, came to be known as Responsive Web Design. Like the separate sites approach, responsive Web design has positive and negative aspects.

+

The Advantages

+

Though it wasn’t initially proposed as method for creating mobile sites, responsive design has recently gained a lot of attention as a way of taking some first steps towards mobile-friendliness in lieu of a separate mobile site.

+
    +
  1. It saves time and money as there isn't a need to maintain separate websites for different devices.
  2. +
  3. Responsive Design provides every page with a single and unique URL.
  4. +
  5. Social sharing stats (Facebook Likes, Tweets, +1 on Google plus) are not split, since the mobile and desktop versions of your web pages use a single and unique URL.
  6. +
  7. Responsive Design doesn't care about user agents.
  8. +
+

There are some really nice aspects to this approach. Since it does not rely on user-agent detection, it is more resilient and future-proof than the separate sites approach. For simple sites, it can also be significantly easier to implement and maintain than other options.

+

The Negatives

+

This approach isn’t without its limitations. Because content must be altered on the client-side with JavaScript, only minimal content changes are encouraged. In general, things can get very hairy very quickly if you are trying to code two separate sets of JavaScript to work with the same DOM. This is a big reason why web applications tend not to adopt this approach.

+

Giving your existing site a responsive design also involves a rewrite of your styles if the you are not sporting a flexible layout already. This could be a blessing in disguise, though; making your site’s layout responsive could be a good opportunity to modernize and clean up your site’s CSS.

+

Finally, since you are adding code to your scripts and styles, performance may be worse than the Separate Sites approach. There is not really any way around this, though a thoughtful refactoring of your scripts and styles might actually save a few bytes in the long run.

+

When it is right to choose this option

+

teixido_responsive-300x177.pngAs mentioned above, because content changes can be difficult, when you take this approach, you are not able to give users a strikingly different experience on mobile without a significant increase in code complexity. That said, if the desktop and mobile versions of your site are very similar, then this approach is a great option. It is well-suited to document-centric sites whose a primary use case is consistent across devices, like product pages. You may notice that the examples below are all blogs or portfolios!

+

Examples

+

Though it is not as popular as the separate sites approach, there are more and more websites employing this technique every day. Luckily, since all the code is client-side, if you’d like to see how a site technically implements this approach, it is as simple as visiting the site and clicking “View Page Source.” Here are a few examples:

+ +

Despite being a relatively young approach, there are already some emerging best practices. For example, if you are designing a site from scratch with this option in mind, it is usually worthwhile to create a small-screen design first, so that the constraints of mobile are with you from the beginning. It’s also great to use progressive enhancement for your styles instead of hiding elements of your existing site with media queries. This way, older browsers that might not support media queries still show the proper layout. An excellent presentation on the merits of this method is available here.

+

Approaches to mobile Web development

+

See the following articles for background and other approaches to developing for mobile platforms.

+ +

See also

+ +
+

Original document information

+

Originally published on 27 May, 2011 on the Mozilla Webdev blog as "Approaches to Mobile Web Development Part 3 - Responsive Design", by Jason Grlicky.

+
+

 

diff --git a/files/ru/conflicting/web/progressive_web_apps_628955cdadd77b10ec99de034fc76374/index.html b/files/ru/conflicting/web/progressive_web_apps_628955cdadd77b10ec99de034fc76374/index.html new file mode 100644 index 0000000000..1ed152b1e8 --- /dev/null +++ b/files/ru/conflicting/web/progressive_web_apps_628955cdadd77b10ec99de034fc76374/index.html @@ -0,0 +1,64 @@ +--- +title: Заметный +slug: Web/Progressive_web_apps/Заметный +tags: + - Веб-манифест + - Видимый + - Манифест + - Приложения + - Прогрессивные веб-приложения + - Современные веб-приложения +translation_of: Web/Progressive_web_apps +translation_of_original: Web/Progressive_web_apps/Discoverable +--- +
+
Как только вы опубликуете новое веб-приложение, вы захотите, чтобы мир узнал об этом. Поисковые системы, конечно, помогают, но, обычно, большее внимание уделяется тому, как Ваши приложения представлены на результатах поиска. Новый манифест W3C для веб-приложений может помочь с этим и предоставить дополнительные возможности.
+ +
+
+ +

Возможные перспективы для веб-приложения:

+ + + +

Основные руководства

+ +

None written as yet; contributions appreciated.

+ +

Технологии

+ + + + + + + + + + + + + + + + + + +
ТехнологияОписаниеПоддержкаПоследняя спецификация
+

Манифест веб-приложения

+
Устанавливает свойства приложения, такие как имя, иконка, окно загрузки и цвета темы для использования в каталогах приложений и т.д.Экспериментальный, поддерживается в Chrome, ограниченная поддержка в Firefox (больше деталей){{SpecName('Manifest')}}
+ +

Инструменты

+ +

Добавьте ссылки на полезные библиотеки и инструменты.

+ +

Смотрите также

+ +
+
Open Graph (англ.)
+
Стандарт, описывающий формат размещения мета-данных в тегах <head>, используя мета-тэги в HTML. Поддерживается Facebook и другими.
+
diff --git a/files/ru/dom/document.createelement/index.html b/files/ru/dom/document.createelement/index.html deleted file mode 100644 index 15542d751d..0000000000 --- a/files/ru/dom/document.createelement/index.html +++ /dev/null @@ -1,82 +0,0 @@ ---- -title: document.createElement -slug: DOM/document.createElement -tags: - - DOM - - Gecko -translation_of: Web/API/Document/createElement ---- -

{{ ApiRef() }}

- -

Общая информация

- -

В HTML-документах создает элемент c тем тегом, что указан в аргументе или HTMLUnknownElement, если имя тега не распознаётся.

- -

В XUL-документах создает указанный в аргументе элемент XUL.

- -

В остальных случаях создаёт элемент с нулевым NamespaceURI.

- -

Параметры

- -
var element = document.createElement(tagName, [options]);
-
- - - -

Пример

- -

Данный пример создает новый элемент <div> и вставляет его перед элементом с идентификатором org_div1:

- -
<!DOCTYPE html>
-<html>
-<head>
-<title>||Работа с элементами||</title>
-</head>
-
-<body>
-<div><h1>Привет!</h1></div>
-<div id='org_div1'>Текст выше сгенерирован автоматически.</div>
-</body>
-
-<script>
-  document.body.onload = addElement;
-  var my_div = newDiv = null;
-
-  function addElement() {
-
-    // Создаем новый элемент div
-    // и добавляем в него немного контента
-
-    var newDiv = document.createElement("div");
-        newDiv.innerHTML = "<h1>Привет!</h1>";
-
-    // Добавляем только что созданый элемент в дерево DOM
-
-    my_div = document.getElementById("org_div1");
-    document.body.insertBefore(newDiv, my_div);
-  }
-</script>
-</html>
-
- -

Заметки

- -

Если существуют атрибуты со значениями по умолчанию, атрибуты узлов предоставляющие их создаются автоматически и применяются к элементу.

- -

Для создания элементов с заданым пространством имен используйте метод createElementNS.

- -

Реализация createElement в Gecko не соответствует DOM спецификации для XUL и XHTML документов: localName и namespaceURI не устанавливаются в  null в созданном документе. Смотрите {{ Bug(280692) }} для подробностей.

- -

Для обратной совместимости с предыдущими версиями спецификации пользовательских элементов некоторые браузеры позволяют передавать здесь строку вместо объекта, где значением строки является имя тега пользовательского элемента.

- -

Спецификации

- -

DOM 2 Модуль: createElement

- -

{{ languages( { "fr": "fr/DOM/document.createElement", "it": "it/DOM/document.createElement", "pl": "pl/DOM/document.createElement" } ) }}

diff --git a/files/ru/dom/document.images/index.html b/files/ru/dom/document.images/index.html deleted file mode 100644 index c9ba4ac1e2..0000000000 --- a/files/ru/dom/document.images/index.html +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: document.images -slug: DOM/document.images -tags: - - DOM - - JavaScript -translation_of: Web/API/Document/images ---- -

{{ ApiRef() }}

-

Кратко об обьекте

-

document.images возвращает коллекцию изображений в текущем HTML документе.

-

Синтаксис

-
var htmlCollection = document.images;
-
-

Пример

-
var images = document.images;
-
-for(var i = 0; i < images.length; i++) {
-    if(images[i].src == "banner.gif") {
-      alert('Баннер найден!');
-    };
-};
-
-

Примечания

-

document.images.length — возвращает количество изображений на странице.

-

document.images является частью DOM HTML, и работает только в HTML документах.

-

Спецификация

-

DOM Level 2 HTML: HTMLDocument.images

-

{{ languages( { "en": "en/DOM/document.images", "fr": "fr/DOM/document.images", "pl": "pl/DOM/document.images","ru":"ru/DOM/document.images" } ) }}

diff --git a/files/ru/dom/dom_reference/events/index.html b/files/ru/dom/dom_reference/events/index.html deleted file mode 100644 index eeadb57328..0000000000 --- a/files/ru/dom/dom_reference/events/index.html +++ /dev/null @@ -1,80 +0,0 @@ ---- -title: Events and the DOM -slug: DOM/DOM_Reference/Events -translation_of: Web/API/Document_Object_Model/Events ---- -

Вступление

- -

Вступление

- -

В этой главе описывается модель событий DOM. Топ скрыть Интерфейс сам по себе описано, а также интерфейсы для регистрации событий на узлах в DOM, Также а слушатели события Главного , Также а Несколько больше Примеры, которые показывают, как Различные интерфейсы связаны друг события Главного с другом.

- -

Существует отличная диаграмма, которая четко объясняет события трех этапов через DOM в проекте DOM Level 3 Events .

- -

Также см. Пример 5: Распространение событий в главе «Примеры» для более подробного примера.

- -

Регистрация слушателей событий

- -

Есть 3 способа регистрации обработанных событий для элемента DOM.

- -

EventTarget.addEventListener

- -
// Предполагая, что myButton является элементом кнопки
-myButton.addEventListener ('click', greet, false);
-function greet (event) {
-    // распечатать и посмотреть на объект события
-    // всегда печатать аргументы в случае пропуска любых других аргументов
-    console.log ('greet:', arguments);
-    оповещение («Привет, мир»);
-}
-
- -

Это метод, который вы должны использовать на современных веб-страницах.

- -

Примечание. Internet Explorer 6-8 не поддерживает этот метод, предлагая аналогичный {{domxref ("EventTarget.attachEvent")}} API. Для кросс-браузерной совместимости используйте одну из множества доступных библиотек JavaScript.

- -

Дополнительную информацию можно найти на справочной странице {{domxref ("EventTarget.addEventListener")}}.

- -

Атрибут HTML

- -
<button onclick = "alert ('Hello world!')">
-
- -

Код JavaScript в атрибуте передается объекту Event через eventпараметр. Возвращаемое значение обрабатывается особым образом, описанным в спецификации HTML .

- -

Этого пути следует избегать. Это делает разметку больше и менее читаемой. Проблемы содержания / структуры и поведения плохо разделены, что затрудняет поиск ошибки.

- -

Свойства элемента DOM

- -
// Предполагая, что myButton является элементом кнопки
-myButton.onclick = function(event){alert('Hello world');};
-
- -

Функция может быть определена для получения eventпараметра. Возвращаемое значение обрабатывается особым образом, описанным в спецификации HTML .

- -

Проблема этого метода в том, что для каждого элемента и для каждого события может быть установлен только один обработчик.

- -

Доступ к интерфейсам событий

- -

Обработчики событий могут быть присоединены к различным объектам, включая элементы DOM, документ, объект окна и т. Д. Когда происходит событие, объект события создается и последовательно передается слушателям события.

- -

Интерфейс {{domxref ("Event")}} доступен из функции-обработчика через объект события, переданный в качестве первого аргумента. В следующем простом примере показано, как объект события передается в функцию-обработчик события и может использоваться из одной такой функции.

- -
function print(evt) {
-  // параметру evt автоматически назначается объект события
-  // позаботимся о различиях в console.log и alert
-  console.log('print:', evt);
-  alert(evt);
-}
-// любая функция должна иметь подходящее имя, это то, что называется семантическим
-table_el.onclick = print; 
-
- - - - diff --git a/files/ru/dom/dom_reference/examples/index.html b/files/ru/dom/dom_reference/examples/index.html deleted file mode 100644 index a3332f7585..0000000000 --- a/files/ru/dom/dom_reference/examples/index.html +++ /dev/null @@ -1,382 +0,0 @@ ---- -title: Examples of web and XML development using the DOM -slug: DOM/DOM_Reference/Examples -translation_of: Web/API/Document_Object_Model/Examples ---- -

В этой главе представлены более длинные примеры разработки веб-сайтов и XML с использованием DOM. По возможности, примеры используют общие API, трюки и шаблоны в JavaScript для управления объектом документа.

- -

Пример 1: высота и ширина

- -

В следующем примере показано использование свойств высоты и ширины для изображений разных размеров:
-  

- -
<!DOCTYPE html>
-<html lang="en">
-<head>
-<title>width/height example</title>
-<script>
-function init() {
-  var arrImages = new Array(3);
-
-  arrImages[0] = document.getElementById("image1");
-  arrImages[1] = document.getElementById("image2");
-  arrImages[2] = document.getElementById("image3");
-
-  var objOutput = document.getElementById("output");
-  var strHtml = "<ul>";
-
-  for (var i = 0; i < arrImages.length; i++) {
-    strHtml += "<li>image" + (i+1) +
-            ": height=" + arrImages[i].height +
-            ", width=" + arrImages[i].width +
-            ", style.height=" + arrImages[i].style.height +
-            ", style.width=" + arrImages[i].style.width +
-            "<\/li>";
-  }
-
-  strHtml += "<\/ul>";
-
-  objOutput.innerHTML = strHtml;
-}
-</script>
-</head>
-<body onload="init();">
-
-<p>Image 1: no height, width, or style
-  <img id="image1" src="http://www.mozilla.org/images/mozilla-banner.gif">
-</p>
-
-<p>Image 2: height="50", width="500", but no style
-  <img id="image2"
-       src="http://www.mozilla.org/images/mozilla-banner.gif"
-       height="50" width="500">
-</p>
-
-<p>Image 3: no height, width, but style="height: 50px; width: 500px;"
-  <img id="image3"
-       src="http://www.mozilla.org/images/mozilla-banner.gif"
-       style="height: 50px; width: 500px;">
-</p>
-
-<div id="output"> </div>
-</body>
-</html>
-
- -

Пример 2: Аттрибуты Изображения

- -
<!DOCTYPE html>
-<html lang="en">
-<head>
-<title>Modifying an image border</title>
-
-<script>
-function setBorderWidth(width) {
-  document.getElementById("img1").style.borderWidth = width + "px";
-}
-</script>
-</head>
-
-<body>
-<p>
-  <img id="img1"
-       src="image1.gif"
-       style="border: 5px solid green;"
-       width="100" height="100" alt="border test">
-</p>
-
-<form name="FormName">
-  <input type="button" value="Make border 20px-wide" onclick="setBorderWidth(20);" />
-  <input type="button" value="Make border 5px-wide"  onclick="setBorderWidth(5);" />
-</form>
-
-</body>
-</html>
-
- -

Пример 3: Управление Стилями

- -

В этом простом примере, некоторые базовые свойства стиля элемента абзаца HTML доступны с помощью объекта стиля элемента и свойств стиля CSS этого объекта, который можно получить и установить из DOM. В этом случае вы напрямую управляете отдельными стилями. В следующем примере (см. Пример 4), вы можете использовать таблицы стилей и их правила для изменения стилей для целых документов.

- -
<!DOCTYPE html>
-<html lang="en">
-<head>
-<title>Changing color and font-size example</title>
-
-<script>
-function changeText() {
-  var p = document.getElementById("pid");
-
-  p.style.color = "blue"
-  p.style.fontSize = "18pt"
-}
-</script>
-</head>
-<body>
-
-<p id="pid" onclick="window.location.href = 'http://www.cnn.com/';">linker</p>
-
-<form>
-  <p><input value="rec" type="button" onclick="changeText();" /></p>
-</form>
-
-</body>
-</html>
-
- -

Пример 4: Использование Стилей

- -

Свойство styleSheets объекта документа возвращает список таблиц стилей, которые были загружены в этот документ. Вы можете получить доступ к этим таблицам стилей и их правилам индивидуально, используя объекты таблицы стилей, стилей и CSS правил объекта, как показано в этом примере, который выводит все селектора правил стиля в консоль.

- -
var ss = document.styleSheets;
-
-for(var i = 0; i < ss.length; i++) {
-  for(var j = 0; j < ss[i].cssRules.length; j++) {
-    dump( ss[i].cssRules[j].selectorText + "\n" );
-  }
-}
- -

Для документа с единой таблицей стилей, в которой определены следующие три правила:

- -
body { background-color: darkblue; }
-p { font-face: Arial; font-size: 10pt; margin-left: .125in; }
-#lumpy { display: none; }
-
- -

Этот скрипт выводит следующее:

- -
BODY
-P
-#LUMPY
-
- -

Пример 5: Распространение Событий

- -

Этот пример демонстрирует, как события срабатывают и обрабатываются в DOM очень простым путём. Когда загружается BODY в составе HTML-документа, обработчик событий регистрируется в верхней строке таблицы TABLE. Обработчик событий реагирует на событие запуском функции stopEvent, изменяющей значение в нижней ячейке.

- -

Однако, stopEvent также вызывает метод объекта событий, {{domxref("event.stopPropagation")}}, что препятствует дальнейшему всплытию события в DOM. Обратите внимание, что сама таблица имеет {{domxref("element.onclick","onclick")}} обработчик событий, который должен отображать сообщение при нажатии на таблицу. Но метод stopEvent метод прекратил распространение, и поэтому после обновления данных в таблице фаза события эффективно завершается, и отображается окно предупреждения для подтверждения.

- -
<!DOCTYPE html>
-<html lang="en">
-<head>
-<title>Event Propagation</title>
-
-<style>
-#t-daddy { border: 1px solid red }
-#c1 { background-color: pink; }
-</style>
-
-<script>
-function stopEvent(ev) {
-  c2 = document.getElementById("c2");
-  c2.innerHTML = "hello";
-
-  // this ought to keep t-daddy from getting the click.
-  ev.stopPropagation();
-  alert("event propagation halted.");
-}
-
-function load() {
-  elem = document.getElementById("tbl1");
-  elem.addEventListener("click", stopEvent, false);
-}
-</script>
-</head>
-
-<body onload="load();">
-
-<table id="t-daddy" onclick="alert('hi');">
-  <tr id="tbl1">
-    <td id="c1">one</td>
-  </tr>
-  <tr>
-    <td id="c2">two</td>
-  </tr>
-</table>
-
-</body>
-</html>
-
- -

Пример 6: getComputedStyle

- -

Этот пример показывает как {{domxref("window.getComputedStyle")}} метод может использоваться для получения стилей элемента, которые не заданы с помощью атрибута style или с помощью JavaScript (e.g., elt.style.backgroundColor="rgb(173, 216, 230)"). Эти последние типы стилей можно получить с помощью более прямых {{domxref("element.style", "elt.style")}} свойств, которые указаны в DOM CSS Properties List.

- -

getComputedStyle () возвращает объект ComputedCSSStyleDeclaration, свойства индивидуального стиля которого могут ссылаться на метод getPropertyValue () этого объекта, как показано в следующем примере документа.

- -
<!DOCTYPE html>
-<html lang="en">
-<head>
-
-<title>getComputedStyle example</title>
-
-<script>
-function cStyles() {
-  var RefDiv = document.getElementById("d1");
-  var txtHeight = document.getElementById("t1");
-  var h_style = document.defaultView.getComputedStyle(RefDiv, null).getPropertyValue("height");
-
-  txtHeight.value = h_style;
-
-  var txtWidth = document.getElementById("t2");
-  var w_style = document.defaultView.getComputedStyle(RefDiv, null).getPropertyValue("width");
-
-  txtWidth.value = w_style;
-
-  var txtBackgroundColor = document.getElementById("t3");
-  var b_style = document.defaultView.getComputedStyle(RefDiv, null).getPropertyValue("background-color");
-
-  txtBackgroundColor.value = b_style;
-}
-</script>
-
-<style>
-#d1 {
-  margin-left: 10px;
-  background-color: rgb(173, 216, 230);
-  height: 20px;
-  max-width: 20px;
-}
-</style>
-
-</head>
-
-<body>
-
-<div id="d1">&nbsp;</div>
-
-<form action="">
-  <p>
-    <button type="button" onclick="cStyles();">getComputedStyle</button>
-    height<input id="t1" type="text" value="1" />
-    max-width<input id="t2" type="text" value="2" />
-    bg-color<input id="t3" type="text" value="3" />
-  </p>
-</form>
-
-</body>
-</html>
-
- -

Пример 7: Отображение Свойств Событий Объекта

- - - -

В этом примере используются методы DOM для отображения всех свойств объекта {{domxref ("window.onload")}} {{domxref ("event")}} и их значений в таблице. Он также показывает полезный метод использования цикла for..in для итерации по свойствам объекта для получения их значений.

- -

Свойства объектов событий сильно различаются между браузерами, WHATWG DOM Standard перечисляет стандартные свойства, однако многие браузеры значительно расширили их.

- -

Поместите следующий код в пустой текстовый файл и загрузите его в различные браузеры, вы будете удивлены различным количеством и именами свойств. Вы также можете добавить некоторые элементы на страницу и вызвать эту функцию из разных обработчиков событий.

- - - -
<!DOCTYPE html>
-<html lang="en">
-<head>
-<meta charset="utf-8"/>
-<title>Show Event properties</title>
-
-<style>
-table { border-collapse: collapse; }
-thead { font-weight: bold; }
-td { padding: 2px 10px 2px 10px; }
-
-.odd { background-color: #efdfef; }
-.even { background-color: #ffffff; }
-</style>
-
-<script>
-
-function showEventProperties(e) {
-  function addCell(row, text) {
-    var cell = row.insertCell(-1);
-    cell.appendChild(document.createTextNode(text));
-  }
-
-  var e = e || window.event;
-  document.getElementById('eventType').innerHTML = e.type;
-
-  var table = document.createElement('table');
-  var thead = table.createTHead();
-  var row = thead.insertRow(-1);
-  var lableList = ['#', 'Property', 'Value'];
-  var len = lableList.length;
-
-  for (var i=0; i<len; i++) {
-    addCell(row, lableList[i]);
-  }
-
-  var tbody = document.createElement('tbody');
-  table.appendChild(tbody);
-
-  for (var p in e) {
-    row = tbody.insertRow(-1);
-    row.className = (row.rowIndex % 2)? 'odd':'even';
-    addCell(row, row.rowIndex);
-    addCell(row, p);
-    addCell(row, e[p]);
-  }
-
-  document.body.appendChild(table);
-}
-
-window.onload = function(event){
-  showEventProperties(event);
-}
-</script>
-</head>
-
-<body>
-<h1>Properties of the DOM <span id="eventType"></span> Event Object</h1>
-</body>
-
-</html>
-
- -

Пример 8: Использование интерфейса таблицы DOM

- - - -

Интерфейс DOM HTMLTableElement предоставляет некоторые удобные методы для создания и управления таблицами. Два часто используемых метода: {{domxref ("HTMLTableElement.insertRow")}} и {{domxref ("tableRow.insertCell")}}.

- -

Чтобы добавить строку и некоторые ячейки в существующую таблицу:

- - - -
<table id="table0">
- <tr>
-  <td>Row 0 Cell 0</td>
-  <td>Row 0 Cell 1</td>
- </tr>
-</table>
-
-<script>
-var table = document.getElementById('table0');
-var row = table.insertRow(-1);
-var cell,
-    text;
-
-for (var i = 0; i < 2; i++) {
-  cell = row.insertCell(-1);
-  text = 'Row ' + row.rowIndex + ' Cell ' + i;
-  cell.appendChild(document.createTextNode(text));
-}
-</script>
-
- -

Заметки

- - - - - - diff --git a/files/ru/dom/dom_reference/index.html b/files/ru/dom/dom_reference/index.html deleted file mode 100644 index db06b01dd8..0000000000 --- a/files/ru/dom/dom_reference/index.html +++ /dev/null @@ -1,387 +0,0 @@ ---- -title: Руководство по DOM -slug: DOM/DOM_Reference -tags: - - DOM - - DOM Reference - - DOM интерфейс - - Intermediate - - Руководство -translation_of: Web/API/Document_Object_Model ---- -

Объектная Модель Документа (DOM) является программным интерфейсом для HTML, XML и SVG документов. Это обеспечивает структурированное представление документа (дерева), и определяет способ, по которому структура может быть доступна для программы, для изменения структуры документа, его стиля и содержания. DOM обеспечивает представление документа в виде структурированной группы узлов и объектов, которые имеют свойства и методы. По сути, она связывает веб -страницы со скриптами или языками программирования.

- -

DOM чаще всего используется в JavaScript, но не является его частью, поэтому иногда с DOM работают в других языках.

- -

Введение в DOM доступно.

- -

DOM интерфейсы

- -
-
    -
  • {{domxref("Attr")}}
  • -
  • {{domxref("CharacterData")}}
  • -
  • {{domxref("ChildNode")}} {{experimental_inline}}
  • -
  • {{domxref("Comment")}}
  • -
  • {{domxref("CustomEvent")}}
  • -
  • {{domxref("Document")}}
  • -
  • {{domxref("DocumentFragment")}}
  • -
  • {{domxref("DocumentType")}}
  • -
  • {{domxref("DOMError")}}
  • -
  • {{domxref("DOMException")}}
  • -
  • {{domxref("DOMImplementation")}}
  • -
  • {{domxref("DOMString")}}
  • -
  • {{domxref("DOMTimeStamp")}}
  • -
  • {{domxref("DOMSettableTokenList")}}
  • -
  • {{domxref("DOMStringList")}}
  • -
  • {{domxref("DOMTokenList")}}
  • -
  • {{domxref("Element")}}
  • -
  • {{domxref("Event")}}
  • -
  • {{domxref("EventTarget")}}
  • -
  • {{domxref("HTMLCollection")}}
  • -
  • {{domxref("MutationObserver")}}
  • -
  • {{domxref("MutationRecord")}}
  • -
  • {{domxref("Node")}}
  • -
  • {{domxref("NodeFilter")}}
  • -
  • {{domxref("NodeIterator")}}
  • -
  • {{domxref("NodeList")}}
  • -
  • {{domxref("ParentNode")}} {{experimental_inline}}
  • -
  • {{domxref("ProcessingInstruction")}}
  • -
  • {{domxref("Promise")}} {{experimental_inline}}
  • -
  • {{domxref("PromiseResolver")}} {{experimental_inline}}
  • -
  • {{domxref("Range")}}
  • -
  • {{domxref("Text")}}
  • -
  • {{domxref("TreeWalker")}}
  • -
  • {{domxref("URL")}}
  • -
  • {{domxref("Window")}}
  • -
  • {{domxref("Worker")}}
  • -
  • {{domxref("XMLDocument")}} {{experimental_inline}}
  • -
-
- -

Устаревшие интерфейсы

- -

Объектная модель документа находится в процессе значительного упрощения. Для того, чтобы достигнуть этого следующие интерфейсы, присутствующие на различных DOM level 3 или более ранних спецификациях были удалены. До сих пор неясно, будут ли некоторые из них возвращены, но на данный момент они должны быть рассмотрены как устаревшие, и их использования следует избегать:

- -
-
    -
  • {{domxref("CDATASection")}}
  • -
  • {{domxref("DOMConfiguration")}}
  • -
  • {{domxref("DOMErrorHandler")}}
  • -
  • {{domxref("DOMImplementationList")}}
  • -
  • {{domxref("DOMImplementationRegistry")}}
  • -
  • {{domxref("DOMImplementationSource")}}
  • -
  • {{domxref("DOMLocator")}}
  • -
  • {{domxref("DOMObject")}}
  • -
  • {{domxref("DOMUserData")}}
  • -
  • {{domxref("Entity")}}
  • -
  • {{domxref("EntityReference")}}
  • -
  • {{domxref("NamedNodeMap")}}
  • -
  • {{domxref("NameList")}}
  • -
  • {{domxref("Notation")}}
  • -
  • {{domxref("TypeInfo")}}
  • -
  • {{domxref("UserDataHandler")}}
  • -
-
- -

HTML интерфейсы

- -

Документ, содержащий HTML описывается с помощью {{domxref("HTMLDocument")}} интерфейса. Обратите внимание, что HTML спецификация также расширяет {{domxref("Document")}} интерфейс.

- -

Объект HTMLDocument также даёт доступ к следующим возможностям браузера: вкладки, окна, в которых отрисовывается страница, используя интерфейс {{domxref("Window")}}, асcоциированный с ним {{domxref("window.style", "Style")}} (обычно CSS), история браузера, относящаяся к контексту, {{domxref("window.history", "History")}}, в конце концов, {{domxref("Selection")}} в документе.

- -

Интерфейсы HTML элементов

- -
-
    -
  • {{domxref("HTMLAnchorElement")}}
  • -
  • {{domxref("HTMLAppletElement")}}
  • -
  • {{domxref("HTMLAreaElement")}}
  • -
  • {{domxref("HTMLAudioElement")}}
  • -
  • {{domxref("HTMLBaseElement")}}
  • -
  • {{domxref("HTMLBodyElement")}}
  • -
  • {{domxref("HTMLBRElement")}}
  • -
  • {{domxref("HTMLButtonElement")}}
  • -
  • {{domxref("HTMLCanvasElement")}}
  • -
  • {{domxref("HTMLDataElement")}}
  • -
  • {{domxref("HTMLDataListElement")}}
  • -
  • {{domxref("HTMLDirectoryElement")}}
  • -
  • {{domxref("HTMLDivElement")}}
  • -
  • {{domxref("HTMLDListElement")}}
  • -
  • {{domxref("HTMLElement")}}
  • -
  • {{domxref("HTMLEmbedElement")}}
  • -
  • {{domxref("HTMLFieldSetElement")}}
  • -
  • {{domxref("HTMLFontElement")}}
  • -
  • {{domxref("HTMLFormElement")}}
  • -
  • {{domxref("HTMLFrameElement")}}
  • -
  • {{domxref("HTMLFrameSetElement")}}
  • -
  • {{domxref("HTMLHeadElement")}}
  • -
  • {{domxref("HTMLHeadingElement")}}
  • -
  • {{domxref("HTMLHtmlElement")}}
  • -
  • {{domxref("HTMLHRElement")}}
  • -
  • {{domxref("HTMLIFrameElement")}}
  • -
  • {{domxref("HTMLImageElement")}}
  • -
  • {{domxref("HTMLInputElement")}}
  • -
  • {{domxref("HTMLKeygenElement")}}
  • -
  • {{domxref("HTMLLabelElement")}}
  • -
  • {{domxref("HTMLLegendElement")}}
  • -
  • {{domxref("HTMLLIElement")}}
  • -
  • {{domxref("HTMLLinkElement")}}
  • -
  • {{domxref("HTMLMapElement")}}
  • -
  • {{domxref("HTMLMediaElement")}}
  • -
  • {{domxref("HTMLMenuElement")}}
  • -
  • {{domxref("HTMLMetaElement")}}
  • -
  • {{domxref("HTMLMeterElement")}}
  • -
  • {{domxref("HTMLModElement")}}
  • -
  • {{domxref("HTMLObjectElement")}}
  • -
  • {{domxref("HTMLOListElement")}}
  • -
  • {{domxref("HTMLOptGroupElement")}}
  • -
  • {{domxref("HTMLOptionElement")}}
  • -
  • {{domxref("HTMLOutputElement")}}
  • -
  • {{domxref("HTMLParagraphElement")}}
  • -
  • {{domxref("HTMLParamElement")}}
  • -
  • {{domxref("HTMLPreElement")}}
  • -
  • {{domxref("HTMLProgressElement")}}
  • -
  • {{domxref("HTMLQuoteElement")}}
  • -
  • {{domxref("HTMLScriptElement")}}
  • -
  • {{domxref("HTMLSelectElement")}}
  • -
  • {{domxref("HTMLSourceElement")}}
  • -
  • {{domxref("HTMLSpanElement")}}
  • -
  • {{domxref("HTMLStyleElement")}}
  • -
  • {{domxref("HTMLTableElement")}}
  • -
  • {{domxref("HTMLTableCaptionElement")}}
  • -
  • {{domxref("HTMLTableCellElement")}}
  • -
  • {{domxref("HTMLTableDataCellElement")}}
  • -
  • {{domxref("HTMLTableHeaderCellElement")}}
  • -
  • {{domxref("HTMLTableColElement")}}
  • -
  • {{domxref("HTMLTableRowElement")}}
  • -
  • {{domxref("HTMLTableSectionElement")}}
  • -
  • {{domxref("HTMLTextAreaElement")}}
  • -
  • {{domxref("HTMLTimeElement")}}
  • -
  • {{domxref("HTMLTitleElement")}}
  • -
  • {{domxref("HTMLTrackElement")}}
  • -
  • {{domxref("HTMLUListElement")}}
  • -
  • {{domxref("HTMLUnknownElement")}}
  • -
  • {{domxref("HTMLVideoElement")}}
  • -
-
- -

Другие интерфейсы

- -
-
    -
  • {{domxref("CanvasRenderingContext2D")}}
  • -
  • {{domxref("CanvasGradient")}}
  • -
  • {{domxref("CanvasPattern")}}
  • -
  • {{domxref("TextMetrics")}}
  • -
  • {{domxref("ImageData")}}
  • -
  • {{domxref("CanvasPixelArray")}}
  • -
  • {{domxref("NotifyAudioAvailableEvent")}}
  • -
  • {{domxref("HTMLAllCollection")}}
  • -
  • {{domxref("HTMLFormControlsCollection")}}
  • -
  • {{domxref("HTMLOptionsCollection")}}
  • -
  • {{domxref("HTMLPropertiesCollection")}}
  • -
  • {{domxref("DOMStringMap")}}
  • -
  • {{domxref("RadioNodeList")}}
  • -
  • {{domxref("MediaError")}}
  • -
-
- -

Устаревшие HTML интерфейсы

- -
-
    -
  • {{domxref("HTMLBaseFontElement")}}
  • -
  • {{domxref("HTMLIsIndexElement")}}
  • -
-
- -

SVG интерфейсы

- -

Интерфейсы SVG элементов

- -
-
    -
  • {{domxref("SVGAElement")}}
  • -
  • {{domxref("SVGAltGlyphElement")}}
  • -
  • {{domxref("SVGAltGlyphDefElement")}}
  • -
  • {{domxref("SVGAltGlyphItemElement")}}
  • -
  • {{domxref("SVGAnimationElement")}}
  • -
  • {{domxref("SVGAnimateElement")}}
  • -
  • {{domxref("SVGAnimateColorElement")}}
  • -
  • {{domxref("SVGAnimateMotionElement")}}
  • -
  • {{domxref("SVGAnimateTransformElement")}}
  • -
  • {{domxref("SVGCircleElement")}}
  • -
  • {{domxref("SVGClipPathElement")}}
  • -
  • {{domxref("SVGColorProfileElement")}}
  • -
  • {{domxref("SVGComponentTransferFunctionElement")}}
  • -
  • {{domxref("SVGCursorElement")}}
  • -
  • {{domxref("SVGDefsElement")}}
  • -
  • {{domxref("SVGDescElement")}}
  • -
  • {{domxref("SVGElement")}}
  • -
  • {{domxref("SVGEllipseElement")}}
  • -
  • {{domxref("SVGFEBlendElement")}}
  • -
  • {{domxref("SVGFEColorMatrixElement")}}
  • -
  • {{domxref("SVGFEComponentTransferElement")}}
  • -
  • {{domxref("SVGFECompositeElement")}}
  • -
  • {{domxref("SVGFEConvolveMatrixElement")}}
  • -
  • {{domxref("SVGFEDiffuseLightingElement")}}
  • -
  • {{domxref("SVGFEDisplacementMapElement")}}
  • -
  • {{domxref("SVGFEDistantLightElement")}}
  • -
  • {{domxref("SVGFEFloodElement")}}
  • -
  • {{domxref("SVGFEGaussianBlurElement")}}
  • -
  • {{domxref("SVGFEImageElement")}}
  • -
  • {{domxref("SVGFEMergeElement")}}
  • -
  • {{domxref("SVGFEMergeNodeElement")}}
  • -
  • {{domxref("SVGFEMorphologyElement")}}
  • -
  • {{domxref("SVGFEOffsetElement")}}
  • -
  • {{domxref("SVGFEPointLightElement")}}
  • -
  • {{domxref("SVGFESpecularLightingElement")}}
  • -
  • {{domxref("SVGFESpotLightElement")}}
  • -
  • {{domxref("SVGFETileElement")}}
  • -
  • {{domxref("SVGFETurbulenceElement")}}
  • -
  • {{domxref("SVGFEFuncRElement")}}
  • -
  • {{domxref("SVGFEFuncGElement")}}
  • -
  • {{domxref("SVGFEFuncBElement")}}
  • -
  • {{domxref("SVGFEFuncAElement")}}
  • -
  • {{domxref("SVGFilterElement")}}
  • -
  • {{domxref("SVGFilterPrimitiveStandardAttributes")}}
  • -
  • {{domxref("SVGFontElement")}}
  • -
  • {{domxref("SVGFontFaceElement")}}
  • -
  • {{domxref("SVGFontFaceFormatElement")}}
  • -
  • {{domxref("SVGFontFaceNameElement")}}
  • -
  • {{domxref("SVGFontFaceSrcElement")}}
  • -
  • {{domxref("SVGFontFaceUriElement")}}
  • -
  • {{domxref("SVGForeignObjectElement")}}
  • -
  • {{domxref("SVGGElement")}}
  • -
  • {{domxref("SVGGlyphElement")}}
  • -
  • {{domxref("SVGGlyphRefElement")}}
  • -
  • {{domxref("SVGGradientElement")}}
  • -
  • {{domxref("SVGHKernElement")}}
  • -
  • {{domxref("SVGImageElement")}}
  • -
  • {{domxref("SVGLinearGradientElement")}}
  • -
  • {{domxref("SVGLineElement")}}
  • -
  • {{domxref("SVGMarkerElement")}}
  • -
  • {{domxref("SVGMaskElement")}}
  • -
  • {{domxref("SVGMetadataElement")}}
  • -
  • {{domxref("SVGMissingGlyphElement")}}
  • -
  • {{domxref("SVGMPathElement")}}
  • -
  • {{domxref("SVGPathElement")}}
  • -
  • {{domxref("SVGPatternElement")}}
  • -
  • {{domxref("SVGPolylineElement")}}
  • -
  • {{domxref("SVGPolygonElement")}}
  • -
  • {{domxref("SVGRadialGradientElement")}}
  • -
  • {{domxref("SVGRectElement")}}
  • -
  • {{domxref("SVGScriptElement")}}
  • -
  • {{domxref("SVGSetElement")}}
  • -
  • {{domxref("SVGStopElement")}}
  • -
  • {{domxref("SVGStyleElement")}}
  • -
  • {{domxref("SVGSVGElement")}}
  • -
  • {{domxref("SVGSwitchElement")}}
  • -
  • {{domxref("SVGSymbolElement")}}
  • -
  • {{domxref("SVGTextElement")}}
  • -
  • {{domxref("SVGTextPathElement")}}
  • -
  • {{domxref("SVGTitleElement")}}
  • -
  • {{domxref("SVGTRefElement")}}
  • -
  • {{domxref("SVGTSpanElement")}}
  • -
  • {{domxref("SVGUseElement")}}
  • -
  • {{domxref("SVGViewElement")}}
  • -
  • {{domxref("SVGVKernElement")}}
  • -
-
- -

Интерфейсы SVG данных

- -

DOM API для типов данных, используемых в определениях SVG свойств и атрибутов.

- -
-

Замечание: Начиная с {{Gecko("5.0")}}, следующие относящиеся к SVG DOM интерфейсы, представляя списки объектов, индексируются и к ним можно иметь доступ как к массивам; к тому же, у них есть свойство длины, обозначающее количество элементов в списках: {{domxref("SVGLengthList")}}, {{domxref("SVGNumberList")}}, {{domxref("SVGPathSegList")}} и {{domxref("SVGPointList")}}.

-
- -

Статический тип

- -
-
    -
  • {{domxref("SVGAngle")}}
  • -
  • {{domxref("SVGColor")}}
  • -
  • {{domxref("SVGICCColor")}}
  • -
  • {{domxref("SVGElementInstance")}}
  • -
  • {{domxref("SVGElementInstanceList")}}
  • -
  • {{domxref("SVGLength")}}
  • -
  • {{domxref("SVGLengthList")}}
  • -
  • {{domxref("SVGMatrix")}}
  • -
  • {{domxref("SVGNumber")}}
  • -
  • {{domxref("SVGNumberList")}}
  • -
  • {{domxref("SVGPaint")}}
  • -
  • {{domxref("SVGPoint")}}
  • -
  • {{domxref("SVGPointList")}}
  • -
  • {{domxref("SVGPreserveAspectRatio")}}
  • -
  • {{domxref("SVGRect")}}
  • -
  • {{domxref("SVGStringList")}}
  • -
  • {{domxref("SVGTransform")}}
  • -
  • {{domxref("SVGTransformList")}}
  • -
-
- -

Анимированный тип

- -
-
    -
  • {{domxref("SVGAnimatedAngle")}}
  • -
  • {{domxref("SVGAnimatedBoolean")}}
  • -
  • {{domxref("SVGAnimatedEnumeration")}}
  • -
  • {{domxref("SVGAnimatedInteger")}}
  • -
  • {{domxref("SVGAnimatedLength")}}
  • -
  • {{domxref("SVGAnimatedLengthList")}}
  • -
  • {{domxref("SVGAnimatedNumber")}}
  • -
  • {{domxref("SVGAnimatedNumberList")}}
  • -
  • {{domxref("SVGAnimatedPreserveAspectRatio")}}
  • -
  • {{domxref("SVGAnimatedRect")}}
  • -
  • {{domxref("SVGAnimatedString")}}
  • -
  • {{domxref("SVGAnimatedTransformList")}}
  • -
-
- -

Относящиеся к SMIL

- -
-
    -
  • {{domxref("ElementTimeControl")}}
  • -
  • {{domxref("TimeEvent")}}
  • -
-
- -

Другие SVG интерфейсы

- -
-
    -
  • {{domxref("SVGAnimatedPathData")}}
  • -
  • {{domxref("SVGAnimatedPoints")}}
  • -
  • {{domxref("SVGColorProfileRule")}}
  • -
  • {{domxref("SVGCSSRule")}}
  • -
  • {{domxref("SVGExternalResourcesRequired")}}
  • -
  • {{domxref("SVGFitToViewBox")}}
  • -
  • {{domxref("SVGLangSpace")}}
  • -
  • {{domxref("SVGLocatable")}}
  • -
  • {{domxref("SVGRenderingIntent")}}
  • -
  • {{domxref("SVGStylable")}}
  • -
  • {{domxref("SVGTests")}}
  • -
  • {{domxref("SVGTextContentElement")}}
  • -
  • {{domxref("SVGTextPositioningElement")}}
  • -
  • {{domxref("SVGTransformable")}}
  • -
  • {{domxref("SVGUnitTypes")}}
  • -
  • {{domxref("SVGURIReference")}}
  • -
  • {{domxref("SVGViewSpec")}}
  • -
  • {{domxref("SVGZoomAndPan")}}
  • -
-
- -

Смотрите также

- - - -
-
-
diff --git a/files/ru/dom/dom_reference/locating_dom_elements_using_selectors/index.html b/files/ru/dom/dom_reference/locating_dom_elements_using_selectors/index.html deleted file mode 100644 index 73538e8616..0000000000 --- a/files/ru/dom/dom_reference/locating_dom_elements_using_selectors/index.html +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: Locating DOM elements using selectors -slug: DOM/DOM_Reference/Locating_DOM_elements_using_selectors -translation_of: Web/API/Document_object_model/Locating_DOM_elements_using_selectors ---- -
{{ gecko_minversion_header("1.9.1") }}
- -
Selectors API предоставляет методы, с помощью которых можно быстро и просто получить доступ к узлам Element из DOM путем сопоставления с набором селекторов. Это намного быстрее, чем прошлые техники, где надо было, например, использовать цикл в JS-коде, чтобы найти конкретные элементы.
- -
 
- -

Интерфейс NodeSelector (The NodeSelector interface)

- -

Эта спецификация добавляет два новых метода к любым объектам, реализующим интерфейс Document, DocumentFragment, или Element:

- -
-
querySelector
-
Возвращает первый совпадающий узел Element внутри поддерева. Если совпадающих узлов нет, будет возвращен null.
-
querySelectorAll
-
Возвращает NodeList, содержащий все подходящие узлы Element внутри поддерева узлов. Или возвращает пустой NodeList, если совпадений не найдено.
-
- -
Замечание: NodeList, возвращаемый методом querySelectorAll(), не настоящий. Этот список отличается от других методов поиска DOM, которые возвращают настоящие (живые) узлы.
- -

Вы можете найти примеры и детали, прочитав документацию для методов querySelector() и querySelectorAll(), а также в статье Code snippets for querySelector.

- -

Selectors

- -

Селекторные методы принимают один или больше селекторов, разделенных запятыми, чтобы определить, какие элементы должны быть возвращены. Например, чтобы все параграфы в документе, которые имеют классы warning или note, можно сделать следующее:

- -
var special = document.querySelectorAll( "p.warning, p.note" );
- -

Также можно искать по ID. Например:

- -
var el = document.querySelector( "#main, #basic, #exclamation" );
- -

После выполнения кода выше, el будет содержать первый элемент в документе, чей ID main, basic или exclamation

- -

Вы можете использовать любые CSS-селекторы в методах querySelector(), querySelectorAll()

- -

See also

- - diff --git "a/files/ru/dom/dom_reference/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265/index.html" "b/files/ru/dom/dom_reference/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265/index.html" deleted file mode 100644 index 3c02e5799f..0000000000 --- "a/files/ru/dom/dom_reference/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265/index.html" +++ /dev/null @@ -1,230 +0,0 @@ ---- -title: Введение -slug: DOM/DOM_Reference/Введение -tags: - - DOM -translation_of: Web/API/Document_Object_Model/Introduction ---- -
-

Этот раздел представляет краткое знакомство с Объектной Моделью Документа (DOM) - что такое DOM, каким образом предоставляются структуры HTML и XML документов, и как взаимодействовать с ними. Данный раздел содержит справочную информацию и примеры.

- -

Что такое Объектная Модель Документа (DOM)?

- -

Объектная Модель Документа (DOM) – это программный интерфейс (API) для HTML и XML документов. DOM предоставляет структурированное представление документа и определяет то, как эта структура может быть доступна из программ, которые могут изменять содержимое, стиль и структуру документа. Представление DOM состоит из структурированной группы узлов и объектов, которые имеют свойства и методы. По существу, DOM соединяет веб-страницу с языками описания сценариев либо языками программирования.
-
- Веб-страница – это документ. Документ может быть представлен как в окне браузера, так и в самом HTML-коде. В любом случае, это один и тот же документ. DOM предоставляет другой способ представления, хранения и управления этого документа. DOM полностью поддерживает объектно-ориентированнное представление веб-страницы, делая возможным её изменение при помощи языка описания сценариев наподобие JavaScript.
-
- Стандарты W3C DOM и WHATWG DOM формируют основы DOM, реализованные в большинстве современных браузеров. Многие браузеры предлагают расширения за пределами данного стандарта, поэтому необходимо проверять работоспособность тех или иных возможностей DOM для каждого конкретного браузера.

- -

Например: стандарт DOM описывает, что метод getElementsByTagName в коде, указанном ниже, должен возращать список всех элементов <p> в документе.

- -
paragraphs = document.getElementsByTagName("P");
-// paragraphs[0] это первый <p> элемент
-// paragraphs[1] это второй <p> элемент и т.д.
-alert(paragraphs[0].nodeName);
- -

Все свойства, методы и события, доступные для управления и создания новых страниц, организованы в виде объектов. Например, объект document, который представляет сам документ, объект table, который реализует специальный интерфейс DOM HTMLTableElement, необходимый для доступа к HTML-таблицам, и так далее. Данная документация даёт справку об объектах DOM, реализованных Gecko-подобных браузерах.

- -

DOM и JavaScript

- -

Небольшой пример выше, как почти все примеры в этой справке – это JavaScript. То есть пример написан на JavaScript, но при этом используется DOM для доступа к документу и его элементам. DOM не является языком программирования, но без него JavaScript не имел бы никакой модели или представления о веб-странице, HTML-документе, XML-документе и их элементах. Каждый элемент в документе - весь документ в целом, заголовок, таблицы внутри документа, заголовки таблицы, текст внутри ячеек таблицы - это части объектной документной модели для этого документа, поэтому все они могут быть доступны и могут изменяться с помощью DOM и скриптового языка наподобие JavaScript.

- -

Вначале JavaScript и DOM были тесно связаны, но впоследствии они развились в различные сущности. Содержимое страницы хранится в DOM и может быть доступно и изменяться с использованием JavaScript, поэтому мы можем записать это в виде приблизительного равенства:

- -

API (веб либо XML страница) = DOM + JS (язык описания скриптов)

- -

DOM спроектирован таким образом, чтобы быть независимым от любого конкретного языка программирования, обеспечивая структурное представление документа согласно единому и последовательному API. Хотя мы всецело сфокусированы на JavaScript в этой справочной документации, реализация DOM может быть построена для любого языка, как в следующем примере на Python:

-
- -
# Пример DOM на языке Python
-import xml.dom.minidom as m
-doc = m.parse("C:\\Projects\\Py\\chap1.xml");
-doc.nodeName # Свойство объекта документа DOM;
-p_list = doc.getElementsByTagName("para");
- -

Для подробной информации о том, какие технологии участвуют в написании JavaScript для веб, смотрите обзорную статью JavaScript technologies overview.

- -

Каким образом доступен DOM? 

- -

Вы не должны делать ничего особенного для работы с DOM. Различные браузеры имеют различную реализацию DOM, эти реализации показывают различную степень соответсвия с действительным стандартом DOM (это тема, которую мы пытались не затрагивать в данной документации), но каждый браузер использует свой DOM, чтобы сделать веб страницы доступными для взаимодествия с языками сценариев.

- -

При создании сценария с использованием элемента <script>, либо включая в веб страницу инструкцию для загрузки скрипта, вы можете немедленно приступить к использованию программного интерфейса (API), используя элементы document или window для взаимодействия с самим документом, либо для получения потомков этого документа, т.е. различных элементов на странице. Ваше программирование DOM может быть чем-то простым, например, вывод сообщения с использованием функции alert() объекта window, или использовать более сложные методы DOM, которые создают новое содержимое, как показанно в следующем примере:

- -
<body onload="window.alert('добро пожаловать на мою домашнюю страницу!');">
-
- -

В следующем примере внутри элемента <script> определен код JavaScript, данный код устанавливает функцию при загрузке документа (когда весь DOM доступен для использования). Эта функция создает новый элемент H1, добавляет текст в данный элемент, а затем добавляет H1 в дерево документа:

- -
<html>
-  <head>
-    <script>
-    // запуск данной функции при загрузке документа
-       window.onload = function() {
-    // создание нескольких элементов
-    // в пустой HTML странице
-       heading = document.createElement("h1");
-       heading_text = document.createTextNode("Big Head!");
-       heading.appendChild(heading_text);
-       document.body.appendChild(heading);
-      }
-    </script>
-  </head>
-  <body>
-  </body>
-</html>
- -

Важные типы данных

- -

Данный раздел предназначен для краткого описания различных типов и объектов в простой и доступной манере. Существует некоторое количество различных типов данных, которые используются в API, на которые вы должны обратить внимание. Для простоты, синтаксис примеров в данном разделе обычно ссылается на узлы как на elements, на массивы узлов как на nodeLists ( либо просто elements ) и на атрибуты узла, просто как на attributes.

- -

Ниже таблица с кратким описанием этих типов данных.

- - - - - - - - - - - - - - - - - - - - - - - - -
documentКогда член возвращает объект типа document (например, свойство элемента ownerDocument возвращает документ к которому он относится), этот обьект document является собственным корневым обьектом. В DOM document Reference разделе описан объект document.
- element   
elementобозначает элемент или узел типа element, возвращаемый членом DOM API. Вместо того, чтобы говорить, что метод document.createElement() возвращает ссылку на node, мы просто скажем, что этот элемент возвращает element, который просто был создан в DOM. Объекты element реализуют DOM element интерфейс и также более общий Node интерфейс. Оба интерфейса включены в эту справку.
- nodeList
NodeList -

массив элементов, как тот, что возвращается методом Document.getElementsByTagName(). Конкретные элементы в массиве доступны по индексу двумя способами:

- -
    -
  •     list.item(1)
  • -
  •     list[1]
  • -
- -

Эти способы эквивалентны. В первом способе item() - единственный метод объекта NodeList. Последний использует обычный синтаксис массивов, чтобы получить второе значение в списке.

-
attributeКогда attribute возвращается членом API (например, метод createAttribute()) - это будет ссылка на объект, который предоставляет специальный (хоть и небольшой) интерфейс для атрибутов. Атрибуты - это узлы в DOM, как и элементы, хотя вы можете редко использовать их в таком виде.
namedNodeMapnamedNodeMap подобна массиву, но элементы доступны по имени или индексу. Доступ по индексу - это лишь для удобства перечисления, т.к. элементы не имеют определенног порядка в списке. Этот тип данных имеет метод item() для этих целей и вы можете также добавлять и удалять элементы из namedNodeMap
- - - -

DOM-интерфейсы (DOM interfaces)

- - - -

Это руководство об объектах и реальных вещах, которые вы можете использовать для управления DOM-иерархией. Есть много моментов, где понимание того, как это работает, может удивлять. Например, объект, представляющий HTML form элемент, берет своё свойство name из интерфейса HTMLFormElement, а свойство className - из интерфейса HTMLElement. В обоих случаях свойство, которое вы хотите, находится в этом объекте формы.

- -

Кроме того, отношение между объектами и интерфейсами, которые они реализуют в DOM может быть удивительным и этот раздел пытается рассказать немного о существующих интерфейсах в DOM и о том, как они могут быть доступны.

- -

Интерфейсы и объекты (Interfaces and objects)

- -

Многие объекты реализуют действия из нескольких интерфейсов. Объект таблицы, например, реализует специальный HTML Table Element Interface, который включает такие методы как createCaption и insertRow. Но так как это таблица - это ещё и HTML-элемент, table реализует интерфейс Element, описанный в разделе DOM element Reference. Наконец, так как HTML-элемент (в смысле DOM) - это узел (node) в дереве, которое составляет объектную модель для HTML- или XML-страницы, табличный элемент также реализует более общий интерфейс Node, из которого происходит Element.

- -

Когда вы получаете ссылку на объект table, как в следующем примере, вы обычно используете все три интерфейса этого объекта, вероятно, даже не зная этого.

- -
var table = document.getElementById("table");
-var tableAttrs = table.attributes; // Node/Element interface
-for (var i = 0; i < tableAttrs.length; i++) {
-  // HTMLTableElement interface: border attribute
-  if(tableAttrs[i].nodeName.toLowerCase() == "border")
-    table.border = "1";
-}
-// HTMLTableElement interface: summary attribute
-table.summary = "note: increased border";
- -

Основные интерфейсы в DOM (Core interfaces in the DOM)

- -

Этот раздел перечисляет несколько самых распространенных интерфейсов в DOM. Идея не в том чтобы описать, что делают эти методы API, но в том чтобы дать вам несколько мыслей насчет видов методов и свойств, которые вы будете часто видеть, используя DOM. Эти распространенные части API использованы в большинстве примеров раздела DOM Examples в конце этой справки.

- -

Document, window - это объекты, чьи интерфейсы вы, как правило, очень часто используете в программировании DOM. Говоря простыми словами, объект window представляет что-то вроде браузера, а объект document - корень самого документа. Element наследуется от общего интерфейса Node, и эти интерфейсы вместе предоставляют много методов и свойств, которые можно применять у отдельных элементов. Эти элементы также могут иметь отдельные интерфейсы для работы с типами данных, которые эти элементы содержат, как в примере с объектом table в предыдущем случае.

- -

Ниже представлен краткий список распространненых членов API, используемых в программировании веб- и XML-страниц с использованием DOM:

- - - -

Тестирование DOM API

- -

Этот документ содержит примеры для каждого интерфейса, который вы можете использовать в своей разработке. В некоторых случаях примеры - полноценные веб-страницы с доступом к DOM в элементе <script>, также перечислены элементы, необходимые чтобы запустить скрипт в форме, и HTML-элементы, над которыми будут производиться операции DOM. Когда встречается такой случай, можно просто копировать и вставить пример в новый HTML-документ, сохранить и запустить его в браузере.

- -

Есть случаи, однако, где примеры более лаконичные. Чтобы запустить примеры, которые лишь демонстрируют основы взаимодействия интерфейсов с HTML-элементами, вы можете подготовить тестовую страницу, в которую будете помещать функции внутрь скриптов. Следующая очень простая веб-страница содержит элемент <script> в заголовке, в который вы можете поместить функции, чтобы протестировать интерфейс. Страница содержит несколько элементов с атрибутами, которые можно возвращать, устанавливать или, другими словами, манипулировать и содержит пользовательский интерфейс, необходимый, чтобы вызывать нужные функции из браузера.

- -

Вы можете использовать эту тестовую страницу или похожую для проверки интерфейсов DOM, которые вас интересуют и просмотра того, как они работают в браузерах. Вы можете обновить содержмое функции test() при необходимости, создать больше кнопок или добавить элементы при необходимости.

- -
<html>
-  <head>
-    <title>DOM Tests</title>
-    <script type="application/javascript">
-    function setBodyAttr(attr, value){
-      if (document.body) eval('document.body.'+attr+'="'+value+'"');
-      else notSupported();
-    }
-    </script>
-  </head>
-  <body>
-    <div style="margin: .5in; height: 400;">
-      <p><b><tt>text</tt></b></p>
-      <form>
-        <select onChange="setBodyAttr('text',
-        this.options[this.selectedIndex].value);">
-          <option value="black">black
-          <option value="darkblue">darkblue
-        </select>
-        <p><b><tt>bgColor</tt></b></p>
-        <select onChange="setBodyAttr('bgColor',
-        this.options[this.selectedIndex].value);">
-          <option value="white">white
-          <option value="lightgrey">gray
-        </select>
-        <p><b><tt>link</tt></b></p>
-        <select onChange="setBodyAttr('link',
-        this.options[this.selectedIndex].value);">
-          <option value="blue">blue
-          <option value="green">green
-        </select>  <small>
-        <a href="http://www.brownhen.com/dom_api_top.html" id="sample">
-        (sample link)</a></small><br>
-      </form>
-      <form>
-        <input type="button" value="version" onclick="ver()" />
-      </form>
-    </div>
-  </body>
-</html>
- -

Чтобы протестировать много интерфейсов на одной странице, набор свойств, которые изменяют цвета веб-страницы, можно создать похожую веб-страницу с целой "консолью" кнопок, текстовых полей и других элементов. Следующий скриншот даёт идею, как интерфейсы могут быть сгруппированы вместе для тестирования

- -

- -

В этом примере выпадающее меню динамически обновляет доступные из DOM части веб-страницы (например, фоновый цвет, цвет ссылок и цвет текста). Однако при разработке тестовых страниц, тестирование интерфейсов, как вы об этом прочитали, важная часть изучения эффективной работы с DOM.

- -

Другие статьи

- - diff --git a/files/ru/dom/index.html b/files/ru/dom/index.html deleted file mode 100644 index 3acab80018..0000000000 --- a/files/ru/dom/index.html +++ /dev/null @@ -1,62 +0,0 @@ ---- -title: DOM -slug: DOM -tags: - - DOM -translation_of: Web/API/Document_Object_Model -translation_of_original: DOM ---- -
-

Объектная модель документа (DOM) — это API для HTML и XML документов. Она предоставляет структуру документа, что позволяет изменять его содержимое и внешний вид. По сути, она связывает веб-страницы со скриптами или языками программирования.

-
- - - - - - - -
-

Документация

-
-
- Справочная информация по Gecko DOM
-
- Объектная модель документа движка Gecko.
-
- Об объектной модели документа
-
- Краткое введение в DOM.
-
- Динамически изменяемый пользовательский интерфейс на XUL
-
- Основы управления XUL UI с помощью методов DOM.
-
- DOM и JavaScript
-
- Что такое DOM? Что такое JavaScript? Как мне использовать их совместно на моей веб-странице? Этот документ отвечает на эти и другие вопросы.
-
- Объектная модель документа Mozilla
-
- Более старая документация по DOM, размещенная на mozilla.org.
-
-

Посмотреть все...

-
-

Сообщество

-
    -
  • Форумы Mozilla... {{ DiscussionList("dev-tech-dom", "mozilla.dev.tech.dom") }}
  • -
-

Инструменты

- -

Посмотреть все...

- - -
-

 

diff --git a/files/ru/dom/using_fullscreen_mode/index.html b/files/ru/dom/using_fullscreen_mode/index.html deleted file mode 100644 index ad21d6d20e..0000000000 --- a/files/ru/dom/using_fullscreen_mode/index.html +++ /dev/null @@ -1,198 +0,0 @@ ---- -title: Fullscreen API -slug: DOM/Using_fullscreen_mode -translation_of: Web/API/Fullscreen_API ---- -
{{DefaultAPISidebar("Fullscreen API")}}
- -

The Fullscreen API adds methods to present a specific {{DOMxRef("Element")}} (and its descendants) in full-screen mode, and to exit full-screen mode once it is no longer needed. This makes it possible to present desired content—such as an online game—using the user's entire screen, removing all browser user interface elements and other applications from the screen until full-screen mode is shut off.

- -

See the article Guide to the Fullscreen API for details on how to use the API.

- -
-

Note: Support for this API varies somewhat across browsers, with many requiring vendor prefixes and/or not implementing the latest specification. See the {{anch("Browser compatibility")}} section below for details on support for this API. You may wish to consider using a library such as Fscreen for vendor agnostic access to the Fullscreen API.

-
- -

Interfaces

- -

The Fullscreen API has no interfaces of its own. Instead, it augments several other interfaces to add the methods, properties, and event handlers needed to provide full-screen functionality. These are listed in the following sections.

- -

Methods

- -

The Fullscreen API adds methods to the {{DOMxRef("Document")}} and {{DOMxRef("Element")}} interfaces to allow turning off and on full-screen mode.

- -

Methods on the Document interface

- -
-
{{DOMxRef("Document.exitFullscreen()")}}
-
Requests that the {{Glossary("user agent")}} switch from full-screen mode back to windowed mode. Returns a {{jsxref("Promise")}} which is resolved once full-screen mode has been completely shut off.
-
- -

Methods on the Element interface

- -
-
{{DOMxRef("Element.requestFullscreen()")}}
-
Asks the user agent to place the specified element (and, by extension, its descendants) into full-screen mode, removing all of the browser's UI elements as well as all other applications from the screen. Returns a {{jsxref("Promise")}} which is resolved once full-screen mode has been activated.
-
- -

Properties

- -

The {{DOMxRef("Document")}} interface provides properties that can be used to determine if full-screen mode is supported and available, and if full-screen mode is currently active, which element is using the screen.

- -
-
{{DOMxRef("DocumentOrShadowRoot.fullscreenElement")}}
-
The fullscreenElement property tells you the {{DOMxRef("Element")}} that's currently being displayed in full-screen mode on the DOM (or shadow DOM). If this is null, the document is not in full-screen mode.
-
{{DOMxRef("Document.fullscreenEnabled")}}
-
The fullscreenEnabled property tells you whether or not it is possible to engage full-screen mode. This is false if full-screen mode is not available for any reason (such as the "fullscreen" feature not being allowed, or full-screen mode not being supported).
-
- -

Event handlers

- -

The Fullscreen API defines two events which can be used to detect when full-screen mode is turned on and off, as well as when errors occur during the process of changing between full-screen and windowed modes. Event handlers for these events are available on the {{DOMxRef("Document")}} and {{DOMxRef("Element")}} interfaces.

- -
-

Note: These event handler properties are not available as HTML content attributes. In other words, you cannot specify event handlers for {{Event("fullscreenchange")}} and {{Event("fullscreenerror")}} in the HTML content. They must be added by JavaScript code.

-
- -

Event handlers on documents

- -
-
{{DOMxRef("Document.onfullscreenchange")}}
-
An event handler for the {{Event("fullscreenchange")}} event that's sent to a {{DOMxRef("Document")}} when that document is placed into full-screen mode, or when that document exits full-screen mode. This handler is called only when the entire document is presented in full-screen mode.
-
{{DOMxRef("Document.onfullscreenerror")}}
-
An event handler for the {{Event("fullscreenerror")}} event that gets sent to a {{DOMxRef("Document")}} when an error occurs while trying to enable or disable full-screen mode for the entire document.
-
- -

Event handlers on elements

- -
-
{{DOMxRef("Element.onfullscreenchange")}}
-
An event handler which is called when the {{Event("fullscreenchange")}} event is sent to the element, indicating that the element has been placed into, or removed from, full-screen mode.
-
{{DOMxRef("Element.onfullscreenerror")}}
-
An event handler for the {{Event("fullscreenerror")}} event when sent to an element which has encountered an error while transitioning into or out of full-screen mode.
-
- -

Obsolete properties

- -
-
{{DOMxRef("Document.fullscreen")}} {{Deprecated_Inline}}
-
A Boolean value which is true if the document has an element currently being displayed in full-screen mode; otherwise, this returns false. -
Note: Use the {{DOMxRef("Document.fullscreenElement", "fullscreenElement")}} property on the {{DOMxRef("Document")}} or {{DOMxRef("ShadowRoot")}} instead; if it's not null, then it's an {{DOMxRef("Element")}} currently being displayed in full-screen mode.
-
-
- -

Events

- -

The Fullscreen API defines two events which can be used to detect when full-screen mode is turned on and off, as well as when errors occur during the process of changing between full-screen and windowed modes.

- -
-
{{Event("fullscreenchange")}}
-
Sent to a {{DOMxRef("Document")}} or {{DOMxRef("Element")}} when it transitions into or out of full-screen mode.
-
{{Event("fullscreenerror")}}
-
Sent to a Document or Element if an error occurs while attempting to switch it into or out of full-screen mode.
-
- -

Dictionaries

- -
-
{{DOMxRef("FullscreenOptions")}}
-
Provides optional settings you can specify when calling {{DOMxRef("Element.requestFullscreen", "requestFullscreen()")}}.
-
- -

Controlling access

- -

The availability of full-screen mode can be controlled using Feature Policy. The full-screen mode feature is identified by the string "fullscreen", with a default allow-list value of "self", meaning that full-screen mode is permitted in top-level document contexts, as well as to nested browsing contexts loaded from the same origin as the top-most document.

- -

See Using Feature Policy to learn more about using Feature Policy to control access to an API.

- -

Usage notes

- -

Users can choose to exit full-screen mode simply by pressing the ESC (or F11) key, rather than waiting for the site or app to programmatically do so. Make sure you provide, somewhere in your user interface, appropriate user interface elements that inform the user that this option is available to them.

- -
-

Note: Navigating to another page, changing tabs, or switching to another application using any application switcher (or Alt-Tab) will likewise exit full-screen mode.

-
- -

Example

- -

In this example, a video is presented in a web page. Pressing the Return or Enter key lets the user toggle between windowed and full-screen presentation of the video.

- -

View Live Examples

- -

Watching for the Enter key

- -

When the page is loaded, this code is run to set up an event listener to watch for the Enter key.

- -
document.addEventListener("keypress", function(e) {
-  if (e.keyCode === 13) {
-    toggleFullScreen();
-  }
-}, false);
-
- -

Toggling full-screen mode

- -

This code is called by the event handler above when the user hits the Enter key.

- -
function toggleFullScreen() {
-  if (!document.fullscreenElement) {
-      document.documentElement.requestFullscreen();
-  } else {
-    if (document.exitFullscreen) {
-      document.exitFullscreen();
-    }
-  }
-}
- -

This starts by looking at the value of the {{DOMxRef("Document", "document")}}'s fullscreenElement attribute. In a real-world deployment, at this time, you'll want to check for prefixed versions of this (mozFullScreenElement, msFullscreenElement, or webkitFullscreenElement, for example). If the value is null, the document is currently in windowed mode, so we need to switch to full-screen mode; otherwise, it's the element that's currently in full-screen mode. Switching to full-screen mode is done by calling {{DOMxRef("Element.requestFullscreen()")}} on the {{HTMLElement("video")}} element.

- -

If full-screen mode is already active (fullscreenElement is not null), we call {{DOMxRef("Document.exitFullscreen", "exitFullscreen()")}} on the document to shut off full-screen mode.

- -

Specifications

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName("Fullscreen")}}{{Spec2("Fullscreen")}}Initial version.
- -

Browser compatibility

- -

Document.fullscreen

- -
- - -

{{Compat("api.Document.fullscreen")}}

-
- -

Document.fullscreenEnabled

- -
- - -

{{Compat("api.Document.fullscreenEnabled")}}

-
- -

See also

- - diff --git a/files/ru/dom/using_web_workers/index.html b/files/ru/dom/using_web_workers/index.html deleted file mode 100644 index 7503eccacb..0000000000 --- a/files/ru/dom/using_web_workers/index.html +++ /dev/null @@ -1,871 +0,0 @@ ---- -title: Использование Web Workers -slug: DOM/Using_web_workers -tags: - - воркер - - поток -translation_of: Web/API/Web_Workers_API/Using_web_workers ---- -
{{DefaultAPISidebar("Web Workers API")}}
- -

Web Worker-ы предоставляют простое средство для запуска скриптов в фоновом потоке. Поток Worker'а может выполнять задачи без вмешательства в пользовательский интерфейс. К тому же, они могут осуществлять ввод/вывод, используя XMLHttpRequest (хотя атрибуты responseXML и channel всегда будут равны null). Существующий Worker может отсылать сообщения JavaScript коду-создателю через обработчик событий, указанный этим кодом (и наоборот). Эта статья дает детальную инструкцию по использованию Web Workers.

- -

Web Workers API

- -

Worker - это объект, создаваемый конструктором (например, {{domxref("Worker.Worker", "Worker()")}}) и запускающий именной JavaScript файл — этот файл содержит код, который будет выполнен в потоке Worker'а; объекты же Workers запускаются в другом глобальном контексте, отличающемся от текущего, - {{domxref("window")}}. Поэтому использование переменной {{domxref("window")}} для получения текущего глобального контекста (вместо {{domxref("window.self","self")}}) внутри {{domxref("Worker")}} вернет ошибку.

- -

Контекст Worker'а представлен объектом {{domxref("DedicatedWorkerGlobalScope")}} в случае выделенных Workers (обычные Workers используются одним скриптом; совместные Workers используют объект {{domxref("SharedWorkerGlobalScope")}}). Выделенный Worker доступен только из скрипта-родителя, в то время как совместные Workers могут быть доступны из нескольких сценариев.

- -
-

Заметка: Смотрите страницу Web Workers API для справки по Workers и прочие руководства.

-
- -

Вы можете запускать любой код внутри потока worker-а, за некоторыми исключениями. Например, вы не можете прямо манипулировать DOM внутри worker-а, или использовать некоторые методы по умолчанию и свойства объекта {{domxref("window")}}. Но вы можете использовать большой набор опций, доступный под Window, включая WebSockets, и механизмы хранения данных, таких как IndexedDB и относящихся только к Firefox OS Data Store API. Для дополнительной информации смотрите Functions and classes available to workers.

- -

Данные передаются между worker-ами и главным потоком через систему сообщений — обе стороны передают свои сообщения, используя метод postMessage() и отвечают на сообщения при помощи обработчика событий onmessage (сообщение хранится в аттрибуте data события {{event("Message")}}). Данные при этом копируются, а не делятся.

- -

Объекты Workers могут, в свою очередь, создавать новые объекты workers, и так до тех пор, пока всё работает в рамках текущей страницы. Плюс к этому, объекты workers могут использовать XMLHttpRequest для сетевого ввода/вывода, но есть исключение - атрибуты responseXML и channel объекта XMLHttpRequest всегда возвращают null.

- -

Выделенные Workers

- -

Как уже упоминалось выше, выделенный Worker доступен только для скрипта, который его вызвал. В этом разделе речь пойдет о JavaScript, который можно найти в нашем основном примере выделенного Worker (запустить скрипт): этот пример позволяет ввести два числа для умножения. Эти числа отправляются в Worker, перемножаются, а результат возвращается на страницу и отображается.

- -

Этот пример достаточно тривиален, но для ознакомления с базовыми концепциями worker-ов мы решили его упростить. Более продвинутые детали описаны далее в статье.

- -

Определение поддержки Worker

- -

Для большего контроля над ошибками и обратной совместимости, рекомендуется обернуть ваш код доступа к worker-у в следующий (main.js):

- -
if (window.Worker) {
-
-  ...
-
-}
- -

Создание выделенного worker

- -

Создание нового worker-а — это легко. Всё что вам нужно это вызвать конструктор {{domxref("Worker.Worker", "Worker()")}}, указав URI скрипта для выполнения в потоке worker-а (main.js):

- -
-
var myWorker = new Worker("worker.js");
-
-
- -

Передача сообщений в и из выделенного worker

- -

Магия worker-ов происходит через {{domxref("Worker.postMessage", "postMessage()")}} метод и обработчик событий {{domxref("Worker.onmessage", "onmessage")}}. Когда вы хотите отправить сообщение в worker, вы доставляете сообщение к нему вот так (main.js):

- -
first.onchange = function() {
-  myWorker.postMessage([first.value,second.value]);
-  console.log('Message posted to worker');
-}
-
-second.onchange = function() {
-  myWorker.postMessage([first.value,second.value]);
-  console.log('Message posted to worker');
-}
- -

В приведенном фрагменте кода мы имеем два {{htmlelement("input")}} элемента, представленных переменными first и second; когда значение любой из переменных изменяется, myWorker.postMessage([first.value,second.value]) используется для отправки обоих значений, представленных в виде массива, в worker. Посредством аргумента message возможна передача практически любых данных в worker.

- -

Внутри worker-a мы можем обрабатывать сообщения и отвечать на них при помощи добавления обработчика события onmessage подобным образом (worker.js):

- -
onmessage = function(e) {
-  console.log('Message received from main script');
-  var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
-  console.log('Posting message back to main script');
-  postMessage(workerResult);
-}
- -

Обработчик onmessage позволяет нам запустить некий код всякий раз, когда получен пакет с сообщением, доступным в атрибуте data события message. В примере выше мы просто перемножаем вместе две цифры, после чего используем postMessage() снова, чтобы отправить полученный результат назад в основной поток.

- -

Возвращаясь в основной поток, мы используем onmessage снова, чтобы отреагировать на сообщение, отправленное нам назад из worker-а:

- -
myWorker.onmessage = function(e) {
-  result.textContent = e.data;
-  console.log('Message received from worker');
-}
- -

В примере выше мы берём данные из события сообщения и ставим их как textContent у результирующего абзаца, чтобы показать пользователю результат этой калькуляции.

- -

Заметка: Обратите внимание, что onmessage()​ и postmessage() должны вызываться из экземпляра Worker в главном потоке, но не в потоке worker-а. Это связано с тем, что внутри потока worker-а, worker выступает в качестве глобального объекта.

- -

Заметка: При передаче сообщения между основным потоком и потоком worker-а, оно копируется или "передается" (перемещается), не делится между потоками. Читайте {{anch("Transferring data to and from workers: further details")}} для более подробного объяснения.

- -

Завершение работы worker-а

- -

Прекращение работы worker-а главного потока достигается методом {{domxref("Worker", "terminate")}}:

- -
myWorker.terminate();
- -

Поток worker-а немедленно уничтожается.

- -

Обработка ошибок

- -

При ошибке во время выполнения worker-а, вызывается его обработчик событий onerror. Он принимает событие error, которое реализует интерфейс ErrorEvent.

- -

Событие не всплывает и его можно отменить. Для отмены действия по умолчанию, worker может вызвать метод preventDefault() в обработчике события ошибки.

- -

У события ошибки есть три поля, которые представляют интерес:

- -
-
message
-
Сообщение об ошибке в читаемом виде.
-
filename
-
Имя файла со скриптом, в котором ошибка произошла.
-
lineno
-
Номер строки в файле, в котором произошла ошибка.
-
- -

Создание subworkers

- -

Worker-ы могут запускать другие worker-ы. Так называемые sub-worker'ы должны быть того же происхождения (same-origin), что и родительский документ. Кроме того, URI для subworker-ов рассчитываются относительно родительского worker'а, а не родительского документа. Это позволяет worker-ам проще следить за тем, где находятся их зависимости.

- -

Импорт скриптов и библиотек

- -

Worker потоки имеют доступ к глобальной функции, importScripts(), которая позволяет импортировать скрипты с того же домена в их область видимости. Функция принимает ноль и более URI параметров, как список ссылок на ресурсы для импорта; все нижеприведенные примеры верны:

- -
importScripts();                        /* imports nothing */
-importScripts('foo.js');                /* imports just "foo.js" */
-importScripts('foo.js', 'bar.js');      /* imports two scripts */
-
- -

Браузер загружает каждый указанный скрипт и исполняет его. Любые глобальные объекты, создаваемые каждым скриптом могут быть использованы в worker'е. Если скрипт не удалось загрузить, будет брошена ошибка NETWORK_ERROR, и последующий код не будет исполнен. Тем не менее код, исполненный ранее (включая отложенный при помощи {{domxref("window.setTimeout()")}}) останется функционален. Объявления функций идущие после вызова метода importScripts() также будут доступны, т.к. объявления функций всегда обрабатываются перед остальным кодом.

- -
Заметка: Скрипты могут быть загружены в произвольном порядке, но их исполнение будет в  том порядке, в котором имена файлов были переданы в importScripts(). Функция выполняется синхронно; importScripts() не вернет исполнение, пока все скрипты не будут загружены и исполнены.
- -

Разделяемые worker-ы (Shared workers)

- -

Разделяемый worker доступен нескольким разным скриптам — даже если они находятся в разных окнах, фреймах или даже worker-ах. В этом разделе мы обсудим JavaScript, который можно найти в нашем базовом примере разделяемых worker-ов (запустить разделяемый worker): Он очень похож на базовый пример выделенных worker-ов, за исключением двух функций, которые доступны из разных скриптовых файлов: умножение двух чисел или возведение числа в степень. Оба скрипта используют один и тот же worker для необходимых вычислений.

- -

Здесь мы сосредоточимся на разнице между выделенными и раздялемыми worker-ами. Обратите внимание, что в данном примере есть две HTML страницы с JavaScript кодом, которые используют один и тот же файл worker-а.

- -
-

Заметка: Если разделяемый worker может быть доступен из нескольких контекстов просмотра, то все они должны иметь одно и то же происхождение (одни и те же протокол, хост и порт).

-
- -
-

Заметка: В Firefox разделяемый worker не может быть использован совместно документами в приватном и неприватном окне ({{bug(1177621)}}).

-
- -

Создание разделяемого worker-а

- -

Запуск разделяемого worker-а очень похож на запуск выделенного worker-а, но используется другой конструктор (см. index.html и index2.html) — в каждом документе необходимо поднять worker, для этого следует написать такой код:

- -
var myWorker = new SharedWorker("worker.js");
- -

Большая разница заключается в том, что с разделяемым worker-ом необходимо взаимодействовать через объект port — явно открыв порт, с помощью которого скрипты могут взаимодействовать с worker-ом (в случае выделенного worker-а это происходит неявно).

- -

Соединение с портом должно быть осуществлено либо неявно, используя обработчик событие onmessage, либо явно, вызвав метод start() перед тем, как отправлять любые сообщения. Вызов метода start() необходим только тогда, когда подписка на событие реализована через метод addEventListener().

- -
-

Заметка: Когда используется метод start() чтобы открыть соединение с портом, его необходимо вызывать и в родительском потоке и в потоке worker-а, если необходима двухсторонняя коммуникация.

-
- -
myWorker.port.start();  // в родительском потоке
- -
port.start();  // в потоке worker-а, где переменная port является ссылкой на порт
- -

Передача сообщений в/из разделяемого worker-а

- -

Теперь сообщения могут быть отправлены worker-у, как и прежде, но метод postMessage() должен вызываться из объекта port (еще раз, вы можете увидеть схожие кострукции в multiply.js и square.js):

- -
squareNumber.onchange = function() {
-  myWorker.port.postMessage([squareNumber.value,squareNumber.value]);
-  console.log('Message posted to worker');
-}
- -

Теперь на стороне worker-а. Здесь код немного сложнее (worker.js):

- -
self.addEventListener('connect', function(e) { // требуется addEventListener()
-  var port = e.ports[0];
-  port.onmessage = function(e) {
-    var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
-    port.postMessage(workerResult);
-  }
-  port.start();  // вызов необязательный, т.к. используется обработчик событий onmessage
-});
- -

Первый этап состоит из события onconnect. Оно срабатывает, когда произошло подключение (т.е. когда в родительском потоке отработало событие onmessage или когда в нем был вызван метод start()).

- -

Мы используем атрибут события ports, чтобы получить порт и сохранить его в переменной.

- -

Второй этап — это обработчик события message на сохраненном порту. Он нужен для подсчета и вывода результата вычисления в основной поток. Установка обработчика message в потоке worker-а также открывает подключение к родительскому потоку, поэтому вызов на port.start() на самом деле не нужен (см. код обработчика onconnect).

- -

Последний этап — возвращение в основной поток и обработка сообщения от worker‑а (еще раз, вы можете увидеть схожие конструкции в multiply.js и square.js):

- -
myWorker.port.onmessage = function(e) {
-  result2.textContent = e.data[0];
-  console.log('Message received from worker');
-}
- -

Когда сообщение приходит через порт от worker-а, мы проверяем тип результата вычислений и затем вставляем его в соответствующий абзац.

- -

О потоковой безопасности

- -

Интерфейс {{domxref("Worker")}} создаёт настоящие потоки на уровне операционной системы, что может смутить опытных программистов и навести их на мысли о проблемах, связанных с конфликтом доступа к общим объектам.

- -

На самом деле создать такие проблемы достаточно сложно, так как worker-ы жёстко контролируются. У них нет доступа к непотокобезопасным объектам DOM, а все данные между потоками передаются в качестве сериализованных объектов. Придётся очень постараться, чтобы вызывать проблемы потокобезопасности в вашем коде.

- -

Передача данных в и из worker-ов: другие детали

- -

Передача данных между главной страницей и worker-ом происходит путем копирования, а не передачи по ссылке. Объекты сериализуются при передаче и затем десериализуются на другом конце. Страница и worker не используют совместно одни и те же экземпляры, для каждого создается свой. Большинство браузеров реализуют это структурированным клонированием (structured cloning).

- -

Для иллюстрации этого мы создадим функцию emulateMessage(), которая будет имитировать поведение значения, которое клонируется, но не используется совместно при переходе от worker-а к главной странице или наоборот.

- -
function emulateMessage (vVal) {
-    return eval("(" + JSON.stringify(vVal) + ")");
-}
-
-// Tests
-
-// test #1
-var example1 = new Number(3);
-console.log(typeof example1); // object
-console.log(typeof emulateMessage(example1)); // number
-
-// test #2
-var example2 = true;
-console.log(typeof example2); // boolean
-console.log(typeof emulateMessage(example2)); // boolean
-
-// test #3
-var example3 = new String("Hello World");
-console.log(typeof example3); // object
-console.log(typeof emulateMessage(example3)); // string
-
-// test #4
-var example4 = {
-    "name": "John Smith",
-    "age": 43
-};
-console.log(typeof example4); // object
-console.log(typeof emulateMessage(example4)); // object
-
-// test #5
-function Animal (sType, nAge) {
-    this.type = sType;
-    this.age = nAge;
-}
-var example5 = new Animal("Cat", 3);
-alert(example5.constructor); // Animal
-alert(emulateMessage(example5).constructor); // Object
- -

Значения, которые клонируются и совместно не используются, называются сообщениями. Как вы, возможно, знаете, сообщения могут быть отправлены в главную страницу и из нее, используя postMessage(), и {{domxref("MessageEvent.data", "data")}}, содержа данные, передаваемые из worker-а.

- -

example.html: (главная страница):

- -
var myWorker = new Worker("my_task.js");
-
-myWorker.onmessage = function (oEvent) {
-  console.log("Worker said : " + oEvent.data);
-};
-
-myWorker.postMessage("ali");
- -

my_task.js (worker):

- -
postMessage("I\'m working before postMessage(\'ali\').");
-
-onmessage = function (oEvent) {
-  postMessage("Hi " + oEvent.data);
-};
- -

Алгоритм структурированного клонирования может принять JSON и некоторые вещи, которые JSON не может принять, например, циклические ссылки.

- -

Примеры передачи данных

- -

Пример #1: Расширенная передача JSON данных и создание системы коммутации

- -

Если вам нужно передать сложные данные и вызвать множество различных функций как на главной странице, так и в worker-е, вы можете создать следующую систему.

- -

В первую очередь мы создаем класс QueryableWorker, который принимает url worker-а, стандартный обработчик событий (defaultListener) и обработчик ошибок. Этот класс будет отслеживать всех обработчиков и поможет нам общаться с воркером.

- -
function QueryableWorker(url, defaultListener, onError) {
-    var instance = this,
-        worker = new Worker(url),
-        listeners = {};
-
-    this.defaultListener = defaultListener || function() {};
-
-    if (onError) {worker.onerror = onError;}
-
-    this.postMessage = function(message) {
-        worker.postMessage(message);
-    }
-
-    this.terminate = function() {
-        worker.terminate();
-    }
-}
-
- -

Затем мы добавляем методы добавления/удаления обработчиков.

- -
this.addListeners = function(name, listener) {
-    listeners[name] = listener;
-}
-
-this.removeListeners = function(name) {
-    delete listeners[name];
-}
-
- -

Здесь мы создадим у worker-а два простых события для примера: получение разницы двух чисел и создание оповещения через три секунды. Но сначала нам нужно реализовать метод sendQuery, который проверит есть ли вообще у worker-а обработчик, который мы собираемся вызвать.

- -
/*
-  Эта функция принимает по крайней мере один аргумент: имя метода, который мы хотим вызвать.
-  Далее мы можем передать методу необходимые ему аргументы.
- */
-this.sendQuery = function() {
-    if (arguments.length < 1) {
-         throw new TypeError('QueryableWorker.sendQuery takes at least one argument');
-         return;
-    }
-    worker.postMessage({
-        'queryMethod': arguments[0],
-        'queryArguments': Array.prototype.slice.call(arguments, 1)
-    });
-}
-
- -

Завершим QueryableWorker методом onmessage.  Если worker имеет соответствующий метод, который мы запросили, он также должен вернуть соответствующий обработчик и аргументы, которые нам нужны. Останется лишь найти его в listeners:

- -
worker.onmessage = function(event) {
-    if (event.data instanceof Object &&
-        event.data.hasOwnProperty('queryMethodListener') &&
-        event.data.hasOwnProperty('queryMethodArguments')) {
-        listeners[event.data.queryMethodListener].apply(instance, event.data.queryMethodArguments);
-    } else {
-        this.defaultListener.call(instance, event.data);
-    }
-}
-
- -

Теперь к самому worker-у. Сначала следует определить эти два простых метода:

- -
var queryableFunctions = {
-    getDifference: function(a, b) {
-        reply('printStuff', a - b);
-    },
-    waitSomeTime: function() {
-        setTimeout(function() {
-            reply('doAlert', 3, 'seconds');
-        }, 3000);
-    }
-}
-
-function reply() {
-    if (arguments.length < 1) {
-        throw new TypeError('reply - takes at least one argument');
-        return;
-    }
-    postMessage({
-        queryMethodListener: arguments[0],
-        queryMethodArguments: Array.prototype.slice.call(arguments, 1)
-    });
-}
-
-/* This method is called when main page calls QueryWorker's postMessage method directly*/
-function defaultReply(message) {
-    // do something
-}
-
- -

И onmessage:

- -
onmessage = function(event) {
-    if (event.data instanceof Object &&
-        event.data.hasOwnProperty('queryMethod') &&
-        event.data.hasOwnProperty('queryMethodArguments')) {
-        queryableFunctions[event.data.queryMethod]
-            .apply(self, event.data.queryMethodArguments);
-    } else {
-        defaultReply(event.data);
-    }
-}
- -

Полный код примера:

- -

example.html (основная страница):

- -
<!doctype html>
-  <html>
-    <head>
-      <meta charset="UTF-8"  />
-      <title>MDN Example - Queryable worker</title>
-    <script type="text/javascript">
-    /*
-      QueryableWorker instances methods:
-        * sendQuery(queryable function name, argument to pass 1, argument to pass 2, etc. etc): calls a Worker's queryable function
-        * postMessage(string or JSON Data): see Worker.prototype.postMessage()
-        * terminate(): terminates the Worker
-        * addListener(name, function): adds a listener
-        * removeListener(name): removes a listener
-      QueryableWorker instances properties:
-        * defaultListener: the default listener executed only when the Worker calls the postMessage() function directly
-     */
-    function QueryableWorker(url, defaultListener, onError) {
-      var instance = this,
-      worker = new Worker(url),
-      listeners = {};
-
-      this.defaultListener = defaultListener || function() {};
-
-      if (onError) {worker.onerror = onError;}
-
-      this.postMessage = function(message) {
-        worker.postMessage(message);
-      }
-
-      this.terminate = function() {
-        worker.terminate();
-      }
-
-      this.addListener = function(name, listener) {
-        listeners[name] = listener;
-      }
-
-      this.removeListener = function(name) {
-        delete listeners[name];
-      }
-
-      /*
-        This functions takes at least one argument, the method name we want to query.
-        Then we can pass in the arguments that the method needs.
-      */
-      this.sendQuery = function() {
-        if (arguments.length < 1) {
-          throw new TypeError('QueryableWorker.sendQuery takes at least one argument');
-          return;
-        }
-        worker.postMessage({
-          'queryMethod': arguments[0],
-          'queryMethodArguments': Array.prototype.slice.call(arguments, 1)
-        });
-      }
-
-      worker.onmessage = function(event) {
-        if (event.data instanceof Object &&
-          event.data.hasOwnProperty('queryMethodListener') &&
-          event.data.hasOwnProperty('queryMethodArguments')) {
-          listeners[event.data.queryMethodListener].apply(instance, event.data.queryMethodArguments);
-        } else {
-          this.defaultListener.call(instance, event.data);
-        }
-      }
-    }
-
-    // your custom "queryable" worker
-    var myTask = new QueryableWorker('my_task.js');
-
-    // your custom "listeners"
-    myTask.addListener('printStuff', function (result) {
-      document.getElementById('firstLink').parentNode.appendChild(document.createTextNode('The difference is ' + result + '!'));
-    });
-
-    myTask.addListener('doAlert', function (time, unit) {
-      alert('Worker waited for ' + time + ' ' + unit + ' :-)');
-    });
-</script>
-</head>
-<body>
-  <ul>
-    <li><a id="firstLink" href="javascript:myTask.sendQuery('getDifference', 5, 3);">What is the difference between 5 and 3?</a></li>
-    <li><a href="javascript:myTask.sendQuery('waitSomeTime');">Wait 3 seconds</a></li>
-    <li><a href="javascript:myTask.terminate();">terminate() the Worker</a></li>
-  </ul>
-</body>
-</html>
- -

my_task.js (код worker-а):

- -
var queryableFunctions = {
-  // пример #1: получить разницу между двумя числами
-  getDifference: function(nMinuend, nSubtrahend) {
-      reply('printStuff', nMinuend - nSubtrahend);
-  },
-  // пример #2: подождать три секунды
-  waitSomeTime: function() {
-      setTimeout(function() { reply('doAlert', 3, 'seconds'); }, 3000);
-  }
-};
-
-// системные функции
-
-function defaultReply(message) {
-  // your default PUBLIC function executed only when main page calls the queryableWorker.postMessage() method directly
-  // do something
-}
-
-function reply() {
-  if (arguments.length < 1) { throw new TypeError('reply - not enough arguments'); return; }
-  postMessage({ 'queryMethodListener': arguments[0], 'queryMethodArguments': Array.prototype.slice.call(arguments, 1) });
-}
-
-onmessage = function(oEvent) {
-  if (oEvent.data instanceof Object && oEvent.data.hasOwnProperty('queryMethod') && oEvent.data.hasOwnProperty('queryMethodArguments')) {
-    queryableFunctions[oEvent.data.queryMethod].apply(self, oEvent.data.queryMethodArguments);
-  } else {
-    defaultReply(oEvent.data);
-  }
-};
-
- -

Можно переключать содержимое каждой главной страницы -> worker и worker -> сообщение главной страницы. И имена свойств "queryMethod", "queryMethodListeners", "queryMethodArguments" могут быть любыми пока они согласуются с QueryableWorker и worker.

- -

Передача данных с помощью передачи владения (передаваемые объекты)

- -

Google Chrome 17+ and Firefox 18+ имеют дополнительную возможность передачи определенных типов объектов (передаваемые объекты реализующие {{domxref("Transferable")}} интерфейс) к или из worker-а с высокой призводительностью. Эти объекты передаются из одного контекста в другой без операций копирования, что приводит к значительному повышению производительности при отправке больших наборов данных. Думайте об этом как о передаче по ссылке в мире C/C++. Однако в отличии от передачи по ссылке, "версия" из вызывающего контекста больше недоступна после передачи. Владельцем становится новый контекст.  Для примера, после передачи {{domxref("ArrayBuffer")}} из главной страницы к worker-у,  исходный {{domxref("ArrayBuffer")}} очищается и более недоступен для использования.  Его содержание (в буквальном смысле) переносится в рабочий контекст.

- -
// Create a 32MB "file" and fill it.
-var uInt8Array = new Uint8Array(1024*1024*32); // 32MB
-for (var i = 0; i < uInt8Array.length; ++i) {
-  uInt8Array[i] = i;
-}
-
-worker.postMessage(uInt8Array.buffer, [uInt8Array.buffer]);
-
- -
-

Заметка: Для дополнительной информации о передаваемых объектах, производительности и поддержки для этого метода, читайте  Transferable Objects: Lightning Fast! на HTML5 Rocks.

-
- -

Встроенные worker-ы

- -

Не существует утвержденного способа встроить код worker-а в рамках веб-страницы, как элемент {{HTMLElement("script")}} делает для обычных скриптов. Но элемент {{HTMLElement("script")}}, который не имеет аттрибута src и аттрибута  type, которому не назначен выполняемый MIME type, можно считать блоком данных для использования JavaScript. Блок данных "Data blocks" — это более общее свойство HTML5, может содержать любые текстовые данные. Так, worker может быть встроен следующим образом:

- -
<!DOCTYPE html>
-<html>
-<head>
-<meta charset="UTF-8" />
-<title>MDN Example - Embedded worker</title>
-<script type="text/js-worker">
-  // Этот script НЕ БУДЕТ анализироваться JS движками, потому что  его MIME-тип text/js-worker.
-  var myVar = 'Hello World!';
-  // Остальная часть кода вашего воркера идет сюда.
-</script>
-<script type="text/javascript">
-  // Этот script БУДЕТ проанализирован JS движкам, потому что его MIME-тип text/javascript.
-  function pageLog(sMsg) {
-    // Use a fragment: browser will only render/reflow once.
-    var oFragm = document.createDocumentFragment();
-    oFragm.appendChild(document.createTextNode(sMsg));
-    oFragm.appendChild(document.createElement('br'));
-    document.querySelector('#logDisplay').appendChild(oFragm);
-  }
-</script>
-<script type="text/js-worker">
-  // Этот script НЕ БУДЕТ анализироваться JS движками, потому что его MIME-тип text/js-worker.
-  onmessage = function(oEvent) {
-    postMessage(myVar);
-  };
-  // Остальная часть кода вашего воркера идет сюда.
-</script>
-<script type="text/javascript">
-  // Этот script БУДЕТ проанализирован JS движкам, потому что его MIME-тип text/javascript.
-
-  // В прошлом...:
-  // blob builder существовал
-  // ... но теперь мы используем Blob...:
-  var blob = new Blob(Array.prototype.map.call(document.querySelectorAll('script[type=\'text\/js-worker\']'), function (oScript) { return oScript.textContent; }),{type: 'text/javascript'});
-
-  // Создание нового свойства document.worker, содержащего все наши "text/js-worker" скрипты.
-  document.worker = new Worker(window.URL.createObjectURL(blob));
-
-  document.worker.onmessage = function(oEvent) {
-    pageLog('Received: ' + oEvent.data);
-  };
-
-  // Запуск воркера.
-  window.onload = function() { document.worker.postMessage(''); };
-</script>
-</head>
-<body><div id="logDisplay"></div></body>
-</html>
-
- -
Встраиваемый worker теперь внесен в новое custom свойство document.worker
- -
- -
Также стоит отметить, что вы также можете преобразовать функцию в BLOB-объект, а затем сгенерировать URL объекта из этого BLOB-объекта. Например:
- -
function fn2workerURL(fn) {
-  var blob = new Blob(['('+fn.toString()+')()'], {type: 'application/javascript'})
-  return URL.createObjectURL(blob)
-}
-
- -

Другие примеры

- -

В этой секции представлено еще несколько примеров как использовать worker-ы.

- -

Выполнение вычислений в фоне

- -

Worker-ы в основном полезны для того, чтобы позволить вашему коду выполнять ресурсоемкие вычисления, не блокируя поток пользовательского интерфейса. В этом примере, worker используется для вычисления числа Фибоначчи.

- -

Код JavaScript

- -

Следующий код JavaScript хранится в файле "fibonacci.js", на который ссылается HTML в следующем разделе.

- -
var results = [];
-
-function resultReceiver(event) {
-  results.push(parseInt(event.data));
-  if (results.length == 2) {
-    postMessage(results[0] + results[1]);
-  }
-}
-
-function errorReceiver(event) {
-  throw event.data;
-}
-
-onmessage = function(event) {
-  var n = parseInt(event.data);
-
-  if (n == 0 || n == 1) {
-    postMessage(n);
-    return;
-  }
-
-  for (var i = 1; i <= 2; i++) {
-    var worker = new Worker("fibonacci.js");
-    worker.onmessage = resultReceiver;
-    worker.onerror = errorReceiver;
-    worker.postMessage(n - i);
-  }
- };
- -

Worker устанавливает свойство onmessage для функции,  которая будет получать сообщения, отправленные при вызове postMessage() рабочего объекта (обратите внимание, что это отличается от определения глобальной переменной с таким именем или определения функции с таким именем. var onmessage и function onmessage будет определять глобальные свойства с этими именами , но они не будут регистрировать функцию для получения сообщений, отправленных веб-страницей, которая создала worker). Это запускает рекурсию, порождая новые копии для обработки каждой итерации вычисления.

- -

HTML код

- -
<!DOCTYPE html>
-<html>
-  <head>
-    <meta charset="UTF-8"  />
-    <title>Test threads fibonacci</title>
-  </head>
-  <body>
-
-  <div id="result"></div>
-
-  <script language="javascript">
-
-    var worker = new Worker('fibonacci.js');
-
-    worker.onmessage = function(event) {
-      document.getElementById('result').textContent = event.data;
-      dump('Got: ' + event.data + '\n');
-    };
-
-    worker.onerror = function(error) {
-      dump('Worker error: ' + error.message + '\n');
-      throw error;
-    };
-
-    worker.postMessage('5');
-
-  </script>
-  </body>
-</html>
- -

Веб-страница создает элемент div с ID result , который используется для отображения результата, а затем порождает worker. После порождения worker-а, обработчик onmessage настроен для отображения результатов путем установки содержимого элемента div, и обработчик onerror настроен на выброс сообщения об ошибке.

- -

Наконец, сообщение отправляется worker-у, чтобы запустить его.

- -

Попробуйте этот пример.

- -

Выполнение веб I/O в фоне

- -

Вы можете найти пример этого в статье Использование worker-ов в расширениях.

- -

Разделение задач между множественными worker-ами

- -

Поскольку многоядерные компьютеры становятся все более распространенными, часто бывает полезно разделить вычислительно сложные задачи между несколькими worker-ами, которые затем могут выполнить эти задачи на многопроцессорных ядрах.

- -

Другие типы worker-ов

- -

В дополнение к выделенным и совместно используемым web worker-ам доступны другие типы worker-ов:

- - - -

Функции и интерфейсы доступные в worker-ах

- -

Внутри web worker-а вы можете использовать большинство стандартных функций JavaScript, включая:

- - - -

Главное, что вы не можете сделать в Worker это напрямую повлиять на родительскую страницу. Это включает в себя манипулирование DOM и использование объектов этой страницы. Вы должны сделать это косвенно, отправив сообщение обратно основному сценарию через {{domxref("DedicatedWorkerGlobalScope.postMessage")}}, а затем выполнив изменения оттуда.

- -
-

Заметка: Для знакомства с  полным списком функций,  доступных для worker-ов, смотрите статью Функции и интерфейсы доступные worker-ам.

-
- -

Спецификации

- - - - - - - - - - - - - - - - - - - -
СпецификацияСтатусКомментарий
{{SpecName('HTML WHATWG', '#toc-workers')}}{{Spec2('HTML WHATWG')}}Без изменений {{SpecName("Web Workers")}}.
{{SpecName('Web Workers')}}{{Spec2('Web Workers')}}Начальное определение.
- -

Браузерная совместимость

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support4[1]{{CompatGeckoDesktop("1.9.1")}}10.010.6[1]4[2]
Shared workers4[1]{{CompatGeckoDesktop(29)}}{{CompatNo}}10.65
- {{CompatNo}} 6.1[4]
Passing data using structured cloning13{{CompatGeckoDesktop(8)}}10.011.56
Passing data using transferable objects17 {{property_prefix("webkit")}}
- 21
{{CompatGeckoDesktop(18)}}{{CompatNo}}156
Global {{domxref("window.URL", "URL")}}10[3]
- 23
{{CompatGeckoDesktop(21)}}11156[3]
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)Firefox OS (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support4.44[1]3.51.0.110.011.5[1]5.1[2]
Shared workers{{CompatNo}}4[1]81.0.1{{CompatNo}}{{CompatNo}}{{CompatNo}}
Passing data using structured cloning{{CompatNo}}481.0.1{{CompatNo}}{{CompatNo}}{{CompatNo}}
Passing data using transferable objects{{CompatNo}}{{CompatNo}}181.0.1{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -

[1] Chrome и Opera выдают ошибку "Uncaught SecurityError: Failed to construct 'Worker': Script at 'file:///Path/to/worker.js' cannot be accessed from origin 'null'." когда вы пытаетесь запустить worker локально. Нужно быть на надлежащем домене.

- -

[2] Начиная с Safari 7.1.2, вы можете вызывать console.log изнутри worker-а, но он ничего не выведет в консоль. Более старые версии Safari не ползволяют вызывать console.log изнутри worker-а

- -

[3] Эта функция реализована с префиксом как webkitURL.

- -

[4] Safari удалил поддержку SharedWorker.

- -

Смотрите также

- - diff --git a/files/ru/dom/window.requestanimationframe/index.html b/files/ru/dom/window.requestanimationframe/index.html deleted file mode 100644 index d451cae62f..0000000000 --- a/files/ru/dom/window.requestanimationframe/index.html +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: window.requestAnimationFrame() -slug: DOM/window.requestAnimationFrame -tags: - - Анимация -translation_of: Web/API/window/requestAnimationFrame ---- -
{{APIRef}}
- -

window.requestAnimationFrame указывает браузеру на то, что вы хотите произвести анимацию, и просит его запланировать перерисовку на следующем кадре анимации. В качестве параметра метод получает функцию, которая будет вызвана перед перерисовкой.

- -
Заметка: Ваш callback метод сам должен вызвать requestAnimationFrame() иначе анимация остановится.
- -

Вы должны вызывать этот метод всякий раз, когда готовы обновить анимацию на экране, чтобы запросить планирование анимации. Обычно запросы происходят 60 раз в секунду, но чаще всего совпадают с частотой обновления экрана. В большинстве браузеров в фоновых вкладках или скрытых <iframe>, вызовы requestAnimationFrame() приостанавливаются, для того, чтобы повысить производительность и время работы батареи.

- -

Callback методу передаётся один аргумент, {{domxref("DOMHighResTimeStamp")}}, который содержит текущее время (количество миллисекунд, прошедших с момента time origin). Когда callback-и, отправленные в очередь с помощью requestAnimationFrame() начинают вызывать несколько callback-ов в одном кадре, каждый получает одинаковый timestamp, хотя для вычисления каждого callback было затрачено время. Этот timestamp - десятичное число в миллисекундах, но с минимальной точностью в 1ms (1000 µs).

- -

Синтаксис

- -
window.requestAnimationFrame(callback);
- -

Параметры

- -
-
callback
-
Функция, которая будет вызвана, когда придёт время обновить вашу анимацию на следующей перерисовке.
-
element {{ optional_inline() }}
-
Необязательный параметр (не используется в Firefox или IE), определяющий элемент, который визуально содержит всю анимацию. Для canvas'а и WebGL'a им должен быть {{ HTMLElement("canvas") }}. Для других элементов вы можете опустить этот параметр для чуть лучшего пользовательского опыта.
-
- -

Возвращаемое значение

- -

requestID — длинное целое, являющееся уникальным идентификатором для записи, содержащей callback. Оно не равно нулю, но других предположений о его значении делать не следует. Вы можете передать его в {{ domxref("window.cancelAnimationFrame()") }} для отмены вызова.

- -

Пример

- -
var start = null;
-var element = document.getElementById('SomeElementYouWantToAnimate');
-
-function step(timestamp) {
-  if (!start) start = timestamp;
-  var progress = timestamp - start;
-  element.style.transform = 'translateX(' + Math.min(progress / 10, 200) + 'px)';
-  if (progress < 2000) {
-    window.requestAnimationFrame(step);
-  }
-}
-
-window.requestAnimationFrame(step);
- -

Примечание

- -

В Edge версиях младше 17 и в Internet Explorer не надежно запускать requestAnimationFrame перед циклом рисования.

- -

Спецификация

- - - - - - - - - - - - - - - - - - - - - -
СпецификацияСтатусКомментарий
{{SpecName('HTML WHATWG', '#animation-frames', 'requestAnimationFrame')}}{{Spec2('HTML WHATWG')}}Без изменений, заменяет предыдущую.
{{SpecName('RequestAnimationFrame', '#dom-windowanimationtiming-requestanimationframe', 'requestAnimationFrame')}}{{Spec2('RequestAnimationFrame')}}Первоначальное описание.
- -

Браузерная совместимость

- -

{{Compat("api.Window.requestAnimationFrame")}}

- -

Смотрите также

- - diff --git "a/files/ru/firefox_3.5_\320\264\320\273\321\217_\321\200\320\260\320\267\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\260/index.html" "b/files/ru/firefox_3.5_\320\264\320\273\321\217_\321\200\320\260\320\267\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\260/index.html" deleted file mode 100644 index a3e9f4c276..0000000000 --- "a/files/ru/firefox_3.5_\320\264\320\273\321\217_\321\200\320\260\320\267\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\260/index.html" +++ /dev/null @@ -1,312 +0,0 @@ ---- -title: Firefox 3.5 для разработчика -slug: Firefox_3.5_для_разработчика -translation_of: Mozilla/Firefox/Releases/3.5 ---- -
{{FirefoxSidebar}}

Firefox 3.5 вводит ряд новых возможностей, а также дополнительную и улучшенную поддержку для самых различных веб-стандартов. Данная статья представляет собой исчерпывающий перечень нововведений со ссылками на статьи, освещающие основные усовершенствования.

-

Новые возможности для разработчиков

-

Для разработчиков веб-сайтов и веб-приложений

-

Поддержка HTML 5

-
-
- Использование аудио и видео
-
- В Firefox 3.5 добавлена поддержка элементов HTML 5 audio и video.
-
- Offline resources in Firefox
-
- Firefox 3.5 now fully supports the HTML 5 offline resource specification.
-
- Drag and drop
-
- The HTML 5 drag and drop API allows support for dragging and dropping items within and between web sites.  This also provides a simpler API for use by extensions and Mozilla-based applications.
-
-

Newly-supported CSS features

-
-
- Downloadable fonts support
-
- The new {{ cssxref("@font-face") }} @rule lets web pages provide downloadable fonts, so that sites can be rendered exactly as the page author expects.
-
- CSS media queries
-
- Firefox 3.5 now supports CSS media queries, which enhance support for media-dependent style sheets.
-
- {{ cssxref(":before") }} and {{ cssxref(":after") }} updated to CSS 2.1
-
- The :before and :after pseudo-elements have been updated to full CSS 2.1 support, adding support for the position, float, list-style-*, and some display properties.
-
- ch units for length
-
- The ch unit can now be used anywhere that accepts a unit of length. 1ch is the width of the "0" (zero) character.
-
- {{ cssxref("opacity") }}
-
- The -moz-opacity Mozilla extension to CSS has been removed in favor of the standard opacity property.
-
- {{ cssxref("text-shadow") }}
-
- The text-shadow property, which allows web content to specify shadow effects to apply to text and text decorations, is now supported.
-
- {{ cssxref("word-wrap") }}
-
- This newly-supported property lets content specify whether or not lines may be broken within words in order to prevent overflow when an otherwise unbreakable string is too long to fit on one line.
-
- white-space property supports the pre-line value
-
- The {{ cssxref("white-space") }} property now accepts the pre-line value.
-
- {{ cssxref("-moz-box-shadow") }}
-
- {{ cssxref("-moz-border-image") }}
-
- {{ cssxref("-moz-column-rule") }}
-
- {{ cssxref("-moz-column-rule-width") }}
-
- {{ cssxref("-moz-column-rule-style") }}
-
- {{ cssxref("-moz-column-rule-color") }}
-
- Firefox 3.5 adds support for these Mozilla extensions to CSS.
-
- The {{ cssxref("color_value#Mozilla_Extensions","-moz-nativehyperlinktext") }} color value
-
- This new color value represents the user's system's default hyperlink color.
-
- The {{ cssxref("-moz-window-shadow") }} property and the {{ cssxref(":-moz-system-metric(mac-graphite-theme)") }} pseudo-class
-
- These new CSS features were added to facilitate theming.
-
- New values for {{ cssxref("-moz-appearance") }}
-
- The -moz-win-glass and -moz-mac-unified-toolbar values have been added to -moz-appearance.
-
- Using CSS transforms
-
- Firefox 3.5 supports CSS transforms.  See {{ cssxref("-moz-transform") }} and {{ cssxref("-moz-transform-origin") }} for details.
-
- {{ cssxref(":nth-child") }}
-
- {{ cssxref(":nth-last-child") }}
-
- {{ cssxref(":nth-of-type") }}
-
- {{ cssxref(":nth-last-of-type") }}
-
- {{ cssxref(":first-of-type") }}
-
- {{ cssxref(":last-of-type") }}
-
- {{ cssxref(":only-of-type") }}
-
- These selectors are all newly-supported in Firefox 3.5.
-
-

Новые возможности DOM

-
-
- localStorage
-
- Firefox 3.5 adds support for the Web Storage localStorage property, which provides a way for web applications to store data locally on the client's computer.
-
- Using web workers
-
- Firefox 3.5 supports web workers to allow easy multi-threading support in web applications.
-
- Using geolocation
-
- Firefox 3.5 supports the Geolocation API, which allows web applications to obtain information about the user's current location if a provider for that information is installed and enabled.
-
- Locating DOM elements using selectors
-
- The selectors API allows querying a document to locate the elements that match a given selection rule.
-
- Mouse gesture events
-
- Firefox 3.5 supports mouse gesture events such as trackpad swipes.
-
- The NodeIterator object
-
- The NodeIterator object provides support for iterating over the list of the nodes in a DOM subtree.
-
- The MozAfterPaint event
-
- This new DOM event is sent after painting updates in windows.
-
- The MozMousePixelScroll event
-
- This new DOM event allows detection of pixel-based mouse scroll wheel events instead of line-based scroll events.
-
-

Новые возможности JavaScript

-
-
- Новое в JavaScript 1.8.1
-
- Обзор всех изменений в JavaScript 1.8.1.
-
- Object.getPrototypeOf()
-
- Новый метод, возвращающий прототип указанного объекта.
-
- Использование встроенного JSON
-
- Firefox 3.5 имеет встроенную поддержку JSON.
-
- Новые методы обрезки строк в объекте String
-
- Объект String теперь имеет методы trim(), trimLeft() и trimRight().
-
-

Networking

-
-
- Cross-site access controls for HTTP
-
- In Firefox 3.5, it's now possible for HTTP requests, including those made by XMLHttpRequest, to work across domains if the server supports it.
-
- Progress events for XMLHttpRequest
-
- Progress events are now offered to enable extensions to monitor the progress of requests.
-
- Improved Synchronous XMLHttpRequest support
-
- DOM Timeout and Input Events are now suppressed during a synchronous XMLHttpRequest.
-
- Controlling DNS prefetching
-
- Firefox 3.5 provides DNS prefetching, whereby it performs domain name resolution ahead of time for links included in the current page, in order to save time when links are actually clicked.  This article describes how you can tune your web site to disable prefetching, or to adjust how prefetching operates.
-
-

New Canvas features

-
-
- HTML 5 text API for canvas elements
-
- Canvas elements now support the HTML 5 text API.
-
- Shadow effects in a canvas
-
- Canvas shadow effects are now supported.
-
- createImageData()
-
- The canvas method createImageData() is now supported, allowing code to specifically create an ImageData object instead of requiring it to be done automatically. This can improve performance of other ImageData methods by preventing them from having to create the object.
-
- moz-opaque attribute
-
- Added the moz-opaque DOM attribute, which lets the canvas know whether or not translucency will be a factor.  If the canvas knows there's no translucency, painting performance can be optimized.
-
-

New SVG features

-
-
- Applying SVG effects to HTML content
-
- You can now apply SVG effects to HTML and XHTML content; this article describes how.
-
-

Miscellaneous new features

-
-
- ICC color correction in Firefox
-
- Firefox 3.5 now supports ICC color correction for tagged images.
-
- The defer attribute is now supported on script elements
-
- This attribute indicates to the browser that it may choose to continue to parse and render the page without waiting for the script to finish executing.
-
-

Другие улучшения

- -

Для разработчиков дополнений

-

If you're an extension developer, you should start by reading Updating extensions for Firefox 3.5, which offers a helpful overview of what changes may affect your extension.

-

New components and functionality

-
-
- Supporting private browsing mode
-
- Firefox 3.5 offers Private Browsing mode, which doesn't record the user's activities.  Extensions may support private browsing following the guidelines offered by this article.
-
- Security changes in Firefox 3.5
-
- This article covers security-related changes in Firefox 3.5.
-
- Theme changes in Firefox 3.5
-
- This article covers theme-related changes in Firefox 3.5.
-
- Monitoring WiFi access points
-
- Code with UniversalXPConnect privileges can now monitor the list of available access points, getting information on their SSIDs, MAC addresses, and signal strength.  This can be used in tandem with Geolocation to offer WiFi-based location service.
-
-

Notable changes and improvements

- -

Новые возможности для конечного пользователя

-

User experience

-
-
- Location aware browsing
-
- If you choose, you may allow Firefox 3.5 to share information about your current location with web sites.  Firefox 3.5 can use information about the network you're connected to to share your location. Of course, it asks for your permission before doing so, to ensure your privacy.
-
- Open audio and video support
-
- Firefox 3.5 supports embedded video and audio using the open Ogg format, as well as WAV for audio. No plugins, no confusing error messages about needing to install something or other that turns out not to be available on your platform anyway.
-
- Local data storage
-
- Web applications can now use Web Storage's local storage capabilities to store data on your computer.  This is great for anything from site preferences to more complex data.
-
-

Безопасность и приватность

-
-
- Private Browsing
-
- Need to use someone else's computer? Switch on Private Browsing mode and nothing will be recorded about your session, including cookies, history, and any other potentially private information.
-
- Better privacy controls
-
- The Privacy preference pane has been completely redesigned to offer users more control over their private information. Users can choose to retain or discard anything including history information, cookies, downloads, and form field information.  In addition, users can specify whether or not to include history and/or bookmarks in the location bar's automated suggestions, so you can keep private web addresses from popping up unexpectedly while typing in the location bar.
-
-

Производительность

-
-
- Faster JavaScript performance
-
- JavaScript, the "J" in "AJAX," is sped up dramatically in Firefox 3.5 with the new TraceMonkey JavaScript engine.  Web applications are much faster than in Firefox 3.
-
- Faster page rendering
-
- Web content draws faster in Firefox 3.5, thanks to technologies such as "speculative parsing." Your users don't need to know what it means, other than "it makes things draw faster."
-
-

Смотрите также

- diff --git a/files/ru/firefox_3_for_developers/index.html b/files/ru/firefox_3_for_developers/index.html deleted file mode 100644 index 98537faee9..0000000000 --- a/files/ru/firefox_3_for_developers/index.html +++ /dev/null @@ -1,299 +0,0 @@ ---- -title: Firefox 3 для разработчиков -slug: Firefox_3_for_developers -translation_of: Mozilla/Firefox/Releases/3 ---- -
{{FirefoxSidebar}}

Если вы разработчик и хотите познакомится со всеми возможностями Firefox 3 вы пришли по адресу. В этой статье представлен список новых статей, в которых рассказывается о новых возможностях Firefox 3. В статьях не будут представлены сведения о незначительных изменениях, однако они помогут вам познакомится с существенными обновлениями.

-

Новые возможности для разработчиков в Firefox 3

-

Для веб-мастеров и разработчиков приложений

-
-
- Обновление веб-приложений для Firefox 3
-
- Предоставляет информацию об изменениях которые вам возможно нужно внести, чтобы получить выгоду от новых возможностей Firefox 3.
-
-
-
- Online и offline события
-
- Firefox 3 поддерживает WHATWG online и offline события, которые позволяют приложениям и расширениям определять есть ли активное Интернет соединение, и так же позволяет определять когда появляется и пропадает соединение.
-
-
-
- Веб-ориентированные обработчики протоколов
-
- Теперь вы можете регистрировать веб-приложения как обработчик протокола используя метод navigator.registerProtocolHandler().
-
-
-
- Рисование текста с использованием canvas
-
- Теперь вы можете рисовать текст с ипользованием нестандартизированного API canvas поддерживаемого Firefox 3.
-
-
-
- Поддержка преобразований для canvas
-
- Firefox now supports the transform() and setTransform() methods on canvases.
-
-
-
- Using microformats
-
- Firefox now has APIs for working with microformats.
-
-
-
- Drag and drop events
-
- Firefox 3 supports new events that are sent to the source node for a drag operation when the drag begins and ends.
-
-
-
- Focus management in HTML
-
- The new HTML 5 activeElement and hasFocus attributes are supported.
-
-
-
- Offline resources in Firefox
-
- Firefox now lets web applications request that resources be cached to allow the application to be used while offline.
-
-
-
- CSS improvements in Firefox 3
-
- Firefox 3 features a number of improvements in its CSS support.
-
-
-
- DOM improvements in Firefox 3
-
- Firefox 3 offers a number of new features in Firefox 3's DOM implementation, including support for several Internet Explorer extensions to the DOM.
-
-
-
- JavaScript 1.8 support
-
- Firefox 3 offers JavaScript 1.8.
-
-
-
- EXSLT support
-
- Firefox 3 provides support for a substantial subset of the EXSLT extensions to XSLT.
-
-
-
- SVG improvements in Firefox 3
-
- SVG support in Firefox 3 has been upgraded significantly, with support for over two dozen new filters, several new elements and attributes, and other improvements.
-
-
-
- Animated PNG graphics
-
- Firefox 3 supports the animated PNG (APNG) image format.
-
-

For XUL and extension developers

-
Notable changes and improvements
-
-
- Updating extensions for Firefox 3
-
- Provides a guide to the things you'll need to do to update your extension to work with Firefox 3.
-
-
-
- XUL improvements in Firefox 3
-
- Firefox 3 offers a number of new XUL elements, including new sliding scales, the date and time pickers, and spin buttons.
-
-
-
- Templates in Firefox 3
-
- Templates have been significantly improved in Firefox 3. The key improvement allows the use of custom query processors to allow data sources other than RDF to be used.
-
-
-
- Securing updates
-
- In order to provide a more secure add-on upgrade path for users, add-ons are now required to provide a secure method for obtaining updates before they can be installed. Add-ons hosted at AMO automatically provide this. Any add-ons installed that do not provide a secure update method when the user upgrades to Firefox 3 will be automatically disabled. Firefox will however continue to check for updates to the extension over the insecure path and attempt to install any update offered (installation will fail if the update also fails to provide a secure update method).
-
-
-
- Places migration guide
-
- An article about how to update an existing extension to use the Places API.
-
-
-
- Download Manager improvements in Firefox 3
-
- The Firefox 3 Download Manager features new and improved APIs, including support for multiple progress listeners.
-
-
-
- Using nsILoginManager
-
- The Password Manager has been replaced by the new Login Manager.
-
-
-
- Embedding XBL bindings
-
- You can now use the data: URL scheme from chrome code to embed XBL bindings directly instead of having them in separate XML files.
-
-
-
- Localizing extension descriptions
-
- Firefox 3 offers a new method for localizing add-on metadata. This lets the localized details be available as soon as the add-on has been downloaded, as well as when the add-on is disabled.
-
-
-
- Localization and Plurals
-
- Firefox 3 adds the new PluralForm module, which provides tools to aid in correctly pluralizing words in multiple localizations.
-
-
-
- Theme changes in Firefox 3
-
- Notes and information of use to people who want to create themes for Firefox 3.
-
-
New components and functionality
-
-
- FUEL Library
-
- FUEL is about making it easier for extension developers to be productive, by minimizing some of the XPCOM formality and adding some "modern" JavaScript ideas.
-
-
-
- Places
-
- The history and bookmarks APIs have been completely replaced by the new Places API.
-
-
-
- Idle service
-
- Firefox 3 offers the new {{ Interface("nsIIdleService") }} interface, which lets extensions determine how long it's been since the user last pressed a key or moved their mouse.
-
-
-
- ZIP writer
-
- The new {{ Interface("nsIZipWriter") }} interface lets extensions create ZIP archives.
-
-
-
- Full page zoom
-
- Firefox 3 improves the user experience by offering full page zoom in addition to text-only zoom.
-
-
-
- Interfacing with the XPCOM cycle collector
-
- XPCOM code can now take advantage of the cycle collector, which helps ensure that unused memory gets released instead of leaking.
-
-
-
- The Thread Manager
-
- Firefox 3 provides the new {{ Interface("nsIThreadManager") }} interface, along with new interfaces for threads and thread events, which provides a convenient way to create and manage threads in your code.
-
-
-
- JavaScript modules
-
- Firefox 3 now offers a new shared code module mechanism that lets you easily create modules in JavaScript that can be loaded by extensions and applications for use, much like shared libraries.
-
-
-
- The nsIJSON interface
-
- Firefox 3 offers the new {{ Interface("nsIJSON") }} interface, which offers high-performance encoding and decoding of JSON strings.
-
-
-
- The nsIParentalControlsService interface
-
- Firefox 3 now supports the Microsoft Windows Vista parental controls feature, and allows code to interact with it.
-
-
-
- Using content preferences
-
- Firefox 3 includes a new service for getting and setting arbitrary site-specific preferences that extensions as well as core code can use to keep track of their users' preferences for individual sites.
-
-
-
- Plug-in Monitoring
-
- A new component of the plugin system is now available to measure how long it takes plugins (e.g., Macromedia Flash) to execute their calls.
-
-
Fixed bugs
-
-
- Notable bugs fixed in Firefox 3
-
- This article provides information about bugs that have been fixed in Firefox 3.
-
-

New features for end users

-

User experience

- -

Security and privacy

- -

Performance

- -

See also

- -

{{ languages( { "es": "es/Firefox_3_para_desarrolladores", "fr": "fr/Firefox_3_pour_les_d\u00e9veloppeurs", "ja": "ja/Firefox_3_for_developers", "zh-tw": "zh_tw/Firefox_3_for_developers", "ko": "ko/Firefox_3_for_developers", "pl": "pl/Firefox_3_dla_programist\u00f3w", "pt": "pt/Firefox_3_para_desenvolvedores" } ) }}

diff --git a/files/ru/games/anatomy/index.html b/files/ru/games/anatomy/index.html new file mode 100644 index 0000000000..0396fc4159 --- /dev/null +++ b/files/ru/games/anatomy/index.html @@ -0,0 +1,337 @@ +--- +title: Анатомия видеоигры +slug: Games/Анатомия +translation_of: Games/Anatomy +--- +
{{GamesSidebar}}
+ +

{{IncludeSubnav("/en-US/docs/Games")}}

+ +
+

Эта статья рассматривает анатомию и рабочий процесс создания средней видеоигры с технической точки зрения и определений того, как должен выглядеть главный цикл приложения. Она служит для помощи начинающим разработчикам в разработке современных игр, а также для понимания того, что необходимо знать при построении игры и как применять различные web-стандарты и инструменты, такие как JavaScript. Опытные разработчики игр, которые только пришли в мир web-разработки тоже могут почерпнуть для себя много интересного.

+
+ +

Показать, получить, преобразовать, вычислить, повторить

+ +

Целью каждой видеоигры является  показ пользователю (пользователям) игровой ситуации, получение пользовательских сигналов, преобразования их в действия и вычисления новой ситуации как результат этих действий. Игры постоянно повторяют эти стадии, снова и снова, до тех пор пока не наступит завершающее условие (такое как победа, поражение, или выход из игры с целью поспать). Не удивительно, что данный шаблон соответствует тому как программируется игровая логика (движок).

+ +

Особенности игр.

+ +

Некоторые игры управляют своим циклом при помощи пользовательского ввода. Представьте, что вы разрабатываете игру типа "найди разницу между этими двумя похожими картинками". Такого рода игры показывают пользователю две картинки; они получают их клики (или касания); они преобразуют ввод в успешный , не успешный, пауза, работа с меню, и так далее; в конечном итоге, в зависимости от данных действий, они вычисляют обновленное состояние сцены. Игровой цикл продвигается пользовательскими действиями и "спит" пока таковые отсутствуют. Это пример так называемой пошаговой игры, которая не зависит от постоянного обновления каждого кадра, а только от действий пользователя.

+ +

Другие игры требуют контроля над каждым из минимально возможных индивидуальных временных интервалов. Те же принципы, что и выше, применяются с небольшим изменением: каждый кадр анимации продолжает цикл, и любое изменение пользовательского ввода фиксируется на первом доступном ходе. Эта покадровая модель реализована в так называемом основном цикле. Если ваша игра зацикливается на времени, то это будет её полномочия, которые будут соблюдать ваши симуляции.

+ +

Но покадровое управление может и не понадобиться. Ваш игровой цикл может быть похож на пример поиска отличий и основан на входных событиях. Это может потребовать как ввода, так и симуляции времени. Он может даже зацикливаться на чем-то совершенно другом.

+ +

Современный JavaScript, как описано в следующих разделах, к счастью, позволяет легко разработать эффективный основной цикл выполнения один раз в кадр. Конечно, ваша игра будет оптимизирована настолько, насколько вы ее сделаете. Если что-то выглядит так, как будто оно должно быть прикрепленно к более редкому исходу, то часто бывает хорошей идеей вырвать его из основного цикла (но не всегда).

+ +

Построение основного цикла в JavaScript 

+ +

Лучше всего JavaScript работает с событиями и callback функциями. Современные браузеры стремятся вызывать методы по мере необходимости и бездействовать (или выполнять другие задачи) в промежутках. Привязать код к моменту, который для него подходит — это отличная идея.  Подумайте о том, действительно ли ваша функция должна вызываться на строго определенном интервале времени, в каждом кадре или только после того, как произойдет что-то еще.  Подумайте о том, действительно ли функцию нужно вызывать в определённом интервале времени, на каждый кадр или только после того, как что-то произойдёт. Больше конкретики с браузером в том, когда функция должна быть вызвана, позволяет ему лучше оптимизировать этот процесс. Так же, вероятно, это облегчит вам работу.   

+ +

Некоторый код должен выполняться кадр за кадром, так зачем же прикреплять эту функцию к чему-то другому, кроме графика перерисовки браузера? В Web, {{ domxref("window.requestAnimationFrame()") }} будет основой большинства хорошо запрограммированных покадровых основных циклов.  Callback функция должна быть передана ему при вызове. Callback функция будет выполнена в подходящее время перед следующей перерисовкой. Вот пример простого основного цикла:

+ +
window.main = function () {
+  window.requestAnimationFrame( main );
+
+  // Код, который цикл должен выполнить
+};
+
+main(); // Start the cycle
+ +
+

Примечание: В каждом из методов main(), обсуждаемых здесь, мы планируем новый requestAnimationFrame перед выполнением нашего содержимого цикла. Это не случайно и считает лучшей практикой. Ранний вызов следующего requestAnimationFrame гарантирует, что браузер получит его вовремя, чтобы спланировать соответствующим образом, даже если ваш текущий кадр пропустит свое окно VSync.

+
+ +

Приведенный выше фрагмент кода содержит два оператора. Первый оператор создает функцию как глобальную переменную с именем main().Эта функция выполняет некоторую работу, а также сообщает браузеру, что нужно вызвать следующий кадр с помощью window.requestAnimationFrame(). Второй оператор вызывает функцию main(), описанную в первом операторе. Поскольку main() вызывается один раз во втором операторе и каждый его вызов помещает себя в очерёдность действий, чтобы отрисовать следующий кадр, main() синхронизируется с вашей частотой кадров.

+ +

Конечно, этот цикл не идеален. Прежде чем мы обсудим способы его изменения, давайте обсудим, что он уже делает хорошо.

+ +

Синхронизация основного цикла с тем, когда браузер рисует на дисплее, позволяет запускать цикл так часто, как браузер хочет рисовать. Вам предоставляется контроль над каждым кадром анимации. Это также очень просто, потому что main() - единственная функция, которая зацикливается. Шутер от первого лица (или подобная игра) представляет новую сцену один раз в каждом кадре. Вы не можете добиться большей плавности и быстродействия.

+ +

Но не стоит сразу предполагать, что анимация требует покадрового управления. Простые анимации можно легко выполнять даже с ускорением на GPU с помощью CSS-анимации и других инструментов, включенных в браузер. Их очень много и они сделают вашу жизнь проще.

+ +

Создание улучшенного основного цикла в JavaScript.

+ +

У нашего цикла есть две очевидные проблемы: main() загрязняет {{ domxref("window") }} объект (в нем хранятся все глобальные переменные) и код не оставляет нам возможность остановить цикл, если только вся вкладка не будет закрыта или обновлена. Для решения первой проблемы, если нужно, чтобы основной цикл просто выполнялся и вам не нужен легкий (прямой) доступ к нему, вы можете поместить его внутрь самовызывающейся Function Expression (IIFE).

+ +
/*
+* Начинаем с точки с запятой в случае, если какая-либо строка кода выше данного примера
+* полагается на автоматическую вставку точки с запятой (ASI). Браузер может случайно решить,
+* что весь этот код начинается с предыдущей строки. Первая точка с запятой отмечает начало
+* новой строки, если предыдущая не была пустой или завершенной.
+*/
+
+;(function () {
+  function main() {
+    window.requestAnimationFrame( main );
+
+    // Содержание вашего основного цикла
+  }
+
+  main(); // Вызов цикла
+})();
+ +

Когда браузер наткнется на IIFE (Immediately Invoked Function Expression), он определит основной цикл и сразу же поставит его в очередь для следующего кадра. Он не будет привязан ни к какому объекту, и main (или main() для методов) будет неиспользуемым именем, доступным в остальной части приложения для определения чего-то другого.

+ +
+

Примечание: На практике распространено предотвращать следующий requestAnimationFrame() используя оператор if вместо вызова cancelAnimationFrame().

+
+ +

Чтобы остановить основной цикл, вам понадобиться отменить вызов main() с помощью {{ domxref("window.cancelAnimationFrame()") }}. Необходимо передать в cancelAnimationFrame() идентификатор последнего вызова requestAnimationFrame(). Давайте предположим, что функции и переменные вашей игры были определены в пространстве имен, которое вы назвали MyGame.  В таком случае, основной цикл будет выглядеть следующим образом:

+ +
/*
+* Начинаем с точки с запятой в случае, если какая-либо строка кода выше данного примера
+* полагается на автоматическую вставку точки с запятой (ASI). Браузер может случайно решить,
+* что весь этот код начинается с предыдущей строки. Первая точка с запятой отмечает начало
+* новой строки, если предыдущая не была пустой или завершенной.
+*
+* Давайте также предположим, что MyGame уже определена.
+*/
+
+;(function () {
+  function main() {
+    MyGame.stopMain = window.requestAnimationFrame( main );
+
+    // Содержание вашего основного цикла
+  }
+
+  main(); // Вызов цикла
+})();
+ +

Теперь у нас есть переменная stopMain, объявленная в нашем пространстве имен MyGame, которая содержит идентификатор последнего вызова requestAnimationFrame() нашего основного цикла.  В любой момент мы может остановить основной цикл, сказав браузеру, чтобы тот отменил запрос, соответствующий последнему маркеру.

+ +
window.cancelAnimationFrame( MyGame.stopMain );
+ +

Ключ к программированию основного цикла в JavaScript заключается в том, чтобы прикрепить его к любому событию, которое должно управлять вашими действиями, и обращать внимание на то, как различные системы учавствуют во взаимодействии. У вас может быть несколько компонентов, управляемых несколькими различными типами событий. Это может показаться излишним усложнением, но также может быть просто хорошей оптимизацией (не обязательно, конечно). Проблема в том, что вы не выстраиваете типичный основной цикл. В JavaScript вы используйте основной цикл браузера и стараетесь сделать это эффективно. 

+ +

Построение более оптимизированного основного цикла в JavaScript

+ +

В конце контов, в JavaScript браузер выполняет свой собственный основной цикл, и ваш код существует на некоторых его этапах. В приведенных выше разделах описываются основные циклы, которые стараются не отнимать контроль у браузера. Их методы прикрепляют себя к  window.requestAnimationFrame(), который запрашивает контроль над предстоящим кадром у браузера.  Браузер решает, как связать эти запросы с их основным циклом. Спецификация W3C для requestAnimationFrame на самом деле точно не определяет, когда браузеры должны выполнять колбэки requestAnimationFrame. Это может быть приемуществом, поскольку позволяет поставщикам браузеров свободно экспериментировать с решениями, которые они считают лучшими, и настраивать их с течением времени.

+ +

Современные версии Firefox и Google Chrome (вероятно, и другие) пытаются подключить колбэки requestAnimationFrame к своему основному потоку в самом начале временного интервала фрэйма. Таким образом основной поток браузера пытается выглядеть следующим образом: 

+ +
    +
  1. Запустить новый кадр (пока предыдущий обрабатывается на дисплее.).
  2. +
  3. Пройтись по кэлбэкам requestAnimationFrame и вызвать их.
  4. +
  5. Выполнить сборку мусора и другие задачи для каждого кадра, когда вышеупомянутые колбэки перестают контролировать основной поток.
  6. +
  7. Спать (если только какое-либо событие не прервет сон браузера) до тех пор, пока монитор не будет готов к вашему изображению (VSync), и повторить его.
  8. +
+ +

Вы можете думать о разработке realtime applications, как о запасе времени для работы. Все вышеперечисленные шаги должны выполняться каждые 16  с половиной миллисекунд, чтобы не отставать от дисплея с чистатой 60Гц.  Браузеры вызывают ваш код таким образом, чтобы предаставить ему максимум времени для вычислений. Ваш основной поток часто запускает рабочие нагрузки, которые даже не находятся в основном потоке (Например, растеризация или шейдеры в WebGL).  Большие вычисления могут выполняться на Web Worker-e или GPU одновременно с тем, как браузер использует свой основной поток для управления сборкой мусора, обработки асинхронных вызовов или других задач. 

+ +

Пока мы обсуждаем распределение нашего временного бюджета, многие браузеры имеют инструмент под названием High Resolution Time. Объект {{ domxref("Date") }} больше не используется в качестве основного метода синхронизации событий, поскольку он очень не точен и может быть изменен системными часами. High Resolution Time, с другой стороны, подсчитывает колличество миллисекунд начиная с navigationStart (при выгрузке предыдущего документа). Это значение возвращается в виде десятичного числа с точностью до миллисекунды.  Он известен как DOMHighResTimeStamp, но для всех целей и задач считайте его числом с плавающей запятой.  

+ +
+

Примечание: Системы (аппаратные или программные), которые не могу обеспечить точность в микросекундах, могут по крайней мере обеспечить точность в миллисекундах.  Однако, они должны обеспечивать точность до 0,001 мс, если способны на это. 

+
+ + + +

Это значение нельзя использовать само по себе, потому что оно относиться к неинтересному событию, но его можно вычесть из другой временной ветки, чтобы четко и точно определить, сколько времени прошло между этими двумя точками. Чтобы получить одну из этих временных меток, вы можете вызвать window.performance.now() и сохранить результат в переменную. 

+ +
var tNow = window.performance.now();
+
+ +

Возвращаемся к основному циклу. Часто вам понадобиться узнать, когда ваша основная функция  была вызвана. Это обычное дело, window.requestAnimationFrame() при выполнени всегда предоставляет метку DOMHighResTimeStamp в качетве аргумента для функций обратного вызова (callbacks). Это приводит к очередному улучшению нашего основного цикла. 

+ +
/*
+* Начинаем с точки с запятой в случае, если какая-либо строка кода выше данного примера
+* полагается на автоматическую вставку точки с запятой (ASI). Браузер может случайно решить,
+* что весь этот код начинается с предыдущей строки. Первая точка с запятой отмечает начало
+* новой строки, если предыдущая не была пустой или завершенной.
+*
+* Давайте также предположим, что MyGame уже определена.
+*/
+
+;(function () {
+  function main( tFrame ) {
+    MyGame.stopMain = window.requestAnimationFrame( main );
+
+    // Содержимое вашего основного цикла
+    // tFrame, из "function main ( tFrame )", это DOMHighResTimeStamp предоставленный requestAnimationFrame.
+  }
+
+  main(); // Начало цикла
+})();
+ +

Возможно несколько других оптимизаций, которые зависят от того, что делает ваша игра. Ваш игровой жанр очевидно будет иметь значение, но он может быть даже более продуманным. 

+ +

Several other optimizations are possible and it really depends on what your game attempts to accomplish. Your game genre will obviously make a difference but it could even be more subtle than that. You could draw every pixel individually on a canvas or you could layer DOM elements (including multiple WebGL canvases with transparent backgrounds if you want) into a complex hierarchy. Each of these paths will lead to different opportunities and constraints.

+ +

It is decision... time

+ +

You will need to make hard decisions about your main loop: how to simulate the accurate progress of time. If you demand per-frame control then you will need to determine how frequently your game will update and draw. You might even want update and draw to occur at different rates. You will also need to consider how gracefully your game will fail if the user's system cannot keep up with the workload. Let us start by assuming that you will handle user input and update the game state every time you draw. We will branch out later.

+ +
+

Note: Changing how your main loop deals with time is a debugging nightmare, everywhere. Think about your needs carefully before working on your main loop.

+
+ +

What most browser games should look like

+ +

If your game can hit the maximum refresh rate of any hardware you support then your job is fairly easy. You can simply update, render, and then do nothing until VSync.

+ +
/*
+* Starting with the semicolon is in case whatever line of code above this example
+* relied on automatic semicolon insertion (ASI). The browser could accidentally
+* think this whole example continues from the previous line. The leading semicolon
+* marks the beginning of our new line if the previous one was not empty or terminated.
+*
+* Let us also assume that MyGame is previously defined.
+*/
+
+;(function () {
+  function main( tFrame ) {
+    MyGame.stopMain = window.requestAnimationFrame( main );
+
+    update( tFrame ); // Call your update method. In our case, we give it rAF's timestamp.
+    render();
+  }
+
+  main(); // Start the cycle
+})();
+ +

If the maximum refresh rate cannot be reached, quality settings could be adjusted to stay under your time budget. The most famous example of this concept is the game from id Software, RAGE. This game removed control from the user in order to keep its calculation time at roughly 16ms (or roughly 60fps). If computation took too long then rendered resolution would decrease, textures and other assets would fail to load or draw, and so forth. This (non-web) case study made a few assumptions and tradeoffs:

+ + + +

Other ways to handle variable refresh rate needs

+ +

Other methods of tackling the problem exist.

+ +

One common technique is to update the simulation at a constant frequency and then draw as much (or as little) of the actual frames as possible. The update method can continue looping without care about what the user sees. The draw method can view the last update and when it happened. Since draw knows when it represents, and the simulation time for the last update, it can predict a plausible frame to draw for the user. It does not matter whether this is more frequent than the official update loop (or even less frequent). The update method sets checkpoints and, as frequently as the system allows, the render method draws instants of time around them. There are many ways to separate the update method in web standards:

+ + + +

Each of these methods have similar tradeoffs:

+ + + +

A separate update and draw method could look like the following example. For the sake of demonstration, the example is based on the third bullet point, just without using Web Workers for readability (and, let's be honest, writability).

+ +
+

Note: This example, specifically, is in need of technical review.

+
+ +
/*
+* Starting with the semicolon is in case whatever line of code above this example
+* relied on automatic semicolon insertion (ASI). The browser could accidentally
+* think this whole example continues from the previous line. The leading semicolon
+* marks the beginning of our new line if the previous one was not empty or terminated.
+*
+* Let us also assume that MyGame is previously defined.
+*
+* MyGame.lastRender keeps track of the last provided requestAnimationFrame timestamp.
+* MyGame.lastTick keeps track of the last update time. Always increments by tickLength.
+* MyGame.tickLength is how frequently the game state updates. It is 20 Hz (50ms) here.
+*
+* timeSinceTick is the time between requestAnimationFrame callback and last update.
+* numTicks is how many updates should have happened between these two rendered frames.
+*
+* render() is passed tFrame because it is assumed that the render method will calculate
+*          how long it has been since the most recently passed update tick for
+*          extrapolation (purely cosmetic for fast devices). It draws the scene.
+*
+* update() calculates the game state as of a given point in time. It should always
+*          increment by tickLength. It is the authority for game state. It is passed
+*          the DOMHighResTimeStamp for the time it represents (which, again, is always
+*          last update + MyGame.tickLength unless a pause feature is added, etc.)
+*
+* setInitialState() Performs whatever tasks are leftover before the mainloop must run.
+*                   It is just a generic example function that you might have added.
+*/
+
+;(function () {
+  function main( tFrame ) {
+    MyGame.stopMain = window.requestAnimationFrame( main );
+    var nextTick = MyGame.lastTick + MyGame.tickLength;
+    var numTicks = 0;
+
+    // If tFrame < nextTick then 0 ticks need to be updated (0 is default for numTicks).
+    // If tFrame = nextTick then 1 tick needs to be updated (and so forth).
+    // Note: As we mention in summary, you should keep track of how large numTicks is.
+    // If it is large, then either your game was asleep, or the machine cannot keep up.
+    if (tFrame > nextTick) {
+      var timeSinceTick = tFrame - MyGame.lastTick;
+      numTicks = Math.floor( timeSinceTick / MyGame.tickLength );
+    }
+
+    queueUpdates( numTicks );
+    render( tFrame );
+    MyGame.lastRender = tFrame;
+  }
+
+  function queueUpdates( numTicks ) {
+    for(var i=0; i < numTicks; i++) {
+      MyGame.lastTick = MyGame.lastTick + MyGame.tickLength; // Now lastTick is this tick.
+      update( MyGame.lastTick );
+    }
+  }
+
+  MyGame.lastTick = performance.now();
+  MyGame.lastRender = MyGame.lastTick; // Pretend the first draw was on first update.
+  MyGame.tickLength = 50; // This sets your simulation to run at 20Hz (50ms)
+
+  setInitialState();
+  main(performance.now()); // Start the cycle
+})();
+ +

Another alternative is to simply do certain things less often. If a portion of your update loop is difficult to compute but insensitive to time, you might consider scaling back its frequency and, ideally, spreading it out into chunks throughout that lengthened period. An implicit example of this is found over at The Artillery Blog for Artillery Games, where they adjust their rate of garbage generation to optimize garbage collection. Obviously, cleaning up resources is not time sensitive (especially if tidying is more disruptive than the garbage itself).

+ +

This may also apply to some of your own tasks. Those are good candidates to throttle when available resources become a concern.

+ +

Summary

+ +

I want to be clear that any of the above, or none of them, could be best for your game. The correct decision entirely depends on the trade-offs that you are willing (and unwilling) to make. The concern is mostly with switching to another option. Fortunately, I do not have any experience with this, but I have heard it is an excruciating game of Whack-a-Mole.

+ +

An important thing to remember for managed platforms, like the web, is that your loop may stop execution for significant periods of time. This could occur when the user unselects your tab and the browser sleeps (or slows) its requestAnimationFrame callback interval. You have many ways to deal with this situation and this could depend on whether your game is single player or multiplayer. Some choices are:

+ + + +

Once your main loop has been developed and you have decided on a set of assumptions and tradeoffs which suit your game, it is now just a matter of using your decisions to calculate any applicable physics, AI, sounds, network synchronization, and whatever else your game may require.

diff --git a/files/ru/games/introduction/index.html b/files/ru/games/introduction/index.html new file mode 100644 index 0000000000..65d1aed2c0 --- /dev/null +++ b/files/ru/games/introduction/index.html @@ -0,0 +1,121 @@ +--- +title: Ввод в разработку Web-игр +slug: Games/Ввод +tags: + - Firefox OS + - Игры + - уроки +translation_of: Games/Introduction +--- +
{{GamesSidebar}}
+ +
{{IncludeSubnav("/ru/docs/Games")}}
+ +

Современный web позволяет не только передавать различную информацию, но и создавать интерактивный контент. Например, потрясающие, высококачественные игры.

+ +

Диапазон игр, которые Вы можете встретить в web поражает и не устапает "нативным" играм, реализованным с использованием языка программирования c++ и java.Причем это касается не только относительно небольших игр, но и объемных игр жанра РПГ, 3d шутерах и многоом другом. Это уже не аналоги простых карточных игр или многопользовательских социальных играх, реализованных с помощью Flash®, а гораздо более сложные вещи. Благодаря значительным улучшениям языка программирования JavaScript и появлению новых API браузера, Вы можете создавать игры, не зависящие от операционной системы. Для их работы необходим только браузер. А иногда, например на устройствах с поддержкой HTML5, таких как Firefox OS, не нужен даже он.

+ +

Игровая платформа HTML5

+ +

Вы действительно можете подумать, что Web - лучшая платформа для вашей игры. Как мы любим говорить:"Web - это тоже платформа." Давайте посмотрим на главные аспекты Web платформы:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ФункционалТехнология
АудиоWeb Audio API
ГрафикаWebGL (OpenGL ES 2.0)
ВводTouch events, Gamepad API, датчики устройства, WebRTC, Full Screen API, Pointer Lock API
ЯзыкJavaScript (или C/C++ используйте Emscripten для компиляции в JavaScript)
СетьWebRTC и/или WebSockets
ДанныеIndexedDB или "облако"
ВебHTML, CSS, SVG, Social API (и многое другое!)
+ +

Экономическое обоснование

+ +

Как разработчик игр, независимо от того, являетесь ли вы частным лицом или крупной игровой студией, вы хотите знать, почему имеет смысл ориентироваться на Web со своим игровым проектом. Давайте посмотрим, как сеть может помочь вам.

+ +

1. Охват паутины огромен, она повсюду. Игры, построенные на HTML5, работают на смартфонах, планшетах, ПК и смарт-телевизорах.

+ +

2. Маркетинг и открытость улучшаются. Вы не ограничиваетесь продвижением своего приложения в чужом магазине приложений. Вместо этого вы можете рекламировать и продвигать свою игру по всему интернету, а также в других средствах массовой информации, используя преимущества присущей сети связности и доступности для новых клиентов.

+ +

3. У вас есть контроль, где это имеет значение: Платежи. Вы не должны отдавать 30% своих доходов кому-то другому только потому, что ваша игра в их экосистеме. Вместо этого, взимать плату, что вы хотите, и использовать любую услугу обработки платежей вам нравится.

+ +

4. Опять же, с большим контролем, вы можете обновить игру, когда захотите. Не жди, затаив дыхание, одобрения, пока кто-то прячется внутри другого.

+ +

5. Контролируйте свою аналитику! Вместо того чтобы полагаться на кого-то другого в принятии решений о том, какая аналитика вам нужна, вы можете собрать свою собственную-или выбрать третью сторону, которая вам больше всего нравится, - чтобы собрать информацию о ваших продажах и досягаемости вашей игры.

+ +

6. Вы можете управлять своими отношениями с клиентами более тесно, по-своему. Больше не придётся работать с обратной связью магазина приложений. Взаимодействуйте со своими клиентами так, как вы хотите, без посредника.

+ +

7. Ваши игроки могут играть в вашу игру в любом месте, в любое время. Поскольку Web распространен повсеместно, ваши клиенты могут проверить статус своей игры на своих телефонах, планшетах, домашних ноутбуках, рабочих столах или на чем-либо еще.

+ +

Web-технологии для разработчиков игр

+ +

Давайте покопаемся в API Web'а, которое приносит на стол и обслуживает разработчиков игр. Вот подробный список, чтобы дать вам представление о том, что Web может сделать для вас:

+ +
+
+
Full Screen API
+
Этот простой API позволяет вашей игре использовать весь экран, тем самым погружая игрока в действие.
+
Gamepad API
+
Если вы хотите, чтобы ваши пользователи могли использовать геймпады и прочие игровые контроллеры для работы с игрой, вам потребуется этот API
+
HTML и CSS
+
Эти технологии помогут вам создать и разместить UI вашей игры, а HTML-элемент {{HTMLElement("canvas")}} это один из способов создать 2D-графику
+
HTML audio
+
Элемент {{HTMLElement ("audio")}} позволяет легко воспроизводить простые звуковые эффекты и музыку. Если ваше потребности выше, ознакомьтесь с Web Audio API для полной мощности обработки звука!
+
IndexedDB
+
Мощный API для хранения пользовательских данных на собственном компьютере или устройстве. Отличный способ локально сохранить состояние игры и другую информацию, без необходимости подгружать ее каждый раз при необходимости. Также полезно дял того, чтобы сделать ваш проект играбельным, даже если пользователь не подключен к Интернету (например, когда он оказался в самолете на несколько часов).
+
JavaScript
+
JavaScript, язык программирования, используемый в Интернете, быстро развивается в современных браузерах и становится ещё быстрее. Используйте его возможности для написания кода своей игры или используйте такие технологии, как Emscripten или Asm.js, чтобы с легкотью переносить существующие игры.
+
Pointer Lock API
+
API Pointer Lock позволяет блокировать мышь или другое указывающее устройство в интерфейсе вашей игры. Вместо абсолютного позиционирования курсора вы получаете координаты дельты, которые дают вам более точные измерения того, что делает пользователь, и предотвращают случайную отправку ввода где-то еще, тем самым упуская важные пользовательские действия.
+
+
SVG (масштабируемая векторная графика)
+
Позволяет создавать векторную графику, которая плавно масштабируется независимо от размера или разрешения дисплея пользователя.
+
Typed Arrays
+
Типизированные массивы JavaScript дают вам доступ к необработанным двоичным данным из кода, что позволяет вам манипулировать текстурами GL, игровыми данными или чем-то еще, даже если код не в формате JavaScript.
+
Web Audio API
+
Этот API необходим для управления воспроизведением, синтезом звука и манипулированием аудио из кода JavaScript. Позволяет создавать потрясающие звуковые эффекты, а также воспроизводить и манипулировать музыкой в ​​режиме реального времени.
+
WebGL
+
Позволяет создавать высокопроизводительную аппаратно-ускоренную 3D (и 2D) графику из веб-контента. Это веб-реализация OpenGL ES 2.0.
+
WebRTC
+
API WebRTC (Real-Time Communications) дает вам возможность управлять аудио- и видеоданными, включая телеконференции и передачу данных из других приложений между двумя пользователями. Хотите, чтобы ваши игроки могли общаться друг с другом, взрывая монстров? Это API для вас!
+
WebSockets
+
+

The WebSocket API позволяет подключить ваше приложение или сайт к серверу для передачи данных в реальном времени. Идеально подходит для многопользовательских игр, чатов и т. д.

+
+
Web Workers
+
Web Workers даёт вам возможность создавать фоновые потоки, выполняющие собственный код JavaScript, используя преимущества современных многоядерных процессоров.
+
XMLHttpRequest и File API
+
+

Комбинация XMLHttpRequest и File API позволяет отправлять и получать любые нужные для вас данные (не позволяйте «XML» выкинуть вас!) с веб-сервера. Это отличный способ сделать что угодно: от загрузки новых игровых уровней и иллюстраций, до передачи информации о статусе игры в режиме  non-real-time и обратно.

+
+
+
diff --git a/files/ru/games/tools/asm.js/index.html b/files/ru/games/tools/asm.js/index.html new file mode 100644 index 0000000000..3f9b2afde0 --- /dev/null +++ b/files/ru/games/tools/asm.js/index.html @@ -0,0 +1,30 @@ +--- +title: asm.js +slug: Games/Инструменты/asm.js +tags: + - JavaScript + - WebAssembly + - asm.js +translation_of: Games/Tools/asm.js +--- +
{{GamesSidebar}}
+ +
{{IncludeSubnav("/en-US/docs/Games")}}
+ +
+

Asm.js - это подмножество JavaScript, имеющее более высокую оптимизацию. В этой статье описаны возможности asm.js, улучшения которые оно дает, где и как это можно применять, а также дополнительные ресурсы и примеры.

+
+ +

Что такое asm.js?

+ +

Это небольшое, более строгое подмножество JavaScript которое ограничивает стандартный язык только конструкциями, типа `while`, `if` и данными в виде чисел, именованных функций, и другими простыми вещами. Оно не разрешает использование объектов, строк, и всего, что требует больших нагрузок. Asm.js напоминает C во многих вещах, но он является полностью валидным кодом на JavaScript и работает на всех имеющихся движках. Он позволяет JS движкам, поддерживающим asm.js, оптимизировать такой код и даёт компиляторам, типа Emscripten, чёткое определение того, как нужно компилировать. Мы покажем, как asm.js код выглядит, чем он полезен и как с ним работать.

+ +

Это подмножество JavaScript уже автоматически используется во многих движках, использующих технологию компиляции Just-In-Time (JIT). Однако, указав явный стандарт, мы можем улучшить оптимизацию такого кода и получить максимальную производительность. Благодаря этому, упрощается совместная работа нескольких JS движков, потому что легче договориться о стандартах. Идея в том, что этот вид кода должен работать очень быстро в каждом движке, и если это не так, это ошибка, и есть четкая спецификация, что именно движки должны оптимизировать.

+ +

Это также делает asm.js достаточно простым для людей, которые пишут компиляторы высокопроизводительного кода под web. Они могут обратиться к спецификации asm.js, чтобы найти более быстрые паттерны для него. Emscripten, компилятор C/C++ в JavaScript, выдает код asm.js, работающий в некоторых браузерах с производительностью, близкой к машинному коду.

+ +

Кроме того, если движок специально распознает код asm.js, то можно сделать еще больше оптимизаций. На данный момент Chrome (статус) и Firefox обладают поддержкой asm.js. Firefox имеет поддержку передовых фич asm.js

+ +

В общем об asm.js

+ +

asm.js - это вспомогательное подмножество языка JavaScript. Он имеет предсказуемый уровень производительности, т.к. ограничен только лишь некоторыми строгими типами и конструкциями. Рабочие характеристики близки скорее к машинному коду, чем к стандартам JS. Использование этого подмножества уже поддерживается главными веб браузерами. Работа asm.js также зависит от браузера и от оборудования.

diff --git a/files/ru/games/tools/index.html b/files/ru/games/tools/index.html new file mode 100644 index 0000000000..8981085874 --- /dev/null +++ b/files/ru/games/tools/index.html @@ -0,0 +1,33 @@ +--- +title: Инструменты для разработки игр +slug: Games/Инструменты +translation_of: Games/Tools +--- +
{{GamesSidebar}}
{{IncludeSubnav("/en-US/docs/Games")}}
+ +
+

На этой странице вы можете найти ссылки на наши статьи по инструментам для разработки игр, которая в конечном итоге нацелена на покрытие фреймворков, компиляторов и инструментов отладки.

+
+ +
+
asm.js
+
asm.js это очень ограниченное подмножество языка JavaScript, которое можно значительно оптимизировать и запустить в опережающем времени (AOT), компилируя движок гораздо быстрее, чем при типичной произвоительности языка. А это, конечно же, замечательно для игр.
+
Emscripten
+
+

Низккоуровневя виртуальная машина(LLVM) для JavaScript; с Emscripten вы можете компилировать C++ и другие языки, которые можно копировать в байткод LLVM с высокоц производительностью JavaScript. Это отличный веб-инструмент! Вот полезный туториал по Emscripten, доступный на вики. Заметьте, что мы стремимся охватить Emscripten в своих разделах на MDN.

+
+
Gecko profiler
+
Gecko profiler позволяет профилировать код, чтобы понять, где имеются проблемы производительности, и добиться максимальной скорости в .
+
Игровые движки и инструменты
+
Список движков, шаблонов и технологий, полезных для разработчиков.
+
Shumway
+
Shumway это рендер для Adobe Flash построенный полностью на JavaScript, WebGL, etc., преодолевающий разрыв между Flash и web-стандартами. Это статья поясняет, как пользоваться Shumway,и как вносить исправления в проекте.
+
Инструментарий для разработки и отладки игр
+
Чем это отличается от обычной отладки веб-приложения? Какие специальные инструменты доступны? Многое из этого доступно в инструментах, но здесь мы должны обеспечить своего рода практический учебник для отладки игры, с ссылками : +
    +
  • Обзор базовых инстурментов
  • +
  • Редактор шейдеров
  • +
  • Производственные инструменты (все еще находятся в производстве, по оценкам, в начале 2014 года)
  • +
+
+
diff --git a/files/ru/games/tutorials/2d_breakout_game_phaser/bounce_off_the_walls/index.html b/files/ru/games/tutorials/2d_breakout_game_phaser/bounce_off_the_walls/index.html new file mode 100644 index 0000000000..aedabaaf25 --- /dev/null +++ b/files/ru/games/tutorials/2d_breakout_game_phaser/bounce_off_the_walls/index.html @@ -0,0 +1,42 @@ +--- +title: Отскакивания +slug: Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Bounce_off_the_walls +translation_of: Games/Tutorials/2D_breakout_game_Phaser/Bounce_off_the_walls +--- +
{{GamesSidebar}}
+ +
{{IncludeSubnav("/ru/docs/")}}
+ +

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Physics", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Платформа_и_управление")}}

+ +
+

Это 6 урок из 16 Руководства разработки игры с помощью Phaser. Вы можете найти исходный код того как должен выглядеть код после завершения урока здесь: Gamedev-Phaser-Content-Kit/demos/lesson06.html.

+
+ +

Теперь, когда мы познакомились с физикой, мы можем начать реализовывать определение столкновений в игре — сначала посмотрим на "стены".

+ +

Отскакивание от границ представления

+ +

Самый простой способ заставить мячик от стен это сообщить фреймворку что мы хотим рассматривать границы элемента {{htmlelement("canvas")}} как стены и не позволять мячу проходить через них. В Phaser это может быть просто реализовано с помощью свойства collideWorldsBound. Добавьте этот код сразу после существующего вызова метода game.physics.enable():

+ +
ball.body.collideWorldBounds = true;
+
+ +

Теперь мяч будет останавливаться у границ экрана, вместо того чтобы исчезать, но он не отскакивает. Чтобы это происодило нам нужно установить его "отскакиваемость". Добавте следующий код ниже предыдущей строки:

+ +
ball.body.bounce.set(1);
+
+ +

Попробуйте перезагрузить index.html опять — теперь мяч отскакивает от стен и движется внутри холста canvas.

+ +

Сравните ваш код

+ +

Вы можете сравнить получившийся код из этого урока в превью и поиграть с ним, чтобы лучше понять как он работает:

+ +

{{JSFiddleEmbed("https://jsfiddle.net/end3r/dcw36opz/","","400")}}

+ +

Следующие шаги

+ +

Это начинает больше походить на игру, но мы никак не можем её контролировать — самое время добавить рычаги управления для игрока.

+ +

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Physics", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Платформа_и_управление")}}

diff --git a/files/ru/games/tutorials/2d_breakout_game_phaser/build_the_brick_field/index.html b/files/ru/games/tutorials/2d_breakout_game_phaser/build_the_brick_field/index.html new file mode 100644 index 0000000000..ffdd6c1d6d --- /dev/null +++ b/files/ru/games/tutorials/2d_breakout_game_phaser/build_the_brick_field/index.html @@ -0,0 +1,156 @@ +--- +title: Создание кирпичей +slug: Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Создание_кирпичей +translation_of: Games/Tutorials/2D_breakout_game_Phaser/Build_the_brick_field +--- +
{{GamesSidebar}}
+ +
{{IncludeSubnav("/ru/docs/Games")}}
+ +

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Game_over", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Обработка_коллизий")}}

+ +
+

Это из 16 уроков руководства разработки игры с помощью Phaser. Исходный код этого урока вы можете найти здесь:  Gamedev-Phaser-Content-Kit/demos/lesson09.html.

+
+ +

Создать поле кирпичей немного сложнее, чем просто добавить объект на экран, но всё же, благодаря Phaser, нам будет полегче, по сравнению с чистым JavaScript. Давайте разберёмся, как создать набор кирпичей и нарисовать их всех, используя цикл.

+ +

Определяем переменные

+ +

Сначала, давайте определим необходимые переменные — добавьте следующий код ниже всех наших текущих опеределений переменных:

+ +
var bricks;
+var newBrick;
+var brickInfo;
+
+ +

Переменная bricks будет использоваться в качестве набора кирпичей, newBrick будет тем самым кирпичем, который мы будем создавать в каждой итерации цикла и добавлять в набор, а в brickInfo будет хранить всю необходимую информацию о кирпичах, как таковых.

+ +

Добавляем графику для кирпича

+ +

Далее, давайте загрузим изображение кирпича brick, при помощи ещё одного вызова функции load.image():

+ +
function preload() {
+    // ...
+    game.load.image('brick', 'img/brick.png');
+}
+
+ +

Не забудьте скачать изображение кирпича с Github в папку /img.

+ +

Рисуем кирпичи

+ +

Для удобства, давайте вынесем код отрисовки кирпичей в отдельную функцию initBricks и вызовем её в конце функции create():

+ +
function create(){
+    // ...
+    initBricks();
+}
+
+ +

Теперь перейдём непосредственно к самой функции. Добавим функцию initBricks() в самый конец нашего кода, прямо перед </script>, а в теле этой функции опишем объект brickInfo, который нам скоро понадобится:

+ +
function initBricks() {
+    brickInfo = {
+        width: 50,
+        height: 20,
+        count: {
+            row: 3,
+            col: 7
+        },
+        offset: {
+            top: 50,
+            left: 60
+        },
+        padding: 10
+    };
+}
+
+ +

Объект brickInfo содержит всю необходимую нам информацию о кирпичах: ширина и высота кирпичика, количество рядов и столбцов кирпичей, которые мы хотим отрисовать на игровом поле, отступы от левого и верхнего края экрана (место на <canvas>, откуда мы начнём располагать кирпичи) и зазоры между самими кирпичами.

+ +

А теперь, собственно, к кирпичам — инициализируйте пустой набор для хранения кирпичей, путём добавления следующей строчки кода в функцию initBricks():

+ +
bricks = game.add.group();
+
+ +

Далее переберём в цикле ряды и столбцы — добавьте следующий код со вложенным циклом после предыдущей строки:

+ +
for(c=0; c<brickInfo.count.col; c++) {
+    for(r=0; r<brickInfo.count.row; r++) {
+        // create new brick and add it to the group
+    }
+}
+
+ +

Теперь необходимо в каждой итерации создавать кирпич, чтобы получить необходимое число кирпичей, нарисовать их всех на экране и добавить в наш набор bricks. Для этого добавим во вложенный цикл немного кода, как показано ниже:

+ +
for(c=0; c<brickInfo.count.col; c++) {
+    for(r=0; r<brickInfo.count.row; r++) {
+        var brickX = 0;
+        var brickY = 0;
+        newBrick = game.add.sprite(brickX, brickY, 'brick');
+        game.physics.enable(newBrick, Phaser.Physics.ARCADE);
+        newBrick.body.immovable = true;
+        newBrick.anchor.set(0.5);
+        bricks.add(newBrick);
+    }
+}
+
+ +

Вот мы и создали новый кирпич в каждой итерации и отрисовали его на экране. Как мы помним из урока 5, мы используем движок Arcade Physics. К каждому новому кирпичу применяем физику из этого движка и делаем его неподвижным, чтобы мячик его не сбивал, а, также, устанавливаем якорь кирпича в его середину. После этого, добавляем кирпич в набор bricks.

+ +

Но у нас осталась проблема — все кирпичи мы рисуем в одном и том же месте, в координатах (0,0). Чтобы это исправить, давайте добавим вычисление координат brickX и brickY в каждой итерации. Обновите строки инициализации этих переменных, как показано ниже:

+ +
var brickX = (c*(brickInfo.width+brickInfo.padding))+brickInfo.offset.left;
+var brickY = (r*(brickInfo.height+brickInfo.padding))+brickInfo.offset.top;
+
+ +

Координата x каждого кирпича рассчитывается на основе суммы ширины кирпича brickInfo.width и зазора brickInfo.padding, умноженной на номер столбца с, после этого добавляем отступ от левого края brickInfo.offset.left; Рассчёт y аналогичен, только используются номер ряда r, высота кирпича brickInfo.height и отступ от верхнего края brickInfo.offset.top. Вот теперь каждый кирпич на своём месте, с учётом всех отступов и зазоров.

+ +

Проверяем код функции initBricks()

+ +

Вот итоговый код функции initBricks():

+ +
function initBricks() {
+    brickInfo = {
+        width: 50,
+        height: 20,
+        count: {
+            row: 3,
+            col: 7
+        },
+        offset: {
+            top: 50,
+            left: 60
+        },
+        padding: 10
+    }
+    bricks = game.add.group();
+    for(c=0; c<brickInfo.count.col; c++) {
+        for(r=0; r<brickInfo.count.row; r++) {
+            var brickX = (c*(brickInfo.width+brickInfo.padding))+brickInfo.offset.left;
+            var brickY = (r*(brickInfo.height+brickInfo.padding))+brickInfo.offset.top;
+            newBrick = game.add.sprite(brickX, brickY, 'brick');
+            game.physics.enable(newBrick, Phaser.Physics.ARCADE);
+            newBrick.body.immovable = true;
+            newBrick.anchor.set(0.5);
+            bricks.add(newBrick);
+        }
+    }
+}
+
+ +

Если вы перезапустите страницу index.html, то увидете кирпичи, нарисованные на расстоянии друг от друга.

+ +

Сравните свой код

+ +

Вы можете проверить код из этого урока и поиграть с ним, чтобы лучше понять, как он работает:

+ +

{{JSFiddleEmbed("https://jsfiddle.net/end3r/cck2b9e8/","","400")}}

+ +

Следующий шаг

+ +

Кажется, что-то не так. Ах да! Мячик же проходит сквозь кирпичи. Добавим обработку коллизий.

+ +

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Game_over", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Обработка_коллизий")}}

diff --git a/files/ru/games/tutorials/2d_breakout_game_phaser/collision_detection/index.html b/files/ru/games/tutorials/2d_breakout_game_phaser/collision_detection/index.html new file mode 100644 index 0000000000..e3fb27724b --- /dev/null +++ b/files/ru/games/tutorials/2d_breakout_game_phaser/collision_detection/index.html @@ -0,0 +1,52 @@ +--- +title: Обработка коллизий +slug: Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Обработка_коллизий +translation_of: Games/Tutorials/2D_breakout_game_Phaser/Collision_detection +--- +
{{GamesSidebar}}
+ +
{{IncludeSubnav("/ru/docs")}}
+ +

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Создание_кирпичей", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Очки")}}

+ +
+

Это 10 из 16 уроков руководства разработки игры с помощью Phaser. Исходный код этого урока вы можете найти здесь:  Gamedev-Phaser-Content-Kit/demos/lesson10.html.

+
+ +

Наша текущая задач — проверка коллизий между мячиком и кирпичами. К счастью, при помощи движка, мы можем проверить коллизии не только между двумя объектами (как это было с мячиком и платформой), но и между объектом и набором других объектов.

+ +

Проверяем коллизии Мячик/Кирпич

+ +

Физический движок облегчает очень многие задачи — нам понадобится, всего лишь, несколько простых кусочков кода. Для начала, добавим в функцию update() строчку проверки коллизий между мячиком и кирпичами, как показано ниже:

+ +
function update() {
+    game.physics.arcade.collide(ball, paddle);
+    game.physics.arcade.collide(ball, bricks, ballHitBrick);
+    paddle.x = game.input.x || game.world.width*0.5;
+}
+
+ +

Теперь будет отслеживаться положение мячика, относительно всех кирпичей из набора bricks. Третьим (опциальным) параметром, мы передаём функцию, которая будет выполняться каждый раз, когда будет найдена коллизия — ballHitBrick. Давайте создадим эту функцию в самом конце нашего кода, прямо перед </script>:

+ +
function ballHitBrick(ball, brick) {
+    brick.kill();
+}
+
+ +

Вот и всё! Перезагрузите страницу и вы увидите, что все коллизии обрабатывается, как следует.

+ +

Спасибо Phaser за то, что передал нам в функцию эти два параметра — мячик и тот кирпич, с которым у мячика произошла коллизия. А дальше мы просто удаляем кирпчи с экрана, вызвав у него функцию kill().

+ +

Вы думали, что нам придётся писать много кода для отслеживания коллизий, как мы это делали на чистом JavaScript? В этом и прелесть фреймворков — рутину они сделают за нас, а мы, в это время, можем сосредоточиться на действительно интересных вещах.

+ +

Сравните свой код

+ +

Вы можете проверить код из этого урока и поиграть с ним, чтобы лучше понять, как он работает:

+ +

{{JSFiddleEmbed("https://jsfiddle.net/end3r/wwneakwf/","","400")}}

+ +

Следующий шаг

+ +

Теперь мы можем разбивать кирпичи, а это уже отличное дополнение к нашему геймплею. Будет ещё лучше, если мы сможем считать количество разбитых кирпичей и присуждать за это очки.

+ +

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Создание_кирпичей", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Очки")}}

diff --git a/files/ru/games/tutorials/2d_breakout_game_phaser/extra_lives/index.html b/files/ru/games/tutorials/2d_breakout_game_phaser/extra_lives/index.html new file mode 100644 index 0000000000..b6bb403469 --- /dev/null +++ b/files/ru/games/tutorials/2d_breakout_game_phaser/extra_lives/index.html @@ -0,0 +1,117 @@ +--- +title: Жизни +slug: Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Жизни +translation_of: Games/Tutorials/2D_breakout_game_Phaser/Extra_lives +--- +
{{GamesSidebar}}
+ +
{{IncludeSubnav("/ru/docs")}}
+ +

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Победа", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Анимация")}}

+ +
+

Это 12 из 16 уроков руководства разработки игры с помощью Phaser. Исходный код этого урока вы можете найти здесь:  Gamedev-Phaser-Content-Kit/demos/lesson13.html.

+
+ +

Мы можем растянуть удовольствие от игры, добавив жизни. Это позволит игроку сделать несколько попыток, а не одну.

+ +

Новый переменные

+ +

Добавьте следующие переменные сразу после всех наших текущих опеределений переменных:

+ +
var lives = 3;
+var livesText;
+var lifeLostText;
+
+ +

Эти переменные хранят, соответственно, количество жизней, надпись с количеством оставшихся жизней, и надпись, которая выведется на экран, если игрок потеряет жизнь.

+ +

Определяем новые надписи

+ +

Надписи мы уже определяли, когда реализовывали систему очков. Добавьте следующие строки кода в после определения надписи scoreText в функции create():

+ +
livesText = game.add.text(game.world.width-5, 5, 'Lives: '+lives, { font: '18px Arial', fill: '#0095DD' });
+livesText.anchor.set(1,0);
+lifeLostText = game.add.text(game.world.width*0.5, game.world.height*0.5, 'Life lost, click to continue', { font: '18px Arial', fill: '#0095DD' });
+lifeLostText.anchor.set(0.5);
+lifeLostText.visible = false;
+
+ +

Объекты livesText иlifeLostText очень похожи на scoreText — они определяют положение на экране, текст надписи и стилизацию шрифта. Чтобы всё выглядило должным образом, надпись с жизнями мы закрепляем в правом верхнем углу, а надпись о потере жизни, мы выводим в центре экрана. И всё это при помощи функции anchor.set().

+ +

Надпись lifeLostText появится только при потере жизни, поэтому её видимость мы выставляем в false.

+ +

Чистим код, стилизирующий надписи

+ +

Как вы могли заметить, мы используем одинаковые стили для всех надписей: scoreText, livesText и lifeLostText. Однако, налицо копирование кода и если мы, когда-либо, захотим изменить размер шрифта или цвет, то нам придётся делать это в нескольких местах. Чтобы избежать этого, мы вынесем стиль в отдельную переменную. Напишите следующую строку сразу после всех наших текущих опеределений переменных:

+ +
var textStyle = { font: '18px Arial', fill: '#0095DD' };
+
+ +

Теперь мы можем использовать эту переменную для нашего текста — обновите ваш код и замените повторяющиеся участки со стилем текста на переменную.

+ +
scoreText = game.add.text(5, 5, 'Points: 0', textStyle);
+livesText = game.add.text(game.world.width-5, 5, 'Lives: '+lives, textStyle);
+livesText.anchor.set(1,0);
+lifeLostText = game.add.text(game.world.width*0.5, game.world.height*0.5, 'Life lost, click to continue', textStyle);
+lifeLostText.anchor.set(0.5);
+lifeLostText.visible = false;
+
+ +

Теперь, чтобы изменить стиль всего текста в игре, достаточно изменить только эту переменную.

+ +

Код обработки жизни

+ +

Чтобы реализовать жизнь в нашей игре, давайте сначала изменим функцию шара, связанную с событием onOutOfBounds. Вместо того, чтобы выполнять анонимную функцию и сразу показывать сообщение:

+ +
ball.events.onOutOfBounds.add(function(){
+    alert('Game over!');
+    location.reload();
+}, this);
+
+ +

Мы объявим новую функцию ballLeaveScreen; Удалим предыдущий обработчик (зачёркнутый код сверху) и заменим его следующей линией:

+ +
ball.events.onOutOfBounds.add(ballLeaveScreen, this);
+
+ +

Мы будем уменьшать количество жизней каждый раз, когда шар выйдет за пределы окна Canvas. Добавьте функцию ballLeaveScreen() в конец кода:

+ +
function ballLeaveScreen() {
+    lives--;
+    if(lives) {
+        livesText.setText('Lives: '+lives);
+        lifeLostText.visible = true;
+        ball.reset(game.world.width*0.5, game.world.height-25);
+        paddle.reset(game.world.width*0.5, game.world.height-5);
+        game.input.onDown.addOnce(function(){
+            lifeLostText.visible = false;
+            ball.body.velocity.set(150, -150);
+        }, this);
+    }
+    else {
+        alert('You lost, game over!');
+        location.reload();
+    }
+}
+
+ +

Вместо того, чтобы сразу вызывать сообщение, когда мяч выходит за пределы Canvas, мы сначала вычитаем одну жизнь из текущего числа и проверяем, не равно ли оно нулю. Если не равно, то у игрока все еще осталось несколько жизней, и он может продолжать играть - он увидит сообщение о потере жизни, позиции мяча и платформы будут сброшены и при следующем клике мышью сообщение будет скрыто и мяч снова начнет двигаться.

+ +

Когда количество жизней достигнет нуля игра заканчивается, а игроку показывается соответствующее сообщение.

+ +

События

+ +

Скорее всего вы заметили вызов методов add() и addOnce() в двух блоках кода выше и хотите знать, чем они отличаются. Разница в том, что метод add()  и привязанная к нему функция выполняется каждый раз, когда выполняется событие, тогда как метод  addOnce() полезен, когда вы хотите, чтобы связанная с ним функция выполнилась единожды и не повторялась снова. В нашем случае при каждом событии outOfBounds будет выполняться ballLeaveScreen, но когда мяч покидает экран, сообщение с экрана удалится единожды.

+ +

Проверь свой код

+ +

Вы можете проверить готовый код этого урока в его демо-версии и поиграть с ним чтобы лучше понять, как он работает:

+ +

{{JSFiddleEmbed("https://jsfiddle.net/end3r/yk1c5n0b/","","400")}}

+ +

Следующий шаг

+ +

Жизни делают игру более казуальной — даже если вы проиграете единожды, у вас будут еще 2 жизни и вы сможете продолжить игру. Теперь мы можем поработать над внешним видом игры, сделать ее более красивой, добавив анимацию и эффекты .

+ +

{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Win_the_game", "Games/Workflows/2D_Breakout_game_Phaser/Animations_and_tweens")}}

diff --git a/files/ru/games/tutorials/2d_breakout_game_phaser/game_over/index.html b/files/ru/games/tutorials/2d_breakout_game_phaser/game_over/index.html new file mode 100644 index 0000000000..a617f8969d --- /dev/null +++ b/files/ru/games/tutorials/2d_breakout_game_phaser/game_over/index.html @@ -0,0 +1,46 @@ +--- +title: Game over +slug: Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Game_over +translation_of: Games/Tutorials/2D_breakout_game_Phaser/Game_over +--- +
{{GamesSidebar}}
+ +
{{IncludeSubnav("/ru/docs/Games")}}
+ +

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Платформа_и_управление", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Создание_кирпичей")}}

+ +
+

Это из 16 уроков руководства разработки игры с помощью Phaser. Исходный код этого урока вы можете найти здесь:  Gamedev-Phaser-Content-Kit/demos/lesson08.html.

+
+ +

Чтобы разнообразить игру, давайте добавим возможность проигрыша — если вы не отобьете мячик и дадите ему упасть на пол, то game over.

+ +

Проигрыш

+ +

Чтобы добавить возможность проигрыша, давай те отключим определение коллизии с нижней гранью экрана. Добавьте следующую строку кода в функцию create(), сразу после кода инициализации всех атрибутов мячика:

+ +
game.physics.arcade.checkCollision.down = false;
+
+ +

Теперь мячик отскакивает только от трёх стен (верхней, левой и правой) и, если не отбить его платформой, проходит сквозь нижнюю стену, выходя за пределы экрана. Осталось только поймать момент выхода мячика за пределы экрана и вывести сообещние о проигрыше. Добавьте эти строки кода сразу после предыдущей:

+ +
ball.checkWorldBounds = true;
+ball.events.onOutOfBounds.add(function(){
+    alert('Game over!');
+    location.reload();
+}, this);
+
+ +

Мы сделали так, чтобы мячик проверял границы игрового мира (в нашем случае границы <canvas>) и, в случае выхода за их пределы (событие onOutOfBounds), выполнял функцию, которую мы привязали к этому событию. После закрытия всплывающего окна с сообщением 'Game over!', происходит перезагрузка страницы, чтобы можно было сыграть снова.

+ +

Сравните свой код

+ +

Вы можете проверить код из этого урока и поиграть с ним, чтобы лучше понять, как он работает:

+ +

{{JSFiddleEmbed("https://jsfiddle.net/end3r/436bckb7/","","400")}}

+ +

Следующий шаг

+ +

Базовый геймплей готов. Но какой арканоид без разбивания кирпичиков

+ +

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Платформа_и_управление", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Создание_кирпичей")}}

diff --git a/files/ru/games/tutorials/2d_breakout_game_phaser/index.html b/files/ru/games/tutorials/2d_breakout_game_phaser/index.html new file mode 100644 index 0000000000..05a0439cc7 --- /dev/null +++ b/files/ru/games/tutorials/2d_breakout_game_phaser/index.html @@ -0,0 +1,64 @@ +--- +title: 2D игра на Phaser +slug: Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser +tags: + - 2D + - Canvas + - JavaScript + - Phaser + - Игры + - Начинающий + - Руководство + - туториал +translation_of: Games/Tutorials/2D_breakout_game_Phaser +--- +
{{GamesSidebar}}
+ +
{{IncludeSubnav("/ru/docs/")}}
+ +

{{Next("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Initialize_the_framework")}}

+ +

В этом пошаговом руководстве мы создадим простую мобильную игру MDN Breakout с помощью JavaScript и фреймворка Phaser.

+ +

Каждый шаг будет сопровождаться настраиваемым и живым примером для того, чтобы вы могли видеть, что должно получиться на промежуточных этапах создания. Вы узнаете основы для работы с фреймворком Phaser: рендер и движение картинок, определение столкновения, управление, встроенные вспомогательныке функции, анимации и отрисовка кадров, изменение игровой статистки.  

+ +

Чтобы получить наибольшую пользу от этого руководства, вам необходимо иметь базовые знания JavaScript. После прочтения вы научитесь создавать собственные простые веб-игры с помощью Phaser.

+ +

Gameplay screen from the game MDN Breakout created with Phaser where you can use your paddle to bounce the ball and destroy the brick field, with keeping the points and lives.

+ +

Дополнительно

+ +

Все уроки и различные версии MDN Breakout, которые мы сделаем вместе, доступны на GitHub

+ +
    +
  1. Инициализация фреймворка
  2. +
  3. Масштабирование
  4. +
  5. Загрузка ресурсов и их вывод
  6. +
  7. Движение мяча
  8. +
  9. Физика
  10. +
  11. Отскакивание от стен
  12. +
  13. Управление
  14. +
  15. Конец игры
  16. +
  17. Создание поля блоков
  18. +
  19. Определение столкновения
  20. +
  21. Счёт
  22. +
  23. Победа в игре
  24. +
  25. Добавление жизней
  26. +
  27. Анимация
  28. +
  29. Кнопки
  30. +
  31. Создание случайных событий
  32. +
+ +

Также мы хотели бы заметить, что лучший способ научиться создавать веб-игры - это чистый (pure) JavaScript. Если вы ещё не знакомы с разработкой на чистом JavaScript, то мы предлагаем вам первым делом пройти туториал 2D игра на чистом JavaScript.

+ +

После этого вы можете выбрать любой фреймворк и использовать его в своих проектах. Мы выбрали Phaser, потому что это прочный фреймворк с хорошей поддержкой, открытым сообществом и набором различных плагинов. Фреймворки ускоряют разработку и заботятся о скучных вещах, позволяя вам сосредоточиться на самом весёлом. Однако они не идеальны, так что если что-то пойдёт не так или вы захотите написать функцию, которую фреймворк не поддерживает, то вам пригодятся знания чистого JavaScript.

+ +
+

Примечание: Эта серия статей может быть использована, как материал для создания игр в мастерских разработчиков. Также вы можете использовать Gamedev Phaser Content, который сделан на основе этого руководства, если захотите углубиться в разработку игр с помощью Phaser.

+
+ +

Следующие шаги

+ +

Давайте начнём! Первая часть руководства — это Инициализация фреймворка.

+ +

{{Next("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Initialize_the_framework")}}

diff --git a/files/ru/games/tutorials/2d_breakout_game_phaser/initialize_the_framework/index.html b/files/ru/games/tutorials/2d_breakout_game_phaser/initialize_the_framework/index.html new file mode 100644 index 0000000000..bf1fac5bfc --- /dev/null +++ b/files/ru/games/tutorials/2d_breakout_game_phaser/initialize_the_framework/index.html @@ -0,0 +1,95 @@ +--- +title: Инициализация фреймворка +slug: Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Initialize_the_framework +tags: + - 2D + - Canvas + - HTML + - JavaScript + - Phaser + - Игры + - Руководство +translation_of: Games/Tutorials/2D_breakout_game_Phaser/Initialize_the_framework +--- +
{{GamesSidebar}}
+ +
{{IncludeSubnav("ru/docs/")}}
+ +

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Scaling")}}

+ +
+

Это первый из 16 уроков о том, как пользоваться Gamedev Phaser. После прочтения вы можете найти исходный код для этого урока на Gamedev-Phaser-Content-Kit/demos/lesson01.html.

+
+ +

Перед тем, как мы начнём разрабатывать функционал игры, нам нужно создать базовую структуру, чтобы рендерить её. Это может быть сделано с помощью HTML:  фреймворк Phaser создаст обязательный элемент {{htmlelement("canvas")}}.

+ +

HTML-код игры

+ +

Структура HTML-документа достаточно простая. Игра будет отображаться в элементе {{htmlelement("canvas")}}, который будет сгенерирован фреймворком. Используя свой любимый редактор, создайте новый HTML-документ, сохраните его как index.html и добавьте в него следующий код:

+ +
<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8" />
+    <title>Gamedev Phaser Workshop - lesson 01: Initialize the framework</title>
+    <style>* { padding: 0; margin: 0; }</style>
+    <script src="js/phaser.min.js"></script>
+</head>
+<body>
+<script>
+    var game = new Phaser.Game(480, 320, Phaser.CANVAS, null, {
+      preload: preload, create: create, update: update
+    });
+    function preload() {}
+    function create() {}
+    function update() {}
+</script>
+</body>
+</html>
+
+ +

Загрузка Phaser

+ +

Дальше мы должны скачать исходный код фреймворка Phaser и использовать его в нашем HTML-документе. Это руководство использует Phaser V2, который не будет работать с текущей версией Phaser V3. Ссылка на скачивание Phaser V2 доступна в разделе Archive. 

+ +
    +
  1. Перейдите на страницу загрузки Phaser.
  2. +
  3. Выберите наиболее удобный для вас вариант загрузки. Я рекоммендую min.js скачивание, потому что исходный код будет меньше, да и вам не придётся разбираться в нём.
  4. +
  5. Сохраните Phaser внутри /js директории, находящейся в том же месте, что и index.html
  6. +
  7. Обновите аттрибут src в первом элементе {{htmlelement("script")}}, как это показано выше.
  8. +
+ +

Что мы имеем

+ +

На данный момент у нас есть обозначенный charset, {{htmlelement("title")}} и немного CSS, что убрать значения свойств margin и padding по умолчанию. Также мы добавили элемент {{htmlelement("script")}}, который позволяет использовать Phaser на странице. Во втором {{htmlelement("script")}} мы написали код, который позволит отображать игру и управлять ею. 

+ +

Фреймворк автоматически создаёт элемент {{htmlelement("canvas")}}. Мы инициализировали его, создав новый Phaser.Game объект и присвоив его переменной. Также мы добавили параметры:

+ + + +
+

Важно: До конца прохождения всех уроков вы должны использовать CANVAS, как метод рендеринга, а не AUTO, как это было в нашем коде. Всё это нужно, потому что метод AUTO больше не поддерживается в последних версиях браузера.

+
+ +

Сравните свой код

+ +

Это весь исходный код, который мы написали на этом уроке:

+ +

{{JSFiddleEmbed("https://jsfiddle.net/end3r/h6cwzv2b/","","400")}}

+ +

Следующее

+ +

Мы создали базовую HTML структуру и узнали немного об инициализации Phaser. Давайте продолжим и узнаем про масштабирование.

+ +

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Scaling")}}

diff --git a/files/ru/games/tutorials/2d_breakout_game_phaser/load_the_assets_and_print_them_on_screen/index.html b/files/ru/games/tutorials/2d_breakout_game_phaser/load_the_assets_and_print_them_on_screen/index.html new file mode 100644 index 0000000000..57274a84c0 --- /dev/null +++ b/files/ru/games/tutorials/2d_breakout_game_phaser/load_the_assets_and_print_them_on_screen/index.html @@ -0,0 +1,73 @@ +--- +title: Загрузка ресурсов и их вывод +slug: >- + Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Load_the_assets_and_print_them_on_screen +tags: + - 2D + - Canvas + - JavaScript + - Phaser +translation_of: >- + Games/Tutorials/2D_breakout_game_Phaser/Load_the_assets_and_print_them_on_screen +--- +
{{GamesSidebar}}
+ +
{{IncludeSubnav("/ru/docs/Games")}}
+ +

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Scaling", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Move_the_ball")}}

+ +
+

Это 3-й урок из 16 в руководстве 2D игра на Phaser. Весь исходный код из этого урока вы можете найти на Gamedev-Phaser-Content-Kit/demos/lesson03.html.

+
+ +

В нашей игре будет мяч, который движется по экрану, отскакивает от стен и уничтожает блоки, чтобы заработать очки. Знакомо? В этом уроке мы посмотрим, как добавлять спрайты в наш игровой мир.

+ +

Создание мяча

+ +

Давайте начнём с создания JavaScript переменной для нашего мячика. Добавьте следующий код между строкой инициализации (var game...) и функцией preload():

+ +
var ball;
+
+ +
+

Примечание: В этом уроке мы для удобства будем использовать глобальные переменные, потому что цель урока - научить пользоваться Phaser для создания игр, а не хорошим практикам разработки.

+
+ +

Загрузка спрайта мяча

+ +

Загрузка и вывод изображений в canvas намного проще с использованием Phaser, чем чистым JavaScript. Чтобы загрузить спрайт, мы будем использовать метод load.image() объекта game. Добавьте новую строку кода в функцию preload():

+ +
function preload() {
+    // ...
+    game.load.image('ball', 'img/ball.png');
+}
+
+ +

Первым параметром, которому мы хотим присвоить имя картинки, является имя, которое будет использоваться в нашем игровом коде - например, в нашем имени переменной ball - поэтому мы должны убедиться, что оно совпадает. Второй параметр - это относительный путь к самой картинке, мы загружаем спрайт для нашего мяча. (Заметьте, что имя файла (asset) не обязано совпадать с именем переменной, которой оно присваивается, однако так проще).

+ +

Конечно, чтобы загрузить картинку, она должна находиться в нашей рабочей директории. Скачайте изображение с GitHub и сохраните его в /img директории, которая находится там же, где и файл index.html.

+ +

Теперь, чтобы вывести наш мяч на экран, мы используем другой метод add.sprite(). Добавьте следующую строку кода в функцию create():  

+ +
function create() {
+    ball = game.add.sprite(50, 50, 'ball');
+}
+
+ +

Это метод добавит мяч в игру и выведет его на экран. Первые два параметра — это координаты x и y элемента canvas соответственно, и последний параметр — это имя картинки, которое мы добавили раннее. Вот и всё: загрузите index.html, и вы увидите, что картинка уже загружена и выведена в canvas!

+ +
+

Важно: Если вы храните ваш JavaScript код отдельно от HTML и используете файл для этого, например, game.js, тогда вам нужно расположить директорию img и JavaScript файл в одной папке, иначе картинка не загрузится. 

+
+ +

Сравните свой код

+ +

Вы можете проверить код из этого урока и поиграть с ним, чтобы лучше понять, как он работает:

+ +

{{JSFiddleEmbed("https://jsfiddle.net/end3r/98xrv9x5/","","400")}}

+ +

Следующее

+ +

Вывод мяча на экран был достаточно прост, теперь попробуем переместить его.

+ +

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Scaling", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Move_the_ball")}}

diff --git a/files/ru/games/tutorials/2d_breakout_game_phaser/move_the_ball/index.html b/files/ru/games/tutorials/2d_breakout_game_phaser/move_the_ball/index.html new file mode 100644 index 0000000000..deed4a9494 --- /dev/null +++ b/files/ru/games/tutorials/2d_breakout_game_phaser/move_the_ball/index.html @@ -0,0 +1,48 @@ +--- +title: Движение мяча +slug: Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Move_the_ball +tags: + - 2D + - Beginner + - Canvas + - JavaScript + - Phaser +translation_of: Games/Tutorials/2D_breakout_game_Phaser/Move_the_ball +--- +
{{GamesSidebar}}
+ +
{{IncludeSubnav("/ru/docs/")}}
+ +

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Load_the_assets_and_print_them_on_screen", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Physics")}}

+ +
+

Это 4-й урок из 16, которые входят в руководство 2D игра на Phaser. Вы можете найти исходный код этого урока на Gamedev-Phaser-Content-Kit/demos/lesson04.html.

+
+ +

У нас есть синий мячик на экране, но он ничего не делает, поэтому будет круто, если он начнёт двигаться. В этом уроке мы узнаем, как это сделать.

+ +

Обновление позиции мяча на каждом кадре

+ +

Помните функцию update() и её назначение? Код внутри этой функции выполняется на каждом кадре, так что это идеальное место для кода, который будет обновлять положение нашего мяча. Добавьте следующие строки внутри update():

+ +
function update() {
+    ball.x += 1;
+    ball.y += 1;
+}
+
+ +

Код выше добавляет 1 к свойствам x и y, которые отвечают за координаты мяча в canvas на каждом кадре. Перезагрузив index.html, вы должны увидеть, как наш мячик движется. 

+ +

Сравните свой код

+ +

Вы можете проверить код из этого урока и поиграть с ним, чтобы лучше понять, как он работает:

+ +

{{JSFiddleEmbed("https://jsfiddle.net/end3r/g1cfp0vv/","","400")}}

+ +

Следующее

+ +

Дальше мы должны добавить обнаружение столкновения мяча со стенками так, чтобы он отскакивал от них. Для этого нужно несколько строк кода, но дальше будет сложнее, особенно если мы хотим добавить обработку столкновений мяча и платформы. К счастью, Phaser позволяет нам делать всё это проще, чем если бы мы использовали чистый JavaScript.

+ +

В любом случае перед тем, как сделать это, мы рассмотрим физический движок Phaser. 

+ +

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Load_the_assets_and_print_them_on_screen", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Physics")}}

diff --git a/files/ru/games/tutorials/2d_breakout_game_phaser/physics/index.html b/files/ru/games/tutorials/2d_breakout_game_phaser/physics/index.html new file mode 100644 index 0000000000..20acffa239 --- /dev/null +++ b/files/ru/games/tutorials/2d_breakout_game_phaser/physics/index.html @@ -0,0 +1,98 @@ +--- +title: Физика +slug: Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Physics +tags: + - 2D + - Beginner + - Canvas + - JavaScript + - Phaser +translation_of: Games/Tutorials/2D_breakout_game_Phaser/Physics +--- +
{{GamesSidebar}}
+ +
{{IncludeSubnav("/ru/docs")}}
+ +

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Move_the_ball", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Bounce_off_the_walls")}}

+ +
+

Это 5 урок из 16, которые входят в руководство 2D игра на Phaser. Вы можете найти исходный код этого урока на Gamedev-Phaser-Content-Kit/demos/lesson05.html.

+
+ +

Для правильного определения столкновений нам необходима физика, и в этом уроке мы покажем, что есть у Phaser на этот счёт, продемонстрировав это на простом примере.

+ +

Добавление физики

+ +

В Phaser есть три разных физических движка: Arcade Physics, P2 и Ninja Physics. Также есть четвёртый Box2D как платный плагин. Для нашей простой игры мы будем использовать Arcade Physics, потому что нам не нужны сложные геометрические вычисления.

+ +

Во-первых, инициализируем Arcade Physics в нашей игре. Добавьте метод physics.startSystem() в начале функции create(). Убедитесь, что следующая строка кода находится в самом начале функции create():

+ +
game.physics.startSystem(Phaser.Physics.ARCADE);
+
+ +

Во-вторых, нам необходимо добавить мяч в физическую систему, потому что объект, отвечающий за физику в Phaser, не включен по умолчанию. Добавьте следующую строку в конце функции create()

+ +
game.physics.enable(ball, Phaser.Physics.ARCADE);
+
+ +

В-третьих, теперь мы можем установить значение свойства velocity нашего мяча через body. Добавьте следующую строку снова в конце функции create():

+ +
ball.body.velocity.set(150, 150);
+
+ +

Удаление предыдущих инструкций при обновлении

+ +

Теперь нам надо убрать старый код, который добавлял 1 к координатам x и y в функции update(): 

+ +
function update() {
+    ball.x += 1;
+    ball.y += 1;
+}
+
+ +

теперь мы сделали тоже самое, но на физическом движке.

+ +

Финальный код

+ +

Весь код должен выглядеть вот так:

+ +
var ball;
+
+function preload() {
+    game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
+    game.scale.pageAlignHorizontally = true;
+    game.scale.pageAlignVertically = true;
+    game.stage.backgroundColor = '#eee';
+    game.load.image('ball', 'img/ball.png');
+}
+
+function create() {
+    game.physics.startSystem(Phaser.Physics.ARCADE);
+    ball = game.add.sprite(50, 50, 'ball');
+    game.physics.enable(ball, Phaser.Physics.ARCADE);
+    ball.body.velocity.set(150, 150);
+}
+
+function update() {
+}
+
+ +

Снова перезагрузите index.html. Мячик должен постоянно двигаться в направлении, которое мы задали. На данный момент в физическом движке гравитация (gravity) и трение (friction) имеют нулевое значение. Добавление гравитации заставит мячик падать вниз, пока трение будет пытаться остановить его.

+ +

Поиграйте с физикой

+ +

Вы можете делать гораздо больше вещей с физикой. Например, добавив ball.body.gravity.y = 100, вы установите вертикальную гравитацию для мячика. Как результат он будет сначала запущен вверх, но затем начнёт падать, находясь под действием гравитации.

+ +

Это лишь верхушка айсберга: есть огромное количество перменных и функции, с помощью которых вы можете взаимодействовать с физическими объектами. Посмотрите официальную документацию, чтобы увидеть огромное количество примеров применения Arcade и P2.

+ +

Сравните свой код

+ +

Вы можете проверить код из этого урока и поиграть с ним, чтобы лучше понять, как он работает:

+ +

{{JSFiddleEmbed("https://jsfiddle.net/end3r/bjto9nj8/","","400")}}

+ +

Следующее

+ +

Теперь мы можем посмотреть, как заставить мяч отскакивать от стен.

+ +

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Move_the_ball", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Bounce_off_the_walls")}}

diff --git a/files/ru/games/tutorials/2d_breakout_game_phaser/player_paddle_and_controls/index.html b/files/ru/games/tutorials/2d_breakout_game_phaser/player_paddle_and_controls/index.html new file mode 100644 index 0000000000..46713cdddb --- /dev/null +++ b/files/ru/games/tutorials/2d_breakout_game_phaser/player_paddle_and_controls/index.html @@ -0,0 +1,116 @@ +--- +title: Платформа и управление +slug: Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Платформа_и_управление +translation_of: Games/Tutorials/2D_breakout_game_Phaser/Player_paddle_and_controls +--- +
{{GamesSidebar}}
+ +
{{IncludeSubnav("/ru/docs/")}}
+ +

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Bounce_off_the_walls", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Game_over")}}

+ +
+

Это из 16 уроков руководства разработки игры с помощью Phaser. Исходный код этого урока вы можете найти здесь: Gamedev-Phaser-Content-Kit/demos/lesson07.html.

+
+ +

Теперь, когда мы научили мячик двигаться и отскакивать от стен, давайте добавим немного геймплея. В этой главе мы создадим платформу-ракетку, которой будем отбивать наш мячик.

+ +

Рисуем платформу

+ +

С точки зрения фреймворка, платформа и мячик не сильно различаются - нам так же понадобится переменная для платформы, спрайт и немного магии.

+ +

Создаем платформу

+ +

Сначала, добавим переменную paddle, сразу после переменной ball:

+ +
var paddle;
+
+ +

После этого, в функции preload, загрузим изображение paddle при помощи ещё одного вызова функции load.image():

+ +
function preload() {
+    // ...
+    game.load.image('ball', 'img/ball.png');
+    game.load.image('paddle', 'img/paddle.png');
+}
+
+ +

Добавляем графику для платформы

+ +

Чуть не забыли, на этом этапе нам надо скачать изображение платформы с Github в папку /img.

+ +

Рисуем платформу с физикой

+ +

Далее, мы инициализируем спрайт нашей платформы при помощи функции add.sprite() — добавьте следующую строку кода в самый конец функции create():

+ +
paddle = game.add.sprite(game.world.width*0.5, game.world.height-5, 'paddle');
+
+ +

Мы можем использовать world.width и world.height для позиционирования платформы в том месте, где мы хотим: game.world.width*0.5 расположит платформу прямо по середине экрана. В данном случае, нам повезло, что наш игровой мир совпадает с <canvas>, однако, в других играх мир может быть гараздо больше экрана. 

+ +

Как вы могли заметить, перезагрузив, на данном этапе, страницу index.html, платформа находится не совсем по середине экрана. Почему? Всё дело в том, что, по умолчанию, точка, из которой начинается позиционирование объекта (якорь), находится в левом верхнем углу. Но мы можем это изменить и переместить якорь в середину платформы по ширине и в самый низ повысоте, чтобы проще было позиционировать платформу, относительно нижней грани экрана. Добавьте следующую строку кода:

+ +
paddle.anchor.set(0.5,1);
+
+ +

Платформу расположили там, где и хотели. Теперь, чтобы платформа могла взаимодействовать с мячиком, добавим ей физику. Добавьте следующую строку кода в самый низ функции create():

+ +
game.physics.enable(paddle, Phaser.Physics.ARCADE);
+
+ +

Вот и настало время для магии - фреймворк сам позаботится о проверке столкновений (коллизий) в каждом кадре. Для того, чтобы включить проверку коллизий между платформой и мячиком, вызовите функцию collide() в функции update() как показано ниже:

+ +
function update() {
+    game.physics.arcade.collide(ball, paddle);
+}
+
+ +

В качестве аргументов, мы передаём два объекта, между которыми проверяются коллизии — в нашем случае, мячик и платформа. Вроде, сработало, но не совсем так, как мы ожидали — когда мячик сталкивается с платформой, последняя падает за пределы экрана! А мы, всего лишь, хотим, чтобы мячик отскакивал от платформы, а платформа, при этом, оставалась на месте. Мы можем использовать свойство immovable, для того, чтобы платформа не двигалась, когда мячик бьётся об неё. Для этого добавьте следующую строку кода в конец функции create():

+ +
paddle.body.immovable = true;
+
+ +

Вот! Теперь всё работает, как надо.

+ +

Управляем платформой

+ +

Следующая проблема заключается в том, что мы не можем двигать платформу. Чтобы сделать это мы можем воспользоваться вводом input (мышь или сенсорный экран, в зависимости от платформы) и расположить нашу плаформу в месте расположения курсора. Добавьте следующую строку кода в функцию update(), как показано ниже:

+ +
function update() {
+    game.physics.arcade.collide(ball, paddle);
+    paddle.x = game.input.x;
+}
+
+ +

Теперь, каждый кадр координата x платформы будет соответствовать координате x курсора. Однако, при старте игры, положение нашей платформы не по центру экрана, из-за того, что положение курсора не определено. Чтобы это исправить, давайте добавим платформе координату x по умолчанию, на случаей, если положение курсора не определено. Обновите предыдущую строку кода:

+ +
paddle.x = game.input.x || game.world.width*0.5;
+
+ +

Если вы этого ещё не сделали, то обновите страницу index.html и попробуйте то, что у нас получилось!

+ +

Расположение мячика

+ +

Теперь давайте разместим мячик на платформе. Так же, как и платформу, расположим мячик по середине экрана по горизонтали, с небольшим отступом от нижней грани экрана по вертикали. Для этого переместим якорь мячика в его середину. Найдите строку ball = game.add.sprite( ... ) и заметите её на следующие две:

+ +
ball = game.add.sprite(game.world.width*0.5, game.world.height-25, 'ball');
+ball.anchor.set(0.5);
+ +

Скорость оставим такую же, но изменим направление по оси y, изменив второй параметр со 150 на -150, и теперь мяч будет двигаться вверх. Найдите строку ball.body.velocity.set( ... ) и измените её, как показано ниже:

+ +
ball.body.velocity.set(150, -150);
+
+ +

Теперь мячик появляется по середине платформы и двигается вверх.

+ +

Сравните свой код

+ +

Вы можете проверить код из этого урока и поиграть с ним, чтобы лучше понять, как он работает:

+ +

{{JSFiddleEmbed("https://jsfiddle.net/end3r/ogqza0ye/","","400")}}

+ +

Следующий шаг

+ +

Мы можем управлять платформой и сделали так, чтобы мячик отскакивал от неё. Но какой от этого толк, если мячик отскакивает и от нижней грани экрана? В следующей главе мы добавим логику проигрыша и экран "Game over".

+ +

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Bounce_off_the_walls", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Game_over")}}

diff --git a/files/ru/games/tutorials/2d_breakout_game_phaser/scaling/index.html b/files/ru/games/tutorials/2d_breakout_game_phaser/scaling/index.html new file mode 100644 index 0000000000..395e9f52de --- /dev/null +++ b/files/ru/games/tutorials/2d_breakout_game_phaser/scaling/index.html @@ -0,0 +1,64 @@ +--- +title: Масштабирование +slug: Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Scaling +tags: + - 2D + - Canvas + - JavaScript + - Phaser + - Начинающий +translation_of: Games/Tutorials/2D_breakout_game_Phaser/Scaling +--- +
{{GamesSidebar}}
+ +
{{IncludeSubnav("/ru/docs/Games")}}
+ +

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Initialize_the_framework", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Load_the_assets_and_print_them_on_screen")}}

+ +
+

Это 2-й урок из 16, которые входят в руководство 2D игра на Phaser. Вы можете найти исходный код этого урока на Gamedev-Phaser-Content-Kit/demos/lesson02.html.

+
+ +

Масштабирование отвечает за то, как ваша игра будет выглядеть на экранах разных размеров. Мы можем заставить игру масштабироваться под каждый экран автоматически во время стадии предзагрузки (preload), чтобы нам не пришлось волноваться об этом в будущем.

+ +

Масштабирование 

+ +

В Phaser есть специальный объект scale, которые имеет несколько полезных методов и свойств. Измените вашу функцию preload() так, как показано ниже:

+ +
function preload() {
+    game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
+    game.scale.pageAlignHorizontally = true;
+    game.scale.pageAlignVertically = true;
+}
+
+ +

scaleMode имеет несколько опций, которые определяют, как {{htmlelement("canvas")}} будет масштабироваться:

+ + + +

Две другие строчки кода в функции preload() отвечают за вертикальное и горизонтальное выравнивание элемента {{htmlelement("canvas")}}, так что он всегда будет находиться по центру независимо от размера экрана.

+ +

Изменение цвета фона

+ +

Мы также можем сделать фон нашего элемента {{htmlelement("canvas")}} таким, каким захотим, чтобы он не оставался постоянно чёрным. Объект stage имеет свойство backgroundColor для этого. Мы можем изменить значение, используя синтаксис CSS для цветов. Добавьте эту строку после трёх, недавно добавленных: 

+ +
game.stage.backgroundColor = '#eee';
+
+ +

Сравните свой код

+ +

Вы можете сравнить весь код из этого урока со своим и поиграть с ним, чтобы понять, как он работает:

+ +

{{JSFiddleEmbed("https://jsfiddle.net/end3r/6a64vecL/","","400")}}

+ +

Следующее

+ +

Мы научились масштабировать нашу игру, так что давайте перейдём к третьему уроку и узнаем, как загружать ресурсы игры и выводить их.

+ +

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Initialize_the_framework", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Load_the_assets_and_print_them_on_screen")}}

diff --git a/files/ru/games/tutorials/2d_breakout_game_phaser/the_score/index.html b/files/ru/games/tutorials/2d_breakout_game_phaser/the_score/index.html new file mode 100644 index 0000000000..9f4b18ace1 --- /dev/null +++ b/files/ru/games/tutorials/2d_breakout_game_phaser/the_score/index.html @@ -0,0 +1,69 @@ +--- +title: Очки +slug: Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Очки +translation_of: Games/Tutorials/2D_breakout_game_Phaser/The_score +--- +
{{GamesSidebar}}
+ +
{{IncludeSubnav("/ru/docs/")}}
+ +

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Обработка_коллизий", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Победа")}}

+ +
+

Это 11 из 16 уроков руководства разработки игры с помощью Phaser. Исходный код этого урока вы можете найти здесь:  Gamedev-Phaser-Content-Kit/demos/lesson11.html.

+
+ +

Очки сделают игру более интересной — вы можете пробовать побить собственный рекорд или рекорд друзей. В этой главе мы добавим систему очков в нашу игру.

+ +

Мы будем использовать отдельные переменные для хранения количества очков и текста, который Phaser выведет на экран при помощи функции text().

+ +

Определим переменные

+ +

Добавьте две новых переменных после всех наших текущих опеределений переменных:

+ +
// ...
+var scoreText;
+var score = 0;
+
+ +

Выводим очки на экран

+ +

А сейчас добавим строку кода в самый конец функции create():

+ +
scoreText = game.add.text(5, 5, 'Points: 0', { font: '18px Arial', fill: '#0095DD' });
+
+ +

Функция text() может принимать четыре параметра:

+ + + +

Последний параметр выглядит очень похожим на CSS-стиль. В нашем случае, текст будет голубой, размер 18 пикселей, шрифт Arial.

+ +

Обновляем очки при разрушении кирпича

+ +

Мы будем увеличивать количество очков каждый раз, когда мячик разобьёт кирпич и обновлять текст scoreText, который отображает на экране текущие очки. Текст обновляется вызовом функции setText(). Добавьте эти две строчки кода в функцию ballHitBrick():

+ +
function ballHitBrick(ball, brick) {
+    brick.kill();
+    score += 10;
+    scoreText.setText('Points: '+score);
+}
+
+ +

Вот и всё — обновите страницу index.html и проверьте, как очки изменяются, при разрушении кирпича.

+ +

Сравните свой код

+ +

Вы можете проверить код из этого урока и поиграть с ним, чтобы лучше понять, как он работает:

+ +

{{JSFiddleEmbed("https://jsfiddle.net/end3r/n8o6rhrf/","","400")}}

+ +

Следующий шаг

+ +

Теперь мы имеем систему очков, но какой смысл в этом, если мы не можем выиграть? Давайте добавим логику выигрыша.

+ +

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Обработка_коллизий", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Победа")}}

diff --git a/files/ru/games/tutorials/2d_breakout_game_phaser/win_the_game/index.html b/files/ru/games/tutorials/2d_breakout_game_phaser/win_the_game/index.html new file mode 100644 index 0000000000..21ff763bbf --- /dev/null +++ b/files/ru/games/tutorials/2d_breakout_game_phaser/win_the_game/index.html @@ -0,0 +1,54 @@ +--- +title: Победа +slug: Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Победа +translation_of: Games/Tutorials/2D_breakout_game_Phaser/Win_the_game +--- +
{{GamesSidebar}}
+ +
{{IncludeSubnav("/ru/docs/Games")}}
+ +

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Очки", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Жизни")}}

+ +
+

Это 12 из 16 уроков руководства разработки игры с помощью Phaser. Исходный код этого урока вы можете найти здесь:  Gamedev-Phaser-Content-Kit/demos/lesson12.html.

+
+ +

Победа в нашей игре будет достаточно простой: если ты разрушил все кирпичи, то победил.

+ +

Как победить?

+ +

Добавьте следующий код в функцию ballHitBrick():

+ +
function ballHitBrick(ball, brick) {
+    brick.kill();
+    score += 10;
+    scoreText.setText('Points: '+score);
+
+    var count_alive = 0;
+    for (i = 0; i < bricks.children.length; i++) {
+      if (bricks.children[i].alive == true) {
+        count_alive++;
+      }
+    }
+    if (count_alive == 0) {
+      alert('You won the game, congratulations!');
+      location.reload();
+    }
+}
+
+ +

Чтобы перебрать все кирпичи в наборе, необходимо обратиться к полю bricks.children. Найдём все неразрушенные кирпичи, проверяя поле alive у каждого кирпича и, если все кирпичи разрушены, выведем всплывающее окно с текстом о победе. После закрытия этого окна, страница перезагрузится.

+ +

Сравните свой код

+ +

Вы можете проверить код из этого урока и поиграть с ним, чтобы лучше понять, как он работает:

+ + + +

{{JSFiddleEmbed("https://jsfiddle.net/u8waa4Lx/1/","","400")}}

+ +

Следующий шаг

+ +

Логику прогрыша и выигрыша мы сделали, так что, основная часть игры готова. Теперь давайте добавим какую-нибудь фишку — дадим игроку три жизни, вместо одной.

+ +

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Очки", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Жизни")}}

diff --git a/files/ru/games/tutorials/2d_breakout_game_pure_javascript/build_the_brick_field/index.html b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/build_the_brick_field/index.html new file mode 100644 index 0000000000..91c7ea5405 --- /dev/null +++ b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/build_the_brick_field/index.html @@ -0,0 +1,119 @@ +--- +title: Создаем зону кирпичей +slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Создаем_зону_кирпичей +translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Build_the_brick_field +--- +
{{GamesSidebar}}
+ +
{{IncludeSubnav("/en-US/docs/Games")}}
+ +

{{PreviousNext("Games/Tutorials/2D_Breakout_game_pure_JavaScript/Game_over", "Games/Tutorials/2D_Breakout_game_pure_JavaScript/Collision_detection")}}

+ +
+

Это 6 шаг из 10 в Gamedev Canvas tutorial. Вы можете найти исходный код, как он будет выглядеть после завершения этого урока, тут - Gamedev-Canvas-workshop/lesson6.html.

+
+ +

После изменения механики игрового процесса мы теперь можем проиграть - это здорово, так как это означает, что игра, наконец, больше похожа на игру. Тем не менее, он быстро станет скучным, если все, что вы делаете, это отскок шара от стен и биты. То, что действительно нужно для прорыва - это кирпичи, которые нужно уничтожить мячом, и это то, что мы сейчас создадим!

+ +

Настройка переменных кирпича

+ +

Общая цель этого урока - сделать несколько строк кода для кирпичей, используя вложенный цикл, который работает через двумерный массив. Однако сначала нам нужно настроить некоторые переменные для определения информации о таких кирпичах, как их ширина и высота, строки и столбцы и т. Д. Добавьте следующие строки в свой код под переменными, которые вы ранее объявили в своей программе.

+ +
var brickRowCount = 3;
+var brickColumnCount = 5;
+var brickWidth = 75;
+var brickHeight = 20;
+var brickPadding = 10;
+var brickOffsetTop = 30;
+var brickOffsetLeft = 30;
+ + + +

Здесь мы определили количество строк и столбцов кирпичей, их ширину и высоту, прокладку между кирпичами, чтобы они не касались друг друга и верхнее и левое смещение, чтобы они не начинали рисоваться прямо от края Холста.

+ +

Мы будем держать все наши кирпичи в двумерном массиве. Он будет содержать кирпичные столбцы (c), которые, в свою очередь, будут содержать кирпичные ряды (r), которые, в свою очередь, будут содержать объект, содержащий положение x и yчтобы рисовать каждый кирпич на экране. Добавьте следующие значения ниже ваших переменных:

+ + + +
var bricks = [];
+for(var c=0; c<brickColumnCount; c++) {
+    bricks[c] = [];
+    for(var r=0; r<brickRowCount; r++) {
+        bricks[c][r] = { x: 0, y: 0 };
+    }
+}
+ +

Вышеприведенный код будет прокручивать строки и столбцы и создавать новые кирпичи. Обратите внимание, что кирпичные объекты также будут использоваться для целей обнаружения столкновений позже.

+ +

Механизм отрисовки кирпичей

+ +

Теперь давайте создадим функцию, чтобы перебрать все кирпичи в массиве и нарисовать их на экране. Наш код может выглядеть так:

+ +
function drawBricks() {
+    for(var c=0; c<brickColumnCount; c++) {
+        for(var r=0; r<brickRowCount; r++) {
+            bricks[c][r].x = 0;
+            bricks[c][r].y = 0;
+            ctx.beginPath();
+            ctx.rect(0, 0, brickWidth, brickHeight);
+            ctx.fillStyle = "#0095DD";
+            ctx.fill();
+            ctx.closePath();
+        }
+    }
+}
+ +

Опять же, мы зацикливаем строки и столбцы, чтобы установить положение x и yкаждого кирпича, и мы также brickWidth кирпич на кирпичной brickWidth Canvas -brickWidth - с каждой итерацией цикла. Проблема в том, что мы рисуем их все в одном месте, в координатах (0,0) . Нам нужно включить некоторые вычисления, которые будут определять положение x и y каждого кирпича для каждой итерации цикла:

+ +
var brickX = (c*(brickWidth+brickPadding))+brickOffsetLeft;
+var brickY = (r*(brickHeight+brickPadding))+brickOffsetTop;
+ + + +

Каждая позиция brickX разрабатывается как brickWidth + brickPadding , умноженная на номер столбца, c , плюс brickOffsetLeft ; логика для brickY идентична, за исключением того, что она использует значения для номера строки, rbrickHeight и brickOffsetTop . Теперь каждый отдельный кирпич может быть помещен в правильное место и столбец места, с отступом между каждым кирпичом, нарисованным на смещение от левого и верхнего краев холста.

+ +

Окончательная версия функции drawBricks() после назначения brickX и brickY в качестве координат вместо (0,0) каждый раз будет выглядеть следующим образом: добавьте это в свой код ниже функции drawPaddle() :

+ + + +
    for(var c=0; c<brickColumnCount; c++) {
+        for(var r=0; r<brickRowCount; r++) {
+            var brickX = (c*(brickWidth+brickPadding))+brickOffsetLeft;
+            var brickY = (r*(brickHeight+brickPadding))+brickOffsetTop;
+            bricks[c][r].x = brickX;
+            bricks[c][r].y = brickY;
+            ctx.beginPath();
+            ctx.rect(brickX, brickY, brickWidth, brickHeight);
+            ctx.fillStyle = "#0095DD";
+            ctx.fill();
+            ctx.closePath();
+        }
+    }
+}
+ +

Сама отрисовка кирпичей

+ +

Последнее, что нужно сделать в этом уроке, - добавить вызов drawBricks() где-нибудь в функции draw() , предпочтительно в начале, между очисткой холста и рисованием шара. Добавьте следующее выше drawBall() :

+ +
drawBricks();
+
+ +

Сравните свой код

+ + + +

На этом этапе игра снова стала интереснее:

+ + + +

{{JSFiddleEmbed("https://jsfiddle.net/yumetodo/t1zqmzLp/","","395")}}

+ +
+

Упражнение: попробуйте изменить количество кирпичей в строке или столбце или их позиции.

+
+ +

Следующие шаги

+ +

Итак, теперь у нас есть кирпичи! Но мяч вообще не взаимодействует с ними - мы изменим это, поскольку мы переходим в седьмую главу: Collision detection.

+ +

{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Game_over", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Collision_detection")}}

diff --git a/files/ru/games/tutorials/2d_breakout_game_pure_javascript/collision_detection/index.html b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/collision_detection/index.html new file mode 100644 index 0000000000..576f17e7cc --- /dev/null +++ b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/collision_detection/index.html @@ -0,0 +1,128 @@ +--- +title: Обнаружение столкновений +slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Обнаружение_столкновений +translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Collision_detection +--- +
{{GamesSidebar}}
+ +
{{IncludeSubnav("/en-US/docs/Games")}}
+ +

{{PreviousNext("Games/Tutorials/2D_Breakout_game_pure_JavaScript/Создаем_зону_кирпичей", "Games/Tutorials/2D_Breakout_game_pure_JavaScript/Track_the_score_and_win")}}

+ +
+

Это 7 шаг из 10 в Gamedev Canvas tutorial. Вы можете найти исходный код, как он будет выглядеть после завершения этого урока, тут Gamedev-Canvas-workshop/lesson7.html.

+ +

У нас уже есть кирпичи, появляющиеся на экране, но игра все еще не так интересна, ведь мяч проходит сквозь них. Нам нужно подумать о добавлении обнаружения столкновений, чтобы он мог отскакивать от кирпичей и ломать их.

+
+ +

Конечно, это наше решение, как реализовать это, но может быть сложно рассчитать, касается ли шар прямоугольника или нет, потому что в Canvas нет вспомогательных функций для этого. В этом уроке мы сделаем это самым простым способом. Мы проверим, сталкивается ли центр мяча с любым из данных кирпичей. Это не идеальное решение на все случаи жизни, и есть намного более сложные и эффективные способы обнаружения столкновений, но это научит вас основным понятиям.

+ +

Функция обнаружения столкновения

+ +

Мы хотим создать функцию обнаружения столкновений, которая будет перебирать все кирпичи и сравнивать позицию каждого кирпича с координатами шара при каждой отрисовке кадра. Для лучшей читаемости кода определим переменную b, чтобы хранить объект кирпича в цикле обнаружения столкновения:

+ +
function collisionDetection() {
+    for(var c=0; c<brickColumnCount; c++) {
+        for(var r=0; r<brickRowCount; r++) {
+            var b = bricks[c][r];
+            // calculations
+        }
+    }
+}
+ +

Если центр шара находится внутри координат одного из наших кирпичей, мы изменим направление шара. Для того, чтобы центр шара находился внутри кирпича, все четыре из следующих утверждений должны быть верны:

+ + + +

Давайте напишем это в коде:

+ +
function collisionDetection() {
+    for(var c=0; c<brickColumnCount; c++) {
+        for(var r=0; r<brickRowCount; r++) {
+            var b = bricks[c][r];
+            if(x > b.x && x < b.x+brickWidth && y > b.y && y < b.y+brickHeight) {
+                dy = -dy;
+            }
+        }
+    }
+}
+ +

Добавьте вышеприведенный блок к вашему коду под keyUpHandler() функцией .

+ +

Удаление кирпичей после их попадания

+ +

Вышеприведенный код будет работать, как и задумано, и мяч изменит свое направление. Проблема в том, что кирпичи остаются на своих местах. Мы должны придумать, как избавляться от тех, в которые мы уже попали мячом. Мы можем сделать это, добавив дополнительный параметр кирпичам, определяющий, будет ли кирпич отрисовываться на экране или нет. В той части кода, где мы инициализируем кирпичи, добавим свойство status к каждому кирпичному объекту. Обновите следующую часть кода, как показано ниже:

+ +
var bricks = [];
+for(var c=0; c<brickColumnCount; c++) {
+    bricks[c] = [];
+    for(var r=0; r<brickRowCount; r++) {
+        bricks[c][r] = { x: 0, y: 0, status: 1 };
+    }
+}
+ +

Теперь мы будем проверять значение свойства status каждого кирпича в функции drawBricks() перед его рисованием - если status равен 1 , нарисуем его, а если равен 0 , то значит в него попал мяч и он не должен больше отрисовываться. Отредактируйте drawBricks() следующим образом:

+ +
function drawBricks() {
+    for(var c=0; c<brickColumnCount; c++) {
+        for(var r=0; r<brickRowCount; r++) {
+            if(bricks[c][r].status == 1) {
+                var brickX = (c*(brickWidth+brickPadding))+brickOffsetLeft;
+                var brickY = (r*(brickHeight+brickPadding))+brickOffsetTop;
+                bricks[c][r].x = brickX;
+                bricks[c][r].y = brickY;
+                ctx.beginPath();
+                ctx.rect(brickX, brickY, brickWidth, brickHeight);
+                ctx.fillStyle = "#0095DD";
+                ctx.fill();
+                ctx.closePath();
+            }
+        }
+    }
+}
+ +

Отслеживание и обновление состояния в функции обнаружения столкновений

+ +

Теперь нам нужно задействовать свойство status кирпича в функции collisionDetection() : если кирпич активен (его статус равен 1 ), мы проверяем, было ли столкновение; если да, мы устанавливаем статус данного кирпича равным 0, чтобы он не был нарисован на экране. Отредактируйте функцию collisionDetection(), как показано ниже:

+ +
function collisionDetection() {
+    for(var c=0; c<brickColumnCount; c++) {
+        for(var r=0; r<brickRowCount; r++) {
+            var b = bricks[c][r];
+            if(b.status == 1) {
+                if(x > b.x && x < b.x+brickWidth && y > b.y && y < b.y+brickHeight) {
+                    dy = -dy;
+                    b.status = 0;
+                }
+            }
+        }
+    }
+}
+ +

Активация нашего обнаружения столкновений

+ +

Последнее, что нужно сделать, это добавить вызов функции collisionDetection() в нашу основную функцию draw() . Добавьте следующую строку в функцию draw() , чуть ниже drawPaddle() :

+ +
collisionDetection();
+
+ +

Сравните свой код

+ +

Обнаружение столкновения шара теперь выполняется на каждом кадре и для каждого кирпича. Теперь мы можем ломать кирпичи! : -

+ +

{{JSFiddleEmbed("https://jsfiddle.net/yumetodo/mkwtxgc3/3/","","395")}}

+ +
+

Упражнение : измените цвет шара, когда он ударит по кирпичу.

+
+ +

Следующие шаги

+ +

Мы уверенно движемся вперёд! Поехали! В восьмой главе мы будем учиться отслеживать счет и выигрывать .

+ +

{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Build_the_brick_field", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Track_the_score_and_win")}}

diff --git a/files/ru/games/tutorials/2d_breakout_game_pure_javascript/create_the_canvas_and_draw_on_it/index.html b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/create_the_canvas_and_draw_on_it/index.html new file mode 100644 index 0000000000..84f23b0e2a --- /dev/null +++ b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/create_the_canvas_and_draw_on_it/index.html @@ -0,0 +1,115 @@ +--- +title: Создание Canvas и рисование на нём +slug: >- + Games/Tutorials/2D_Breakout_game_pure_JavaScript/Создание_Canvas_и_рисование_на_нём +tags: + - JavaScript + - Игры + - разработка игр + - создание игр +translation_of: >- + Games/Tutorials/2D_Breakout_game_pure_JavaScript/Create_the_Canvas_and_draw_on_it +--- +
{{GamesSidebar}}
+ +
{{IncludeSubnav("/ru/docs/Games")}}
+ +

{{PreviousNext("Games/Tutorials/2D_Breakout_game_pure_JavaScript", "Games/Tutorials/2D_Breakout_game_pure_JavaScript/Переместить_мяч")}}

+ +
+

Это 1й шаг из 10 Gamedev Canvas tutorial. Вы можете найти исходный код для этого урока по ссылке Gamedev-Canvas-workshop/lesson1.html.

+
+ +

Прежде чем мы сможем начать писать функциональные возможности игры, нам необходимо создать базовую структуру для рендеринга игры внутри. Это можно сделать с помощью HTML и элемента {{htmlelement ("canvas")}}.

+ +

HTML игры

+ +

Структура HTML документа довольно проста, так как игра будет полностью визуализироваться в {{htmlelement("canvas")}} элементе. Используя Ваш любимый текстовый редактор, создайте новый HTML документ, сохраните его как index.html в любом удобном месте, и скопируйте в него этот код:

+ +
<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8" />
+    <title>Gamedev Canvas Workshop</title>
+    <style>
+    	* { padding: 0; margin: 0; }
+    	canvas { background: #eee; display: block; margin: 0 auto; }
+    </style>
+</head>
+<body>
+
+<canvas id="myCanvas" width="480" height="320"></canvas>
+
+<script>
+	// JavaScript код будем писать здесь
+</script>
+
+</body>
+</html>
+
+ +

Мы определили charset, {{htmlelement("title")}} и некий базовый CSS в заголовке. Тело документа содержит элементы {{htmlelement("canvas")}} и {{htmlelement("script")}} — мы будем визуализировать игру внутри первого и писать JavaScript код, который управляет игрой, во втором. Элемент {{htmlelement("canvas")}} имеет id равный myCanvas, который позволяет однозначно отыскать элемент. Так же этот элемент имеет ширину 480 пикселей и высоту 320 пикселей. Весь JavaScript код мы будем писать между открывающим тегом <script> и закрывающим тегом </script>.

+ +

Основы Canvas

+ +

Чтобы иметь возможность визуализировать игру в {{htmlelement("canvas")}} элементе, сначала мы должны сослаться на этот элемент в коде JavaScript. Добавьте следующий код после открывающего тега <script>.

+ +
var canvas = document.getElementById("myCanvas");
+var ctx = canvas.getContext("2d");
+ +

Таким образом, мы храним ссылку на {{htmlelement("canvas")}} элемент в переменной canvas. Далее мы создаём переменную ctx для хранения 2D визуализации контекста — метод, который используется для отрисовки в Canvas.

+ +

Давайте рассмотрим пример отрисовки красного квадрата на canvas. Добавьте этот код ниже предыдущего кода на JavaScript и загрузите index.html в браузере, чтобы посмотреть результат.

+ +
ctx.beginPath();
+ctx.rect(20, 40, 50, 50);
+ctx.fillStyle = "#FF0000";
+ctx.fill();
+ctx.closePath();
+ +

Все инструкции располагаются между методами {{domxref("CanvasRenderingContext2D.beginPath()","beginPath()")}} и {{domxref("CanvasRenderingContext2D.closePath()","closePath()")}}. Мы определяем прямоугольник, используя  {{domxref("CanvasRenderingContext2D.rect()","rect()")}}: первые два параметра определяют координаты верхнего левого угла прямоугольника на canvas, в то время, как два других параметра определяют ширину и высоту прямоугольника. В нашем случае прямоугольник нарисован на расстоянии 20 пикселей слева и 40 пикселей сверху, 50 пикселей в ширину и 50 пикселей в высоту, что делает его квадратом. Свойство {{domxref("CanvasRenderingContext2D.fillStyle","fillStyle")}} хранит цвет, который будет использован методом {{domxref("CanvasRenderingContext2D.fill()","fill()")}} для отрисовки нашего квадрата.

+ +

Мы не ограничены только прямоугольниками - ниже часть кода для отрисовки зелёного круга. Попробуйте добавить этот код вконец Вашего кода JavaScript, сохраните и обновите страницу в браузере:

+ +
ctx.beginPath();
+ctx.arc(240, 160, 20, 0, Math.PI*2, false);
+ctx.fillStyle = "green";
+ctx.fill();
+ctx.closePath();
+ +

Как видите, мы снова используем методы {{domxref("CanvasRenderingContext2D.beginPath()","beginPath()")}} и {{domxref("CanvasRenderingContext2D.closePath()","closePath()")}}. Между ними наиболее важная часть кода - метод {{domxref("CanvasRenderingContext2D.arc()","arc()")}}. Он принимает шесть параметров:

+ + + +

Свойство {{domxref("CanvasRenderingContext2D.fillStyle","fillStyle")}} выглядит не так, как прежде. Это потому что, как и в CSS, цвет может быть задан в шестнадцатиричном формате, названием цвета, функцией rgba() , или же любым другим методом для цвета.

+ +

Вместо {{domxref("CanvasRenderingContext2D.fill()","fill()")}} и заполнения фигур цветом, можно использовать {{domxref("CanvasRenderingContext2D.stroke()","stroke()")}}, чтобы окрасить только внешнюю обводку фигуры. Попробуйте добавить этот код к Вашему коду JavaScript:

+ +
ctx.beginPath();
+ctx.rect(160, 10, 100, 40);
+ctx.strokeStyle = "rgba(0, 0, 255, 0.5)";
+ctx.stroke();
+ctx.closePath();
+ +

Код выше отрисовывает пустой прямоугольник с синей обводкой. Благодаря функции альфа-канала rgba() , голубой цвет полупрозрачный.

+ +

Сравните Ваш код

+ +

Здесь полный исходный код для первого урока, посмотреть онлайн можно на JSFiddle:

+ +

{{JSFiddleEmbed("https://jsfiddle.net/end3r/x62h15e2/","","395")}}

+ +
+

Упражнение: попробуйте изменить цвет и размер созданных фигур.

+
+ +

Следующие шаги

+ +

Сейчас мы создали базовый HTML и немного узнали о canvas, давайте на следующем шаге изучим, как Двигать мяч в нашей игре.

+ +

{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Move_the_ball")}}

diff --git a/files/ru/games/tutorials/2d_breakout_game_pure_javascript/finishing_up/index.html b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/finishing_up/index.html new file mode 100644 index 0000000000..d8f40896e1 --- /dev/null +++ b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/finishing_up/index.html @@ -0,0 +1,103 @@ +--- +title: Заключение +slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Заключение +tags: + - Игры + - Канва + - Начинающий + - жизни +translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Finishing_up +--- +
{{GamesSidebar}}
+ +
{{IncludeSubnav("/en-US/docs/Games")}}
+ +

{{Previous("Games/Tutorials/2D_Breakout_game_pure_JavaScript/Управление_мышью")}}

+ +
+

Это 10-й и заключительный шаг в Gamedev Canvas tutorial. Вы можете найти исходный код, как он должен выглядеть, после завершения этого урока в Gamedev-Canvas-workshop/lesson10.html.

+
+ +

В любой игре, которую мы пишем, всегда есть место для улучшений. Например, мы можем предложить игроку несколько жизней. Они могут сделать несколько ошибок и все равно закончить игру. Мы также можем улучшить отрисовку кода.

+ +

Предоставление игроку нескольких жизней

+ +

Реализация довольно проста. Давайте сначала добавим переменную для хранения количества жизней в том же месте, где мы объявляли другие наши переменные:

+ +
var lives = 3;
+ +

Отрисовка счетчика жизни выглядит почти так же, как и счетчика баллов - добавьте в код следующую функцию под функцией drawScore() :

+ +
function drawLives() {
+    ctx.font = "16px Arial";
+    ctx.fillStyle = "#0095DD";
+    ctx.fillText("Lives: "+lives, canvas.width-65, 20);
+}
+ +

Вместо того, чтобы немедленно закончить игру, мы уменьшим количество жизней, пока они больше не будут доступны. Мы также можем сбросить позиции мяча и биты, когда игрок начинает игру со следующей жизнью. Итак, в функции draw() замените следующие три строки:

+ +
alert("GAME OVER");
+document.location.reload();
+clearInterval(interval); // Needed for Chrome to end game
+ +

Давайте добавим немного более сложную логику к ней, как показано ниже:

+ +
lives--;
+if(!lives) {
+    alert("GAME OVER");
+    document.location.reload();
+}
+else {
+    x = canvas.width/2;
+    y = canvas.height-30;
+    dx = 2;
+    dy = -2;
+    paddleX = (canvas.width-paddleWidth)/2;
+}
+ +

Теперь, когда мяч попадает в нижний край экрана, мы вычитаем одну жизнь из переменной lives. Если жизней не осталось, игра проиграна, если осталось еще несколько жизней, то положение мяча и биты сбрасываются вместе с движением мяча.

+ +

Визуализация дисплея жизней

+ +

Теперь вам нужно добавить вызов drawLives() внутри функции draw() и добавить его под вызовом drawScore().

+ +
drawLives();
+
+ +

Улучшение рендеринга с requestAnimationFrame()

+ +

Теперь давайте работать над чем-то, что не связано с игровой механикой, но с тем, как она рендерится. {{domxref("window.requestAnimationFrame", "requestAnimationFrame")}} поможет браузеру рендерить игру лучше, чем фиксированная частота кадров, которую в настоящее время мы реализовали, используя {{domxref("windowTimers.setInterval()", "setInterval()")}}. Замените следующую строку:

+ +
setInterval(draw, 10);
+ +

на:

+ +
draw();
+ +

и удалите каждый экземпляр:

+ +
clearInterval(interval); // Needed for Chrome to end game
+ +

Затем в самом низу функции draw() (непосредственно перед закрывающей фигурной скобкой) добавьте следующую строку, которая заставляет функцию draw() вызывать себя снова и снова:

+ +
requestAnimationFrame(draw);
+ +

Функция draw() теперь выполняется снова и снова в цикле requestAnimationFrame(), но вместо фиксированной частоты кадров в 10 миллисекунд, мы возвращаем управление частотой кадров обратно в браузер. Соответственно он будет синхронизировать частоту кадров и отображать фигуры только при необходимости. Это обеспечивает более эффективный и плавный цикл анимации, чем более старый метод setInterval().

+ +

Сравните свой код

+ +

Вот и все-финальная версия игры готова!

+ +

{{JSFiddleEmbed("https://jsfiddle.net/yumetodo/3becw9fy/1/","","395")}}

+ +
+

Упражнение: измените количество жизней и угол отскока мяча от биты.

+
+ +

Игра закончена - на данный момент!

+ +

Вы закончили все уроки — поздравляем! К этому моменту вы должны знать основы манипулирования canvas и логику простых 2D-игр. Сейчас самое время изучить некоторые фреймворки и продолжить разработку игр. Вы можете проверить аналог этой серии, 2D breakout game using Phaser или Cyber Orb built in Phaser учебник. Вы также можете просмотреть раздел Games section on MDN для вдохновения и  увеличения знаний.

+ +

Вы также можете вернуться на this tutorial series' index page учебника. Получайте удовольствие от написания кода!

+ +

{{Previous("Games/Workflows/2D_Breakout_game_pure_JavaScript/Mouse_controls")}}

diff --git a/files/ru/games/tutorials/2d_breakout_game_pure_javascript/mouse_controls/index.html b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/mouse_controls/index.html new file mode 100644 index 0000000000..b3ab4efaca --- /dev/null +++ b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/mouse_controls/index.html @@ -0,0 +1,58 @@ +--- +title: Управление мышью +slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Управление_мышью +tags: + - Игры + - Начинающий + - канвас + - мышь +translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Mouse_controls +--- +
{{GamesSidebar}}
+ +
{{IncludeSubnav("/en-US/docs/Games")}}
+ +

{{PreviousNext("Games/Tutorials/2D_Breakout_game_pure_JavaScript/Track_the_score_and_win", "Games/Tutorials/2D_Breakout_game_pure_JavaScript/Заключение")}}

+ +
+

Это 9-й шаг из 10 в Gamedev Canvas tutorial. Вы можете найти исходный код к этому уроку в Gamedev-Canvas-workshop/lesson9.html.

+
+ +

Сама игра на самом деле закончена, так что давайте отполируем её. Мы уже добавили элементы управления клавиатуру, но мы могли бы легко добавить элемент управления мышь.

+ +

Отслеживание движений мыши

+ +

Отслеживание движений мыши еще проще, чем прослушивание нажатий клавиш. Все, что нам нужно, это следить за событиями {{event("mousemove")}}. Добавьте следующую строку в том же месте, как и для других событий, чуть ниже keyup event:

+ +
document.addEventListener("mousemove", mouseMoveHandler, false);
+ +

Привязка движения ракетки к движению мыши

+ +

Мы можем обновить положение ракетки на основе координат указателя - следующая функция обработчика сделает именно это. Добавьте в код следующую функцию под предыдущей добавленной строкой:

+ +
function mouseMoveHandler(e) {
+    var relativeX = e.clientX - canvas.offsetLeft;
+    if(relativeX > 0 && relativeX < canvas.width) {
+        paddleX = relativeX - paddleWidth/2;
+    }
+}
+ +

В этой функции мы сначала разрабатываем значение relativeX, которое равно горизонтальному положению мыши в окне браузера (e.clientX) минус расстояние между левым краем canvas и левым краем окна браузера (canvas.offsetLeft) - фактически это равно расстоянию между левым краем canvas и указателем мыши. Если относительный указатель позиции X больше нуля и меньше, чем ширина Canvas, указатель находится в пределах границы Canvas, и paddleX установки (крепится на левый край ракетки) - устанавливается на relativeX значение минус половина ширины ракетки, так что движение будет по отношению к середине ракетки.

+ +

Ракетка теперь будет следовать за положением курсора мыши, но так как мы ограничиваем движение размером Canvas, он не исчезнет полностью с обеих сторон.

+ +

Сравните свой код

+ +

Это последнее состояние кода для сравнения:

+ +

{{JSFiddleEmbed("https://jsfiddle.net/yumetodo/1L9ep9r2/1/","","395")}}

+ +
+

Упражнение: отрегулируйте границы движения ракетки так, что вся ракетка будет видна на обоих краях Canvas, а не только на его половину.

+
+ +

Следующий шаг

+ +

Теперь у нас есть полная игра, мы закончим нашу серию уроков с еще несколькими небольшими хитростями — Finishing up.

+ +

{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Track_the_score_and_win", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Finishing_up")}}

diff --git a/files/ru/games/tutorials/2d_breakout_game_pure_javascript/move_the_ball/index.html b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/move_the_ball/index.html new file mode 100644 index 0000000000..f6d26cfc52 --- /dev/null +++ b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/move_the_ball/index.html @@ -0,0 +1,146 @@ +--- +title: Переместить мяч +slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Переместить_мяч +tags: + - 2D + - Canvas + - Игры + - Обучение + - Цикл + - передвижение + - пишем игру на javascript +translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Move_the_ball +--- +
{{GamesSidebar}}
+ +
{{IncludeSubnav("/en-US/docs/Games")}}
+ +

{{PreviousNext("Games/Tutorials/2D_Breakout_game_pure_JavaScript/Создание_Canvas_и_рисование_на_нём", "Games/Tutorials/2D_Breakout_game_pure_JavaScript/Bounce_off_the_walls")}}

+ +
+

Это 2й шаг из 10 Gamedev Canvas tutorial. Вы можете найти исходный код для данного урока по ссылке Gamedev-Canvas-workshop/lesson2.html.

+
+ +

Из предыдущей статьи Вы уже знаете, как нарисовать мяч, а сейчас давайте заставим его двигаться. Технически, мы будем рисовать мяч на экране, стирать его и рисовать заново на немного другой позиции каждый раз, чтобы создать эффект движения - точно так же, как это работает в фильмах.

+ +

Определяем цикл рисования

+ +

Чтобы canvas постоянно обновлялся, необходимо определить функцию отрисовки, которая будет циклически запускаться с разными параметрами, чтобы изменять позицию элемента. Функцию можно циклически запускать с помощью JavaScript временной функции, такой как {{domxref("WindowTimers.setInterval()", "setInterval()")}} или {{domxref("window.requestAnimationFrame()", "requestAnimationFrame()")}}.

+ +

Удалите весь JavaScript код, который сейчас хранился в Вашем HTML файле, за исключением первых двух строк, и добавьте следующий код после них. Функция draw() будет исполняться внутри функции setInterval каждые 10 мс:

+ +
function draw() {
+    // код отрисовки
+}
+setInterval(draw, 10);
+ +

Благодаря бесконечности функции setInterval функция draw() будет выполняться каждые 10 мс бесконечно или же пока мы не остановим её. Теперь давайте нарисуем мяч - добавьте в свой код функцию draw():

+ +
ctx.beginPath();
+ctx.arc(50, 50, 10, 0, Math.PI*2);
+ctx.fillStyle = "#0095DD";
+ctx.fill();
+ctx.closePath();
+
+ +

Попробуйте сейчас Ваш обновлённый код - каждый раз мяч будет перерисовываться.

+ +

Перемещение

+ +

Вы не можете определить, перерисовывается ли мяч в конкретный момент, так как его позиция не меняется. Давайте исправим это. Прежде всего, в позиции (50,50) определим стартовую точку в нижней центральной части Canvas в переменной x и y, и потом используем их для определения текущего положения мяча.

+ +

Для начала добавьте следующие две строки до функции draw(), чтобы определить переменные x и y:

+ +
var x = canvas.width/2;
+var y = canvas.height-30;
+
+ +

Далее обновите функцию draw(), чтобы использовать переменные x и y в методе {{domxref("CanvasRenderingContext2D.arc()","arc()")}}, как показано на подсвеченной линии:

+ +
function draw() {
+    ctx.beginPath();
+    ctx.arc(x, y, 10, 0, Math.PI*2);
+    ctx.fillStyle = "#0095DD";
+    ctx.fill();
+    ctx.closePath();
+}
+
+ +

Теперь важная часть: мы хотим добавлять небольшое значение к переменным x и y после каждой итерации, чтобы заставить мяч двигаться. Давайте определим эти небольшие значения в переменных dx и dy и установим их 2 и -2 соответственно. Добавьте следующий код после определения переменных x и y:

+ +
var dx = 2;
+var dy = -2;
+
+ +

И последнее, необходимо обновить переменные x и y на значение dx и dy каждую итерацию, чтобы мяч отрисовывался каждый раз на новой позиции. Добавьте ещё две строки кода в функции draw():

+ +
function draw() {
+    ctx.beginPath();
+    ctx.arc(x, y, 10, 0, Math.PI*2);
+    ctx.fillStyle = "#0095DD";
+    ctx.fill();
+    ctx.closePath();
+    x += dx;
+    y += dy;
+}
+ +

Сохраните Ваш код и откройте страницу в браузере. Всё работает хорошо, вот только мяч оставляет позади след:

+ +

+ +

Очищение объекта после каждого кадра

+ +

Мяч оставляет след, потому что мы рисуем круг на каждой итерации без удаления предыдущей отрисованной фигуры. Не переживайте, потому что существует метод для очистки canvas элемента: {{domxref("CanvasRenderingContext2D.clearRect()","clearRect()")}}. Этот метод принимает четыре параметра: x и y координаты верхнего левого угла прямоугольника, x и y координаты нижнего правого угла прямоугольника. Вся площадь, покрытая прямоугольником, будет очищена от любого содержимого, которое когда-либо было там отрисовано.

+ +

Добавьте следующую подсвеченную строку в функцию draw():

+ +
function draw() {
+    ctx.clearRect(0, 0, canvas.width, canvas.height);
+    ctx.beginPath();
+    ctx.arc(x, y, 10, 0, Math.PI*2);
+    ctx.fillStyle = "#0095DD";
+    ctx.fill();
+    ctx.closePath();
+    x += dx;
+    y += dy;
+}
+
+ +

Сохраните Ваш код и попробуйте снова, и на этот раз Вы увидите, что мяч перемещается без следов. Каждые 10 мс canvas очищается, голубой круг (наш мяч) отрисовывается на заданной позиции, переменные x и y каждую итерацию обновляются.

+ +

Рефакторинг

+ +

Мы будем добавлять каждый раз всё больше команд в функцию draw(), поэтому было бы неплохо содержать наш код настолько простым и понятным, на сколько это возможно. Давайте вынесем команды перемещения мяча в отдельную функцию.

+ +

Замените существующую функцию draw() следующими двумя функциями:

+ +
function drawBall() {
+    ctx.beginPath();
+    ctx.arc(x, y, 10, 0, Math.PI*2);
+    ctx.fillStyle = "#0095DD";
+    ctx.fill();
+    ctx.closePath();
+}
+
+function draw() {
+    ctx.clearRect(0, 0, canvas.width, canvas.height);
+    drawBall();
+    x += dx;
+    y += dy;
+}
+ +

Сравните Ваш код

+ +

Вы можете проверить итоговый код для этого урока с помощью демо, а так же поэкспериментировать с ним, изменяя те или иные параметры:

+ +

{{JSFiddleEmbed("https://jsfiddle.net/end3r/3x5foxb1/","","395")}}

+ +
+

Упражнение: попробуйте изменить скорость перемещения мяча, или направление перемещения.

+
+ +

Следующие шаги

+ +

Мы нарисовали мяч и заставили его двигаться, но он продолжает пропадать на краю canvas. В третьей части мы рассмотрим, как заставить его отскакивать от стен.

+ +

{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Create_the_Canvas_and_draw_on_it", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Bounce_off_the_walls")}}

diff --git "a/files/ru/games/tutorials/2d_breakout_game_pure_javascript/\320\267\320\260\320\272\320\273\321\216\321\207\320\265\320\275\320\270\320\265/index.html" "b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/\320\267\320\260\320\272\320\273\321\216\321\207\320\265\320\275\320\270\320\265/index.html" deleted file mode 100644 index d8f40896e1..0000000000 --- "a/files/ru/games/tutorials/2d_breakout_game_pure_javascript/\320\267\320\260\320\272\320\273\321\216\321\207\320\265\320\275\320\270\320\265/index.html" +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: Заключение -slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Заключение -tags: - - Игры - - Канва - - Начинающий - - жизни -translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Finishing_up ---- -
{{GamesSidebar}}
- -
{{IncludeSubnav("/en-US/docs/Games")}}
- -

{{Previous("Games/Tutorials/2D_Breakout_game_pure_JavaScript/Управление_мышью")}}

- -
-

Это 10-й и заключительный шаг в Gamedev Canvas tutorial. Вы можете найти исходный код, как он должен выглядеть, после завершения этого урока в Gamedev-Canvas-workshop/lesson10.html.

-
- -

В любой игре, которую мы пишем, всегда есть место для улучшений. Например, мы можем предложить игроку несколько жизней. Они могут сделать несколько ошибок и все равно закончить игру. Мы также можем улучшить отрисовку кода.

- -

Предоставление игроку нескольких жизней

- -

Реализация довольно проста. Давайте сначала добавим переменную для хранения количества жизней в том же месте, где мы объявляли другие наши переменные:

- -
var lives = 3;
- -

Отрисовка счетчика жизни выглядит почти так же, как и счетчика баллов - добавьте в код следующую функцию под функцией drawScore() :

- -
function drawLives() {
-    ctx.font = "16px Arial";
-    ctx.fillStyle = "#0095DD";
-    ctx.fillText("Lives: "+lives, canvas.width-65, 20);
-}
- -

Вместо того, чтобы немедленно закончить игру, мы уменьшим количество жизней, пока они больше не будут доступны. Мы также можем сбросить позиции мяча и биты, когда игрок начинает игру со следующей жизнью. Итак, в функции draw() замените следующие три строки:

- -
alert("GAME OVER");
-document.location.reload();
-clearInterval(interval); // Needed for Chrome to end game
- -

Давайте добавим немного более сложную логику к ней, как показано ниже:

- -
lives--;
-if(!lives) {
-    alert("GAME OVER");
-    document.location.reload();
-}
-else {
-    x = canvas.width/2;
-    y = canvas.height-30;
-    dx = 2;
-    dy = -2;
-    paddleX = (canvas.width-paddleWidth)/2;
-}
- -

Теперь, когда мяч попадает в нижний край экрана, мы вычитаем одну жизнь из переменной lives. Если жизней не осталось, игра проиграна, если осталось еще несколько жизней, то положение мяча и биты сбрасываются вместе с движением мяча.

- -

Визуализация дисплея жизней

- -

Теперь вам нужно добавить вызов drawLives() внутри функции draw() и добавить его под вызовом drawScore().

- -
drawLives();
-
- -

Улучшение рендеринга с requestAnimationFrame()

- -

Теперь давайте работать над чем-то, что не связано с игровой механикой, но с тем, как она рендерится. {{domxref("window.requestAnimationFrame", "requestAnimationFrame")}} поможет браузеру рендерить игру лучше, чем фиксированная частота кадров, которую в настоящее время мы реализовали, используя {{domxref("windowTimers.setInterval()", "setInterval()")}}. Замените следующую строку:

- -
setInterval(draw, 10);
- -

на:

- -
draw();
- -

и удалите каждый экземпляр:

- -
clearInterval(interval); // Needed for Chrome to end game
- -

Затем в самом низу функции draw() (непосредственно перед закрывающей фигурной скобкой) добавьте следующую строку, которая заставляет функцию draw() вызывать себя снова и снова:

- -
requestAnimationFrame(draw);
- -

Функция draw() теперь выполняется снова и снова в цикле requestAnimationFrame(), но вместо фиксированной частоты кадров в 10 миллисекунд, мы возвращаем управление частотой кадров обратно в браузер. Соответственно он будет синхронизировать частоту кадров и отображать фигуры только при необходимости. Это обеспечивает более эффективный и плавный цикл анимации, чем более старый метод setInterval().

- -

Сравните свой код

- -

Вот и все-финальная версия игры готова!

- -

{{JSFiddleEmbed("https://jsfiddle.net/yumetodo/3becw9fy/1/","","395")}}

- -
-

Упражнение: измените количество жизней и угол отскока мяча от биты.

-
- -

Игра закончена - на данный момент!

- -

Вы закончили все уроки — поздравляем! К этому моменту вы должны знать основы манипулирования canvas и логику простых 2D-игр. Сейчас самое время изучить некоторые фреймворки и продолжить разработку игр. Вы можете проверить аналог этой серии, 2D breakout game using Phaser или Cyber Orb built in Phaser учебник. Вы также можете просмотреть раздел Games section on MDN для вдохновения и  увеличения знаний.

- -

Вы также можете вернуться на this tutorial series' index page учебника. Получайте удовольствие от написания кода!

- -

{{Previous("Games/Workflows/2D_Breakout_game_pure_JavaScript/Mouse_controls")}}

diff --git "a/files/ru/games/tutorials/2d_breakout_game_pure_javascript/\320\276\320\261\320\275\320\260\321\200\321\203\320\266\320\265\320\275\320\270\320\265_\321\201\321\202\320\276\320\273\320\272\320\275\320\276\320\262\320\265\320\275\320\270\320\271/index.html" "b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/\320\276\320\261\320\275\320\260\321\200\321\203\320\266\320\265\320\275\320\270\320\265_\321\201\321\202\320\276\320\273\320\272\320\275\320\276\320\262\320\265\320\275\320\270\320\271/index.html" deleted file mode 100644 index 576f17e7cc..0000000000 --- "a/files/ru/games/tutorials/2d_breakout_game_pure_javascript/\320\276\320\261\320\275\320\260\321\200\321\203\320\266\320\265\320\275\320\270\320\265_\321\201\321\202\320\276\320\273\320\272\320\275\320\276\320\262\320\265\320\275\320\270\320\271/index.html" +++ /dev/null @@ -1,128 +0,0 @@ ---- -title: Обнаружение столкновений -slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Обнаружение_столкновений -translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Collision_detection ---- -
{{GamesSidebar}}
- -
{{IncludeSubnav("/en-US/docs/Games")}}
- -

{{PreviousNext("Games/Tutorials/2D_Breakout_game_pure_JavaScript/Создаем_зону_кирпичей", "Games/Tutorials/2D_Breakout_game_pure_JavaScript/Track_the_score_and_win")}}

- -
-

Это 7 шаг из 10 в Gamedev Canvas tutorial. Вы можете найти исходный код, как он будет выглядеть после завершения этого урока, тут Gamedev-Canvas-workshop/lesson7.html.

- -

У нас уже есть кирпичи, появляющиеся на экране, но игра все еще не так интересна, ведь мяч проходит сквозь них. Нам нужно подумать о добавлении обнаружения столкновений, чтобы он мог отскакивать от кирпичей и ломать их.

-
- -

Конечно, это наше решение, как реализовать это, но может быть сложно рассчитать, касается ли шар прямоугольника или нет, потому что в Canvas нет вспомогательных функций для этого. В этом уроке мы сделаем это самым простым способом. Мы проверим, сталкивается ли центр мяча с любым из данных кирпичей. Это не идеальное решение на все случаи жизни, и есть намного более сложные и эффективные способы обнаружения столкновений, но это научит вас основным понятиям.

- -

Функция обнаружения столкновения

- -

Мы хотим создать функцию обнаружения столкновений, которая будет перебирать все кирпичи и сравнивать позицию каждого кирпича с координатами шара при каждой отрисовке кадра. Для лучшей читаемости кода определим переменную b, чтобы хранить объект кирпича в цикле обнаружения столкновения:

- -
function collisionDetection() {
-    for(var c=0; c<brickColumnCount; c++) {
-        for(var r=0; r<brickRowCount; r++) {
-            var b = bricks[c][r];
-            // calculations
-        }
-    }
-}
- -

Если центр шара находится внутри координат одного из наших кирпичей, мы изменим направление шара. Для того, чтобы центр шара находился внутри кирпича, все четыре из следующих утверждений должны быть верны:

- - - -

Давайте напишем это в коде:

- -
function collisionDetection() {
-    for(var c=0; c<brickColumnCount; c++) {
-        for(var r=0; r<brickRowCount; r++) {
-            var b = bricks[c][r];
-            if(x > b.x && x < b.x+brickWidth && y > b.y && y < b.y+brickHeight) {
-                dy = -dy;
-            }
-        }
-    }
-}
- -

Добавьте вышеприведенный блок к вашему коду под keyUpHandler() функцией .

- -

Удаление кирпичей после их попадания

- -

Вышеприведенный код будет работать, как и задумано, и мяч изменит свое направление. Проблема в том, что кирпичи остаются на своих местах. Мы должны придумать, как избавляться от тех, в которые мы уже попали мячом. Мы можем сделать это, добавив дополнительный параметр кирпичам, определяющий, будет ли кирпич отрисовываться на экране или нет. В той части кода, где мы инициализируем кирпичи, добавим свойство status к каждому кирпичному объекту. Обновите следующую часть кода, как показано ниже:

- -
var bricks = [];
-for(var c=0; c<brickColumnCount; c++) {
-    bricks[c] = [];
-    for(var r=0; r<brickRowCount; r++) {
-        bricks[c][r] = { x: 0, y: 0, status: 1 };
-    }
-}
- -

Теперь мы будем проверять значение свойства status каждого кирпича в функции drawBricks() перед его рисованием - если status равен 1 , нарисуем его, а если равен 0 , то значит в него попал мяч и он не должен больше отрисовываться. Отредактируйте drawBricks() следующим образом:

- -
function drawBricks() {
-    for(var c=0; c<brickColumnCount; c++) {
-        for(var r=0; r<brickRowCount; r++) {
-            if(bricks[c][r].status == 1) {
-                var brickX = (c*(brickWidth+brickPadding))+brickOffsetLeft;
-                var brickY = (r*(brickHeight+brickPadding))+brickOffsetTop;
-                bricks[c][r].x = brickX;
-                bricks[c][r].y = brickY;
-                ctx.beginPath();
-                ctx.rect(brickX, brickY, brickWidth, brickHeight);
-                ctx.fillStyle = "#0095DD";
-                ctx.fill();
-                ctx.closePath();
-            }
-        }
-    }
-}
- -

Отслеживание и обновление состояния в функции обнаружения столкновений

- -

Теперь нам нужно задействовать свойство status кирпича в функции collisionDetection() : если кирпич активен (его статус равен 1 ), мы проверяем, было ли столкновение; если да, мы устанавливаем статус данного кирпича равным 0, чтобы он не был нарисован на экране. Отредактируйте функцию collisionDetection(), как показано ниже:

- -
function collisionDetection() {
-    for(var c=0; c<brickColumnCount; c++) {
-        for(var r=0; r<brickRowCount; r++) {
-            var b = bricks[c][r];
-            if(b.status == 1) {
-                if(x > b.x && x < b.x+brickWidth && y > b.y && y < b.y+brickHeight) {
-                    dy = -dy;
-                    b.status = 0;
-                }
-            }
-        }
-    }
-}
- -

Активация нашего обнаружения столкновений

- -

Последнее, что нужно сделать, это добавить вызов функции collisionDetection() в нашу основную функцию draw() . Добавьте следующую строку в функцию draw() , чуть ниже drawPaddle() :

- -
collisionDetection();
-
- -

Сравните свой код

- -

Обнаружение столкновения шара теперь выполняется на каждом кадре и для каждого кирпича. Теперь мы можем ломать кирпичи! : -

- -

{{JSFiddleEmbed("https://jsfiddle.net/yumetodo/mkwtxgc3/3/","","395")}}

- -
-

Упражнение : измените цвет шара, когда он ударит по кирпичу.

-
- -

Следующие шаги

- -

Мы уверенно движемся вперёд! Поехали! В восьмой главе мы будем учиться отслеживать счет и выигрывать .

- -

{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Build_the_brick_field", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Track_the_score_and_win")}}

diff --git "a/files/ru/games/tutorials/2d_breakout_game_pure_javascript/\320\277\320\265\321\200\320\265\320\274\320\265\321\201\321\202\320\270\321\202\321\214_\320\274\321\217\321\207/index.html" "b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/\320\277\320\265\321\200\320\265\320\274\320\265\321\201\321\202\320\270\321\202\321\214_\320\274\321\217\321\207/index.html" deleted file mode 100644 index f6d26cfc52..0000000000 --- "a/files/ru/games/tutorials/2d_breakout_game_pure_javascript/\320\277\320\265\321\200\320\265\320\274\320\265\321\201\321\202\320\270\321\202\321\214_\320\274\321\217\321\207/index.html" +++ /dev/null @@ -1,146 +0,0 @@ ---- -title: Переместить мяч -slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Переместить_мяч -tags: - - 2D - - Canvas - - Игры - - Обучение - - Цикл - - передвижение - - пишем игру на javascript -translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Move_the_ball ---- -
{{GamesSidebar}}
- -
{{IncludeSubnav("/en-US/docs/Games")}}
- -

{{PreviousNext("Games/Tutorials/2D_Breakout_game_pure_JavaScript/Создание_Canvas_и_рисование_на_нём", "Games/Tutorials/2D_Breakout_game_pure_JavaScript/Bounce_off_the_walls")}}

- -
-

Это 2й шаг из 10 Gamedev Canvas tutorial. Вы можете найти исходный код для данного урока по ссылке Gamedev-Canvas-workshop/lesson2.html.

-
- -

Из предыдущей статьи Вы уже знаете, как нарисовать мяч, а сейчас давайте заставим его двигаться. Технически, мы будем рисовать мяч на экране, стирать его и рисовать заново на немного другой позиции каждый раз, чтобы создать эффект движения - точно так же, как это работает в фильмах.

- -

Определяем цикл рисования

- -

Чтобы canvas постоянно обновлялся, необходимо определить функцию отрисовки, которая будет циклически запускаться с разными параметрами, чтобы изменять позицию элемента. Функцию можно циклически запускать с помощью JavaScript временной функции, такой как {{domxref("WindowTimers.setInterval()", "setInterval()")}} или {{domxref("window.requestAnimationFrame()", "requestAnimationFrame()")}}.

- -

Удалите весь JavaScript код, который сейчас хранился в Вашем HTML файле, за исключением первых двух строк, и добавьте следующий код после них. Функция draw() будет исполняться внутри функции setInterval каждые 10 мс:

- -
function draw() {
-    // код отрисовки
-}
-setInterval(draw, 10);
- -

Благодаря бесконечности функции setInterval функция draw() будет выполняться каждые 10 мс бесконечно или же пока мы не остановим её. Теперь давайте нарисуем мяч - добавьте в свой код функцию draw():

- -
ctx.beginPath();
-ctx.arc(50, 50, 10, 0, Math.PI*2);
-ctx.fillStyle = "#0095DD";
-ctx.fill();
-ctx.closePath();
-
- -

Попробуйте сейчас Ваш обновлённый код - каждый раз мяч будет перерисовываться.

- -

Перемещение

- -

Вы не можете определить, перерисовывается ли мяч в конкретный момент, так как его позиция не меняется. Давайте исправим это. Прежде всего, в позиции (50,50) определим стартовую точку в нижней центральной части Canvas в переменной x и y, и потом используем их для определения текущего положения мяча.

- -

Для начала добавьте следующие две строки до функции draw(), чтобы определить переменные x и y:

- -
var x = canvas.width/2;
-var y = canvas.height-30;
-
- -

Далее обновите функцию draw(), чтобы использовать переменные x и y в методе {{domxref("CanvasRenderingContext2D.arc()","arc()")}}, как показано на подсвеченной линии:

- -
function draw() {
-    ctx.beginPath();
-    ctx.arc(x, y, 10, 0, Math.PI*2);
-    ctx.fillStyle = "#0095DD";
-    ctx.fill();
-    ctx.closePath();
-}
-
- -

Теперь важная часть: мы хотим добавлять небольшое значение к переменным x и y после каждой итерации, чтобы заставить мяч двигаться. Давайте определим эти небольшие значения в переменных dx и dy и установим их 2 и -2 соответственно. Добавьте следующий код после определения переменных x и y:

- -
var dx = 2;
-var dy = -2;
-
- -

И последнее, необходимо обновить переменные x и y на значение dx и dy каждую итерацию, чтобы мяч отрисовывался каждый раз на новой позиции. Добавьте ещё две строки кода в функции draw():

- -
function draw() {
-    ctx.beginPath();
-    ctx.arc(x, y, 10, 0, Math.PI*2);
-    ctx.fillStyle = "#0095DD";
-    ctx.fill();
-    ctx.closePath();
-    x += dx;
-    y += dy;
-}
- -

Сохраните Ваш код и откройте страницу в браузере. Всё работает хорошо, вот только мяч оставляет позади след:

- -

- -

Очищение объекта после каждого кадра

- -

Мяч оставляет след, потому что мы рисуем круг на каждой итерации без удаления предыдущей отрисованной фигуры. Не переживайте, потому что существует метод для очистки canvas элемента: {{domxref("CanvasRenderingContext2D.clearRect()","clearRect()")}}. Этот метод принимает четыре параметра: x и y координаты верхнего левого угла прямоугольника, x и y координаты нижнего правого угла прямоугольника. Вся площадь, покрытая прямоугольником, будет очищена от любого содержимого, которое когда-либо было там отрисовано.

- -

Добавьте следующую подсвеченную строку в функцию draw():

- -
function draw() {
-    ctx.clearRect(0, 0, canvas.width, canvas.height);
-    ctx.beginPath();
-    ctx.arc(x, y, 10, 0, Math.PI*2);
-    ctx.fillStyle = "#0095DD";
-    ctx.fill();
-    ctx.closePath();
-    x += dx;
-    y += dy;
-}
-
- -

Сохраните Ваш код и попробуйте снова, и на этот раз Вы увидите, что мяч перемещается без следов. Каждые 10 мс canvas очищается, голубой круг (наш мяч) отрисовывается на заданной позиции, переменные x и y каждую итерацию обновляются.

- -

Рефакторинг

- -

Мы будем добавлять каждый раз всё больше команд в функцию draw(), поэтому было бы неплохо содержать наш код настолько простым и понятным, на сколько это возможно. Давайте вынесем команды перемещения мяча в отдельную функцию.

- -

Замените существующую функцию draw() следующими двумя функциями:

- -
function drawBall() {
-    ctx.beginPath();
-    ctx.arc(x, y, 10, 0, Math.PI*2);
-    ctx.fillStyle = "#0095DD";
-    ctx.fill();
-    ctx.closePath();
-}
-
-function draw() {
-    ctx.clearRect(0, 0, canvas.width, canvas.height);
-    drawBall();
-    x += dx;
-    y += dy;
-}
- -

Сравните Ваш код

- -

Вы можете проверить итоговый код для этого урока с помощью демо, а так же поэкспериментировать с ним, изменяя те или иные параметры:

- -

{{JSFiddleEmbed("https://jsfiddle.net/end3r/3x5foxb1/","","395")}}

- -
-

Упражнение: попробуйте изменить скорость перемещения мяча, или направление перемещения.

-
- -

Следующие шаги

- -

Мы нарисовали мяч и заставили его двигаться, но он продолжает пропадать на краю canvas. В третьей части мы рассмотрим, как заставить его отскакивать от стен.

- -

{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Create_the_Canvas_and_draw_on_it", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Bounce_off_the_walls")}}

diff --git "a/files/ru/games/tutorials/2d_breakout_game_pure_javascript/\321\201\320\276\320\267\320\264\320\260\320\265\320\274_\320\267\320\276\320\275\321\203_\320\272\320\270\321\200\320\277\320\270\321\207\320\265\320\271/index.html" "b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/\321\201\320\276\320\267\320\264\320\260\320\265\320\274_\320\267\320\276\320\275\321\203_\320\272\320\270\321\200\320\277\320\270\321\207\320\265\320\271/index.html" deleted file mode 100644 index 91c7ea5405..0000000000 --- "a/files/ru/games/tutorials/2d_breakout_game_pure_javascript/\321\201\320\276\320\267\320\264\320\260\320\265\320\274_\320\267\320\276\320\275\321\203_\320\272\320\270\321\200\320\277\320\270\321\207\320\265\320\271/index.html" +++ /dev/null @@ -1,119 +0,0 @@ ---- -title: Создаем зону кирпичей -slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Создаем_зону_кирпичей -translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Build_the_brick_field ---- -
{{GamesSidebar}}
- -
{{IncludeSubnav("/en-US/docs/Games")}}
- -

{{PreviousNext("Games/Tutorials/2D_Breakout_game_pure_JavaScript/Game_over", "Games/Tutorials/2D_Breakout_game_pure_JavaScript/Collision_detection")}}

- -
-

Это 6 шаг из 10 в Gamedev Canvas tutorial. Вы можете найти исходный код, как он будет выглядеть после завершения этого урока, тут - Gamedev-Canvas-workshop/lesson6.html.

-
- -

После изменения механики игрового процесса мы теперь можем проиграть - это здорово, так как это означает, что игра, наконец, больше похожа на игру. Тем не менее, он быстро станет скучным, если все, что вы делаете, это отскок шара от стен и биты. То, что действительно нужно для прорыва - это кирпичи, которые нужно уничтожить мячом, и это то, что мы сейчас создадим!

- -

Настройка переменных кирпича

- -

Общая цель этого урока - сделать несколько строк кода для кирпичей, используя вложенный цикл, который работает через двумерный массив. Однако сначала нам нужно настроить некоторые переменные для определения информации о таких кирпичах, как их ширина и высота, строки и столбцы и т. Д. Добавьте следующие строки в свой код под переменными, которые вы ранее объявили в своей программе.

- -
var brickRowCount = 3;
-var brickColumnCount = 5;
-var brickWidth = 75;
-var brickHeight = 20;
-var brickPadding = 10;
-var brickOffsetTop = 30;
-var brickOffsetLeft = 30;
- - - -

Здесь мы определили количество строк и столбцов кирпичей, их ширину и высоту, прокладку между кирпичами, чтобы они не касались друг друга и верхнее и левое смещение, чтобы они не начинали рисоваться прямо от края Холста.

- -

Мы будем держать все наши кирпичи в двумерном массиве. Он будет содержать кирпичные столбцы (c), которые, в свою очередь, будут содержать кирпичные ряды (r), которые, в свою очередь, будут содержать объект, содержащий положение x и yчтобы рисовать каждый кирпич на экране. Добавьте следующие значения ниже ваших переменных:

- - - -
var bricks = [];
-for(var c=0; c<brickColumnCount; c++) {
-    bricks[c] = [];
-    for(var r=0; r<brickRowCount; r++) {
-        bricks[c][r] = { x: 0, y: 0 };
-    }
-}
- -

Вышеприведенный код будет прокручивать строки и столбцы и создавать новые кирпичи. Обратите внимание, что кирпичные объекты также будут использоваться для целей обнаружения столкновений позже.

- -

Механизм отрисовки кирпичей

- -

Теперь давайте создадим функцию, чтобы перебрать все кирпичи в массиве и нарисовать их на экране. Наш код может выглядеть так:

- -
function drawBricks() {
-    for(var c=0; c<brickColumnCount; c++) {
-        for(var r=0; r<brickRowCount; r++) {
-            bricks[c][r].x = 0;
-            bricks[c][r].y = 0;
-            ctx.beginPath();
-            ctx.rect(0, 0, brickWidth, brickHeight);
-            ctx.fillStyle = "#0095DD";
-            ctx.fill();
-            ctx.closePath();
-        }
-    }
-}
- -

Опять же, мы зацикливаем строки и столбцы, чтобы установить положение x и yкаждого кирпича, и мы также brickWidth кирпич на кирпичной brickWidth Canvas -brickWidth - с каждой итерацией цикла. Проблема в том, что мы рисуем их все в одном месте, в координатах (0,0) . Нам нужно включить некоторые вычисления, которые будут определять положение x и y каждого кирпича для каждой итерации цикла:

- -
var brickX = (c*(brickWidth+brickPadding))+brickOffsetLeft;
-var brickY = (r*(brickHeight+brickPadding))+brickOffsetTop;
- - - -

Каждая позиция brickX разрабатывается как brickWidth + brickPadding , умноженная на номер столбца, c , плюс brickOffsetLeft ; логика для brickY идентична, за исключением того, что она использует значения для номера строки, rbrickHeight и brickOffsetTop . Теперь каждый отдельный кирпич может быть помещен в правильное место и столбец места, с отступом между каждым кирпичом, нарисованным на смещение от левого и верхнего краев холста.

- -

Окончательная версия функции drawBricks() после назначения brickX и brickY в качестве координат вместо (0,0) каждый раз будет выглядеть следующим образом: добавьте это в свой код ниже функции drawPaddle() :

- - - -
    for(var c=0; c<brickColumnCount; c++) {
-        for(var r=0; r<brickRowCount; r++) {
-            var brickX = (c*(brickWidth+brickPadding))+brickOffsetLeft;
-            var brickY = (r*(brickHeight+brickPadding))+brickOffsetTop;
-            bricks[c][r].x = brickX;
-            bricks[c][r].y = brickY;
-            ctx.beginPath();
-            ctx.rect(brickX, brickY, brickWidth, brickHeight);
-            ctx.fillStyle = "#0095DD";
-            ctx.fill();
-            ctx.closePath();
-        }
-    }
-}
- -

Сама отрисовка кирпичей

- -

Последнее, что нужно сделать в этом уроке, - добавить вызов drawBricks() где-нибудь в функции draw() , предпочтительно в начале, между очисткой холста и рисованием шара. Добавьте следующее выше drawBall() :

- -
drawBricks();
-
- -

Сравните свой код

- - - -

На этом этапе игра снова стала интереснее:

- - - -

{{JSFiddleEmbed("https://jsfiddle.net/yumetodo/t1zqmzLp/","","395")}}

- -
-

Упражнение: попробуйте изменить количество кирпичей в строке или столбце или их позиции.

-
- -

Следующие шаги

- -

Итак, теперь у нас есть кирпичи! Но мяч вообще не взаимодействует с ними - мы изменим это, поскольку мы переходим в седьмую главу: Collision detection.

- -

{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Game_over", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Collision_detection")}}

diff --git "a/files/ru/games/tutorials/2d_breakout_game_pure_javascript/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_canvas_\320\270_\321\200\320\270\321\201\320\276\320\262\320\260\320\275\320\270\320\265_\320\275\320\260_\320\275\321\221\320\274/index.html" "b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_canvas_\320\270_\321\200\320\270\321\201\320\276\320\262\320\260\320\275\320\270\320\265_\320\275\320\260_\320\275\321\221\320\274/index.html" deleted file mode 100644 index 84f23b0e2a..0000000000 --- "a/files/ru/games/tutorials/2d_breakout_game_pure_javascript/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_canvas_\320\270_\321\200\320\270\321\201\320\276\320\262\320\260\320\275\320\270\320\265_\320\275\320\260_\320\275\321\221\320\274/index.html" +++ /dev/null @@ -1,115 +0,0 @@ ---- -title: Создание Canvas и рисование на нём -slug: >- - Games/Tutorials/2D_Breakout_game_pure_JavaScript/Создание_Canvas_и_рисование_на_нём -tags: - - JavaScript - - Игры - - разработка игр - - создание игр -translation_of: >- - Games/Tutorials/2D_Breakout_game_pure_JavaScript/Create_the_Canvas_and_draw_on_it ---- -
{{GamesSidebar}}
- -
{{IncludeSubnav("/ru/docs/Games")}}
- -

{{PreviousNext("Games/Tutorials/2D_Breakout_game_pure_JavaScript", "Games/Tutorials/2D_Breakout_game_pure_JavaScript/Переместить_мяч")}}

- -
-

Это 1й шаг из 10 Gamedev Canvas tutorial. Вы можете найти исходный код для этого урока по ссылке Gamedev-Canvas-workshop/lesson1.html.

-
- -

Прежде чем мы сможем начать писать функциональные возможности игры, нам необходимо создать базовую структуру для рендеринга игры внутри. Это можно сделать с помощью HTML и элемента {{htmlelement ("canvas")}}.

- -

HTML игры

- -

Структура HTML документа довольно проста, так как игра будет полностью визуализироваться в {{htmlelement("canvas")}} элементе. Используя Ваш любимый текстовый редактор, создайте новый HTML документ, сохраните его как index.html в любом удобном месте, и скопируйте в него этот код:

- -
<!DOCTYPE html>
-<html>
-<head>
-    <meta charset="utf-8" />
-    <title>Gamedev Canvas Workshop</title>
-    <style>
-    	* { padding: 0; margin: 0; }
-    	canvas { background: #eee; display: block; margin: 0 auto; }
-    </style>
-</head>
-<body>
-
-<canvas id="myCanvas" width="480" height="320"></canvas>
-
-<script>
-	// JavaScript код будем писать здесь
-</script>
-
-</body>
-</html>
-
- -

Мы определили charset, {{htmlelement("title")}} и некий базовый CSS в заголовке. Тело документа содержит элементы {{htmlelement("canvas")}} и {{htmlelement("script")}} — мы будем визуализировать игру внутри первого и писать JavaScript код, который управляет игрой, во втором. Элемент {{htmlelement("canvas")}} имеет id равный myCanvas, который позволяет однозначно отыскать элемент. Так же этот элемент имеет ширину 480 пикселей и высоту 320 пикселей. Весь JavaScript код мы будем писать между открывающим тегом <script> и закрывающим тегом </script>.

- -

Основы Canvas

- -

Чтобы иметь возможность визуализировать игру в {{htmlelement("canvas")}} элементе, сначала мы должны сослаться на этот элемент в коде JavaScript. Добавьте следующий код после открывающего тега <script>.

- -
var canvas = document.getElementById("myCanvas");
-var ctx = canvas.getContext("2d");
- -

Таким образом, мы храним ссылку на {{htmlelement("canvas")}} элемент в переменной canvas. Далее мы создаём переменную ctx для хранения 2D визуализации контекста — метод, который используется для отрисовки в Canvas.

- -

Давайте рассмотрим пример отрисовки красного квадрата на canvas. Добавьте этот код ниже предыдущего кода на JavaScript и загрузите index.html в браузере, чтобы посмотреть результат.

- -
ctx.beginPath();
-ctx.rect(20, 40, 50, 50);
-ctx.fillStyle = "#FF0000";
-ctx.fill();
-ctx.closePath();
- -

Все инструкции располагаются между методами {{domxref("CanvasRenderingContext2D.beginPath()","beginPath()")}} и {{domxref("CanvasRenderingContext2D.closePath()","closePath()")}}. Мы определяем прямоугольник, используя  {{domxref("CanvasRenderingContext2D.rect()","rect()")}}: первые два параметра определяют координаты верхнего левого угла прямоугольника на canvas, в то время, как два других параметра определяют ширину и высоту прямоугольника. В нашем случае прямоугольник нарисован на расстоянии 20 пикселей слева и 40 пикселей сверху, 50 пикселей в ширину и 50 пикселей в высоту, что делает его квадратом. Свойство {{domxref("CanvasRenderingContext2D.fillStyle","fillStyle")}} хранит цвет, который будет использован методом {{domxref("CanvasRenderingContext2D.fill()","fill()")}} для отрисовки нашего квадрата.

- -

Мы не ограничены только прямоугольниками - ниже часть кода для отрисовки зелёного круга. Попробуйте добавить этот код вконец Вашего кода JavaScript, сохраните и обновите страницу в браузере:

- -
ctx.beginPath();
-ctx.arc(240, 160, 20, 0, Math.PI*2, false);
-ctx.fillStyle = "green";
-ctx.fill();
-ctx.closePath();
- -

Как видите, мы снова используем методы {{domxref("CanvasRenderingContext2D.beginPath()","beginPath()")}} и {{domxref("CanvasRenderingContext2D.closePath()","closePath()")}}. Между ними наиболее важная часть кода - метод {{domxref("CanvasRenderingContext2D.arc()","arc()")}}. Он принимает шесть параметров:

- - - -

Свойство {{domxref("CanvasRenderingContext2D.fillStyle","fillStyle")}} выглядит не так, как прежде. Это потому что, как и в CSS, цвет может быть задан в шестнадцатиричном формате, названием цвета, функцией rgba() , или же любым другим методом для цвета.

- -

Вместо {{domxref("CanvasRenderingContext2D.fill()","fill()")}} и заполнения фигур цветом, можно использовать {{domxref("CanvasRenderingContext2D.stroke()","stroke()")}}, чтобы окрасить только внешнюю обводку фигуры. Попробуйте добавить этот код к Вашему коду JavaScript:

- -
ctx.beginPath();
-ctx.rect(160, 10, 100, 40);
-ctx.strokeStyle = "rgba(0, 0, 255, 0.5)";
-ctx.stroke();
-ctx.closePath();
- -

Код выше отрисовывает пустой прямоугольник с синей обводкой. Благодаря функции альфа-канала rgba() , голубой цвет полупрозрачный.

- -

Сравните Ваш код

- -

Здесь полный исходный код для первого урока, посмотреть онлайн можно на JSFiddle:

- -

{{JSFiddleEmbed("https://jsfiddle.net/end3r/x62h15e2/","","395")}}

- -
-

Упражнение: попробуйте изменить цвет и размер созданных фигур.

-
- -

Следующие шаги

- -

Сейчас мы создали базовый HTML и немного узнали о canvas, давайте на следующем шаге изучим, как Двигать мяч в нашей игре.

- -

{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Move_the_ball")}}

diff --git "a/files/ru/games/tutorials/2d_breakout_game_pure_javascript/\321\203\320\277\321\200\320\260\320\262\320\273\320\265\320\275\320\270\320\265_\320\274\321\213\321\210\321\214\321\216/index.html" "b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/\321\203\320\277\321\200\320\260\320\262\320\273\320\265\320\275\320\270\320\265_\320\274\321\213\321\210\321\214\321\216/index.html" deleted file mode 100644 index b3ab4efaca..0000000000 --- "a/files/ru/games/tutorials/2d_breakout_game_pure_javascript/\321\203\320\277\321\200\320\260\320\262\320\273\320\265\320\275\320\270\320\265_\320\274\321\213\321\210\321\214\321\216/index.html" +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: Управление мышью -slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Управление_мышью -tags: - - Игры - - Начинающий - - канвас - - мышь -translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Mouse_controls ---- -
{{GamesSidebar}}
- -
{{IncludeSubnav("/en-US/docs/Games")}}
- -

{{PreviousNext("Games/Tutorials/2D_Breakout_game_pure_JavaScript/Track_the_score_and_win", "Games/Tutorials/2D_Breakout_game_pure_JavaScript/Заключение")}}

- -
-

Это 9-й шаг из 10 в Gamedev Canvas tutorial. Вы можете найти исходный код к этому уроку в Gamedev-Canvas-workshop/lesson9.html.

-
- -

Сама игра на самом деле закончена, так что давайте отполируем её. Мы уже добавили элементы управления клавиатуру, но мы могли бы легко добавить элемент управления мышь.

- -

Отслеживание движений мыши

- -

Отслеживание движений мыши еще проще, чем прослушивание нажатий клавиш. Все, что нам нужно, это следить за событиями {{event("mousemove")}}. Добавьте следующую строку в том же месте, как и для других событий, чуть ниже keyup event:

- -
document.addEventListener("mousemove", mouseMoveHandler, false);
- -

Привязка движения ракетки к движению мыши

- -

Мы можем обновить положение ракетки на основе координат указателя - следующая функция обработчика сделает именно это. Добавьте в код следующую функцию под предыдущей добавленной строкой:

- -
function mouseMoveHandler(e) {
-    var relativeX = e.clientX - canvas.offsetLeft;
-    if(relativeX > 0 && relativeX < canvas.width) {
-        paddleX = relativeX - paddleWidth/2;
-    }
-}
- -

В этой функции мы сначала разрабатываем значение relativeX, которое равно горизонтальному положению мыши в окне браузера (e.clientX) минус расстояние между левым краем canvas и левым краем окна браузера (canvas.offsetLeft) - фактически это равно расстоянию между левым краем canvas и указателем мыши. Если относительный указатель позиции X больше нуля и меньше, чем ширина Canvas, указатель находится в пределах границы Canvas, и paddleX установки (крепится на левый край ракетки) - устанавливается на relativeX значение минус половина ширины ракетки, так что движение будет по отношению к середине ракетки.

- -

Ракетка теперь будет следовать за положением курсора мыши, но так как мы ограничиваем движение размером Canvas, он не исчезнет полностью с обеих сторон.

- -

Сравните свой код

- -

Это последнее состояние кода для сравнения:

- -

{{JSFiddleEmbed("https://jsfiddle.net/yumetodo/1L9ep9r2/1/","","395")}}

- -
-

Упражнение: отрегулируйте границы движения ракетки так, что вся ракетка будет видна на обоих краях Canvas, а не только на его половину.

-
- -

Следующий шаг

- -

Теперь у нас есть полная игра, мы закончим нашу серию уроков с еще несколькими небольшими хитростями — Finishing up.

- -

{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Track_the_score_and_win", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Finishing_up")}}

diff --git "a/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/bounce_off_the_walls/index.html" "b/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/bounce_off_the_walls/index.html" deleted file mode 100644 index aedabaaf25..0000000000 --- "a/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/bounce_off_the_walls/index.html" +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: Отскакивания -slug: Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Bounce_off_the_walls -translation_of: Games/Tutorials/2D_breakout_game_Phaser/Bounce_off_the_walls ---- -
{{GamesSidebar}}
- -
{{IncludeSubnav("/ru/docs/")}}
- -

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Physics", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Платформа_и_управление")}}

- -
-

Это 6 урок из 16 Руководства разработки игры с помощью Phaser. Вы можете найти исходный код того как должен выглядеть код после завершения урока здесь: Gamedev-Phaser-Content-Kit/demos/lesson06.html.

-
- -

Теперь, когда мы познакомились с физикой, мы можем начать реализовывать определение столкновений в игре — сначала посмотрим на "стены".

- -

Отскакивание от границ представления

- -

Самый простой способ заставить мячик от стен это сообщить фреймворку что мы хотим рассматривать границы элемента {{htmlelement("canvas")}} как стены и не позволять мячу проходить через них. В Phaser это может быть просто реализовано с помощью свойства collideWorldsBound. Добавьте этот код сразу после существующего вызова метода game.physics.enable():

- -
ball.body.collideWorldBounds = true;
-
- -

Теперь мяч будет останавливаться у границ экрана, вместо того чтобы исчезать, но он не отскакивает. Чтобы это происодило нам нужно установить его "отскакиваемость". Добавте следующий код ниже предыдущей строки:

- -
ball.body.bounce.set(1);
-
- -

Попробуйте перезагрузить index.html опять — теперь мяч отскакивает от стен и движется внутри холста canvas.

- -

Сравните ваш код

- -

Вы можете сравнить получившийся код из этого урока в превью и поиграть с ним, чтобы лучше понять как он работает:

- -

{{JSFiddleEmbed("https://jsfiddle.net/end3r/dcw36opz/","","400")}}

- -

Следующие шаги

- -

Это начинает больше походить на игру, но мы никак не можем её контролировать — самое время добавить рычаги управления для игрока.

- -

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Physics", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Платформа_и_управление")}}

diff --git "a/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/game_over/index.html" "b/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/game_over/index.html" deleted file mode 100644 index a617f8969d..0000000000 --- "a/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/game_over/index.html" +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: Game over -slug: Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Game_over -translation_of: Games/Tutorials/2D_breakout_game_Phaser/Game_over ---- -
{{GamesSidebar}}
- -
{{IncludeSubnav("/ru/docs/Games")}}
- -

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Платформа_и_управление", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Создание_кирпичей")}}

- -
-

Это из 16 уроков руководства разработки игры с помощью Phaser. Исходный код этого урока вы можете найти здесь:  Gamedev-Phaser-Content-Kit/demos/lesson08.html.

-
- -

Чтобы разнообразить игру, давайте добавим возможность проигрыша — если вы не отобьете мячик и дадите ему упасть на пол, то game over.

- -

Проигрыш

- -

Чтобы добавить возможность проигрыша, давай те отключим определение коллизии с нижней гранью экрана. Добавьте следующую строку кода в функцию create(), сразу после кода инициализации всех атрибутов мячика:

- -
game.physics.arcade.checkCollision.down = false;
-
- -

Теперь мячик отскакивает только от трёх стен (верхней, левой и правой) и, если не отбить его платформой, проходит сквозь нижнюю стену, выходя за пределы экрана. Осталось только поймать момент выхода мячика за пределы экрана и вывести сообещние о проигрыше. Добавьте эти строки кода сразу после предыдущей:

- -
ball.checkWorldBounds = true;
-ball.events.onOutOfBounds.add(function(){
-    alert('Game over!');
-    location.reload();
-}, this);
-
- -

Мы сделали так, чтобы мячик проверял границы игрового мира (в нашем случае границы <canvas>) и, в случае выхода за их пределы (событие onOutOfBounds), выполнял функцию, которую мы привязали к этому событию. После закрытия всплывающего окна с сообщением 'Game over!', происходит перезагрузка страницы, чтобы можно было сыграть снова.

- -

Сравните свой код

- -

Вы можете проверить код из этого урока и поиграть с ним, чтобы лучше понять, как он работает:

- -

{{JSFiddleEmbed("https://jsfiddle.net/end3r/436bckb7/","","400")}}

- -

Следующий шаг

- -

Базовый геймплей готов. Но какой арканоид без разбивания кирпичиков

- -

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Платформа_и_управление", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Создание_кирпичей")}}

diff --git "a/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/index.html" "b/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/index.html" deleted file mode 100644 index 05a0439cc7..0000000000 --- "a/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/index.html" +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: 2D игра на Phaser -slug: Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser -tags: - - 2D - - Canvas - - JavaScript - - Phaser - - Игры - - Начинающий - - Руководство - - туториал -translation_of: Games/Tutorials/2D_breakout_game_Phaser ---- -
{{GamesSidebar}}
- -
{{IncludeSubnav("/ru/docs/")}}
- -

{{Next("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Initialize_the_framework")}}

- -

В этом пошаговом руководстве мы создадим простую мобильную игру MDN Breakout с помощью JavaScript и фреймворка Phaser.

- -

Каждый шаг будет сопровождаться настраиваемым и живым примером для того, чтобы вы могли видеть, что должно получиться на промежуточных этапах создания. Вы узнаете основы для работы с фреймворком Phaser: рендер и движение картинок, определение столкновения, управление, встроенные вспомогательныке функции, анимации и отрисовка кадров, изменение игровой статистки.  

- -

Чтобы получить наибольшую пользу от этого руководства, вам необходимо иметь базовые знания JavaScript. После прочтения вы научитесь создавать собственные простые веб-игры с помощью Phaser.

- -

Gameplay screen from the game MDN Breakout created with Phaser where you can use your paddle to bounce the ball and destroy the brick field, with keeping the points and lives.

- -

Дополнительно

- -

Все уроки и различные версии MDN Breakout, которые мы сделаем вместе, доступны на GitHub

- -
    -
  1. Инициализация фреймворка
  2. -
  3. Масштабирование
  4. -
  5. Загрузка ресурсов и их вывод
  6. -
  7. Движение мяча
  8. -
  9. Физика
  10. -
  11. Отскакивание от стен
  12. -
  13. Управление
  14. -
  15. Конец игры
  16. -
  17. Создание поля блоков
  18. -
  19. Определение столкновения
  20. -
  21. Счёт
  22. -
  23. Победа в игре
  24. -
  25. Добавление жизней
  26. -
  27. Анимация
  28. -
  29. Кнопки
  30. -
  31. Создание случайных событий
  32. -
- -

Также мы хотели бы заметить, что лучший способ научиться создавать веб-игры - это чистый (pure) JavaScript. Если вы ещё не знакомы с разработкой на чистом JavaScript, то мы предлагаем вам первым делом пройти туториал 2D игра на чистом JavaScript.

- -

После этого вы можете выбрать любой фреймворк и использовать его в своих проектах. Мы выбрали Phaser, потому что это прочный фреймворк с хорошей поддержкой, открытым сообществом и набором различных плагинов. Фреймворки ускоряют разработку и заботятся о скучных вещах, позволяя вам сосредоточиться на самом весёлом. Однако они не идеальны, так что если что-то пойдёт не так или вы захотите написать функцию, которую фреймворк не поддерживает, то вам пригодятся знания чистого JavaScript.

- -
-

Примечание: Эта серия статей может быть использована, как материал для создания игр в мастерских разработчиков. Также вы можете использовать Gamedev Phaser Content, который сделан на основе этого руководства, если захотите углубиться в разработку игр с помощью Phaser.

-
- -

Следующие шаги

- -

Давайте начнём! Первая часть руководства — это Инициализация фреймворка.

- -

{{Next("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Initialize_the_framework")}}

diff --git "a/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/initialize_the_framework/index.html" "b/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/initialize_the_framework/index.html" deleted file mode 100644 index bf1fac5bfc..0000000000 --- "a/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/initialize_the_framework/index.html" +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: Инициализация фреймворка -slug: Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Initialize_the_framework -tags: - - 2D - - Canvas - - HTML - - JavaScript - - Phaser - - Игры - - Руководство -translation_of: Games/Tutorials/2D_breakout_game_Phaser/Initialize_the_framework ---- -
{{GamesSidebar}}
- -
{{IncludeSubnav("ru/docs/")}}
- -

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Scaling")}}

- -
-

Это первый из 16 уроков о том, как пользоваться Gamedev Phaser. После прочтения вы можете найти исходный код для этого урока на Gamedev-Phaser-Content-Kit/demos/lesson01.html.

-
- -

Перед тем, как мы начнём разрабатывать функционал игры, нам нужно создать базовую структуру, чтобы рендерить её. Это может быть сделано с помощью HTML:  фреймворк Phaser создаст обязательный элемент {{htmlelement("canvas")}}.

- -

HTML-код игры

- -

Структура HTML-документа достаточно простая. Игра будет отображаться в элементе {{htmlelement("canvas")}}, который будет сгенерирован фреймворком. Используя свой любимый редактор, создайте новый HTML-документ, сохраните его как index.html и добавьте в него следующий код:

- -
<!DOCTYPE html>
-<html>
-<head>
-    <meta charset="utf-8" />
-    <title>Gamedev Phaser Workshop - lesson 01: Initialize the framework</title>
-    <style>* { padding: 0; margin: 0; }</style>
-    <script src="js/phaser.min.js"></script>
-</head>
-<body>
-<script>
-    var game = new Phaser.Game(480, 320, Phaser.CANVAS, null, {
-      preload: preload, create: create, update: update
-    });
-    function preload() {}
-    function create() {}
-    function update() {}
-</script>
-</body>
-</html>
-
- -

Загрузка Phaser

- -

Дальше мы должны скачать исходный код фреймворка Phaser и использовать его в нашем HTML-документе. Это руководство использует Phaser V2, который не будет работать с текущей версией Phaser V3. Ссылка на скачивание Phaser V2 доступна в разделе Archive. 

- -
    -
  1. Перейдите на страницу загрузки Phaser.
  2. -
  3. Выберите наиболее удобный для вас вариант загрузки. Я рекоммендую min.js скачивание, потому что исходный код будет меньше, да и вам не придётся разбираться в нём.
  4. -
  5. Сохраните Phaser внутри /js директории, находящейся в том же месте, что и index.html
  6. -
  7. Обновите аттрибут src в первом элементе {{htmlelement("script")}}, как это показано выше.
  8. -
- -

Что мы имеем

- -

На данный момент у нас есть обозначенный charset, {{htmlelement("title")}} и немного CSS, что убрать значения свойств margin и padding по умолчанию. Также мы добавили элемент {{htmlelement("script")}}, который позволяет использовать Phaser на странице. Во втором {{htmlelement("script")}} мы написали код, который позволит отображать игру и управлять ею. 

- -

Фреймворк автоматически создаёт элемент {{htmlelement("canvas")}}. Мы инициализировали его, создав новый Phaser.Game объект и присвоив его переменной. Также мы добавили параметры:

- - - -
-

Важно: До конца прохождения всех уроков вы должны использовать CANVAS, как метод рендеринга, а не AUTO, как это было в нашем коде. Всё это нужно, потому что метод AUTO больше не поддерживается в последних версиях браузера.

-
- -

Сравните свой код

- -

Это весь исходный код, который мы написали на этом уроке:

- -

{{JSFiddleEmbed("https://jsfiddle.net/end3r/h6cwzv2b/","","400")}}

- -

Следующее

- -

Мы создали базовую HTML структуру и узнали немного об инициализации Phaser. Давайте продолжим и узнаем про масштабирование.

- -

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Scaling")}}

diff --git "a/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/load_the_assets_and_print_them_on_screen/index.html" "b/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/load_the_assets_and_print_them_on_screen/index.html" deleted file mode 100644 index 57274a84c0..0000000000 --- "a/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/load_the_assets_and_print_them_on_screen/index.html" +++ /dev/null @@ -1,73 +0,0 @@ ---- -title: Загрузка ресурсов и их вывод -slug: >- - Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Load_the_assets_and_print_them_on_screen -tags: - - 2D - - Canvas - - JavaScript - - Phaser -translation_of: >- - Games/Tutorials/2D_breakout_game_Phaser/Load_the_assets_and_print_them_on_screen ---- -
{{GamesSidebar}}
- -
{{IncludeSubnav("/ru/docs/Games")}}
- -

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Scaling", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Move_the_ball")}}

- -
-

Это 3-й урок из 16 в руководстве 2D игра на Phaser. Весь исходный код из этого урока вы можете найти на Gamedev-Phaser-Content-Kit/demos/lesson03.html.

-
- -

В нашей игре будет мяч, который движется по экрану, отскакивает от стен и уничтожает блоки, чтобы заработать очки. Знакомо? В этом уроке мы посмотрим, как добавлять спрайты в наш игровой мир.

- -

Создание мяча

- -

Давайте начнём с создания JavaScript переменной для нашего мячика. Добавьте следующий код между строкой инициализации (var game...) и функцией preload():

- -
var ball;
-
- -
-

Примечание: В этом уроке мы для удобства будем использовать глобальные переменные, потому что цель урока - научить пользоваться Phaser для создания игр, а не хорошим практикам разработки.

-
- -

Загрузка спрайта мяча

- -

Загрузка и вывод изображений в canvas намного проще с использованием Phaser, чем чистым JavaScript. Чтобы загрузить спрайт, мы будем использовать метод load.image() объекта game. Добавьте новую строку кода в функцию preload():

- -
function preload() {
-    // ...
-    game.load.image('ball', 'img/ball.png');
-}
-
- -

Первым параметром, которому мы хотим присвоить имя картинки, является имя, которое будет использоваться в нашем игровом коде - например, в нашем имени переменной ball - поэтому мы должны убедиться, что оно совпадает. Второй параметр - это относительный путь к самой картинке, мы загружаем спрайт для нашего мяча. (Заметьте, что имя файла (asset) не обязано совпадать с именем переменной, которой оно присваивается, однако так проще).

- -

Конечно, чтобы загрузить картинку, она должна находиться в нашей рабочей директории. Скачайте изображение с GitHub и сохраните его в /img директории, которая находится там же, где и файл index.html.

- -

Теперь, чтобы вывести наш мяч на экран, мы используем другой метод add.sprite(). Добавьте следующую строку кода в функцию create():  

- -
function create() {
-    ball = game.add.sprite(50, 50, 'ball');
-}
-
- -

Это метод добавит мяч в игру и выведет его на экран. Первые два параметра — это координаты x и y элемента canvas соответственно, и последний параметр — это имя картинки, которое мы добавили раннее. Вот и всё: загрузите index.html, и вы увидите, что картинка уже загружена и выведена в canvas!

- -
-

Важно: Если вы храните ваш JavaScript код отдельно от HTML и используете файл для этого, например, game.js, тогда вам нужно расположить директорию img и JavaScript файл в одной папке, иначе картинка не загрузится. 

-
- -

Сравните свой код

- -

Вы можете проверить код из этого урока и поиграть с ним, чтобы лучше понять, как он работает:

- -

{{JSFiddleEmbed("https://jsfiddle.net/end3r/98xrv9x5/","","400")}}

- -

Следующее

- -

Вывод мяча на экран был достаточно прост, теперь попробуем переместить его.

- -

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Scaling", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Move_the_ball")}}

diff --git "a/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/move_the_ball/index.html" "b/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/move_the_ball/index.html" deleted file mode 100644 index deed4a9494..0000000000 --- "a/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/move_the_ball/index.html" +++ /dev/null @@ -1,48 +0,0 @@ ---- -title: Движение мяча -slug: Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Move_the_ball -tags: - - 2D - - Beginner - - Canvas - - JavaScript - - Phaser -translation_of: Games/Tutorials/2D_breakout_game_Phaser/Move_the_ball ---- -
{{GamesSidebar}}
- -
{{IncludeSubnav("/ru/docs/")}}
- -

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Load_the_assets_and_print_them_on_screen", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Physics")}}

- -
-

Это 4-й урок из 16, которые входят в руководство 2D игра на Phaser. Вы можете найти исходный код этого урока на Gamedev-Phaser-Content-Kit/demos/lesson04.html.

-
- -

У нас есть синий мячик на экране, но он ничего не делает, поэтому будет круто, если он начнёт двигаться. В этом уроке мы узнаем, как это сделать.

- -

Обновление позиции мяча на каждом кадре

- -

Помните функцию update() и её назначение? Код внутри этой функции выполняется на каждом кадре, так что это идеальное место для кода, который будет обновлять положение нашего мяча. Добавьте следующие строки внутри update():

- -
function update() {
-    ball.x += 1;
-    ball.y += 1;
-}
-
- -

Код выше добавляет 1 к свойствам x и y, которые отвечают за координаты мяча в canvas на каждом кадре. Перезагрузив index.html, вы должны увидеть, как наш мячик движется. 

- -

Сравните свой код

- -

Вы можете проверить код из этого урока и поиграть с ним, чтобы лучше понять, как он работает:

- -

{{JSFiddleEmbed("https://jsfiddle.net/end3r/g1cfp0vv/","","400")}}

- -

Следующее

- -

Дальше мы должны добавить обнаружение столкновения мяча со стенками так, чтобы он отскакивал от них. Для этого нужно несколько строк кода, но дальше будет сложнее, особенно если мы хотим добавить обработку столкновений мяча и платформы. К счастью, Phaser позволяет нам делать всё это проще, чем если бы мы использовали чистый JavaScript.

- -

В любом случае перед тем, как сделать это, мы рассмотрим физический движок Phaser. 

- -

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Load_the_assets_and_print_them_on_screen", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Physics")}}

diff --git "a/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/physics/index.html" "b/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/physics/index.html" deleted file mode 100644 index 20acffa239..0000000000 --- "a/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/physics/index.html" +++ /dev/null @@ -1,98 +0,0 @@ ---- -title: Физика -slug: Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Physics -tags: - - 2D - - Beginner - - Canvas - - JavaScript - - Phaser -translation_of: Games/Tutorials/2D_breakout_game_Phaser/Physics ---- -
{{GamesSidebar}}
- -
{{IncludeSubnav("/ru/docs")}}
- -

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Move_the_ball", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Bounce_off_the_walls")}}

- -
-

Это 5 урок из 16, которые входят в руководство 2D игра на Phaser. Вы можете найти исходный код этого урока на Gamedev-Phaser-Content-Kit/demos/lesson05.html.

-
- -

Для правильного определения столкновений нам необходима физика, и в этом уроке мы покажем, что есть у Phaser на этот счёт, продемонстрировав это на простом примере.

- -

Добавление физики

- -

В Phaser есть три разных физических движка: Arcade Physics, P2 и Ninja Physics. Также есть четвёртый Box2D как платный плагин. Для нашей простой игры мы будем использовать Arcade Physics, потому что нам не нужны сложные геометрические вычисления.

- -

Во-первых, инициализируем Arcade Physics в нашей игре. Добавьте метод physics.startSystem() в начале функции create(). Убедитесь, что следующая строка кода находится в самом начале функции create():

- -
game.physics.startSystem(Phaser.Physics.ARCADE);
-
- -

Во-вторых, нам необходимо добавить мяч в физическую систему, потому что объект, отвечающий за физику в Phaser, не включен по умолчанию. Добавьте следующую строку в конце функции create()

- -
game.physics.enable(ball, Phaser.Physics.ARCADE);
-
- -

В-третьих, теперь мы можем установить значение свойства velocity нашего мяча через body. Добавьте следующую строку снова в конце функции create():

- -
ball.body.velocity.set(150, 150);
-
- -

Удаление предыдущих инструкций при обновлении

- -

Теперь нам надо убрать старый код, который добавлял 1 к координатам x и y в функции update(): 

- -
function update() {
-    ball.x += 1;
-    ball.y += 1;
-}
-
- -

теперь мы сделали тоже самое, но на физическом движке.

- -

Финальный код

- -

Весь код должен выглядеть вот так:

- -
var ball;
-
-function preload() {
-    game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
-    game.scale.pageAlignHorizontally = true;
-    game.scale.pageAlignVertically = true;
-    game.stage.backgroundColor = '#eee';
-    game.load.image('ball', 'img/ball.png');
-}
-
-function create() {
-    game.physics.startSystem(Phaser.Physics.ARCADE);
-    ball = game.add.sprite(50, 50, 'ball');
-    game.physics.enable(ball, Phaser.Physics.ARCADE);
-    ball.body.velocity.set(150, 150);
-}
-
-function update() {
-}
-
- -

Снова перезагрузите index.html. Мячик должен постоянно двигаться в направлении, которое мы задали. На данный момент в физическом движке гравитация (gravity) и трение (friction) имеют нулевое значение. Добавление гравитации заставит мячик падать вниз, пока трение будет пытаться остановить его.

- -

Поиграйте с физикой

- -

Вы можете делать гораздо больше вещей с физикой. Например, добавив ball.body.gravity.y = 100, вы установите вертикальную гравитацию для мячика. Как результат он будет сначала запущен вверх, но затем начнёт падать, находясь под действием гравитации.

- -

Это лишь верхушка айсберга: есть огромное количество перменных и функции, с помощью которых вы можете взаимодействовать с физическими объектами. Посмотрите официальную документацию, чтобы увидеть огромное количество примеров применения Arcade и P2.

- -

Сравните свой код

- -

Вы можете проверить код из этого урока и поиграть с ним, чтобы лучше понять, как он работает:

- -

{{JSFiddleEmbed("https://jsfiddle.net/end3r/bjto9nj8/","","400")}}

- -

Следующее

- -

Теперь мы можем посмотреть, как заставить мяч отскакивать от стен.

- -

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Move_the_ball", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Bounce_off_the_walls")}}

diff --git "a/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/scaling/index.html" "b/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/scaling/index.html" deleted file mode 100644 index 395e9f52de..0000000000 --- "a/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/scaling/index.html" +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: Масштабирование -slug: Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Scaling -tags: - - 2D - - Canvas - - JavaScript - - Phaser - - Начинающий -translation_of: Games/Tutorials/2D_breakout_game_Phaser/Scaling ---- -
{{GamesSidebar}}
- -
{{IncludeSubnav("/ru/docs/Games")}}
- -

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Initialize_the_framework", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Load_the_assets_and_print_them_on_screen")}}

- -
-

Это 2-й урок из 16, которые входят в руководство 2D игра на Phaser. Вы можете найти исходный код этого урока на Gamedev-Phaser-Content-Kit/demos/lesson02.html.

-
- -

Масштабирование отвечает за то, как ваша игра будет выглядеть на экранах разных размеров. Мы можем заставить игру масштабироваться под каждый экран автоматически во время стадии предзагрузки (preload), чтобы нам не пришлось волноваться об этом в будущем.

- -

Масштабирование 

- -

В Phaser есть специальный объект scale, которые имеет несколько полезных методов и свойств. Измените вашу функцию preload() так, как показано ниже:

- -
function preload() {
-    game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
-    game.scale.pageAlignHorizontally = true;
-    game.scale.pageAlignVertically = true;
-}
-
- -

scaleMode имеет несколько опций, которые определяют, как {{htmlelement("canvas")}} будет масштабироваться:

- - - -

Две другие строчки кода в функции preload() отвечают за вертикальное и горизонтальное выравнивание элемента {{htmlelement("canvas")}}, так что он всегда будет находиться по центру независимо от размера экрана.

- -

Изменение цвета фона

- -

Мы также можем сделать фон нашего элемента {{htmlelement("canvas")}} таким, каким захотим, чтобы он не оставался постоянно чёрным. Объект stage имеет свойство backgroundColor для этого. Мы можем изменить значение, используя синтаксис CSS для цветов. Добавьте эту строку после трёх, недавно добавленных: 

- -
game.stage.backgroundColor = '#eee';
-
- -

Сравните свой код

- -

Вы можете сравнить весь код из этого урока со своим и поиграть с ним, чтобы понять, как он работает:

- -

{{JSFiddleEmbed("https://jsfiddle.net/end3r/6a64vecL/","","400")}}

- -

Следующее

- -

Мы научились масштабировать нашу игру, так что давайте перейдём к третьему уроку и узнаем, как загружать ресурсы игры и выводить их.

- -

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Initialize_the_framework", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Load_the_assets_and_print_them_on_screen")}}

diff --git "a/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/\320\266\320\270\320\267\320\275\320\270/index.html" "b/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/\320\266\320\270\320\267\320\275\320\270/index.html" deleted file mode 100644 index b6bb403469..0000000000 --- "a/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/\320\266\320\270\320\267\320\275\320\270/index.html" +++ /dev/null @@ -1,117 +0,0 @@ ---- -title: Жизни -slug: Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Жизни -translation_of: Games/Tutorials/2D_breakout_game_Phaser/Extra_lives ---- -
{{GamesSidebar}}
- -
{{IncludeSubnav("/ru/docs")}}
- -

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Победа", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Анимация")}}

- -
-

Это 12 из 16 уроков руководства разработки игры с помощью Phaser. Исходный код этого урока вы можете найти здесь:  Gamedev-Phaser-Content-Kit/demos/lesson13.html.

-
- -

Мы можем растянуть удовольствие от игры, добавив жизни. Это позволит игроку сделать несколько попыток, а не одну.

- -

Новый переменные

- -

Добавьте следующие переменные сразу после всех наших текущих опеределений переменных:

- -
var lives = 3;
-var livesText;
-var lifeLostText;
-
- -

Эти переменные хранят, соответственно, количество жизней, надпись с количеством оставшихся жизней, и надпись, которая выведется на экран, если игрок потеряет жизнь.

- -

Определяем новые надписи

- -

Надписи мы уже определяли, когда реализовывали систему очков. Добавьте следующие строки кода в после определения надписи scoreText в функции create():

- -
livesText = game.add.text(game.world.width-5, 5, 'Lives: '+lives, { font: '18px Arial', fill: '#0095DD' });
-livesText.anchor.set(1,0);
-lifeLostText = game.add.text(game.world.width*0.5, game.world.height*0.5, 'Life lost, click to continue', { font: '18px Arial', fill: '#0095DD' });
-lifeLostText.anchor.set(0.5);
-lifeLostText.visible = false;
-
- -

Объекты livesText иlifeLostText очень похожи на scoreText — они определяют положение на экране, текст надписи и стилизацию шрифта. Чтобы всё выглядило должным образом, надпись с жизнями мы закрепляем в правом верхнем углу, а надпись о потере жизни, мы выводим в центре экрана. И всё это при помощи функции anchor.set().

- -

Надпись lifeLostText появится только при потере жизни, поэтому её видимость мы выставляем в false.

- -

Чистим код, стилизирующий надписи

- -

Как вы могли заметить, мы используем одинаковые стили для всех надписей: scoreText, livesText и lifeLostText. Однако, налицо копирование кода и если мы, когда-либо, захотим изменить размер шрифта или цвет, то нам придётся делать это в нескольких местах. Чтобы избежать этого, мы вынесем стиль в отдельную переменную. Напишите следующую строку сразу после всех наших текущих опеределений переменных:

- -
var textStyle = { font: '18px Arial', fill: '#0095DD' };
-
- -

Теперь мы можем использовать эту переменную для нашего текста — обновите ваш код и замените повторяющиеся участки со стилем текста на переменную.

- -
scoreText = game.add.text(5, 5, 'Points: 0', textStyle);
-livesText = game.add.text(game.world.width-5, 5, 'Lives: '+lives, textStyle);
-livesText.anchor.set(1,0);
-lifeLostText = game.add.text(game.world.width*0.5, game.world.height*0.5, 'Life lost, click to continue', textStyle);
-lifeLostText.anchor.set(0.5);
-lifeLostText.visible = false;
-
- -

Теперь, чтобы изменить стиль всего текста в игре, достаточно изменить только эту переменную.

- -

Код обработки жизни

- -

Чтобы реализовать жизнь в нашей игре, давайте сначала изменим функцию шара, связанную с событием onOutOfBounds. Вместо того, чтобы выполнять анонимную функцию и сразу показывать сообщение:

- -
ball.events.onOutOfBounds.add(function(){
-    alert('Game over!');
-    location.reload();
-}, this);
-
- -

Мы объявим новую функцию ballLeaveScreen; Удалим предыдущий обработчик (зачёркнутый код сверху) и заменим его следующей линией:

- -
ball.events.onOutOfBounds.add(ballLeaveScreen, this);
-
- -

Мы будем уменьшать количество жизней каждый раз, когда шар выйдет за пределы окна Canvas. Добавьте функцию ballLeaveScreen() в конец кода:

- -
function ballLeaveScreen() {
-    lives--;
-    if(lives) {
-        livesText.setText('Lives: '+lives);
-        lifeLostText.visible = true;
-        ball.reset(game.world.width*0.5, game.world.height-25);
-        paddle.reset(game.world.width*0.5, game.world.height-5);
-        game.input.onDown.addOnce(function(){
-            lifeLostText.visible = false;
-            ball.body.velocity.set(150, -150);
-        }, this);
-    }
-    else {
-        alert('You lost, game over!');
-        location.reload();
-    }
-}
-
- -

Вместо того, чтобы сразу вызывать сообщение, когда мяч выходит за пределы Canvas, мы сначала вычитаем одну жизнь из текущего числа и проверяем, не равно ли оно нулю. Если не равно, то у игрока все еще осталось несколько жизней, и он может продолжать играть - он увидит сообщение о потере жизни, позиции мяча и платформы будут сброшены и при следующем клике мышью сообщение будет скрыто и мяч снова начнет двигаться.

- -

Когда количество жизней достигнет нуля игра заканчивается, а игроку показывается соответствующее сообщение.

- -

События

- -

Скорее всего вы заметили вызов методов add() и addOnce() в двух блоках кода выше и хотите знать, чем они отличаются. Разница в том, что метод add()  и привязанная к нему функция выполняется каждый раз, когда выполняется событие, тогда как метод  addOnce() полезен, когда вы хотите, чтобы связанная с ним функция выполнилась единожды и не повторялась снова. В нашем случае при каждом событии outOfBounds будет выполняться ballLeaveScreen, но когда мяч покидает экран, сообщение с экрана удалится единожды.

- -

Проверь свой код

- -

Вы можете проверить готовый код этого урока в его демо-версии и поиграть с ним чтобы лучше понять, как он работает:

- -

{{JSFiddleEmbed("https://jsfiddle.net/end3r/yk1c5n0b/","","400")}}

- -

Следующий шаг

- -

Жизни делают игру более казуальной — даже если вы проиграете единожды, у вас будут еще 2 жизни и вы сможете продолжить игру. Теперь мы можем поработать над внешним видом игры, сделать ее более красивой, добавив анимацию и эффекты .

- -

{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Win_the_game", "Games/Workflows/2D_Breakout_game_Phaser/Animations_and_tweens")}}

diff --git "a/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/\320\276\320\261\321\200\320\260\320\261\320\276\321\202\320\272\320\260_\320\272\320\276\320\273\320\273\320\270\320\267\320\270\320\271/index.html" "b/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/\320\276\320\261\321\200\320\260\320\261\320\276\321\202\320\272\320\260_\320\272\320\276\320\273\320\273\320\270\320\267\320\270\320\271/index.html" deleted file mode 100644 index e3fb27724b..0000000000 --- "a/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/\320\276\320\261\321\200\320\260\320\261\320\276\321\202\320\272\320\260_\320\272\320\276\320\273\320\273\320\270\320\267\320\270\320\271/index.html" +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: Обработка коллизий -slug: Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Обработка_коллизий -translation_of: Games/Tutorials/2D_breakout_game_Phaser/Collision_detection ---- -
{{GamesSidebar}}
- -
{{IncludeSubnav("/ru/docs")}}
- -

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Создание_кирпичей", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Очки")}}

- -
-

Это 10 из 16 уроков руководства разработки игры с помощью Phaser. Исходный код этого урока вы можете найти здесь:  Gamedev-Phaser-Content-Kit/demos/lesson10.html.

-
- -

Наша текущая задач — проверка коллизий между мячиком и кирпичами. К счастью, при помощи движка, мы можем проверить коллизии не только между двумя объектами (как это было с мячиком и платформой), но и между объектом и набором других объектов.

- -

Проверяем коллизии Мячик/Кирпич

- -

Физический движок облегчает очень многие задачи — нам понадобится, всего лишь, несколько простых кусочков кода. Для начала, добавим в функцию update() строчку проверки коллизий между мячиком и кирпичами, как показано ниже:

- -
function update() {
-    game.physics.arcade.collide(ball, paddle);
-    game.physics.arcade.collide(ball, bricks, ballHitBrick);
-    paddle.x = game.input.x || game.world.width*0.5;
-}
-
- -

Теперь будет отслеживаться положение мячика, относительно всех кирпичей из набора bricks. Третьим (опциальным) параметром, мы передаём функцию, которая будет выполняться каждый раз, когда будет найдена коллизия — ballHitBrick. Давайте создадим эту функцию в самом конце нашего кода, прямо перед </script>:

- -
function ballHitBrick(ball, brick) {
-    brick.kill();
-}
-
- -

Вот и всё! Перезагрузите страницу и вы увидите, что все коллизии обрабатывается, как следует.

- -

Спасибо Phaser за то, что передал нам в функцию эти два параметра — мячик и тот кирпич, с которым у мячика произошла коллизия. А дальше мы просто удаляем кирпчи с экрана, вызвав у него функцию kill().

- -

Вы думали, что нам придётся писать много кода для отслеживания коллизий, как мы это делали на чистом JavaScript? В этом и прелесть фреймворков — рутину они сделают за нас, а мы, в это время, можем сосредоточиться на действительно интересных вещах.

- -

Сравните свой код

- -

Вы можете проверить код из этого урока и поиграть с ним, чтобы лучше понять, как он работает:

- -

{{JSFiddleEmbed("https://jsfiddle.net/end3r/wwneakwf/","","400")}}

- -

Следующий шаг

- -

Теперь мы можем разбивать кирпичи, а это уже отличное дополнение к нашему геймплею. Будет ещё лучше, если мы сможем считать количество разбитых кирпичей и присуждать за это очки.

- -

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Создание_кирпичей", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Очки")}}

diff --git "a/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/\320\276\321\207\320\272\320\270/index.html" "b/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/\320\276\321\207\320\272\320\270/index.html" deleted file mode 100644 index 9f4b18ace1..0000000000 --- "a/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/\320\276\321\207\320\272\320\270/index.html" +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: Очки -slug: Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Очки -translation_of: Games/Tutorials/2D_breakout_game_Phaser/The_score ---- -
{{GamesSidebar}}
- -
{{IncludeSubnav("/ru/docs/")}}
- -

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Обработка_коллизий", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Победа")}}

- -
-

Это 11 из 16 уроков руководства разработки игры с помощью Phaser. Исходный код этого урока вы можете найти здесь:  Gamedev-Phaser-Content-Kit/demos/lesson11.html.

-
- -

Очки сделают игру более интересной — вы можете пробовать побить собственный рекорд или рекорд друзей. В этой главе мы добавим систему очков в нашу игру.

- -

Мы будем использовать отдельные переменные для хранения количества очков и текста, который Phaser выведет на экран при помощи функции text().

- -

Определим переменные

- -

Добавьте две новых переменных после всех наших текущих опеределений переменных:

- -
// ...
-var scoreText;
-var score = 0;
-
- -

Выводим очки на экран

- -

А сейчас добавим строку кода в самый конец функции create():

- -
scoreText = game.add.text(5, 5, 'Points: 0', { font: '18px Arial', fill: '#0095DD' });
-
- -

Функция text() может принимать четыре параметра:

- - - -

Последний параметр выглядит очень похожим на CSS-стиль. В нашем случае, текст будет голубой, размер 18 пикселей, шрифт Arial.

- -

Обновляем очки при разрушении кирпича

- -

Мы будем увеличивать количество очков каждый раз, когда мячик разобьёт кирпич и обновлять текст scoreText, который отображает на экране текущие очки. Текст обновляется вызовом функции setText(). Добавьте эти две строчки кода в функцию ballHitBrick():

- -
function ballHitBrick(ball, brick) {
-    brick.kill();
-    score += 10;
-    scoreText.setText('Points: '+score);
-}
-
- -

Вот и всё — обновите страницу index.html и проверьте, как очки изменяются, при разрушении кирпича.

- -

Сравните свой код

- -

Вы можете проверить код из этого урока и поиграть с ним, чтобы лучше понять, как он работает:

- -

{{JSFiddleEmbed("https://jsfiddle.net/end3r/n8o6rhrf/","","400")}}

- -

Следующий шаг

- -

Теперь мы имеем систему очков, но какой смысл в этом, если мы не можем выиграть? Давайте добавим логику выигрыша.

- -

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Обработка_коллизий", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Победа")}}

diff --git "a/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/\320\277\320\273\320\260\321\202\321\204\320\276\321\200\320\274\320\260_\320\270_\321\203\320\277\321\200\320\260\320\262\320\273\320\265\320\275\320\270\320\265/index.html" "b/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/\320\277\320\273\320\260\321\202\321\204\320\276\321\200\320\274\320\260_\320\270_\321\203\320\277\321\200\320\260\320\262\320\273\320\265\320\275\320\270\320\265/index.html" deleted file mode 100644 index 46713cdddb..0000000000 --- "a/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/\320\277\320\273\320\260\321\202\321\204\320\276\321\200\320\274\320\260_\320\270_\321\203\320\277\321\200\320\260\320\262\320\273\320\265\320\275\320\270\320\265/index.html" +++ /dev/null @@ -1,116 +0,0 @@ ---- -title: Платформа и управление -slug: Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Платформа_и_управление -translation_of: Games/Tutorials/2D_breakout_game_Phaser/Player_paddle_and_controls ---- -
{{GamesSidebar}}
- -
{{IncludeSubnav("/ru/docs/")}}
- -

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Bounce_off_the_walls", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Game_over")}}

- -
-

Это из 16 уроков руководства разработки игры с помощью Phaser. Исходный код этого урока вы можете найти здесь: Gamedev-Phaser-Content-Kit/demos/lesson07.html.

-
- -

Теперь, когда мы научили мячик двигаться и отскакивать от стен, давайте добавим немного геймплея. В этой главе мы создадим платформу-ракетку, которой будем отбивать наш мячик.

- -

Рисуем платформу

- -

С точки зрения фреймворка, платформа и мячик не сильно различаются - нам так же понадобится переменная для платформы, спрайт и немного магии.

- -

Создаем платформу

- -

Сначала, добавим переменную paddle, сразу после переменной ball:

- -
var paddle;
-
- -

После этого, в функции preload, загрузим изображение paddle при помощи ещё одного вызова функции load.image():

- -
function preload() {
-    // ...
-    game.load.image('ball', 'img/ball.png');
-    game.load.image('paddle', 'img/paddle.png');
-}
-
- -

Добавляем графику для платформы

- -

Чуть не забыли, на этом этапе нам надо скачать изображение платформы с Github в папку /img.

- -

Рисуем платформу с физикой

- -

Далее, мы инициализируем спрайт нашей платформы при помощи функции add.sprite() — добавьте следующую строку кода в самый конец функции create():

- -
paddle = game.add.sprite(game.world.width*0.5, game.world.height-5, 'paddle');
-
- -

Мы можем использовать world.width и world.height для позиционирования платформы в том месте, где мы хотим: game.world.width*0.5 расположит платформу прямо по середине экрана. В данном случае, нам повезло, что наш игровой мир совпадает с <canvas>, однако, в других играх мир может быть гараздо больше экрана. 

- -

Как вы могли заметить, перезагрузив, на данном этапе, страницу index.html, платформа находится не совсем по середине экрана. Почему? Всё дело в том, что, по умолчанию, точка, из которой начинается позиционирование объекта (якорь), находится в левом верхнем углу. Но мы можем это изменить и переместить якорь в середину платформы по ширине и в самый низ повысоте, чтобы проще было позиционировать платформу, относительно нижней грани экрана. Добавьте следующую строку кода:

- -
paddle.anchor.set(0.5,1);
-
- -

Платформу расположили там, где и хотели. Теперь, чтобы платформа могла взаимодействовать с мячиком, добавим ей физику. Добавьте следующую строку кода в самый низ функции create():

- -
game.physics.enable(paddle, Phaser.Physics.ARCADE);
-
- -

Вот и настало время для магии - фреймворк сам позаботится о проверке столкновений (коллизий) в каждом кадре. Для того, чтобы включить проверку коллизий между платформой и мячиком, вызовите функцию collide() в функции update() как показано ниже:

- -
function update() {
-    game.physics.arcade.collide(ball, paddle);
-}
-
- -

В качестве аргументов, мы передаём два объекта, между которыми проверяются коллизии — в нашем случае, мячик и платформа. Вроде, сработало, но не совсем так, как мы ожидали — когда мячик сталкивается с платформой, последняя падает за пределы экрана! А мы, всего лишь, хотим, чтобы мячик отскакивал от платформы, а платформа, при этом, оставалась на месте. Мы можем использовать свойство immovable, для того, чтобы платформа не двигалась, когда мячик бьётся об неё. Для этого добавьте следующую строку кода в конец функции create():

- -
paddle.body.immovable = true;
-
- -

Вот! Теперь всё работает, как надо.

- -

Управляем платформой

- -

Следующая проблема заключается в том, что мы не можем двигать платформу. Чтобы сделать это мы можем воспользоваться вводом input (мышь или сенсорный экран, в зависимости от платформы) и расположить нашу плаформу в месте расположения курсора. Добавьте следующую строку кода в функцию update(), как показано ниже:

- -
function update() {
-    game.physics.arcade.collide(ball, paddle);
-    paddle.x = game.input.x;
-}
-
- -

Теперь, каждый кадр координата x платформы будет соответствовать координате x курсора. Однако, при старте игры, положение нашей платформы не по центру экрана, из-за того, что положение курсора не определено. Чтобы это исправить, давайте добавим платформе координату x по умолчанию, на случаей, если положение курсора не определено. Обновите предыдущую строку кода:

- -
paddle.x = game.input.x || game.world.width*0.5;
-
- -

Если вы этого ещё не сделали, то обновите страницу index.html и попробуйте то, что у нас получилось!

- -

Расположение мячика

- -

Теперь давайте разместим мячик на платформе. Так же, как и платформу, расположим мячик по середине экрана по горизонтали, с небольшим отступом от нижней грани экрана по вертикали. Для этого переместим якорь мячика в его середину. Найдите строку ball = game.add.sprite( ... ) и заметите её на следующие две:

- -
ball = game.add.sprite(game.world.width*0.5, game.world.height-25, 'ball');
-ball.anchor.set(0.5);
- -

Скорость оставим такую же, но изменим направление по оси y, изменив второй параметр со 150 на -150, и теперь мяч будет двигаться вверх. Найдите строку ball.body.velocity.set( ... ) и измените её, как показано ниже:

- -
ball.body.velocity.set(150, -150);
-
- -

Теперь мячик появляется по середине платформы и двигается вверх.

- -

Сравните свой код

- -

Вы можете проверить код из этого урока и поиграть с ним, чтобы лучше понять, как он работает:

- -

{{JSFiddleEmbed("https://jsfiddle.net/end3r/ogqza0ye/","","400")}}

- -

Следующий шаг

- -

Мы можем управлять платформой и сделали так, чтобы мячик отскакивал от неё. Но какой от этого толк, если мячик отскакивает и от нижней грани экрана? В следующей главе мы добавим логику проигрыша и экран "Game over".

- -

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Bounce_off_the_walls", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Game_over")}}

diff --git "a/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/\320\277\320\276\320\261\320\265\320\264\320\260/index.html" "b/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/\320\277\320\276\320\261\320\265\320\264\320\260/index.html" deleted file mode 100644 index 21ff763bbf..0000000000 --- "a/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/\320\277\320\276\320\261\320\265\320\264\320\260/index.html" +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: Победа -slug: Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Победа -translation_of: Games/Tutorials/2D_breakout_game_Phaser/Win_the_game ---- -
{{GamesSidebar}}
- -
{{IncludeSubnav("/ru/docs/Games")}}
- -

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Очки", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Жизни")}}

- -
-

Это 12 из 16 уроков руководства разработки игры с помощью Phaser. Исходный код этого урока вы можете найти здесь:  Gamedev-Phaser-Content-Kit/demos/lesson12.html.

-
- -

Победа в нашей игре будет достаточно простой: если ты разрушил все кирпичи, то победил.

- -

Как победить?

- -

Добавьте следующий код в функцию ballHitBrick():

- -
function ballHitBrick(ball, brick) {
-    brick.kill();
-    score += 10;
-    scoreText.setText('Points: '+score);
-
-    var count_alive = 0;
-    for (i = 0; i < bricks.children.length; i++) {
-      if (bricks.children[i].alive == true) {
-        count_alive++;
-      }
-    }
-    if (count_alive == 0) {
-      alert('You won the game, congratulations!');
-      location.reload();
-    }
-}
-
- -

Чтобы перебрать все кирпичи в наборе, необходимо обратиться к полю bricks.children. Найдём все неразрушенные кирпичи, проверяя поле alive у каждого кирпича и, если все кирпичи разрушены, выведем всплывающее окно с текстом о победе. После закрытия этого окна, страница перезагрузится.

- -

Сравните свой код

- -

Вы можете проверить код из этого урока и поиграть с ним, чтобы лучше понять, как он работает:

- - - -

{{JSFiddleEmbed("https://jsfiddle.net/u8waa4Lx/1/","","400")}}

- -

Следующий шаг

- -

Логику прогрыша и выигрыша мы сделали, так что, основная часть игры готова. Теперь давайте добавим какую-нибудь фишку — дадим игроку три жизни, вместо одной.

- -

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Очки", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Жизни")}}

diff --git "a/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\320\272\320\270\321\200\320\277\320\270\321\207\320\265\320\271/index.html" "b/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\320\272\320\270\321\200\320\277\320\270\321\207\320\265\320\271/index.html" deleted file mode 100644 index ffdd6c1d6d..0000000000 --- "a/files/ru/games/tutorials/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_2d_breakout_\320\270\320\263\321\200\321\213_\320\275\320\260_phaser/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\320\272\320\270\321\200\320\277\320\270\321\207\320\265\320\271/index.html" +++ /dev/null @@ -1,156 +0,0 @@ ---- -title: Создание кирпичей -slug: Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Создание_кирпичей -translation_of: Games/Tutorials/2D_breakout_game_Phaser/Build_the_brick_field ---- -
{{GamesSidebar}}
- -
{{IncludeSubnav("/ru/docs/Games")}}
- -

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Game_over", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Обработка_коллизий")}}

- -
-

Это из 16 уроков руководства разработки игры с помощью Phaser. Исходный код этого урока вы можете найти здесь:  Gamedev-Phaser-Content-Kit/demos/lesson09.html.

-
- -

Создать поле кирпичей немного сложнее, чем просто добавить объект на экран, но всё же, благодаря Phaser, нам будет полегче, по сравнению с чистым JavaScript. Давайте разберёмся, как создать набор кирпичей и нарисовать их всех, используя цикл.

- -

Определяем переменные

- -

Сначала, давайте определим необходимые переменные — добавьте следующий код ниже всех наших текущих опеределений переменных:

- -
var bricks;
-var newBrick;
-var brickInfo;
-
- -

Переменная bricks будет использоваться в качестве набора кирпичей, newBrick будет тем самым кирпичем, который мы будем создавать в каждой итерации цикла и добавлять в набор, а в brickInfo будет хранить всю необходимую информацию о кирпичах, как таковых.

- -

Добавляем графику для кирпича

- -

Далее, давайте загрузим изображение кирпича brick, при помощи ещё одного вызова функции load.image():

- -
function preload() {
-    // ...
-    game.load.image('brick', 'img/brick.png');
-}
-
- -

Не забудьте скачать изображение кирпича с Github в папку /img.

- -

Рисуем кирпичи

- -

Для удобства, давайте вынесем код отрисовки кирпичей в отдельную функцию initBricks и вызовем её в конце функции create():

- -
function create(){
-    // ...
-    initBricks();
-}
-
- -

Теперь перейдём непосредственно к самой функции. Добавим функцию initBricks() в самый конец нашего кода, прямо перед </script>, а в теле этой функции опишем объект brickInfo, который нам скоро понадобится:

- -
function initBricks() {
-    brickInfo = {
-        width: 50,
-        height: 20,
-        count: {
-            row: 3,
-            col: 7
-        },
-        offset: {
-            top: 50,
-            left: 60
-        },
-        padding: 10
-    };
-}
-
- -

Объект brickInfo содержит всю необходимую нам информацию о кирпичах: ширина и высота кирпичика, количество рядов и столбцов кирпичей, которые мы хотим отрисовать на игровом поле, отступы от левого и верхнего края экрана (место на <canvas>, откуда мы начнём располагать кирпичи) и зазоры между самими кирпичами.

- -

А теперь, собственно, к кирпичам — инициализируйте пустой набор для хранения кирпичей, путём добавления следующей строчки кода в функцию initBricks():

- -
bricks = game.add.group();
-
- -

Далее переберём в цикле ряды и столбцы — добавьте следующий код со вложенным циклом после предыдущей строки:

- -
for(c=0; c<brickInfo.count.col; c++) {
-    for(r=0; r<brickInfo.count.row; r++) {
-        // create new brick and add it to the group
-    }
-}
-
- -

Теперь необходимо в каждой итерации создавать кирпич, чтобы получить необходимое число кирпичей, нарисовать их всех на экране и добавить в наш набор bricks. Для этого добавим во вложенный цикл немного кода, как показано ниже:

- -
for(c=0; c<brickInfo.count.col; c++) {
-    for(r=0; r<brickInfo.count.row; r++) {
-        var brickX = 0;
-        var brickY = 0;
-        newBrick = game.add.sprite(brickX, brickY, 'brick');
-        game.physics.enable(newBrick, Phaser.Physics.ARCADE);
-        newBrick.body.immovable = true;
-        newBrick.anchor.set(0.5);
-        bricks.add(newBrick);
-    }
-}
-
- -

Вот мы и создали новый кирпич в каждой итерации и отрисовали его на экране. Как мы помним из урока 5, мы используем движок Arcade Physics. К каждому новому кирпичу применяем физику из этого движка и делаем его неподвижным, чтобы мячик его не сбивал, а, также, устанавливаем якорь кирпича в его середину. После этого, добавляем кирпич в набор bricks.

- -

Но у нас осталась проблема — все кирпичи мы рисуем в одном и том же месте, в координатах (0,0). Чтобы это исправить, давайте добавим вычисление координат brickX и brickY в каждой итерации. Обновите строки инициализации этих переменных, как показано ниже:

- -
var brickX = (c*(brickInfo.width+brickInfo.padding))+brickInfo.offset.left;
-var brickY = (r*(brickInfo.height+brickInfo.padding))+brickInfo.offset.top;
-
- -

Координата x каждого кирпича рассчитывается на основе суммы ширины кирпича brickInfo.width и зазора brickInfo.padding, умноженной на номер столбца с, после этого добавляем отступ от левого края brickInfo.offset.left; Рассчёт y аналогичен, только используются номер ряда r, высота кирпича brickInfo.height и отступ от верхнего края brickInfo.offset.top. Вот теперь каждый кирпич на своём месте, с учётом всех отступов и зазоров.

- -

Проверяем код функции initBricks()

- -

Вот итоговый код функции initBricks():

- -
function initBricks() {
-    brickInfo = {
-        width: 50,
-        height: 20,
-        count: {
-            row: 3,
-            col: 7
-        },
-        offset: {
-            top: 50,
-            left: 60
-        },
-        padding: 10
-    }
-    bricks = game.add.group();
-    for(c=0; c<brickInfo.count.col; c++) {
-        for(r=0; r<brickInfo.count.row; r++) {
-            var brickX = (c*(brickInfo.width+brickInfo.padding))+brickInfo.offset.left;
-            var brickY = (r*(brickInfo.height+brickInfo.padding))+brickInfo.offset.top;
-            newBrick = game.add.sprite(brickX, brickY, 'brick');
-            game.physics.enable(newBrick, Phaser.Physics.ARCADE);
-            newBrick.body.immovable = true;
-            newBrick.anchor.set(0.5);
-            bricks.add(newBrick);
-        }
-    }
-}
-
- -

Если вы перезапустите страницу index.html, то увидете кирпичи, нарисованные на расстоянии друг от друга.

- -

Сравните свой код

- -

Вы можете проверить код из этого урока и поиграть с ним, чтобы лучше понять, как он работает:

- -

{{JSFiddleEmbed("https://jsfiddle.net/end3r/cck2b9e8/","","400")}}

- -

Следующий шаг

- -

Кажется, что-то не так. Ах да! Мячик же проходит сквозь кирпичи. Добавим обработку коллизий.

- -

{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Game_over", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Обработка_коллизий")}}

diff --git "a/files/ru/games/\320\260\320\275\320\260\321\202\320\276\320\274\320\270\321\217/index.html" "b/files/ru/games/\320\260\320\275\320\260\321\202\320\276\320\274\320\270\321\217/index.html" deleted file mode 100644 index 0396fc4159..0000000000 --- "a/files/ru/games/\320\260\320\275\320\260\321\202\320\276\320\274\320\270\321\217/index.html" +++ /dev/null @@ -1,337 +0,0 @@ ---- -title: Анатомия видеоигры -slug: Games/Анатомия -translation_of: Games/Anatomy ---- -
{{GamesSidebar}}
- -

{{IncludeSubnav("/en-US/docs/Games")}}

- -
-

Эта статья рассматривает анатомию и рабочий процесс создания средней видеоигры с технической точки зрения и определений того, как должен выглядеть главный цикл приложения. Она служит для помощи начинающим разработчикам в разработке современных игр, а также для понимания того, что необходимо знать при построении игры и как применять различные web-стандарты и инструменты, такие как JavaScript. Опытные разработчики игр, которые только пришли в мир web-разработки тоже могут почерпнуть для себя много интересного.

-
- -

Показать, получить, преобразовать, вычислить, повторить

- -

Целью каждой видеоигры является  показ пользователю (пользователям) игровой ситуации, получение пользовательских сигналов, преобразования их в действия и вычисления новой ситуации как результат этих действий. Игры постоянно повторяют эти стадии, снова и снова, до тех пор пока не наступит завершающее условие (такое как победа, поражение, или выход из игры с целью поспать). Не удивительно, что данный шаблон соответствует тому как программируется игровая логика (движок).

- -

Особенности игр.

- -

Некоторые игры управляют своим циклом при помощи пользовательского ввода. Представьте, что вы разрабатываете игру типа "найди разницу между этими двумя похожими картинками". Такого рода игры показывают пользователю две картинки; они получают их клики (или касания); они преобразуют ввод в успешный , не успешный, пауза, работа с меню, и так далее; в конечном итоге, в зависимости от данных действий, они вычисляют обновленное состояние сцены. Игровой цикл продвигается пользовательскими действиями и "спит" пока таковые отсутствуют. Это пример так называемой пошаговой игры, которая не зависит от постоянного обновления каждого кадра, а только от действий пользователя.

- -

Другие игры требуют контроля над каждым из минимально возможных индивидуальных временных интервалов. Те же принципы, что и выше, применяются с небольшим изменением: каждый кадр анимации продолжает цикл, и любое изменение пользовательского ввода фиксируется на первом доступном ходе. Эта покадровая модель реализована в так называемом основном цикле. Если ваша игра зацикливается на времени, то это будет её полномочия, которые будут соблюдать ваши симуляции.

- -

Но покадровое управление может и не понадобиться. Ваш игровой цикл может быть похож на пример поиска отличий и основан на входных событиях. Это может потребовать как ввода, так и симуляции времени. Он может даже зацикливаться на чем-то совершенно другом.

- -

Современный JavaScript, как описано в следующих разделах, к счастью, позволяет легко разработать эффективный основной цикл выполнения один раз в кадр. Конечно, ваша игра будет оптимизирована настолько, насколько вы ее сделаете. Если что-то выглядит так, как будто оно должно быть прикрепленно к более редкому исходу, то часто бывает хорошей идеей вырвать его из основного цикла (но не всегда).

- -

Построение основного цикла в JavaScript 

- -

Лучше всего JavaScript работает с событиями и callback функциями. Современные браузеры стремятся вызывать методы по мере необходимости и бездействовать (или выполнять другие задачи) в промежутках. Привязать код к моменту, который для него подходит — это отличная идея.  Подумайте о том, действительно ли ваша функция должна вызываться на строго определенном интервале времени, в каждом кадре или только после того, как произойдет что-то еще.  Подумайте о том, действительно ли функцию нужно вызывать в определённом интервале времени, на каждый кадр или только после того, как что-то произойдёт. Больше конкретики с браузером в том, когда функция должна быть вызвана, позволяет ему лучше оптимизировать этот процесс. Так же, вероятно, это облегчит вам работу.   

- -

Некоторый код должен выполняться кадр за кадром, так зачем же прикреплять эту функцию к чему-то другому, кроме графика перерисовки браузера? В Web, {{ domxref("window.requestAnimationFrame()") }} будет основой большинства хорошо запрограммированных покадровых основных циклов.  Callback функция должна быть передана ему при вызове. Callback функция будет выполнена в подходящее время перед следующей перерисовкой. Вот пример простого основного цикла:

- -
window.main = function () {
-  window.requestAnimationFrame( main );
-
-  // Код, который цикл должен выполнить
-};
-
-main(); // Start the cycle
- -
-

Примечание: В каждом из методов main(), обсуждаемых здесь, мы планируем новый requestAnimationFrame перед выполнением нашего содержимого цикла. Это не случайно и считает лучшей практикой. Ранний вызов следующего requestAnimationFrame гарантирует, что браузер получит его вовремя, чтобы спланировать соответствующим образом, даже если ваш текущий кадр пропустит свое окно VSync.

-
- -

Приведенный выше фрагмент кода содержит два оператора. Первый оператор создает функцию как глобальную переменную с именем main().Эта функция выполняет некоторую работу, а также сообщает браузеру, что нужно вызвать следующий кадр с помощью window.requestAnimationFrame(). Второй оператор вызывает функцию main(), описанную в первом операторе. Поскольку main() вызывается один раз во втором операторе и каждый его вызов помещает себя в очерёдность действий, чтобы отрисовать следующий кадр, main() синхронизируется с вашей частотой кадров.

- -

Конечно, этот цикл не идеален. Прежде чем мы обсудим способы его изменения, давайте обсудим, что он уже делает хорошо.

- -

Синхронизация основного цикла с тем, когда браузер рисует на дисплее, позволяет запускать цикл так часто, как браузер хочет рисовать. Вам предоставляется контроль над каждым кадром анимации. Это также очень просто, потому что main() - единственная функция, которая зацикливается. Шутер от первого лица (или подобная игра) представляет новую сцену один раз в каждом кадре. Вы не можете добиться большей плавности и быстродействия.

- -

Но не стоит сразу предполагать, что анимация требует покадрового управления. Простые анимации можно легко выполнять даже с ускорением на GPU с помощью CSS-анимации и других инструментов, включенных в браузер. Их очень много и они сделают вашу жизнь проще.

- -

Создание улучшенного основного цикла в JavaScript.

- -

У нашего цикла есть две очевидные проблемы: main() загрязняет {{ domxref("window") }} объект (в нем хранятся все глобальные переменные) и код не оставляет нам возможность остановить цикл, если только вся вкладка не будет закрыта или обновлена. Для решения первой проблемы, если нужно, чтобы основной цикл просто выполнялся и вам не нужен легкий (прямой) доступ к нему, вы можете поместить его внутрь самовызывающейся Function Expression (IIFE).

- -
/*
-* Начинаем с точки с запятой в случае, если какая-либо строка кода выше данного примера
-* полагается на автоматическую вставку точки с запятой (ASI). Браузер может случайно решить,
-* что весь этот код начинается с предыдущей строки. Первая точка с запятой отмечает начало
-* новой строки, если предыдущая не была пустой или завершенной.
-*/
-
-;(function () {
-  function main() {
-    window.requestAnimationFrame( main );
-
-    // Содержание вашего основного цикла
-  }
-
-  main(); // Вызов цикла
-})();
- -

Когда браузер наткнется на IIFE (Immediately Invoked Function Expression), он определит основной цикл и сразу же поставит его в очередь для следующего кадра. Он не будет привязан ни к какому объекту, и main (или main() для методов) будет неиспользуемым именем, доступным в остальной части приложения для определения чего-то другого.

- -
-

Примечание: На практике распространено предотвращать следующий requestAnimationFrame() используя оператор if вместо вызова cancelAnimationFrame().

-
- -

Чтобы остановить основной цикл, вам понадобиться отменить вызов main() с помощью {{ domxref("window.cancelAnimationFrame()") }}. Необходимо передать в cancelAnimationFrame() идентификатор последнего вызова requestAnimationFrame(). Давайте предположим, что функции и переменные вашей игры были определены в пространстве имен, которое вы назвали MyGame.  В таком случае, основной цикл будет выглядеть следующим образом:

- -
/*
-* Начинаем с точки с запятой в случае, если какая-либо строка кода выше данного примера
-* полагается на автоматическую вставку точки с запятой (ASI). Браузер может случайно решить,
-* что весь этот код начинается с предыдущей строки. Первая точка с запятой отмечает начало
-* новой строки, если предыдущая не была пустой или завершенной.
-*
-* Давайте также предположим, что MyGame уже определена.
-*/
-
-;(function () {
-  function main() {
-    MyGame.stopMain = window.requestAnimationFrame( main );
-
-    // Содержание вашего основного цикла
-  }
-
-  main(); // Вызов цикла
-})();
- -

Теперь у нас есть переменная stopMain, объявленная в нашем пространстве имен MyGame, которая содержит идентификатор последнего вызова requestAnimationFrame() нашего основного цикла.  В любой момент мы может остановить основной цикл, сказав браузеру, чтобы тот отменил запрос, соответствующий последнему маркеру.

- -
window.cancelAnimationFrame( MyGame.stopMain );
- -

Ключ к программированию основного цикла в JavaScript заключается в том, чтобы прикрепить его к любому событию, которое должно управлять вашими действиями, и обращать внимание на то, как различные системы учавствуют во взаимодействии. У вас может быть несколько компонентов, управляемых несколькими различными типами событий. Это может показаться излишним усложнением, но также может быть просто хорошей оптимизацией (не обязательно, конечно). Проблема в том, что вы не выстраиваете типичный основной цикл. В JavaScript вы используйте основной цикл браузера и стараетесь сделать это эффективно. 

- -

Построение более оптимизированного основного цикла в JavaScript

- -

В конце контов, в JavaScript браузер выполняет свой собственный основной цикл, и ваш код существует на некоторых его этапах. В приведенных выше разделах описываются основные циклы, которые стараются не отнимать контроль у браузера. Их методы прикрепляют себя к  window.requestAnimationFrame(), который запрашивает контроль над предстоящим кадром у браузера.  Браузер решает, как связать эти запросы с их основным циклом. Спецификация W3C для requestAnimationFrame на самом деле точно не определяет, когда браузеры должны выполнять колбэки requestAnimationFrame. Это может быть приемуществом, поскольку позволяет поставщикам браузеров свободно экспериментировать с решениями, которые они считают лучшими, и настраивать их с течением времени.

- -

Современные версии Firefox и Google Chrome (вероятно, и другие) пытаются подключить колбэки requestAnimationFrame к своему основному потоку в самом начале временного интервала фрэйма. Таким образом основной поток браузера пытается выглядеть следующим образом: 

- -
    -
  1. Запустить новый кадр (пока предыдущий обрабатывается на дисплее.).
  2. -
  3. Пройтись по кэлбэкам requestAnimationFrame и вызвать их.
  4. -
  5. Выполнить сборку мусора и другие задачи для каждого кадра, когда вышеупомянутые колбэки перестают контролировать основной поток.
  6. -
  7. Спать (если только какое-либо событие не прервет сон браузера) до тех пор, пока монитор не будет готов к вашему изображению (VSync), и повторить его.
  8. -
- -

Вы можете думать о разработке realtime applications, как о запасе времени для работы. Все вышеперечисленные шаги должны выполняться каждые 16  с половиной миллисекунд, чтобы не отставать от дисплея с чистатой 60Гц.  Браузеры вызывают ваш код таким образом, чтобы предаставить ему максимум времени для вычислений. Ваш основной поток часто запускает рабочие нагрузки, которые даже не находятся в основном потоке (Например, растеризация или шейдеры в WebGL).  Большие вычисления могут выполняться на Web Worker-e или GPU одновременно с тем, как браузер использует свой основной поток для управления сборкой мусора, обработки асинхронных вызовов или других задач. 

- -

Пока мы обсуждаем распределение нашего временного бюджета, многие браузеры имеют инструмент под названием High Resolution Time. Объект {{ domxref("Date") }} больше не используется в качестве основного метода синхронизации событий, поскольку он очень не точен и может быть изменен системными часами. High Resolution Time, с другой стороны, подсчитывает колличество миллисекунд начиная с navigationStart (при выгрузке предыдущего документа). Это значение возвращается в виде десятичного числа с точностью до миллисекунды.  Он известен как DOMHighResTimeStamp, но для всех целей и задач считайте его числом с плавающей запятой.  

- -
-

Примечание: Системы (аппаратные или программные), которые не могу обеспечить точность в микросекундах, могут по крайней мере обеспечить точность в миллисекундах.  Однако, они должны обеспечивать точность до 0,001 мс, если способны на это. 

-
- - - -

Это значение нельзя использовать само по себе, потому что оно относиться к неинтересному событию, но его можно вычесть из другой временной ветки, чтобы четко и точно определить, сколько времени прошло между этими двумя точками. Чтобы получить одну из этих временных меток, вы можете вызвать window.performance.now() и сохранить результат в переменную. 

- -
var tNow = window.performance.now();
-
- -

Возвращаемся к основному циклу. Часто вам понадобиться узнать, когда ваша основная функция  была вызвана. Это обычное дело, window.requestAnimationFrame() при выполнени всегда предоставляет метку DOMHighResTimeStamp в качетве аргумента для функций обратного вызова (callbacks). Это приводит к очередному улучшению нашего основного цикла. 

- -
/*
-* Начинаем с точки с запятой в случае, если какая-либо строка кода выше данного примера
-* полагается на автоматическую вставку точки с запятой (ASI). Браузер может случайно решить,
-* что весь этот код начинается с предыдущей строки. Первая точка с запятой отмечает начало
-* новой строки, если предыдущая не была пустой или завершенной.
-*
-* Давайте также предположим, что MyGame уже определена.
-*/
-
-;(function () {
-  function main( tFrame ) {
-    MyGame.stopMain = window.requestAnimationFrame( main );
-
-    // Содержимое вашего основного цикла
-    // tFrame, из "function main ( tFrame )", это DOMHighResTimeStamp предоставленный requestAnimationFrame.
-  }
-
-  main(); // Начало цикла
-})();
- -

Возможно несколько других оптимизаций, которые зависят от того, что делает ваша игра. Ваш игровой жанр очевидно будет иметь значение, но он может быть даже более продуманным. 

- -

Several other optimizations are possible and it really depends on what your game attempts to accomplish. Your game genre will obviously make a difference but it could even be more subtle than that. You could draw every pixel individually on a canvas or you could layer DOM elements (including multiple WebGL canvases with transparent backgrounds if you want) into a complex hierarchy. Each of these paths will lead to different opportunities and constraints.

- -

It is decision... time

- -

You will need to make hard decisions about your main loop: how to simulate the accurate progress of time. If you demand per-frame control then you will need to determine how frequently your game will update and draw. You might even want update and draw to occur at different rates. You will also need to consider how gracefully your game will fail if the user's system cannot keep up with the workload. Let us start by assuming that you will handle user input and update the game state every time you draw. We will branch out later.

- -
-

Note: Changing how your main loop deals with time is a debugging nightmare, everywhere. Think about your needs carefully before working on your main loop.

-
- -

What most browser games should look like

- -

If your game can hit the maximum refresh rate of any hardware you support then your job is fairly easy. You can simply update, render, and then do nothing until VSync.

- -
/*
-* Starting with the semicolon is in case whatever line of code above this example
-* relied on automatic semicolon insertion (ASI). The browser could accidentally
-* think this whole example continues from the previous line. The leading semicolon
-* marks the beginning of our new line if the previous one was not empty or terminated.
-*
-* Let us also assume that MyGame is previously defined.
-*/
-
-;(function () {
-  function main( tFrame ) {
-    MyGame.stopMain = window.requestAnimationFrame( main );
-
-    update( tFrame ); // Call your update method. In our case, we give it rAF's timestamp.
-    render();
-  }
-
-  main(); // Start the cycle
-})();
- -

If the maximum refresh rate cannot be reached, quality settings could be adjusted to stay under your time budget. The most famous example of this concept is the game from id Software, RAGE. This game removed control from the user in order to keep its calculation time at roughly 16ms (or roughly 60fps). If computation took too long then rendered resolution would decrease, textures and other assets would fail to load or draw, and so forth. This (non-web) case study made a few assumptions and tradeoffs:

- - - -

Other ways to handle variable refresh rate needs

- -

Other methods of tackling the problem exist.

- -

One common technique is to update the simulation at a constant frequency and then draw as much (or as little) of the actual frames as possible. The update method can continue looping without care about what the user sees. The draw method can view the last update and when it happened. Since draw knows when it represents, and the simulation time for the last update, it can predict a plausible frame to draw for the user. It does not matter whether this is more frequent than the official update loop (or even less frequent). The update method sets checkpoints and, as frequently as the system allows, the render method draws instants of time around them. There are many ways to separate the update method in web standards:

- - - -

Each of these methods have similar tradeoffs:

- - - -

A separate update and draw method could look like the following example. For the sake of demonstration, the example is based on the third bullet point, just without using Web Workers for readability (and, let's be honest, writability).

- -
-

Note: This example, specifically, is in need of technical review.

-
- -
/*
-* Starting with the semicolon is in case whatever line of code above this example
-* relied on automatic semicolon insertion (ASI). The browser could accidentally
-* think this whole example continues from the previous line. The leading semicolon
-* marks the beginning of our new line if the previous one was not empty or terminated.
-*
-* Let us also assume that MyGame is previously defined.
-*
-* MyGame.lastRender keeps track of the last provided requestAnimationFrame timestamp.
-* MyGame.lastTick keeps track of the last update time. Always increments by tickLength.
-* MyGame.tickLength is how frequently the game state updates. It is 20 Hz (50ms) here.
-*
-* timeSinceTick is the time between requestAnimationFrame callback and last update.
-* numTicks is how many updates should have happened between these two rendered frames.
-*
-* render() is passed tFrame because it is assumed that the render method will calculate
-*          how long it has been since the most recently passed update tick for
-*          extrapolation (purely cosmetic for fast devices). It draws the scene.
-*
-* update() calculates the game state as of a given point in time. It should always
-*          increment by tickLength. It is the authority for game state. It is passed
-*          the DOMHighResTimeStamp for the time it represents (which, again, is always
-*          last update + MyGame.tickLength unless a pause feature is added, etc.)
-*
-* setInitialState() Performs whatever tasks are leftover before the mainloop must run.
-*                   It is just a generic example function that you might have added.
-*/
-
-;(function () {
-  function main( tFrame ) {
-    MyGame.stopMain = window.requestAnimationFrame( main );
-    var nextTick = MyGame.lastTick + MyGame.tickLength;
-    var numTicks = 0;
-
-    // If tFrame < nextTick then 0 ticks need to be updated (0 is default for numTicks).
-    // If tFrame = nextTick then 1 tick needs to be updated (and so forth).
-    // Note: As we mention in summary, you should keep track of how large numTicks is.
-    // If it is large, then either your game was asleep, or the machine cannot keep up.
-    if (tFrame > nextTick) {
-      var timeSinceTick = tFrame - MyGame.lastTick;
-      numTicks = Math.floor( timeSinceTick / MyGame.tickLength );
-    }
-
-    queueUpdates( numTicks );
-    render( tFrame );
-    MyGame.lastRender = tFrame;
-  }
-
-  function queueUpdates( numTicks ) {
-    for(var i=0; i < numTicks; i++) {
-      MyGame.lastTick = MyGame.lastTick + MyGame.tickLength; // Now lastTick is this tick.
-      update( MyGame.lastTick );
-    }
-  }
-
-  MyGame.lastTick = performance.now();
-  MyGame.lastRender = MyGame.lastTick; // Pretend the first draw was on first update.
-  MyGame.tickLength = 50; // This sets your simulation to run at 20Hz (50ms)
-
-  setInitialState();
-  main(performance.now()); // Start the cycle
-})();
- -

Another alternative is to simply do certain things less often. If a portion of your update loop is difficult to compute but insensitive to time, you might consider scaling back its frequency and, ideally, spreading it out into chunks throughout that lengthened period. An implicit example of this is found over at The Artillery Blog for Artillery Games, where they adjust their rate of garbage generation to optimize garbage collection. Obviously, cleaning up resources is not time sensitive (especially if tidying is more disruptive than the garbage itself).

- -

This may also apply to some of your own tasks. Those are good candidates to throttle when available resources become a concern.

- -

Summary

- -

I want to be clear that any of the above, or none of them, could be best for your game. The correct decision entirely depends on the trade-offs that you are willing (and unwilling) to make. The concern is mostly with switching to another option. Fortunately, I do not have any experience with this, but I have heard it is an excruciating game of Whack-a-Mole.

- -

An important thing to remember for managed platforms, like the web, is that your loop may stop execution for significant periods of time. This could occur when the user unselects your tab and the browser sleeps (or slows) its requestAnimationFrame callback interval. You have many ways to deal with this situation and this could depend on whether your game is single player or multiplayer. Some choices are:

- - - -

Once your main loop has been developed and you have decided on a set of assumptions and tradeoffs which suit your game, it is now just a matter of using your decisions to calculate any applicable physics, AI, sounds, network synchronization, and whatever else your game may require.

diff --git "a/files/ru/games/\320\262\320\262\320\276\320\264/index.html" "b/files/ru/games/\320\262\320\262\320\276\320\264/index.html" deleted file mode 100644 index 65d1aed2c0..0000000000 --- "a/files/ru/games/\320\262\320\262\320\276\320\264/index.html" +++ /dev/null @@ -1,121 +0,0 @@ ---- -title: Ввод в разработку Web-игр -slug: Games/Ввод -tags: - - Firefox OS - - Игры - - уроки -translation_of: Games/Introduction ---- -
{{GamesSidebar}}
- -
{{IncludeSubnav("/ru/docs/Games")}}
- -

Современный web позволяет не только передавать различную информацию, но и создавать интерактивный контент. Например, потрясающие, высококачественные игры.

- -

Диапазон игр, которые Вы можете встретить в web поражает и не устапает "нативным" играм, реализованным с использованием языка программирования c++ и java.Причем это касается не только относительно небольших игр, но и объемных игр жанра РПГ, 3d шутерах и многоом другом. Это уже не аналоги простых карточных игр или многопользовательских социальных играх, реализованных с помощью Flash®, а гораздо более сложные вещи. Благодаря значительным улучшениям языка программирования JavaScript и появлению новых API браузера, Вы можете создавать игры, не зависящие от операционной системы. Для их работы необходим только браузер. А иногда, например на устройствах с поддержкой HTML5, таких как Firefox OS, не нужен даже он.

- -

Игровая платформа HTML5

- -

Вы действительно можете подумать, что Web - лучшая платформа для вашей игры. Как мы любим говорить:"Web - это тоже платформа." Давайте посмотрим на главные аспекты Web платформы:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ФункционалТехнология
АудиоWeb Audio API
ГрафикаWebGL (OpenGL ES 2.0)
ВводTouch events, Gamepad API, датчики устройства, WebRTC, Full Screen API, Pointer Lock API
ЯзыкJavaScript (или C/C++ используйте Emscripten для компиляции в JavaScript)
СетьWebRTC и/или WebSockets
ДанныеIndexedDB или "облако"
ВебHTML, CSS, SVG, Social API (и многое другое!)
- -

Экономическое обоснование

- -

Как разработчик игр, независимо от того, являетесь ли вы частным лицом или крупной игровой студией, вы хотите знать, почему имеет смысл ориентироваться на Web со своим игровым проектом. Давайте посмотрим, как сеть может помочь вам.

- -

1. Охват паутины огромен, она повсюду. Игры, построенные на HTML5, работают на смартфонах, планшетах, ПК и смарт-телевизорах.

- -

2. Маркетинг и открытость улучшаются. Вы не ограничиваетесь продвижением своего приложения в чужом магазине приложений. Вместо этого вы можете рекламировать и продвигать свою игру по всему интернету, а также в других средствах массовой информации, используя преимущества присущей сети связности и доступности для новых клиентов.

- -

3. У вас есть контроль, где это имеет значение: Платежи. Вы не должны отдавать 30% своих доходов кому-то другому только потому, что ваша игра в их экосистеме. Вместо этого, взимать плату, что вы хотите, и использовать любую услугу обработки платежей вам нравится.

- -

4. Опять же, с большим контролем, вы можете обновить игру, когда захотите. Не жди, затаив дыхание, одобрения, пока кто-то прячется внутри другого.

- -

5. Контролируйте свою аналитику! Вместо того чтобы полагаться на кого-то другого в принятии решений о том, какая аналитика вам нужна, вы можете собрать свою собственную-или выбрать третью сторону, которая вам больше всего нравится, - чтобы собрать информацию о ваших продажах и досягаемости вашей игры.

- -

6. Вы можете управлять своими отношениями с клиентами более тесно, по-своему. Больше не придётся работать с обратной связью магазина приложений. Взаимодействуйте со своими клиентами так, как вы хотите, без посредника.

- -

7. Ваши игроки могут играть в вашу игру в любом месте, в любое время. Поскольку Web распространен повсеместно, ваши клиенты могут проверить статус своей игры на своих телефонах, планшетах, домашних ноутбуках, рабочих столах или на чем-либо еще.

- -

Web-технологии для разработчиков игр

- -

Давайте покопаемся в API Web'а, которое приносит на стол и обслуживает разработчиков игр. Вот подробный список, чтобы дать вам представление о том, что Web может сделать для вас:

- -
-
-
Full Screen API
-
Этот простой API позволяет вашей игре использовать весь экран, тем самым погружая игрока в действие.
-
Gamepad API
-
Если вы хотите, чтобы ваши пользователи могли использовать геймпады и прочие игровые контроллеры для работы с игрой, вам потребуется этот API
-
HTML и CSS
-
Эти технологии помогут вам создать и разместить UI вашей игры, а HTML-элемент {{HTMLElement("canvas")}} это один из способов создать 2D-графику
-
HTML audio
-
Элемент {{HTMLElement ("audio")}} позволяет легко воспроизводить простые звуковые эффекты и музыку. Если ваше потребности выше, ознакомьтесь с Web Audio API для полной мощности обработки звука!
-
IndexedDB
-
Мощный API для хранения пользовательских данных на собственном компьютере или устройстве. Отличный способ локально сохранить состояние игры и другую информацию, без необходимости подгружать ее каждый раз при необходимости. Также полезно дял того, чтобы сделать ваш проект играбельным, даже если пользователь не подключен к Интернету (например, когда он оказался в самолете на несколько часов).
-
JavaScript
-
JavaScript, язык программирования, используемый в Интернете, быстро развивается в современных браузерах и становится ещё быстрее. Используйте его возможности для написания кода своей игры или используйте такие технологии, как Emscripten или Asm.js, чтобы с легкотью переносить существующие игры.
-
Pointer Lock API
-
API Pointer Lock позволяет блокировать мышь или другое указывающее устройство в интерфейсе вашей игры. Вместо абсолютного позиционирования курсора вы получаете координаты дельты, которые дают вам более точные измерения того, что делает пользователь, и предотвращают случайную отправку ввода где-то еще, тем самым упуская важные пользовательские действия.
-
-
SVG (масштабируемая векторная графика)
-
Позволяет создавать векторную графику, которая плавно масштабируется независимо от размера или разрешения дисплея пользователя.
-
Typed Arrays
-
Типизированные массивы JavaScript дают вам доступ к необработанным двоичным данным из кода, что позволяет вам манипулировать текстурами GL, игровыми данными или чем-то еще, даже если код не в формате JavaScript.
-
Web Audio API
-
Этот API необходим для управления воспроизведением, синтезом звука и манипулированием аудио из кода JavaScript. Позволяет создавать потрясающие звуковые эффекты, а также воспроизводить и манипулировать музыкой в ​​режиме реального времени.
-
WebGL
-
Позволяет создавать высокопроизводительную аппаратно-ускоренную 3D (и 2D) графику из веб-контента. Это веб-реализация OpenGL ES 2.0.
-
WebRTC
-
API WebRTC (Real-Time Communications) дает вам возможность управлять аудио- и видеоданными, включая телеконференции и передачу данных из других приложений между двумя пользователями. Хотите, чтобы ваши игроки могли общаться друг с другом, взрывая монстров? Это API для вас!
-
WebSockets
-
-

The WebSocket API позволяет подключить ваше приложение или сайт к серверу для передачи данных в реальном времени. Идеально подходит для многопользовательских игр, чатов и т. д.

-
-
Web Workers
-
Web Workers даёт вам возможность создавать фоновые потоки, выполняющие собственный код JavaScript, используя преимущества современных многоядерных процессоров.
-
XMLHttpRequest и File API
-
-

Комбинация XMLHttpRequest и File API позволяет отправлять и получать любые нужные для вас данные (не позволяйте «XML» выкинуть вас!) с веб-сервера. Это отличный способ сделать что угодно: от загрузки новых игровых уровней и иллюстраций, до передачи информации о статусе игры в режиме  non-real-time и обратно.

-
-
-
diff --git "a/files/ru/games/\320\270\320\275\321\201\321\202\321\200\321\203\320\274\320\265\320\275\321\202\321\213/asm.js/index.html" "b/files/ru/games/\320\270\320\275\321\201\321\202\321\200\321\203\320\274\320\265\320\275\321\202\321\213/asm.js/index.html" deleted file mode 100644 index 3f9b2afde0..0000000000 --- "a/files/ru/games/\320\270\320\275\321\201\321\202\321\200\321\203\320\274\320\265\320\275\321\202\321\213/asm.js/index.html" +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: asm.js -slug: Games/Инструменты/asm.js -tags: - - JavaScript - - WebAssembly - - asm.js -translation_of: Games/Tools/asm.js ---- -
{{GamesSidebar}}
- -
{{IncludeSubnav("/en-US/docs/Games")}}
- -
-

Asm.js - это подмножество JavaScript, имеющее более высокую оптимизацию. В этой статье описаны возможности asm.js, улучшения которые оно дает, где и как это можно применять, а также дополнительные ресурсы и примеры.

-
- -

Что такое asm.js?

- -

Это небольшое, более строгое подмножество JavaScript которое ограничивает стандартный язык только конструкциями, типа `while`, `if` и данными в виде чисел, именованных функций, и другими простыми вещами. Оно не разрешает использование объектов, строк, и всего, что требует больших нагрузок. Asm.js напоминает C во многих вещах, но он является полностью валидным кодом на JavaScript и работает на всех имеющихся движках. Он позволяет JS движкам, поддерживающим asm.js, оптимизировать такой код и даёт компиляторам, типа Emscripten, чёткое определение того, как нужно компилировать. Мы покажем, как asm.js код выглядит, чем он полезен и как с ним работать.

- -

Это подмножество JavaScript уже автоматически используется во многих движках, использующих технологию компиляции Just-In-Time (JIT). Однако, указав явный стандарт, мы можем улучшить оптимизацию такого кода и получить максимальную производительность. Благодаря этому, упрощается совместная работа нескольких JS движков, потому что легче договориться о стандартах. Идея в том, что этот вид кода должен работать очень быстро в каждом движке, и если это не так, это ошибка, и есть четкая спецификация, что именно движки должны оптимизировать.

- -

Это также делает asm.js достаточно простым для людей, которые пишут компиляторы высокопроизводительного кода под web. Они могут обратиться к спецификации asm.js, чтобы найти более быстрые паттерны для него. Emscripten, компилятор C/C++ в JavaScript, выдает код asm.js, работающий в некоторых браузерах с производительностью, близкой к машинному коду.

- -

Кроме того, если движок специально распознает код asm.js, то можно сделать еще больше оптимизаций. На данный момент Chrome (статус) и Firefox обладают поддержкой asm.js. Firefox имеет поддержку передовых фич asm.js

- -

В общем об asm.js

- -

asm.js - это вспомогательное подмножество языка JavaScript. Он имеет предсказуемый уровень производительности, т.к. ограничен только лишь некоторыми строгими типами и конструкциями. Рабочие характеристики близки скорее к машинному коду, чем к стандартам JS. Использование этого подмножества уже поддерживается главными веб браузерами. Работа asm.js также зависит от браузера и от оборудования.

diff --git "a/files/ru/games/\320\270\320\275\321\201\321\202\321\200\321\203\320\274\320\265\320\275\321\202\321\213/index.html" "b/files/ru/games/\320\270\320\275\321\201\321\202\321\200\321\203\320\274\320\265\320\275\321\202\321\213/index.html" deleted file mode 100644 index 8981085874..0000000000 --- "a/files/ru/games/\320\270\320\275\321\201\321\202\321\200\321\203\320\274\320\265\320\275\321\202\321\213/index.html" +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: Инструменты для разработки игр -slug: Games/Инструменты -translation_of: Games/Tools ---- -
{{GamesSidebar}}
{{IncludeSubnav("/en-US/docs/Games")}}
- -
-

На этой странице вы можете найти ссылки на наши статьи по инструментам для разработки игр, которая в конечном итоге нацелена на покрытие фреймворков, компиляторов и инструментов отладки.

-
- -
-
asm.js
-
asm.js это очень ограниченное подмножество языка JavaScript, которое можно значительно оптимизировать и запустить в опережающем времени (AOT), компилируя движок гораздо быстрее, чем при типичной произвоительности языка. А это, конечно же, замечательно для игр.
-
Emscripten
-
-

Низккоуровневя виртуальная машина(LLVM) для JavaScript; с Emscripten вы можете компилировать C++ и другие языки, которые можно копировать в байткод LLVM с высокоц производительностью JavaScript. Это отличный веб-инструмент! Вот полезный туториал по Emscripten, доступный на вики. Заметьте, что мы стремимся охватить Emscripten в своих разделах на MDN.

-
-
Gecko profiler
-
Gecko profiler позволяет профилировать код, чтобы понять, где имеются проблемы производительности, и добиться максимальной скорости в .
-
Игровые движки и инструменты
-
Список движков, шаблонов и технологий, полезных для разработчиков.
-
Shumway
-
Shumway это рендер для Adobe Flash построенный полностью на JavaScript, WebGL, etc., преодолевающий разрыв между Flash и web-стандартами. Это статья поясняет, как пользоваться Shumway,и как вносить исправления в проекте.
-
Инструментарий для разработки и отладки игр
-
Чем это отличается от обычной отладки веб-приложения? Какие специальные инструменты доступны? Многое из этого доступно в инструментах, но здесь мы должны обеспечить своего рода практический учебник для отладки игры, с ссылками : -
    -
  • Обзор базовых инстурментов
  • -
  • Редактор шейдеров
  • -
  • Производственные инструменты (все еще находятся в производстве, по оценкам, в начале 2014 года)
  • -
-
-
diff --git a/files/ru/glossary/404/index.html b/files/ru/glossary/404/index.html new file mode 100644 index 0000000000..f198be3c1c --- /dev/null +++ b/files/ru/glossary/404/index.html @@ -0,0 +1,15 @@ +--- +title: '404' +slug: Словарь/404 +translation_of: Glossary/404 +--- +

Ошибка 404 - код стандартного ответа, означающий, что {{Glossary("Server", "сервер")}} не может найти ресурс по запрашиваемому адресу.

+ +

Узнать больше

+ + + +

 

diff --git a/files/ru/glossary/502/index.html b/files/ru/glossary/502/index.html new file mode 100644 index 0000000000..5879d7c153 --- /dev/null +++ b/files/ru/glossary/502/index.html @@ -0,0 +1,20 @@ +--- +title: Код ошибки 502 +slug: Словарь/502 +tags: + - '502' + - Глоссарий + - Коды ошибок HTTP +translation_of: Glossary/502 +--- +

Код ошибки в протоколе {{Glossary("HTTP")}}, означающий "Ошибка шлюза".

+ +

{{Glossary("Server", "Сервер")}} может выступать в качестве шлюза или прокси-сервера между клиентом (например, веб-браузером) и другим вышестоящим сервером. Когда вы делаете запрос на получение данных по {{Glossary("URL")}}, шлюз сервера может передать ваш запрос к вышестоящему серверу. Код «502» означает, что вышестоящий сервер вернул недействительный ответ.

+ +

Обычно вышестоящий сервер не не работает (т. е не не отвечает шлюзу / прокси-серверу), а просто не понимает тот же протокол обмена данными, который используется шлюзом / прокси-сервером. Интернет-{{Glossary("протокол", "протоколы")}} довольно просты для понимания, поэтому код 502 обычно означает, что одна или обе машины были неправильно или не полностью запрограммированы.

+ +

Узнайте больше

+ + diff --git a/files/ru/glossary/abstraction/index.html b/files/ru/glossary/abstraction/index.html new file mode 100644 index 0000000000..860db30148 --- /dev/null +++ b/files/ru/glossary/abstraction/index.html @@ -0,0 +1,12 @@ +--- +title: Абстракция +slug: Словарь/Abstraction +translation_of: Glossary/Abstraction +--- +

Абстракция(обобщение) в {{Glossary("computer programming", "программировании")}} это способ дать упрощённое представление о компонентах системы, скрыть их сложность и детали реализации, предоставив подходящий {{Glossary("API", "программный интерфейс")}}.

+ +

Дополнительно

+ + diff --git a/files/ru/glossary/accessibility/index.html b/files/ru/glossary/accessibility/index.html new file mode 100644 index 0000000000..2d2b7fc6da --- /dev/null +++ b/files/ru/glossary/accessibility/index.html @@ -0,0 +1,33 @@ +--- +title: Accessibility +slug: Словарь/Доступность +tags: + - Доступность web-контента + - Словарь + - доступность +translation_of: Glossary/Accessibility +--- +

Accessibility (Web Accessibility, A11Y - "Доступность Web-контента") - регламентирует лучшие практики обеспечения работоспособности и доступности сайта вне зависимости от физических и технических ограничений. Web Accessibility описывается и обсуждается в рамках Инициативы по обеспечению доступности {{Glossary("W3С")}} ({{Glossary("WAI","Web Accessibility Initiative (WAI)")}}).

+ +

См. также

+ +

Общие сведения

+ + + +

Техническая документация

+ + + +

Изучение Web Accessibility

+ + diff --git a/files/ru/glossary/adobe_flash/index.html b/files/ru/glossary/adobe_flash/index.html new file mode 100644 index 0000000000..645dc39095 --- /dev/null +++ b/files/ru/glossary/adobe_flash/index.html @@ -0,0 +1,21 @@ +--- +title: Adobe Flash +slug: Словарь/Adobe-Flash +tags: + - Adobe + - Flash + - Словарь + - инфраструктура +translation_of: Glossary/Adobe_Flash +--- +

Adobe Flash, Flash - устаревшая технология, разработанная Adobe, благодаря которой стали возможными {{Interwiki("wikipedia", "Rich Internet Application", "RIA")}} (Rich Internet Application), векторная графика и мультимедия. Для использования Flash необходимо установить соответствующий плагин в ваш {{Glossary("Browser","браузер")}}.

+ +

См. также

+ +

Общие сведения

+ + diff --git a/files/ru/glossary/ajax/index.html b/files/ru/glossary/ajax/index.html new file mode 100644 index 0000000000..6c727c56cf --- /dev/null +++ b/files/ru/glossary/ajax/index.html @@ -0,0 +1,32 @@ +--- +title: AJAX +slug: Словарь/AJAX +tags: + - AJAX + - Glossary + - Словарь + - инфраструктура +translation_of: Glossary/AJAX +--- +

Асинхронный {{Glossary ("JavaScript")}} And {{Glossary ("XML")}} (AJAX) - это практика программирования для создания более сложных, динамических веб-страниц с использованием технологии, известной как {{Glossary("XHR_(XMLHttpRequest)","XMLHttpRequest")}}..

+ +

AJAX позволяет вам просто обновлять части {{Glossary ("DOM")}} {{Glossary ("HTML")}} веб-страницы вместо того, чтобы заново загружать всю страницу целиком. AJAX также позволяет вам работать асинхронно, что означает, что ваш код продолжает работать, пока обновляемая часть вашей веб-страницы пытается перезагрузиться (по сравнению с синхронным, который блокирует ваш код до тех пор, пока часть вашей веб-страницы не будет перезагружена полностью).
+
+ Благодаря интерактивным веб-сайтам и современным веб-стандартам, AJAX постепенно заменяется функциями в рамках JavaScript и официальным {{domxref ("Fetch API")}} стандартом.

+ +

См. также

+ +

Общая информация

+ + + +

Техническая документация

+ + diff --git a/files/ru/glossary/algorithm/index.html b/files/ru/glossary/algorithm/index.html new file mode 100644 index 0000000000..83fc20ca7e --- /dev/null +++ b/files/ru/glossary/algorithm/index.html @@ -0,0 +1,38 @@ +--- +title: Алгоритм +slug: Словарь/Algorithm +tags: + - CodingScripting + - Glossary + - Словарь +translation_of: Glossary/Algorithm +--- +

Алгоритм - это независимая серия инструкций для выполнения функции.

+ +

Другими словами, алгоритм - это средство описания способа решения проблемы, чтобы ее можно было многократно решать людьми или машинами.  Компьютерные ученые сравнивают эффективность алгоритмов с помощью понятия «Алгоритмическая Сложность» или «Big O».

+ +

Например:

+ + + +

Распространенными алгоритмами являются алгоритмы поиска пути, такие как задача коммивояжера, алгоритмы обхода дерева и так далее.

+ +

Существуют также алгоритмы машинного обучения, такие как линейная регрессия, логистическая регрессия, дерево решений, случайный лес, машина опорных векторов, рекуррентная нейронная сеть (РНС), долгая краткосрочная память (LSTM), сверточная нейронная сеть (CNN), глубокая сверточная нейронная сеть и так далее.

+ +

Узнать больше

+ +

Общие сведения

+ + + +

Технический справочник

+ + diff --git a/files/ru/glossary/api/index.html b/files/ru/glossary/api/index.html new file mode 100644 index 0000000000..b83cecf0fe --- /dev/null +++ b/files/ru/glossary/api/index.html @@ -0,0 +1,25 @@ +--- +title: API +slug: Словарь/API +tags: + - Словарь + - инфраструктура +translation_of: Glossary/API +--- +

API (Application Programming Interface - интерфейс программных приложений )   это установка функций и правил позволяющая взаимодействовать между программным обеспечением, которое предоставляет API и другими программными компонентами. В Веб разработке, под API обычно подразумевают набор стандартных методов, свойств, событий и URL ссылок для взаимодействия с Веб контентом.

+ +

В веб-разработке API обычно представляет собой набор элементов кода (например {{glossary("method","методов")}}, {{Glossary("property","свойств")}}, событий и {{Glossary("URL")}}), которые разработчик может использовать в своих приложениях для взаимодействия с компонентами веб-браузера пользователя или другим программным/аппаратным обеспечением на компьютере пользователя, а также сторонними веб-сайтами и сервисами.

+ +

Узнать больше

+ +

Основные знания

+ + + +

Техническая справка

+ + diff --git a/files/ru/glossary/apple_safari/index.html b/files/ru/glossary/apple_safari/index.html new file mode 100644 index 0000000000..fafc97520d --- /dev/null +++ b/files/ru/glossary/apple_safari/index.html @@ -0,0 +1,29 @@ +--- +title: Apple Safari +slug: Словарь/Apple_Safari +tags: + - Glossary + - Navigation + - WebMechanics + - Навигация + - Словарь +translation_of: Glossary/Apple_Safari +--- +

Safari (Сафари) - это {{Glossary("Browser","веб-браузер")}} разработанный компанией Apple, входит в состав операционных систем Mac OS X и iOS. Safari работает на движке WebKit.

+ +

Узнайте больше

+ +

Общая информация

+ + + +

Техническая информация

+ + diff --git a/files/ru/glossary/application_context/index.html b/files/ru/glossary/application_context/index.html new file mode 100644 index 0000000000..f14a41fa76 --- /dev/null +++ b/files/ru/glossary/application_context/index.html @@ -0,0 +1,14 @@ +--- +title: Контекст приложения +slug: Словарь/application_context +tags: + - CodingScripting + - Glossary + - Словарь +translation_of: Glossary/application_context +--- +

Контекст приложения - это  browsing context (контекст просмотра) верхнего уровня, к которому применяется манифест

+ +

Если контекст приложения создается в результате запроса агента пользователя на переход к глубинному связыванию, агент пользователя должен немедленно перейти к глубинному связыванию с включенной заменой. Иначе говоря, при создании контекста приложения, агент пользователя должен немедленно перейти к  начальному URL-адресу с включенной заменой.

+ +

Обратите внимание, что начальный URL-адрес не обязательно является значением элемента start_url : пользователь или агент пользователя мог изменить его при добавлении приложения на главный экран или в закладки.

diff --git a/files/ru/glossary/argument/index.html b/files/ru/glossary/argument/index.html new file mode 100644 index 0000000000..c1314c28f9 --- /dev/null +++ b/files/ru/glossary/argument/index.html @@ -0,0 +1,24 @@ +--- +title: Аргумент +slug: Словарь/Аргумент +tags: + - CodingScripting + - Glossary + - JavaScript +translation_of: Glossary/Argument +--- +

Аргумент - это {{glossary("value")}} ({{Glossary("primitive")}} или {{Glossary("object")}}) , переданное в качестве входных данных в {{Glossary("function")}}.

+ +

См. также

+ +

Общие сведения

+ + + +

Техническая документация

+ + diff --git a/files/ru/glossary/aria/index.html b/files/ru/glossary/aria/index.html new file mode 100644 index 0000000000..3571787b67 --- /dev/null +++ b/files/ru/glossary/aria/index.html @@ -0,0 +1,19 @@ +--- +title: ARIA +slug: Словарь/ARIA +tags: + - Accessibility + - Glossary + - Словарь + - доступность +translation_of: Glossary/ARIA +--- +

ARIA (Accessible Rich {{glossary("Internet")}} Applications) является {{Glossary("W3C")}} спецификацией для добавления семантики и других метаданных в {{Glossary("HTML")}} при использовании вспомогательных технологий.

+ +

Например, вы можете добавить атрибут role="alert" в {{glossary("tag","тег")}} {{HTMLElement("p")}}, чтобы оповестить пользователя о том, что информация является важной и зависимой от времени (иначе вы могли бы передать это через цвет текста).

+ +

Материалы для изучения

+ + diff --git a/files/ru/glossary/arpa/index.html b/files/ru/glossary/arpa/index.html new file mode 100644 index 0000000000..4de5199f91 --- /dev/null +++ b/files/ru/glossary/arpa/index.html @@ -0,0 +1,20 @@ +--- +title: ARPA +slug: Словарь/ARPA +tags: + - Glossary + - Infrastructure + - Словарь + - инфраструктура +translation_of: Glossary/ARPA +--- +

.arpa (address and routing parameter area) является {{glossary("TLD","доменом верхнего уровня")}}, который используется в интернет-инфраструктуре, особенно в обратном DNS запросе (т.е., определить {{glossary("domain name", "имя домена")}} для заданного {{glossary("IP address", "IP адреса")}}).

+ +

Подробнее

+ +

Общие сведения

+ + diff --git a/files/ru/glossary/arpanet/index.html b/files/ru/glossary/arpanet/index.html new file mode 100644 index 0000000000..e3261c859a --- /dev/null +++ b/files/ru/glossary/arpanet/index.html @@ -0,0 +1,19 @@ +--- +title: Arpanet +slug: Словарь/Arpanet +tags: + - Glossary + - Infrastructure + - Словарь + - инфраструктура +translation_of: Glossary/Arpanet +--- +

Компьютерная сеть ARPAnet (advanced research projects agency network) является одной из первых компьютерных сетей, была создана в 1969 как надежная среда для передачи конфиденциальных военных данных и для подключения ведущих исследовательских групп по всей территории Соединенных Штатов. Изначально ARPAnet использовал NCP (протокол сетевого управления), а затем первую версию интернет-протокола или пакета {{glossary ("TCP")}} / {{glossary ("IPv6", "IP")}}, что делает ARPAnet выдающейся частью зарождающегося {{glossary("Internet","Интернета")}}. ARPAnet была закрыта в начале 1990 года.

+ +

Подробнее

+ +

Общие сведения

+ + diff --git a/files/ru/glossary/array/index.html b/files/ru/glossary/array/index.html new file mode 100644 index 0000000000..3fb91ee460 --- /dev/null +++ b/files/ru/glossary/array/index.html @@ -0,0 +1,36 @@ +--- +title: Maccив +slug: Словарь/Массив +tags: + - JavaScript + - 'Массив,' + - Программирование + - Словарь +translation_of: Glossary/array +--- +

Массив это упорядоченный набор информации (смотрите еще {{Glossary("Примитив")}} или {{Glossary("Объект")}} зависит от языка). Массивы используются, что сохранять множество значений или единичные переменные. Это относится к переменным, которые могут сохранять только одно значение.

+ +

Каждому элементу в массиве соответствует свой номер, называется он индексом, который позволяет получить к нему доступ. В JavaScript, массивы начинаются с индекса ноль и их можно изменять различными методами( Словарь:{{Glossary("Method", " Методы")}}).

+ +

Пример массива на JavaScript:

+ +
var myArray = [1, 2, 3, 4];
+
+var catNamesArray = ["Jacqueline", "Sophia", "Autumn"];
+
+//Массивы в JavaScript могут содержать информацию различных типов, как представлено выше.
+
+ +

Смотрите также

+ +

Основные знания

+ + + +

Техническая справка

+ + diff --git a/files/ru/glossary/ascii/index.html b/files/ru/glossary/ascii/index.html new file mode 100644 index 0000000000..a0b95692b3 --- /dev/null +++ b/files/ru/glossary/ascii/index.html @@ -0,0 +1,15 @@ +--- +title: ASCII +slug: Словарь/ASCII +tags: + - Glossary + - Infrastructure +translation_of: Glossary/ASCII +--- +

ASCII (American Standard Code for Information Interchange) это один из самых известных методов кодирования, используемый компьютерами для превращения букв, чисел, знаков препинания и кодов управления в цифровую форму. С 2007, {{Glossary("UTF-8")}} заменил его в Web.

+ +

Смотрите также

+ +

Основные знания

+ +

{{Interwiki("wikipedia", "ASCII")}} on Wikipedia

diff --git a/files/ru/glossary/asynchronous/index.html b/files/ru/glossary/asynchronous/index.html new file mode 100644 index 0000000000..36ca8210e4 --- /dev/null +++ b/files/ru/glossary/asynchronous/index.html @@ -0,0 +1,23 @@ +--- +title: Асинхронный +slug: Словарь/Asynchronous +tags: + - Glossary + - Web + - WebMechanics +translation_of: Glossary/Asynchronous +--- +

Асинхронный относится к среде связи, где каждый участник получает и обрабатывает сообщение, когда это удобно, или возможно, а не сразу.

+ +

Это может использовать для описания такой среды связи, как e-mail — отправитель отправляет сообщение, а получатель ответит на него, когда ему будет удобно; они не должны отвечать немедленно.

+ +

Это также можно использовать, для описания программной среды связи, например, {{domxref("Ajax")}} это асинхронный механизм для запроса небольшого объема данных через протокол HTTP; результат отправляется обратно, когда ответ будет сформирован, а не сразу.

+ +

Смотрите также

+ +

Техническая справка

+ + diff --git a/files/ru/glossary/atag/index.html b/files/ru/glossary/atag/index.html new file mode 100644 index 0000000000..9723709297 --- /dev/null +++ b/files/ru/glossary/atag/index.html @@ -0,0 +1,28 @@ +--- +title: ATAG +slug: Словарь/ATAG +tags: + - ATAG + - Accessibility + - Authoring Tool Accessibility Guidelines + - Glossary + - Общедоступность + - Словарь +translation_of: Glossary/ATAG +--- +

ATAG (Authoring Tool {{glossary("Accessibility")}} Guidelines) - это {{Glossary("W3C")}} рекомендации для создания общедоступных инструментов разработчика, которые создают общедоступный контент.

+ +

Подробнее

+ +

Общие сведения

+ + + +

Технические ссылки

+ + diff --git a/files/ru/glossary/attribute/index.html b/files/ru/glossary/attribute/index.html new file mode 100644 index 0000000000..c7b35806e5 --- /dev/null +++ b/files/ru/glossary/attribute/index.html @@ -0,0 +1,18 @@ +--- +title: Атрибут +slug: Словарь/Атрибут +tags: + - HTML + - Словарь +translation_of: Glossary/Attribute +--- +

Атрибут является частью {{Glossary("tag", "тега")}}, позволяющей менять его поведение или добавлять метаданные. Атрибут всегда представлен в виде название=значение, которые определяют соответственно идентификатор атрибута и присвоенное ему значение.

+ +

Узнать подробнее

+ +

Техническая информация

+ + diff --git a/files/ru/glossary/bandwidth/index.html b/files/ru/glossary/bandwidth/index.html new file mode 100644 index 0000000000..ec85dd71fd --- /dev/null +++ b/files/ru/glossary/bandwidth/index.html @@ -0,0 +1,15 @@ +--- +title: Пропускная способность +slug: Словарь/Bandwidth +tags: + - Глоссарий + - инфраструктура +translation_of: Glossary/Bandwidth +--- +

Пропускная способность (скорость передачи данных) - мера количества информции, которая может быть передана по каналу связи за заданный промежуток времени. Обычно измеряется в величинах, кратных битам в секунду (бит/с), например в мегабитах (Мбит/с) или гигабитах (Гбит/с) в секунду.

+ +

Узнать больше

+ + diff --git a/files/ru/glossary/base64/index.html b/files/ru/glossary/base64/index.html new file mode 100644 index 0000000000..b85f3671ef --- /dev/null +++ b/files/ru/glossary/base64/index.html @@ -0,0 +1,138 @@ +--- +title: Кодирование и декодирование в формате Base64 +slug: Web/API/WindowBase64/Base64_encoding_and_decoding +translation_of: Glossary/Base64 +--- +

Base64 - это группа cхожих binary-to-text encoding схем, которые представляют двоичные данные в ASCII-формате методом перевода в radix-64 представление. Термин Base64 происходит от a specific MIME content transfer encoding.

+ +

Кодирование Base64 широко используется в случаях, когда требуется перекодировать двоичные данные для передачи по каналу приспособленному для передачи текстовых данных. Это делается с целью защиты двоичных данных от любых возможных повреждений при передаче. Base64 широко используется во многих приложениях, включая электронную почту (MIME), и при сохранении больших объёмов данных в XML.

+ +

В языке JavaScript существуют две функции, для кодирования и декодирования данных в/из формат Base64 соответственно:

+ + + +

Функция atob() декодирует Base64-кодированную строку. В противоположность ей, функция btoa() создаёт Base64 кодированную ASCII строку из "строки" бинарных данных.

+ +

Обе функции atob() и btoa() работают со строками. Если вам необходимо работать с ArrayBuffers, обратитесь к этому параграфу.

+ + + + + + + + +
+

Документация

+ +
+
data URIs
+
data URIs, описанные в RFC 2397, позволяют создателям контента встроить в документ маленькие файлы в виде строки (инлайном).
+
Base64
+
Wikipedia article about Base64 encoding.
+
{{domxref("WindowBase64.atob","atob()")}}
+
Decodes a string of data which has been encoded using base-64 encoding.
+
{{domxref("WindowBase64.btoa","btoa()")}}
+
Creates a base-64 encoded ASCII string from a "string" of binary data.
+
The "Unicode Problem"
+
In most browsers, calling btoa() on a Unicode string will cause a Character Out Of Range exception. This paragraph shows some solutions.
+
URIScheme
+
List of Mozilla supported URI schemes
+
StringView
+
In this article is published a library of ours whose aims are: +
    +
  • creating a C-like interface for strings (i.e. array of characters codes — ArrayBufferView in JavaScript) based upon the JavaScript ArrayBuffer interface,
  • +
  • creating a collection of methods for such string-like objects (since now: stringViews) which work strictly on array of numbers rather than on immutable JavaScript strings,
  • +
  • working with other Unicode encodings, different from default JavaScript's UTF-16 DOMStrings,
  • +
+
+
+ +

View All...

+
+

Tools

+ + + +

View All...

+ + + + +
+ +

The "Unicode Problem"

+ +

Since DOMStrings are 16-bit-encoded strings, in most browsers calling window.btoa on a Unicode string will cause a Character Out Of Range exception if a character exceeds the range of a 8-bit byte (0x00~0xFF). There are two possible methods to solve this problem:

+ + + +

Here are the two possible methods.

+ +

Solution #1 – escaping the string before encoding it

+ +
function b64EncodeUnicode(str) {
+    // first we use encodeURIComponent to get percent-encoded UTF-8,
+    // then we convert the percent encodings into raw bytes which
+    // can be fed into btoa.
+    return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
+        function toSolidBytes(match, p1) {
+            return String.fromCharCode('0x' + p1);
+    }));
+}
+
+b64EncodeUnicode('✓ à la mode'); // "4pyTIMOgIGxhIG1vZGU="
+b64EncodeUnicode('\n'); // "Cg=="
+
+ +

To decode the Base64-encoded value back into a String:

+ +
function b64DecodeUnicode(str) {
+    // Going backwards: from bytestream, to percent-encoding, to original string.
+    return decodeURIComponent(atob(str).split('').map(function(c) {
+        return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
+    }).join(''));
+}
+
+b64DecodeUnicode('4pyTIMOgIGxhIG1vZGU='); // "✓ à la mode"
+b64DecodeUnicode('Cg=='); // "\n"
+
+ +

Unibabel implements common conversions using this strategy.

+ +

Solution #2 – rewrite the DOMs atob() and btoa() using JavaScript's TypedArrays and UTF-8

+ +

Use a TextEncoder polyfill such as TextEncoding (also includes legacy windows, mac, and ISO encodings), TextEncoderLite, combined with a Buffer and a Base64 implementation such as base64-js.

+ +

When a native TextEncoder implementation is not available, the most light-weight solution would be to use TextEncoderLite with base64-js. Use the browser implementation when you can.

+ +

The following function implements such a strategy. It assumes base64-js imported as <script type="text/javascript" src="base64js.min.js"/>. Note that TextEncoderLite only works with UTF-8.

+ +
function Base64Encode(str, encoding = 'utf-8') {
+    var bytes = new (TextEncoder || TextEncoderLite)(encoding).encode(str);
+    return base64js.fromByteArray(bytes);
+}
+
+function Base64Decode(str, encoding = 'utf-8') {
+    var bytes = base64js.toByteArray(str);
+    return new (TextDecoder || TextDecoderLite)(encoding).decode(bytes);
+}
+
diff --git a/files/ru/glossary/baseline/index.html b/files/ru/glossary/baseline/index.html new file mode 100644 index 0000000000..38a90cea5d --- /dev/null +++ b/files/ru/glossary/baseline/index.html @@ -0,0 +1,30 @@ +--- +title: Baseline +slug: Словарь/baseline +tags: + - CSS + - SVG + - Выравнивание + - Глоссарий + - типография +translation_of: Glossary/baseline +--- +

Базовая линия - это термин, используемый в европейской и западно-азиатской типографии, означающий воображаемую линию, на которую опираются символы шрифта.

+ +

Потомки символов типа g и p простираются ниже этой строки. {{Glossary("glyph", "Глифы")}} с закругленными нижними и верхними окончаниями типа C или 3 слегка простираются под ним.

+ +

Восточно-азиатские шрифты не имеют исходной линии. Их глифы помещаются в квадратную коробку без восходов и нисходов.

+ +

См. также

+ +

Общие сведения

+ + + +

Техническая документация

+ + diff --git a/files/ru/glossary/bidi/index.html b/files/ru/glossary/bidi/index.html new file mode 100644 index 0000000000..ee2b409eb7 --- /dev/null +++ b/files/ru/glossary/bidi/index.html @@ -0,0 +1,25 @@ +--- +title: BiDi +slug: Словарь/BiDi +tags: + - Accessibility + - Glossary + - Общедоступность + - Словарь +translation_of: Glossary/BiDi +--- +

BiDi (BiDirectional) относится к документу, содержащему текст справа налево и слева направо. Даже когда оба направления встречаются в одном и том же абзаце, текст на каждом языке должен отображаться в правильной направленности.

+ +

Подробности

+ +

Общие сведения

+ + + +

Техническая справка

+ + diff --git a/files/ru/glossary/bigint/index.html b/files/ru/glossary/bigint/index.html new file mode 100644 index 0000000000..cf03adc216 --- /dev/null +++ b/files/ru/glossary/bigint/index.html @@ -0,0 +1,28 @@ +--- +title: BigInt +slug: Словарь/BigInt +tags: + - BigInt + - JavaScript + - Глоссарий + - Длинная арифметика +translation_of: Glossary/BigInt +--- +

В {{Glossary("JavaScript")}}, BigInt - числовой тип данных, который может представлять данные в формате длинной арифметики. В других языках программирования могут быть другие числовые типы, например целые числа, числа с плавающей запятой, числа двойной точности, большие числа.

+ +

См. также

+ +

Общие сведения

+ + + +

Техническая документация

+ + diff --git a/files/ru/glossary/blink/index.html b/files/ru/glossary/blink/index.html new file mode 100644 index 0000000000..005f5ef336 --- /dev/null +++ b/files/ru/glossary/blink/index.html @@ -0,0 +1,16 @@ +--- +title: Blink +slug: Словарь/Blink +translation_of: Glossary/Blink +--- +

Blink - это браузерный движок с открытым исходным кодом разработанный Google как часть Chromium (и следовательно как часть Chrome). Конкретней, Blink - это ответвление WebCore библиотеки {{glossary("WebKit")}}, поддерживающей макет, рендеринг, и {{Glossary("DOM")}}.

+ +

Узнать больше

+ +

Основная информация

+ + diff --git a/files/ru/glossary/block/scripting/index.html b/files/ru/glossary/block/scripting/index.html new file mode 100644 index 0000000000..71e5b54af7 --- /dev/null +++ b/files/ru/glossary/block/scripting/index.html @@ -0,0 +1,20 @@ +--- +title: Блок (скриптинг) +slug: Glossary/Block/Скриптинг +tags: + - JavaScript + - Глоссарий + - Словарь +translation_of: Glossary/Block/Scripting +--- +

В {{glossary("JavaScript")}} блок это набор связанных {{glossary("statement","statements")}} заключенных в скобки ("{}"). Например, можно поместить блок инструкций после блока {{jsxref("Statements/if...else","if (condition)")}}, чтобы интерпретатор выполнял код в блоке, если условие имеет значение true, или пропускал целый блок, если значение условия false.

+ +

Узнай больше

+ +

Почитай вот это

+ + + +

 

diff --git "a/files/ru/glossary/block/\321\201\320\272\321\200\320\270\320\277\321\202\320\270\320\275\320\263/index.html" "b/files/ru/glossary/block/\321\201\320\272\321\200\320\270\320\277\321\202\320\270\320\275\320\263/index.html" deleted file mode 100644 index 71e5b54af7..0000000000 --- "a/files/ru/glossary/block/\321\201\320\272\321\200\320\270\320\277\321\202\320\270\320\275\320\263/index.html" +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: Блок (скриптинг) -slug: Glossary/Block/Скриптинг -tags: - - JavaScript - - Глоссарий - - Словарь -translation_of: Glossary/Block/Scripting ---- -

В {{glossary("JavaScript")}} блок это набор связанных {{glossary("statement","statements")}} заключенных в скобки ("{}"). Например, можно поместить блок инструкций после блока {{jsxref("Statements/if...else","if (condition)")}}, чтобы интерпретатор выполнял код в блоке, если условие имеет значение true, или пропускал целый блок, если значение условия false.

- -

Узнай больше

- -

Почитай вот это

- - - -

 

diff --git a/files/ru/glossary/boolean/index.html b/files/ru/glossary/boolean/index.html new file mode 100644 index 0000000000..f89e0ff8b1 --- /dev/null +++ b/files/ru/glossary/boolean/index.html @@ -0,0 +1,62 @@ +--- +title: 'Boolean (Булев, Логический тип данных)' +slug: Словарь/Boolean +tags: + - Boolean + - JavaScript + - Глоссарий + - Логический тип данных + - Типы данных + - языки программирования +translation_of: Glossary/Boolean +--- +

Boolean (Булев, Логический тип данных) — примитивный тип данных в информатике, которые могут принимать два возможных значения, иногда называемых истиной (true) и ложью (false). Например, в JavaScript Булевы состояния часто используются для того, чтобы определить какие части кода выполнять (например, в операторах if) или повторять (например, циклы for).

+ +

Ниже приведен некоторый псевдокод JavaScript (это не действительно исполняемый код), демонстрирующий эту концепцию.

+ +

Пример использования оператора if:

+ +
if (условие) {
+    блок кода, выполняемый если условие возвращает true
+} else {
+    блок кода, выполняемый если условие возвращает false
+}
+
+ +

К примеру:

+ +
if (hour < 18) {
+    greeting = "Добрый день";
+} else {
+    greeting = "Добрый вечер";
+}
+ +

Пример использования логического условия в цикле for:

+ +
for (начало; условие; шаг) {
+    // ... тело цикла ...
+}
+
+ +

К примеру:

+ +
for (let i = 0; i < 3; i++) {
+    alert(i);
+}
+ +

Булевы значения названы в честь английского математика {{interwiki("wikipedia", "George Boole")}}, который был первопроходцем в области математической логики.

+ +

Смотрите также

+ +

Общие сведения

+ + + +

Техническая справка

+ + diff --git a/files/ru/glossary/bootstrap/index.html b/files/ru/glossary/bootstrap/index.html new file mode 100644 index 0000000000..ef1da85d02 --- /dev/null +++ b/files/ru/glossary/bootstrap/index.html @@ -0,0 +1,22 @@ +--- +title: Bootstrap +slug: Словарь/Bootstrap +tags: + - Bootstrap + - CSS + - Введение + - Словарь + - фреймворк +translation_of: Glossary/Bootstrap +--- +

Bootstrap - это бесплатный фреймворк {{Glossary("HTML")}} , {{Glossary("CSS")}} и {{Glossary("JavaScript")}} с открытым исходным кодом для быстрого создания адаптивных веб-сайтов.

+ +

Изначально Bootstrap назывался Twitter Blueprint и был разработан командой, работающей в Twitter. Он поддерживает адаптивный дизайн и имеет предопределенные шаблоны дизайна, которые вы можете использовать из коробки или настроить для своих нужд с помощью кода. Вам также не нужно беспокоиться о совместимости с другими браузерами, так как Bootstrap совместим со всеми современными браузерами и новыми версиями {{glossary("Microsoft Internet Explorer", "Internet Explorer")}} .

+ + diff --git a/files/ru/glossary/browser/index.html b/files/ru/glossary/browser/index.html new file mode 100644 index 0000000000..cdeb2f300b --- /dev/null +++ b/files/ru/glossary/browser/index.html @@ -0,0 +1,24 @@ +--- +title: Браузер +slug: Словарь/Browser +translation_of: Glossary/Browser +--- +

Веб браузер — это программа которая извлекает и показывает страницы из {{Glossary("World Wide Web","Web")}}, и даёт пользователям доступ к веб-страницам через {{Glossary("hyperlink","гиперссылки")}}.

+ +

Узнай больше

+ +

Общие знания

+ + + +

Скачай браузер

+ + diff --git a/files/ru/glossary/browsing_context/index.html b/files/ru/glossary/browsing_context/index.html new file mode 100644 index 0000000000..85baf77aa4 --- /dev/null +++ b/files/ru/glossary/browsing_context/index.html @@ -0,0 +1,19 @@ +--- +title: Browsing context +slug: Словарь/Browsing_context +translation_of: Glossary/Browsing_context +--- +

Browsing context(контекст просмотра) - это окружение, в котором {{glossary("browser")}} отображает {{domxref("Document")}} (на сегодняшний день обычно это вкладки, однако, возможно окно или frame внутри страницы).

+ +

Каждый контекст просмотра имеет определенный {{glossary("origin")}} (источник), источник текущего активного документа и историю, которая содержит все отображенные документы в соответствующем порядке.

+ +

Взаимодействие между контекстами просмотра очень ограничено. Между контекстами просмотра из одного источника может быть открыт и использован {{domxref("BroadcastChannel")}}.

+ +

Learn more

+ +

Техническая документация

+ + diff --git a/files/ru/glossary/buffer/index.html b/files/ru/glossary/buffer/index.html new file mode 100644 index 0000000000..479a9ac4d1 --- /dev/null +++ b/files/ru/glossary/buffer/index.html @@ -0,0 +1,21 @@ +--- +title: Буфер +slug: Словарь/Буфер +tags: + - Buffer + - CodingScripting + - Glossary + - NeedsContent + - Буфер + - Словарь +translation_of: Glossary/buffer +--- +

Буфер - это хранилище в физической памяти, используемое для временного хранения данных, во время их передачи из одного места в другое.

+ +

См. также

+ +

Общие сведения

+ + diff --git "a/files/ru/glossary/b\303\251zier_curve/index.html" "b/files/ru/glossary/b\303\251zier_curve/index.html" new file mode 100644 index 0000000000..0952421dda --- /dev/null +++ "b/files/ru/glossary/b\303\251zier_curve/index.html" @@ -0,0 +1,32 @@ +--- +title: Кривая Безье +slug: Словарь/Bézier_curve +tags: + - Графика + - Кривая Безье + - Словарь +translation_of: Glossary/Bézier_curve +--- +

Кривая Безье — это математически описанная кривая, используемая в компьютерной графике и анимации. В {{Glossary("vector image", "vector images")}} они используются для создания плавных кривых, которые можно бесконечно сильно масштабировать.

+ +

Кривая описывается массивом контрольных точек, которых должно быть, как минимум, две. В веб-графике и анимациях используются кривые Безье с 4 контрольными точками P0, P1, P2 и P3.

+ +

Для того чтобы нарисовать кривую, необходимо нарисовать две воображаемые линии, одна из которых будет иметь координаты P0 и P1, а другая — P1 и P2. Затем крайние точки этих линий начинают непрерывно двигаться к следующим точкам. Третья воображаемая линия рисуется с начальной точкой, непрерывно двигающейся по первой линии, и конечной точкой, двигающейся по второй линии. На этой воображаемой линии рисуется точка, постепенно движущаяся от начала линии до самого конца. Кривая, которую эта точка будет описывать называется кривая Безье. Ниже приведена анимация, демонстрирующая процесс создания кривой:

+ +

Drawing a Bézier curve

+ +

Подробнее

+ +

Общая информация

+ + + +

Подробнее по теме

+ + diff --git a/files/ru/glossary/cache/index.html b/files/ru/glossary/cache/index.html new file mode 100644 index 0000000000..03803b2895 --- /dev/null +++ b/files/ru/glossary/cache/index.html @@ -0,0 +1,14 @@ +--- +title: Кэш +slug: Словарь/Кэш +translation_of: Glossary/Cache +--- +

Кэш (веб кэш или HTTP кэш) это компонент, который временно сохраняет HTTP ответы от сервера для того, чтобы их затем можно было использовать в последующих HTTP запросах, до тех пор пока он удовлетовяет некоторым условиям. 

+ +

Learn More

+ +

General knowledge

+ + diff --git a/files/ru/glossary/cacheable/index.html b/files/ru/glossary/cacheable/index.html new file mode 100644 index 0000000000..54f93bb14c --- /dev/null +++ b/files/ru/glossary/cacheable/index.html @@ -0,0 +1,59 @@ +--- +title: Кэшируемые методы +slug: Словарь/cacheable +tags: + - Glossary + - HTTP +translation_of: Glossary/cacheable +--- +

Кэшируемые ответы - это HTTP-ответы, которые могут быть закэшированы, то есть сохранены для дальнейшего восстановления и использования позже, тем самым снижая число запросов к серверу. Не все HTTP-ответы могут быть закэшированы. Вот несколько ограничений:

+ + + +

Обратите внимание, что некоторые некэшируемые запросы-ответы к определённым URI могут сделать недействительным (инвалидируют) предыдущие закэшированные ответы на тех же URI. Например, {{HTTPMethod("PUT")}} к странице pageX.html инвалидируют все закэшированные ответы {{HTTPMethod("GET")}} или {{HTTPMethod("HEAD")}} запросов к этой странице.

+ +

Когда и метод запроса и статус ответа кэшированы, то ответ к запросу тоже может быть закэширован:

+ +
GET /pageX.html HTTP/1.1
+(…)
+
+200 OK
+(…)
+
+ +

Запрос {{HTTPMethod("PUT")}} не может быть закэширован. Более того, он инвалидирует закэшированные данные запросов к тому же URI, сделанных через {{HTTPMethod("HEAD")}} или {{HTTPMethod("GET")}}:

+ +
PUT /pageX.html HTTP/1.1
+(…)
+
+200 OK
+(…)
+
+ +

Специальный заголовок {{HTTPHeader("Cache-Control")}} в ответе может предотвратить кэширование:

+ +
GET /pageX.html HTTP/1.1
+(…)
+
+200 OK
+Cache-Control: no-cache
+(…)
+ +

Материалы для изучения

+ +

Основные

+ + + +

Технические

+ + diff --git a/files/ru/glossary/call_stack/index.html b/files/ru/glossary/call_stack/index.html new file mode 100644 index 0000000000..04eb95fdb5 --- /dev/null +++ b/files/ru/glossary/call_stack/index.html @@ -0,0 +1,102 @@ +--- +title: Call stack +slug: Словарь/Call_stack +tags: + - Glossary +translation_of: Glossary/Call_stack +--- +

Стек вызовов(call stack) - это механизм для интерпретаторов (таких как интерпретатор JavaScript в веб-браузере) для отслеживания текущего местонахождения интерпретатора в скрипте, который вызывает  несколько функций типа {{glossary("function","functions")}}, — какая из функций выполняется на данный момент, какие функции вызываются изнутри этой (выполняемой) функции, какая будет вызвана следующей и т. д.

+ + + +

Пример

+ +

 

+ +
function greeting() {
+   // [1] Some codes here
+   sayHi();
+   // [2] Some codes here
+}
+function sayHi() {
+   return "Hi!";
+}
+
+// Invoke the `greeting` function
+greeting();
+
+// [3] Some codes here
+ +

Код выше будет выполнен следующим образом:

+ +
    +
  1. Игнорирование всех функций, пока не будет достигнуто место вызова функции greeting().
  2. +
  3. Вызывается функция greeting().
  4. +
  5. Функция "greeting" помещается в очередь стека вызовов.
  6. +
+ +
+

Очередь стека вызовов:
+ - greeting

+
+ +

 

+ +
    +
  1. Выполняется код внутри функции `greeting`.
  2. +
  3. Вызывается функция sayHi().
  4. +
  5. Функция sayHi() помещается в очередь стека вызовов.
  6. +
+ +
+

Очередь стека вызовов:
+ - greeting
+ - sayHi

+
+ +
    +
  1. Выполняется весь код внутри функции sayHi() до самого конца.
  2. +
  3. Возврат выполнения кода  с места вызова функции sayHi() и продолжение выполнения оставшегося кода функции greeting().
  4. +
  5. Выполненная функция sayHi() удаляется из очереди стека вызовов.
    + +
    +

    Очередь стека вызовов:
    + - greeting

    +
    +
  6. +
  7. Когда весь код внутри функции greeting() выполнен, происходит возврат выполнения оставшейся части основного скрипта JS с места вызова функции greeting().
  8. +
  9. Выполненная функция greeting() удаляется из очереди стека вызовов.
    + +
    +

    Очередь стека вызовов:
    + ПУСТО

    +
    +
  10. +
+ +

Выполнение кода началось с пустого стека вызовов, и всякий раз, когда мы вызывали функцию, она автоматически добавлялась в очередь стека вызовов, после выполнения всего своего кода она автоматически удалялась из очереди стека вызовов. И в конце выполнение кода также завершилось с пустым стеком вызовов.

+ +

Узнать больше

+ +

Общие знания

+ + + + diff --git a/files/ru/glossary/callback_function/index.html b/files/ru/glossary/callback_function/index.html new file mode 100644 index 0000000000..b1433d4ee8 --- /dev/null +++ b/files/ru/glossary/callback_function/index.html @@ -0,0 +1,70 @@ +--- +title: Функция обратного вызова +slug: Словарь/функция_обратного_вызова +tags: + - Callback + - Функция обратного вызова +translation_of: Glossary/Callback_function +--- +

Функция обратного вызова - это функция, переданная в другую функцию в качестве аргумента, которая затем вызывается по завершению какого-либо действия.

+ +

Вот краткий пример:

+ +
function greeting(name) {
+  alert('Hello ' + name);
+}
+
+function processUserInput(callback) {
+  var name = prompt('Please enter your name.');
+  callback(name);
+}
+
+processUserInput(greeting);
+ +

Выше приведен пример синхронного обратного вызова, поскольку функция processUserInput выполняется синхронно.

+ +

Функции обратного вызова часто используются для продолжения выполнения кода после завершения асинхронной операции - они называются асинхронными обратными вызовами.

+ +
async function pageLoader(callback) {
+  const data = await fetch('/ru/docs/Словарь/функция_обратного_вызова')
+  callback(data)
+}
+
+function onPageLoadingFinished(pageData) {
+  console.log('Page was sucessfully loaded!')
+  console.log('Response:')
+  console.log(pageData)
+}
+
+pageLoader(onPageLoadingFinished)
+
+ +

Вот еще один пример асинхронного обратного вызова: maps-example.html (живой пример). Он использует Google Maps API и Geolocation API для отображения карты текущего местоположения вашего устройства.

+ +
// maps-example.html
+// Вызов асинхронной функции getCurrentPosition
+// с передачей callback функции принимающей координаты
+// в качестве параметра
+navigator.geolocation.getCurrentPosition(function(position) {
+  var latlng = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
+  var myOptions = {
+    zoom: 8,
+    center: latlng,
+    mapTypeId: google.maps.MapTypeId.TERRAIN,
+    disableDefaultUI: true
+  }
+  var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
+});
+
+ +

Поскольку получение координат устройства из его GPS является асинхронным (мы точно не знаем, когда данные будут возвращены), метод Geolocation.getCurrentPosition() принимает анонимную функцию обратного вызова в качестве параметра, которая получает найденые данные координат. Эта функция выполняется только по возвращению данных координат.

+ +

Больше информации

+ +

Основное

+ + diff --git a/files/ru/glossary/canvas/index.html b/files/ru/glossary/canvas/index.html new file mode 100644 index 0000000000..56cbc2b5e4 --- /dev/null +++ b/files/ru/glossary/canvas/index.html @@ -0,0 +1,37 @@ +--- +title: Canvas +slug: Словарь/Canvas +tags: + - CodingScripting + - Glossary + - Graphics + - HTML + - JavaScript +translation_of: Glossary/Canvas +--- +
+

 {{Glossary("HTML")}} {{HTMLElement("canvas")}}  (англ. canvas — «холст», рус. канва́с) элемент предоставляет пустую графическую зону, на которой специальные {{Glossary("JavaScript")}} {{Glossary("API","APIs")}} могут рисовать (такие как Canvas 2D или {{Glossary("WebGL")}}).

+ +

См. также

+ +

Общие сведения

+ +
    +
  • {{Interwiki("wikipedia", "Canvas element", "Canvas")}} в Википедии
  • +
+ +

Обучающие ресурсы

+ + + +

Техническая информация

+ + +
diff --git a/files/ru/glossary/card_sorting/index.html b/files/ru/glossary/card_sorting/index.html new file mode 100644 index 0000000000..e70834e888 --- /dev/null +++ b/files/ru/glossary/card_sorting/index.html @@ -0,0 +1,17 @@ +--- +title: Card sorting +slug: Словарь/Card_sorting +tags: + - Дизайн + - Сортировка карточками +translation_of: Glossary/Card_sorting +--- +

Сортировка карточек - это простая техника, используемая в информационной архитектуре, когда людям, участвующим в разработке веб-сайта (или другого типа продукта), предлагается записать контент / услуги / функции, которые, по их мнению, должен содержать продукт, а затем организовать эти функции в категории или группировки. Это может быть использовано, например, для определения того, что должно идти на каждой странице веб-сайта. Название происходит от того факта, что сортировка карточек часто осуществляется путем буквального написания предметов для сортировки на карточках, а затем размещения карточек в стопки.

+ +

Узнать больше 

+ +

Общие знания

+ + diff --git a/files/ru/glossary/cdn/index.html b/files/ru/glossary/cdn/index.html new file mode 100644 index 0000000000..58b5cf6f8a --- /dev/null +++ b/files/ru/glossary/cdn/index.html @@ -0,0 +1,21 @@ +--- +title: CDN +slug: Словарь/CDN +tags: + - Словарь + - инфраструктура +translation_of: Glossary/CDN +--- +

CDN (сеть доставки контента) - это группа серверов, расположенных во многих местах. Эти сервера хранят дубликаты данных, чтобы сервера могли выполнять запросы данных на основе того, какие сервера ближе всего к конечным пользователям. CND увеличивают скорость доступа к сервису уменьшая влияние высокого трафика.

+ + + +

CDN широко используются для доставки таблиц стилей и файлов Javascript (статических ресурсов) библиотек, таких как Bootstrap, jQuery и т. д. Использование CDN для статических библиотечных файлов предпочтительно по ряду причин:

+ + + + diff --git a/files/ru/glossary/certified/index.html b/files/ru/glossary/certified/index.html new file mode 100644 index 0000000000..20e8e567ff --- /dev/null +++ b/files/ru/glossary/certified/index.html @@ -0,0 +1,25 @@ +--- +title: Сертифицировано +slug: Словарь/Сертифицировано +translation_of: Glossary/Certified +--- +

Сертифицировано означает, что приложение, информация или передача данных успешно прошли проверку экспертами в соответствующих областях, таким образом сигнализируя о достоверности, безопасности и законченности.

+ +

За подробностями о сертификации в {{glossary("Cryptography")}}, просьба обратиться к {{glossary("Digital Certificate")}}.

+ +

Подробнее

+ +

Основная информация

+ + + +

Firefox OS

+ + + +

 

diff --git a/files/ru/glossary/character/index.html b/files/ru/glossary/character/index.html new file mode 100644 index 0000000000..248ab150d6 --- /dev/null +++ b/files/ru/glossary/character/index.html @@ -0,0 +1,20 @@ +--- +title: Символ +slug: Словарь/Character +tags: + - Glossary +translation_of: Glossary/Character +--- +

Символ (англ. Character или Symbol) - буква, цифра, знак препинания, непечатаемый символ (например возврат коретки).  {{glossary("UTF-8")}} - самый распространенный стандарт кодировки символов, содержащий большое количество графем популярных языков людей.

+ +

Узнайте больше

+ +

Связанные темы

+ + diff --git a/files/ru/glossary/character_encoding/index.html b/files/ru/glossary/character_encoding/index.html new file mode 100644 index 0000000000..c8bb4782e6 --- /dev/null +++ b/files/ru/glossary/character_encoding/index.html @@ -0,0 +1,27 @@ +--- +title: Кодировка символов +slug: Словарь/character_encoding +tags: + - Composing + - Glossary + - Словарь +translation_of: Glossary/character_encoding +--- +

Кодировка определяет связность между байтами и текстом.  Последовательность байтов допускает различные текстовые интерпретации.  Указывая конкретную кодировку (например, UTF-8), мы указываем, как следует интерпретировать последовательность байтов.

+ +

Например, в HTML мы обычно указываем  кодировку символов UTF-8, используя следующую строку:

+ +
+
<meta charset="utf-8">
+ +

Это гарантирует, что вы можете использовать символы практически любого человеческого языка в вашем HTML-документе, и они будут отображаться надежно.

+
+ +

Узнать больше

+ +

Общие сведения

+ + diff --git a/files/ru/glossary/chrome/index.html b/files/ru/glossary/chrome/index.html new file mode 100644 index 0000000000..3f2f4aa62d --- /dev/null +++ b/files/ru/glossary/chrome/index.html @@ -0,0 +1,11 @@ +--- +title: chrome +slug: Словарь/Chrome +tags: + - Chrome + - Glossary + - WebMechanics + - Браузер +translation_of: Glossary/Chrome +--- +

Не путать с {{glossary("Google Chrome")}}; chrome — видимые элементы {{glossary("Browser", "браузер")}}а, не относящиеся к веб-страницам (например, панели инструментов, панель меню, вкладки).

diff --git a/files/ru/glossary/cia/index.html b/files/ru/glossary/cia/index.html new file mode 100644 index 0000000000..671ddc3046 --- /dev/null +++ b/files/ru/glossary/cia/index.html @@ -0,0 +1,17 @@ +--- +title: КЦД +slug: Словарь/КЦД +tags: + - Безопасность + - Глоссарий +translation_of: Glossary/CIA +--- +

КЦД (Конфиденциальность, Целостность, Доступность) (также называемая триадой КЦД) - модель, регулирующая политику информационной безопасности организации.

+ +

Узнать больше

+ +

Общая информация

+ + diff --git a/files/ru/glossary/class/index.html b/files/ru/glossary/class/index.html new file mode 100644 index 0000000000..c096fe93f0 --- /dev/null +++ b/files/ru/glossary/class/index.html @@ -0,0 +1,23 @@ +--- +title: Класс +slug: Словарь/Class +tags: + - Глоссарий + - Написание скриптов + - Прототипы +translation_of: Glossary/Class +--- +

В ООП класс определяет характеристи объекта. Класс - это шаблон, в котором описываются свойства и методы будущего объекта. Класс - своего рода чертёж по которому будет реализовываться конкретный объект.

+ +

В {{glossary("OOP","объектно-ориентированном программировании")}} класс описывает характеристики {{glossary("object","объекта")}}. Класс описывает {{glossary("property","свойства")}} и {{glossary("method","методы")}} объекта. Он является шаблоном, с которого срисовываются конкретные экземпляры объектов.

+ +

Узнать больше

+ +

Общие знания

+ + diff --git a/files/ru/glossary/cms/index.html b/files/ru/glossary/cms/index.html new file mode 100644 index 0000000000..0123601b27 --- /dev/null +++ b/files/ru/glossary/cms/index.html @@ -0,0 +1,16 @@ +--- +title: CMS +slug: Словарь/CMS +translation_of: Glossary/CMS +--- +

CMS (Content Management System, рус. "Система управления содержимым")  - это программа, которая позволяет пользователям публиковать, организовывать, изменять или удалять различные виды контента: не только текст, но и встроенные картинки, видео, аудио, и интерактивный код.

+ +

Learn More

+ +

General Knowledge

+ + + +

 

diff --git a/files/ru/glossary/codec/index.html b/files/ru/glossary/codec/index.html new file mode 100644 index 0000000000..bd048430c8 --- /dev/null +++ b/files/ru/glossary/codec/index.html @@ -0,0 +1,20 @@ +--- +title: Codec +slug: Словарь/Codec +translation_of: Glossary/Codec +--- +

Кодек  (от англ. codec - "coder-decoder")  -  это программа, алгоритм, или же устройство, которое позволяет кодировать и декодировать поток данных. Предоставленный codec знает, как работать со специфичной кодировкой или с технологией сжатия.

+ +

Смотрите также

+ +

Общие сведения

+ + + +

Технические ссылки

+ + diff --git a/files/ru/glossary/compile/index.html b/files/ru/glossary/compile/index.html new file mode 100644 index 0000000000..f9a4efe6e7 --- /dev/null +++ b/files/ru/glossary/compile/index.html @@ -0,0 +1,29 @@ +--- +title: Compile +slug: Словарь/Compile +tags: + - Глоссарий +translation_of: Glossary/Compile +--- +

Компиляция - это процесс преобразования компьютерной программы, написанной на данном языке, в эквивалентную программу на другом языке. Компилятор - это программа для выполнения этой задачи. Иногда эту задачу называют также "assembling" или "build", что, как правило, свидетельствует о том, что выполняется не только компиляция, например, упаковка в двоичном формате.

+ +

Обычно компилятор преобразует язык более высокого уровня, такой как C или Java который понимает человек, в машинный язык, такой как ассемблер, который понимает процессор. Некоторые компиляторы, которые переводят между языками схожего уровня, называются транспайлерами или кросс-компиляторами, например, для компиляции с TypeScript на JavaScript. Они считаются инструментами производительности.

+ +

Большинство компиляторов работают либо перед исполнением (AOT), либо во время исполнения (JIT). Как программист, вы обычно вызываете AOT-компиляторы из командной строки или из {{Glossary("IDE")}}. Самый известный "gcc" - это один из примеров.
+ JIT компиляторы обычно прозрачны для Вас и используются для повышения производительности. Например, в браузере: Firefox' SpiderMonkey JavaScript Engine имеет встроенный JIT, который скомпилирует JavaScript на сайте в машинный код, пока Вы его просматриваете, чтобы он работал быстрее. Такие проекты, как WebAssembly, работают над тем, чтобы сделать это еще лучше.

+ +

См. также

+ +

Общие сведения

+ + + +

Обучающие ресурсы

+ + diff --git a/files/ru/glossary/computer_programming/index.html b/files/ru/glossary/computer_programming/index.html new file mode 100644 index 0000000000..24247a348e --- /dev/null +++ b/files/ru/glossary/computer_programming/index.html @@ -0,0 +1,24 @@ +--- +title: Компьютерное программирование +slug: Словарь/Computer_Programming +tags: + - Beginner + - Computer Programming + - Glossary + - Начинающим + - компьютерное программирование + - языки программирования +translation_of: Glossary/Computer_Programming +--- +

Компьютерное программирование - это процесс составления и организации набора инструкций. Они говорят компьютерной программе, что делать на языке, понятном компьютеру. Эти инструкции представлены в виде множества различных языков, таких как C++, Java, JavaScript, HTML, Python, Ruby и Rust.

+ +

Используя соответствующий язык, вы можете программировать / создавать все виды программного обеспечения. Например, программу, которая помогает ученым со сложными вычислениями, базу данных, которая хранит огромные объемы данных, веб-сайт, который позволяет людям загружать музыку, или анимационное программное обеспечение, которое позволяет людям создавать анимированные фильмы.

+ +

Узнать больше

+ +

Общие сведения

+ + diff --git a/files/ru/glossary/conditional/index.html b/files/ru/glossary/conditional/index.html new file mode 100644 index 0000000000..945844e79c --- /dev/null +++ b/files/ru/glossary/conditional/index.html @@ -0,0 +1,34 @@ +--- +title: Conditional (условное выражение) +slug: Словарь/Conditional +tags: + - Beginner + - Conditional + - Glossary + - Начинающим + - Словарь +translation_of: Glossary/Conditional +--- +

Условие - это набор правил, которые могут прерывать нормальное выполнение кода или изменять его в зависимости от того, удовлетворено ли условие или нет.

+ +

Инструкция или набор инструкций выполняется, если удовлетворяется определенное условие. В противном случае выполняется другая инструкция. Также возможно повторить выполнение инструкции или набора инструкций, пока условие еще не удовлетворено.

+ +

Узнать больше

+ +

Общие сведения

+ + + +

Техническая справка

+ + + +

Узнайте об этом

+ + diff --git a/files/ru/glossary/constant/index.html b/files/ru/glossary/constant/index.html new file mode 100644 index 0000000000..366f26e0ea --- /dev/null +++ b/files/ru/glossary/constant/index.html @@ -0,0 +1,19 @@ +--- +title: Constant +slug: Словарь/Константа +tags: + - Constant + - Glossary +translation_of: Glossary/Constant +--- +

Константа хранит значение, которое программист не хочет изменять, например числа(1, 2, 42). С другой стороны, у {{glossary("variable","переменных")}} программист может установить новое {{glossary("value","значение")}} к переменной, имя которой уже используется.

+ +

Как и переменные, константы привязываются к индентификаторам(именам). Например, индентификатор pi может быть привязан к значению 3.14… .

+ +

Узнайте больше

+ +

Общие сведения

+ + diff --git a/files/ru/glossary/constructor/index.html b/files/ru/glossary/constructor/index.html new file mode 100644 index 0000000000..6304608ca5 --- /dev/null +++ b/files/ru/glossary/constructor/index.html @@ -0,0 +1,47 @@ +--- +title: Конструктор +slug: Словарь/Constructor +tags: + - Glossary +translation_of: Glossary/Constructor +--- +

Конструктор принадлежит к определенному классу {{glossary("object")}}, который создается. Конструктор инициализирует этот объект и может предоставлять доступ к его личной информации. Концепция конструкутора может быть применена к большинству {{glossary("OOP","object-oriented programming")}} языков. По существу, конструктор в {{glossary("JavaScript")}} обычно объявляется в экземпляре {{glossary("class")}}.

+ +

Синтаксис

+ +
// Это конструктор по умолчанию класса Default
+function Default() {
+}
+
+// Это перегруженый конструктор класса Overloaded
+// с аргументами параметров
+function Overloaded(arg1, arg2, ...,argN){
+}
+
+ +

Для вызова конструктора класса в JavaScript, используется оператор new чтобы присвоить переменной ({{glossary("variable")}}) ссылку на объект ({{glossary("object reference")}}).

+ +
function Default() {
+}
+
+// Новая ссылка обхекта Default object назначена
+// локальной переменной defaultReference
+var defaultReference = new Default();
+
+ +

 

+ +

Смотреть также

+ +

Основные знания

+ + + +

Техническая справка

+ + diff --git a/files/ru/glossary/cookie/index.html b/files/ru/glossary/cookie/index.html new file mode 100644 index 0000000000..994b51f3b9 --- /dev/null +++ b/files/ru/glossary/cookie/index.html @@ -0,0 +1,21 @@ +--- +title: Cookie +slug: Словарь/Cookie +tags: + - Glossary + - WebMechanics +translation_of: Glossary/Cookie +--- +

Cookie - это небольшой фрагмент информации, сохраненный на компьютере посетителя веб-сайтом через веб-браузер.

+ +

Файлы Cookie используются для персонализации  работы пользователя с веб-сайтом . Они могут содержать предпочтения или введенные данные пользователя при работе с этим веб сайтом . Пользователь может настроить свой веб-браузер таким образом, чтобы он принимал, отклонял или удалял куки.

+ +

Файлы Cookie могут быть установлены и изменены на уровне сервера с помощью заголовка Set-Cookie HTTP или с помощью JavaScript, используя document.cookie.

+ +

Узнать больше

+ +

Общие знания

+ + diff --git a/files/ru/glossary/copyleft/index.html b/files/ru/glossary/copyleft/index.html new file mode 100644 index 0000000000..91b70bf322 --- /dev/null +++ b/files/ru/glossary/copyleft/index.html @@ -0,0 +1,19 @@ +--- +title: Copyleft +slug: Словарь/Copyleft +tags: + - Copyleft + - Копилефт + - Распространение + - Словарь +translation_of: Glossary/Copyleft +--- +

Copyleft — это термин, обычно относящийся к лицензии, который используется для обозначения того, что такая лицензия требует, что бы распространение данного продукта подчинялось той же лицензии, что и оригинал. Примерами лицензий с copyleft являются лицензии GNU {{Glossary ("GPL")}} (для программного обеспечения) и лицензии Creative Commons SA (Share Alike) (для рисунков, фотографий и т.д.).

+ +

Подробнее

+ +

Общие сведения

+ + diff --git a/files/ru/glossary/cors/index.html b/files/ru/glossary/cors/index.html new file mode 100644 index 0000000000..e8100eabfb --- /dev/null +++ b/files/ru/glossary/cors/index.html @@ -0,0 +1,46 @@ +--- +title: CORS +slug: Словарь/CORS +translation_of: Glossary/CORS +--- +

CORS (Cross-Origin Resource Sharing, рус. "Совместное использование ресурсов между разными источниками") - это система, состоящая из отправки HTTP заголовков, которые определяют: заблокировать или выполнить запрос к ограниченному ресурсу на веб-странице из другого домена, отличного от домена происхождения запрашиваемого ресурса.

+ +

The same-origin security policy (рус. "правило ограничения домена") по умолчанию запрещает междоменные запросы. CORS предоставляет веб-серверам возможность контролировать междоменные запросы и позволяет производить безопасный обмен данными между разными доменами.

+ +

Узнать больше

+ +

Основная база знаний

+ + + +

CORS заголовки

+ +
+
{{HTTPHeader("Access-Control-Allow-Origin")}}
+
Указывает, разрешен ли такой запрос для ресурсов из данного источника.
+
{{HTTPHeader("Access-Control-Allow-Credentials")}}
+
Указывает, разрешен ли ответ на запрос в случае, если credentials flag выставлен в true.
+
{{HTTPHeader("Access-Control-Allow-Headers")}}
+
Используется в ответе на запрос в случае "предполетной проверки"({{glossary("preflight request")}}) - проверки, какие из HTTP заголовков могут быть использованы для запроса.
+
{{HTTPHeader("Access-Control-Allow-Methods")}}
+
Указывает метод или методы, которые разрешены для доступа к ресурсу в ответ на "предполетный запрос"({{glossary("preflight request")}}).
+
{{HTTPHeader("Access-Control-Expose-Headers")}}
+
Указывает, какие заголовки могут быть предоставлены как часть ответа, перечисляя их имена.
+
{{HTTPHeader("Access-Control-Max-Age")}}
+
Указывает, как долго могут быть закешированы результаты "предполетного запроса"({{glossary("preflight request")}}).
+
{{HTTPHeader("Access-Control-Request-Headers")}}
+
Используется для исполнения "предполетного запроса"({{glossary("preflight request")}}), чтобы указать серверу, какие из HTTP заголовков будут использоваться во время реального запроса.
+
{{HTTPHeader("Access-Control-Request-Method")}}
+
Используется для исполнения "предполетного запроса"({{glossary("preflight request")}}), чтобы указать серверу, какие HTTP методы будут использоваться во время реального запроса.
+
{{HTTPHeader("Origin")}}
+
Указывает, откуда производится запрос.
+
+ +

Техническая документация

+ + diff --git a/files/ru/glossary/crawler/index.html b/files/ru/glossary/crawler/index.html new file mode 100644 index 0000000000..b4a70953c6 --- /dev/null +++ b/files/ru/glossary/crawler/index.html @@ -0,0 +1,23 @@ +--- +title: Crawler +slug: Словарь/Crawler +translation_of: Glossary/Crawler +--- +

Поисковый робот(паук, краулер) часто называемый просто "бот" или "робот" это программа, систематически обходящая {{glossary("World Wide Web","Web")}} для сбора данных со страниц веб-сайтов. Обычно поисковые сервисы (напр. Google, Bing, и пр.) используют поисковых роботов для индексирования сайтов.

+ +

Узнать больше

+ + + + diff --git a/files/ru/glossary/crlf/index.html b/files/ru/glossary/crlf/index.html new file mode 100644 index 0000000000..d773d3b899 --- /dev/null +++ b/files/ru/glossary/crlf/index.html @@ -0,0 +1,13 @@ +--- +title: CRLF +slug: Словарь/CRLF +translation_of: Glossary/CRLF +--- +

CR и LF это управляющие символы или байт-код которые можно использовать для обозначения разрыва строки в текстовых файлах.

+ + + +

CR, за которым сразу следует LF (CRLF, \r\n, или 0x0D0A) перемещает курсор на следующую строку и затем перемещает его в начало строки.

diff --git a/files/ru/glossary/csp/index.html b/files/ru/glossary/csp/index.html new file mode 100644 index 0000000000..c3ffad563c --- /dev/null +++ b/files/ru/glossary/csp/index.html @@ -0,0 +1,27 @@ +--- +title: CSP +slug: Словарь/CSP +tags: + - CSP + - Content Security Policy + - HTTP + - Словарь +translation_of: Glossary/CSP +--- +

CSP (Политика безопасности контента) используется для обнаружения и смягчения определенных типов атак, связанных с веб-сайтами, таких как {{Glossary("XSS")}} и инъекции данных.

+ +

Реализация основана на заголовке {{Glossary ("HTTP")}} с именем {{HTTPHeader("Content-Security-Policy")}}.

+ +

Узнать больше

+ +

Общие сведения

+ + + +

Техническая информация

+ + diff --git a/files/ru/glossary/csrf/index.html b/files/ru/glossary/csrf/index.html new file mode 100644 index 0000000000..287c077616 --- /dev/null +++ b/files/ru/glossary/csrf/index.html @@ -0,0 +1,16 @@ +--- +title: CSRF +slug: Словарь/CSRF +translation_of: Glossary/CSRF +--- +

CSRF (Cross-Site Request Forgery, рус. "Межсайтовая подделка запроса") - вид атаки, при которой вражеский сайт выдает себя за доверенного пользователя и отсылает на сайт нежелательные комманды. Это может быть сделано, к примеру, с помощью отправки  параметров в {{glossary("URL")}} в конце ссылки с целью перехода куда-либо в другое место.

+ +

Learn more

+ +

General knowledge

+ + diff --git a/files/ru/glossary/css/index.html b/files/ru/glossary/css/index.html new file mode 100644 index 0000000000..b47954e978 --- /dev/null +++ b/files/ru/glossary/css/index.html @@ -0,0 +1,48 @@ +--- +title: CSS +slug: Словарь/CSS +tags: + - CSS + - Glossary + - Дизайн +translation_of: Glossary/CSS +--- +

CSS (Cascading Style Sheets, или каскадные таблицы стилей) - это декларативный язык, который отвечает за то, как страницы выглядят в {{glossary("browser","веб браузере")}}. CSS стили содержат свойства и их значения, которые и определяют, как будет выглядеть сайт.

+ +

CSS одна из ключевых Web технологий, наряду с {{Glossary("HTML")}} и {{Glossary("JavaScript")}}. Как правило CSS используется для определения стилей {{Glossary("Element","HTML элементов")}}, но также может быть применен совместно с другими языками разметки, такими как {{Glossary("SVG")}} или {{Glossary("XML")}}.

+ +

CSS правило состоит из {{Glossary("selector","селектора")}} и набора {{Glossary("CSS Property","свойств")}} с их значениями. В этом примере все HTML параграфы будут иметь текст желтого цвета на черном фоне:

+ +
/* Селектор "p" означает, что данное правило будет применено ко всем параграфам в документе */
+p {
+  /* Свойство "color" определяет цвет текста, в данном случае желтый. */
+  color: yellow;
+
+  /* Свойство "background-color" определяет цвет фона элемента, в данном случае черный. */
+  background-color: black;
+}
+ +

"Каскадность" CSS - это правила, которые регулируют приоритет селекторов при отображении внешнего вида элементов страницы. Это очень важная особенность, поскольку сложный веб-сайт может иметь тысячи CSS-селекторов.

+ +

Смотрите также

+ +

Базовые знания

+ + + +

Техническая документация

+ + + +

Веб-курсы CSS

+ + diff --git a/files/ru/glossary/css_preprocessor/index.html b/files/ru/glossary/css_preprocessor/index.html new file mode 100644 index 0000000000..e517efb0b0 --- /dev/null +++ b/files/ru/glossary/css_preprocessor/index.html @@ -0,0 +1,24 @@ +--- +title: CSS препроцессор +slug: Словарь/CSS_preprocessor +tags: + - CSS + - Glossary +translation_of: Glossary/CSS_preprocessor +--- +

CSS препроцессор (CSS preprocessor) - это программа, которая имеет свой собственный синтаксис ({{Glossary("syntax")}}), но может сгенерировать из него {{Glossary("CSS")}} код . Существует множество препроцессоров. Большинство из них расширяет функционал чистого CSS, добавляя такие опции как: примеси, вложенные правила, селекторы наследования и др. Эти особенности облегчают работу с CSS: упрощают чтение кода и его дальнейшую поддержку.

+ +

Для использования CSS препроцессора нужно установить CSS компилятор на ваш веб-сервер ({{Glossary("server")}}).

+ +

Узнать больше

+ +

Общие знания

+ +

Несколько самых популярных CSS препоцессоров:

+ + diff --git a/files/ru/glossary/css_selector/index.html b/files/ru/glossary/css_selector/index.html new file mode 100644 index 0000000000..c8d8885062 --- /dev/null +++ b/files/ru/glossary/css_selector/index.html @@ -0,0 +1,73 @@ +--- +title: CSS-селектор +slug: Словарь/CSS_Selector +tags: + - CSS + - CSS-селектор + - HTML + - Глоссарий + - селектор +translation_of: Glossary/CSS_Selector +--- +

CSS-селектор это часть CSS-правила, которая позволяет Вам указать, к какому элементу (элементам) применить стиль. Например:

+ +
***HTML***
+<div> I am inside of a div element. </div>
+<p> I am inside of a paragraph element. </p>
+
+
+***CSS***
+div {
+ color: green;
+}
+
+p {
+ color: red;
+}
+
+ +

В первом CSS-правиле я выбираю элемент div и задаю его стиль (цвет текста зелёный). Во втором CSS-правиле выбираю элемент p и задаю красный цвет текста. Вот как выглядит результат:

+ +

CSS selector coding results

+ + + +

Смотрите также

+ +

Основные статьи

+ +
    +
  1. Базовые селекторы +
      +
    1. Селекторы по типу elementname
    2. +
    3. Селекторы по классу .classname
    4. +
    5. Селекторы по ID #idname
    6. +
    7. Универсальные селекторы * ns|* *|*
    8. +
    9. Атрибутивные селекторы [attr=value]
    10. +
    11. Селекторы состояния элементов a:active, a:visited
    12. +
    +
  2. +
  3. Группирующие селекторы +
      +
    1. Список селекторов A, B
    2. +
    +
  4. +
  5. Комбинаторы +
      +
    1. Adjacent sibling selectors A + B
    2. +
    3. General sibling selectors A ~ B
    4. +
    5. Child selectors A > B
    6. +
    7. Descendant selectors A B
    8. +
    +
  6. +
  7. Псевдо +
      +
    1. Псевдоклассы :
    2. +
    3. Псевдоэлементы ::
    4. +
    +
  8. +
+ +

Техническая справка

+ +

{{SpecName("CSS3 Selectors")}}

diff --git a/files/ru/glossary/data_structure/index.html b/files/ru/glossary/data_structure/index.html new file mode 100644 index 0000000000..192f354fb1 --- /dev/null +++ b/files/ru/glossary/data_structure/index.html @@ -0,0 +1,17 @@ +--- +title: Cтруктура данных +slug: Словарь/data_structure +tags: + - Data structure + - структура данных +translation_of: Glossary/Data_structure +--- +

Cтруктура данных (data structure) — способ представления множества данных как связного целого, имеющего определённый программный интерфейс (методы доступа и манипулирования над элементами этих данных).

+ +
Learn more
+ + + +

 

diff --git a/files/ru/glossary/decryption/index.html b/files/ru/glossary/decryption/index.html new file mode 100644 index 0000000000..1e64097284 --- /dev/null +++ b/files/ru/glossary/decryption/index.html @@ -0,0 +1,22 @@ +--- +title: Дешифрование +slug: Словарь/Дешифрование +translation_of: Glossary/Decryption +--- +

В {{glossary("cryptography")}}, дешифрование это конвертация {{glossary("ciphertext")}} в {{glossary("cleartext")}}.

+ +

Расшифровка это криптографическая основа: это трансформация кодированного текста в простой текст при помощи криптографического алгоритма под названием {{glossary("cipher")}}. Шифрование, как и дешифрование в современных способах кодирования осуществляется благодаря определенному алгоритму и секретному элементу: {{glossary("key")}}. Если алгоритм обычно доступен публично, то по соображениям безопасности, ключ должен оставатся в тайне.

+ +

 

+ +

The decryption primitive.

+ +

Дешифрование это обратный процесс {{glossary("encryption")}} и если ключ остается в тайне, дешифрование становиться математически сложным. Степень сложности зависит от уровня безопасности действующих криптографических алгоритмов и эволюционирует с развитием {{glossary("cryptanalysis")}}.

+ +

Подробнее

+ +

Техническая справка

+ + diff --git a/files/ru/glossary/developer_tools/index.html b/files/ru/glossary/developer_tools/index.html new file mode 100644 index 0000000000..bf976c49fe --- /dev/null +++ b/files/ru/glossary/developer_tools/index.html @@ -0,0 +1,27 @@ +--- +title: Инструменты разработчика +slug: Словарь/Инструменты_разработчика +tags: + - Инспектор + - инструменты +translation_of: Glossary/Developer_Tools +--- +

Инструменты разработчика (от англ. "development tools" или сокращенно "DevTools") - это программы, которые позволяют создавать, тестировать и отлаживать ({{Glossary("debug")}}) программное обеспечение.

+ +

Современные браузеры имеют встроенные инструменты разработчика, позволяющие просмотреть исходный код сайта. С их помощью можно просматривать и отлаживать {{Glossary("HTML")}} сайта, его {{Glossary("CSS")}} и {{Glossary("JavaScript")}}. Также можно проверить сетевой трафик, потребляемый сайтом, его быстродействие и много других параметров.

+ +

General knowledge

+ + + +

Technical reference

+ + diff --git a/files/ru/glossary/dns/index.html b/files/ru/glossary/dns/index.html new file mode 100644 index 0000000000..d40b9ee401 --- /dev/null +++ b/files/ru/glossary/dns/index.html @@ -0,0 +1,24 @@ +--- +title: DNS +slug: Словарь/DNS +tags: + - DNS + - Система доменных имён + - Словарь + - инфраструктура +translation_of: Glossary/DNS +--- +

DNS (Система доменных имён, англ. Domain Name System) — это иерахическая децентрализованная система именования для интернет-ресурсов подключённых к Интернет, которая ведёт список {{glossary("domain name","доменных имён")}} вместе с их числовыми {{Glossary("IP address","IP-адресами")}} или местонахождениями. DNS позволяет перевести простое запоминаемое {{Glossary("hostname","имя хоста")}} в IP-адрес. DNS lookup (Поиск DNS) — это процесс с помощью которого от DNS-сервер возвращается DNS запись, необходимая для нахождения конкретного компьютерного сервиса в {{Glossary("Internet","Интернет")}} или частной сети.

+ +

Взаимосвязанные компьютеры, сервера и смартфоны должны знать как преобразовать email адреса и доменные имена, которые используют люди, в значимые числовые адреса. Эту фукнцию выполняет DNS lookup.

+ +

Reverse DNS lookup (rDNS, обратный просмотр DNS) — это метод запроса к DNS для определения доменного имени по его IP-адресу.

+ +

Узнать больше

+ +

Общие знания

+ + diff --git a/files/ru/glossary/doctype/index.html b/files/ru/glossary/doctype/index.html new file mode 100644 index 0000000000..6059777378 --- /dev/null +++ b/files/ru/glossary/doctype/index.html @@ -0,0 +1,28 @@ +--- +title: Doctype +slug: Словарь/Doctype +tags: + - Browser + - CodingScripting + - DOCTYPE + - Glossary + - HTML + - Intro +translation_of: Glossary/Doctype +--- +

В {{Glossary("HTML")}} объявление типа документа тегом "<!DOCTYPE html>" - обязательная преамбула, расположенная в верхней части документа. Единственное предназначение тега - не допустить переключение {{Glossary("browser","браузера")}} в так называемый режим совместимости (“quirks mode”) во время рендеринга документа; то есть, тег "<!DOCTYPE html>" гарантирует, что браузер с максимальными усилиями будет следовать соответствующей спецификации, а не использовать другой тип рендеринга, несовместимый с некоторыми спецификациями.

+ +

Смотрите также

+ +

Основная информация

+ + + +

Техническая документация

+ + diff --git a/files/ru/glossary/dom/index.html b/files/ru/glossary/dom/index.html new file mode 100644 index 0000000000..10e85608e9 --- /dev/null +++ b/files/ru/glossary/dom/index.html @@ -0,0 +1,27 @@ +--- +title: DOM +slug: Словарь/DOM +tags: + - Словарь +translation_of: Glossary/DOM +--- +

DOM (Document Object Model) это {{glossary("API")}} который представляет и взаимодействует со всеми {{glossary("HTML")}} или {{glossary("XML")}} документами. DOM это модель документа загруженная в {{glossary("browser")}} и представляющая документ как узел дерева, где каждый узел представляет часть (e.g. an {{Glossary("element")}} документа, строку текста, или комментарий).

+ +

DOM это самый используемый {{Glossary("API")}} в {{glossary("World Wide Web","Web")}} потому, что он даёт коду запущенному в браузере доступ и взаимодействие с каждым узлом в документе. Узлы могут быть созданы, перемещены и изменены. Прослушиватели событий могут быть добавлены к узлам и срабатывают при наступлении данного события.

+ +

DOM не был определен изначально — он пришел когда браузеры начали реализовывать поддержку {{Glossary("JavaScript")}}. Этот унаследованный DOM иногда называют DOM 0. Сегодня, W3C руководит процессом спецификации DOM, и DOM Working Group в настоящее время подготавливают 4-ую версию.

+ +

Узнать больше

+ +

Общие знания

+ + + +

Техническая информация

+ + diff --git a/files/ru/glossary/domain/index.html b/files/ru/glossary/domain/index.html new file mode 100644 index 0000000000..f79eaa991e --- /dev/null +++ b/files/ru/glossary/domain/index.html @@ -0,0 +1,17 @@ +--- +title: Domain +slug: Словарь/Домен +tags: + - Браузер + - домен + - инфраструктура + - сеть +translation_of: Glossary/Domain +--- +

Домен - это часть компьютерной сети, в которой один объект контролирует ресурсы обработки данных, например веб-сайт.

+ +

Узнать больше

+ + diff --git a/files/ru/glossary/domain_name/index.html b/files/ru/glossary/domain_name/index.html new file mode 100644 index 0000000000..249e3f60d2 --- /dev/null +++ b/files/ru/glossary/domain_name/index.html @@ -0,0 +1,23 @@ +--- +title: Доменное имя +slug: Словарь/Domain_name +tags: + - Domain Name + - Glossary + - Protocol + - WebMechanics + - Словарь + - доменное имя + - протокол +translation_of: Glossary/Domain_name +--- +

Имя домена является адресом веб-сайта в {{Glossary("Internet","интернете")}}. Доменные имена используются в {{Glossary("URL","URLs")}}, чтобы идентифицировать сервер, на котором находится определенная веб-страница. Имя домена состоит из иерархической последовательности имен (меток), разделенных точками и заканчивающейся   {{glossary("TLD","расширением верхнего уровня")}}.

+ +

Подробнее

+ +

Общие сведения

+ + diff --git a/files/ru/glossary/dos_attack/index.html b/files/ru/glossary/dos_attack/index.html new file mode 100644 index 0000000000..140782b6f9 --- /dev/null +++ b/files/ru/glossary/dos_attack/index.html @@ -0,0 +1,32 @@ +--- +title: DoS атака +slug: Словарь/DOS_attack +translation_of: Glossary/DOS_attack +--- +

DoS (отказ в обслуживании) - это сетевая атака, которая препятствует обычному  использованию ресурсов {{glossary ('server')}}, нагружая сервер "ложными", "фиктивными" запросами.

+ +

Компьютеры имеют ограниченные ресурсы, например вычислительные мощности(процессорная частота) или размер памяти. Когда они исчерпаны, программа может зависнуть или аварийно завершить работу, делая ее недоступной. DoS-атака состоит из различных методов, позволяющих исчерпать эти ресурсы и сделать сервер или сеть недоступными для обычных пользователей или, по крайней мере, заставить сервер работать медленно

+ +

Существуют также распределенные атаки типа «отказ в обслуживании» (DDoS), в которых используется множество серверов-злоумышленников, нацеленных на исчерпания вычислительной мощности атакуемого компьютера.

+ +

Типы DoS атак

+ +

DoS-атаки - это больше категория, чем определенный вид атак. Вот неполный список типов DoS-атак:

+ + + +

Learn more

+ + diff --git a/files/ru/glossary/dynamic_programming_language/index.html b/files/ru/glossary/dynamic_programming_language/index.html new file mode 100644 index 0000000000..fe4043c7a6 --- /dev/null +++ b/files/ru/glossary/dynamic_programming_language/index.html @@ -0,0 +1,16 @@ +--- +title: Динамический язык программирования +slug: Словарь/Dynamic_programming_language +tags: + - Словарь +translation_of: Glossary/Dynamic_programming_language +--- +

Динамический язык — язык программирования, который позволяет определять типы данных и осуществлять синтаксический анализ и компиляцию «на лету», на этапе выполнения программы. Динамические языки удобны для быстрой разработки приложений. Например, в JavaScript можно изменить тип переменной, или добавить новые свойства, или методы к объекту в то время, как программа работает.

+ +

Это свойство отличает динамические языки от статических языков программирования, в которых подобные изменения обычно невозможны.

+ +

Подробнее:

+ + diff --git a/files/ru/glossary/ecma/index.html b/files/ru/glossary/ecma/index.html new file mode 100644 index 0000000000..335808f037 --- /dev/null +++ b/files/ru/glossary/ecma/index.html @@ -0,0 +1,17 @@ +--- +title: ECMA +slug: Словарь/ECMA +translation_of: Glossary/ECMA +--- +

 

+ +

Ecma International, ранее известная как European Computers Manufactures Association (Европейская Ассоциация Производителей Компьютеров) — некоммерческая организация, утверждающая и развивающая стандарты в областях аппаратного обеспечения компьютеров, коммуникационных технологий и языков программирования.

+ +

В интернете она прежде всего известна, как организация, утвердившая спецификацию ECMA-262 (она же  {{Glossary("ECMAScript")}}), являющуюсяся основной спецификацией языка {{Glossary("JavaScript")}}.

+ +

Узнать больше

+ + diff --git a/files/ru/glossary/ecmascript/index.html b/files/ru/glossary/ecmascript/index.html new file mode 100644 index 0000000000..acaff14a0b --- /dev/null +++ b/files/ru/glossary/ecmascript/index.html @@ -0,0 +1,22 @@ +--- +title: ECMAScript +slug: Словарь/ECMAScript +translation_of: Glossary/ECMAScript +--- +

ECMAScript - это скриптовый язык на котором основан {{glossary("JavaScript")}} . Ecma International - организация отвечающая за стандартизацию ECMAScript.

+ +

Learn more

+ +

General knowledge

+ + + +

Technical reference

+ + + +
 
diff --git a/files/ru/glossary/element/index.html b/files/ru/glossary/element/index.html new file mode 100644 index 0000000000..e830c4a29b --- /dev/null +++ b/files/ru/glossary/element/index.html @@ -0,0 +1,20 @@ +--- +title: Элемент +slug: Словарь/Элемент +tags: + - HTML + - Словарь +translation_of: Glossary/Element +--- +

Элемент - это часть веб-страницы. В XML и HTML элемент может содержать данные, фрагмент текста или изображения, или не содержать ничего. Обычный элемент включает в себя открывающий тэг с некоторыми атрибутами, текст и закрывающий тэг.
+ Example: in <p class="nice">Hello world!</p>, '<p class="nice">' is an opening tag, 'class="nice"' is an attribute and its value, 'Hello world!' is enclosed text content, and '</p>' is a closing tag.

+ +

Элементы и тэги это не одни и те же вещи. Тэги открывают или закрывают элементы в исходном коде, тогда как элементы являются частью {{Glossary("DOM")}}, объектной моделью документа для отображения страницы в {{glossary("browser", "браузере")}}.

+ +

Смотрите также

+ + diff --git a/files/ru/glossary/empty_element/index.html b/files/ru/glossary/empty_element/index.html new file mode 100644 index 0000000000..e9c3c7370d --- /dev/null +++ b/files/ru/glossary/empty_element/index.html @@ -0,0 +1,35 @@ +--- +title: Пустой элемент +slug: Словарь/Empty_element +tags: + - CodingScripting + - Glossary + - Intermediate + - Словарь +translation_of: Glossary/Empty_element +--- +

Пустой элемент — {{Glossary("element", "элемент")}} HTML, SVG или MathML, который не может иметь дочерних узлов (т.е. вложенных элементов или текста внутри себя).

+ +

Спецификации HTML, SVG и MathML спецификации очень строго определяют, какой элемент что может содержать. Многие комбинации семантически не имеют смысла, например элемент {{HTMLElement("audio")}} внутри элемента {{HTMLElement("hr")}}.

+ +

В HTML использование закрывающего тега для пустого элемента обычно ошибочно. Например, <input type="text"></input> является недопустимым HTML.

+ +

Пустые элементы в HTML:

+ + diff --git a/files/ru/glossary/encapsulation/index.html b/files/ru/glossary/encapsulation/index.html new file mode 100644 index 0000000000..f89f467f50 --- /dev/null +++ b/files/ru/glossary/encapsulation/index.html @@ -0,0 +1,18 @@ +--- +title: Инкапсуляция +slug: Словарь/Encapsulation +tags: + - CodingScripting + - Glossary +translation_of: Glossary/Encapsulation +--- +

Инкапсуляция - это упаковка данных и {{glossary("function","functions")}} в один компонент (например, {{glossary("class")}}) и последующий контроль доступа к этому компоненту, создавая тем самым "черный ящик" из {{glossary("object")}}. По этой причине, пользователю необходмо знать только интерфейс этого класса (то есть данные и функции, предоставляемые для взаимодействия с классом извне), а не то, как он реализован внутри.

+ +

Изучить больше

+ +

Общие знания

+ + diff --git a/files/ru/glossary/entity/index.html b/files/ru/glossary/entity/index.html new file mode 100644 index 0000000000..3ed0f645b8 --- /dev/null +++ b/files/ru/glossary/entity/index.html @@ -0,0 +1,59 @@ +--- +title: Сущности +slug: Словарь/Сущности +tags: + - HTML + - Словарь +translation_of: Glossary/Entity +--- +

{{glossary("HTML")}}-сущности — это части текста ("cтроки"), которые начинаются с символа амперсанда (&) и заканчиваются точкой с запятой (;). Сущности чаще всего используются для представления специальных символов (которые могут быть восприняты как часть HTML-кода) или невидимых символов (таких как неразрывный пробел). Также вы можете использовать их вместо символов, печать которых с обычной клавиатуры труднодоступна. 

+ +
+

Многие символы имеют запоминающиеся сущности (мнемоники). Например для символа копирайта (©) мнемоникой будет &copy;.  Для менее запоминающихся сущностей, таких как &#8212; или &#x2014; вы можете воспользоваться таблицей символов или инструментом перекодирования.

+
+ +

Зарезервированные (специальные) символы

+ +

Некоторые специальные символы зарезервированы для использования в HTML. Это означает, что браузер может распознать их как часть HTML-кода. Например, если вы используете знак "меньше" (<), браузер может воспринять следующий за ним текст как {{Glossary('tag', 'тег')}}.

+ +

Чтобы такие символы отображались как текст, необходимо заменить их на соответствующие сущности, представленные в таблице ниже.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
СимволСушностьПримечание
&&amp;Может быть интерпретирован как начало последовательности-сущности.
<&lt;Может быть интерпретирован как начало {{Glossary("tag", "тега")}}
>&gt;Может быть интерпретирован как окончание {{Glossary("tag", "тега")}}
"&quot;Может быть интерпретирован как обрамляющая значение {{Glossary('attribute', "атрибута")}} кавычка.
+ +

Узнать больше

+ +

Техническая справка

+ + diff --git a/files/ru/glossary/entity_header/index.html b/files/ru/glossary/entity_header/index.html new file mode 100644 index 0000000000..269f88ecbd --- /dev/null +++ b/files/ru/glossary/entity_header/index.html @@ -0,0 +1,25 @@ +--- +title: Заголовок сущности +slug: Словарь/Entity_header +tags: + - Словарь +translation_of: Glossary/Entity_header +--- +

Заголовок сущности - это {{Glossary("header", "HTTP header")}}, описывающий содержимое тела сообщения. Заголовки сущности используются в HTTP-запросах и ответах. Заголовки, такие как {{HTTPHeader("Content-Length")}}, {{HTTPHeader("Content-Language")}}, {{HTTPHeader("Content-Encoding")}} являются заголовками сущности.

+ +

Даже если заголовки сущности не являются заголовками запросов или ответов, они часто включаются в эти понятия.

+ +

В следующем примере, {{HTTPHeader("Content-Length")}} - это заголовок сущности, в то время как {{HTTPHeader("Host")}} и {{HTTPHeader("User-Agent")}} представляют собой {{Glossary("request header", "заголовок запроса")}}:

+ +
POST /myform.html HTTP/1.1
+Host: developer.mozilla.org
+User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
+Content-Length: 128
+ +

Узнать больше

+ +

Технические знания

+ + diff --git a/files/ru/glossary/event/index.html b/files/ru/glossary/event/index.html new file mode 100644 index 0000000000..cd1abf198e --- /dev/null +++ b/files/ru/glossary/event/index.html @@ -0,0 +1,25 @@ +--- +title: Событие +slug: Словарь/event +tags: + - events + - Словарь + - события +translation_of: Glossary/event +--- +

События - это сгенерированные DOM-элементами свойства, которыми можно манипулировать с помощью Javascript-кода.

+ +

Подробнее

+ +

Техническая информация

+ + + +

Общая информация

+ + diff --git a/files/ru/glossary/expando/index.html b/files/ru/glossary/expando/index.html new file mode 100644 index 0000000000..05e9246629 --- /dev/null +++ b/files/ru/glossary/expando/index.html @@ -0,0 +1,10 @@ +--- +title: Expando +slug: Словарь/Expando +translation_of: Glossary/Expando +--- +

Expando-свойства — это свойства, добавленные в узлы {{glossary("DOM")}} с помощью {{glossary("JavaScript")}}, когда эти свойства не являются частью DOM-спецификации {{glossary("object","объекта")}}:

+ +
window.document.foo = 5; // foo — это expando
+ +

Термин может быть применён к свойствам, добавленным к объекту без учёта его изначального предназначения, например, когда свойства с не числовым именем добавлены к {{glossary("Array","массиву")}}.

diff --git a/files/ru/glossary/falsy/index.html b/files/ru/glossary/falsy/index.html new file mode 100644 index 0000000000..480f972044 --- /dev/null +++ b/files/ru/glossary/falsy/index.html @@ -0,0 +1,93 @@ +--- +title: Falsy +slug: Словарь/Falsy +tags: + - Glossary + - JavaScript + - falsy +translation_of: Glossary/Falsy +--- +

Ложное (falsy) значение - это значение, которое считается ложным, когда встречается в контексте {{Glossary("Boolean")}} .

+ +

{{Glossary("JavaScript")}} использует {{Glossary("Type_Conversion", "Type Conversion")}} для приведения любого значения к логическому в контекстах, которые требуют его, такие как {{Glossary("Conditional", "условные выражения")}} и {{Glossary("Loop", "циклы")}}.

+ +
+

В JavaScript есть только 7 ложных значений

+ +

Это означает, что когда JavaScript ожидает логическое значение и ему присваивается одно из значений ниже, он всегда будет оцениваться как «ложное»

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
falseКлючевое слово {{jsxref('Lexical_grammar','false','Зарезервированные_ключевые_слова_в_более_старых_версиях')}}
0Число zero
0n{{jsxref('Global_Objects/BigInt','BigInt')}}, при использовании в качестве логического значения, следует тому же правилу, что и число. 0n - это ложь.
"", '', `` +

Это пустая строка(длина строки ноль). Строки в JavaScript могут быть определены с помощью двойных кавычек (") или одинарных кавычек ('), а также {{jsxref ('template_strings', 'Template literals')}} (`)

+
{{Glossary("null")}}{{jsxref('Global_Objects/null','null')}} - отсутствие какого-либо значения
{{Glossary("undefined")}}{{jsxref('Global_Objects/undefined','undefined')}} - примитивное значение
{{Glossary("NaN")}}{{jsxref('Global_Objects/NaN','NaN')}} - не число
+ +

Примеры

+ +

Примеры ложных значений в JavaScript (которые приводятся к ложному в булевых контекстах и, таким образом, обходят блок if):

+ +
if (false)
+if (null)
+if (undefined)
+if (0)
+if (0n)
+if (NaN)
+if ('')
+if ("")
+if (``)
+if (document.all)
+
+ +

Логический оператор И, &&

+ +

Если первый объект ложный, он возвращает этот объект

+ +
let pet = false && "dog";
+
+// ↪ false
+
+ +
+

В прошлом для обнаружения браузером использовался document.all, а Спецификация HTML здесь определяет преднамеренное нарушение стандарта ECMAScript для сохранения совместимости с устаревшим кодом. (if (document.all) { // Internet Explorer code here(except IE11) } or using document.all without checking its presence first: document.all.foo).

+
+ +

Иногда пишется falsy, хотя на английском языке обычно превращают слово в прилагательное с окончанием -y, любое окончание e отбрасывается(noise => noisy, ice => icy, shine => shiny)

+ +

Узнать больше

+ + + +
{{QuickLinksWithSubpages("/en-US/docs/Glossary")}}
diff --git a/files/ru/glossary/first-class_function/index.html b/files/ru/glossary/first-class_function/index.html new file mode 100644 index 0000000000..aaae7749e5 --- /dev/null +++ b/files/ru/glossary/first-class_function/index.html @@ -0,0 +1,32 @@ +--- +title: Функции первого класса +slug: Словарь/First-class_Function +tags: + - Glossary + - Глоссарий +translation_of: Glossary/First-class_Function +--- +

Если язык программирования имеет функции первого класса, то значит они трактуются как объекты, то есть могут быть переданы другим функциям и их можно вернуть из функций. Так же их можно присваивать переменным.

+ +

Пример

+ +
/* функция не имеет имени и находится в правой части команды присваивания переменной.*/
+
+var dog = function(num) {
+    for (var i = 0; i < num; i++) {
+        alert("Woof");
+    }
+};
+dog(3); //Эту функцию можно вызвать через переменную dog.
+ +

Такое использование ключевого слова function — внутри команды, как в команде присваивания, — называется функциональным выражением. В отличие от объявления, эта функция не имеет имени. Кроме того, результатом этого выражения является значение, которое затем присваивается переменной dog. Что это за значение? Мы присваиваем его переменной dog, а затем вызываем через эту переменную, значит, это есть ссылка на функцию.

+ +

Узнать больше

+ +

Общее представление

+ + + +

 

diff --git a/files/ru/glossary/first_contentful_paint/index.html b/files/ru/glossary/first_contentful_paint/index.html new file mode 100644 index 0000000000..52425b24d4 --- /dev/null +++ b/files/ru/glossary/first_contentful_paint/index.html @@ -0,0 +1,15 @@ +--- +title: First contentful paint +slug: Словарь/First_contentful_paint +translation_of: Glossary/First_contentful_paint +--- +

Первое существенное отображение (англ. First Contentful Paint, FCP) - время, за которое пользователь увидит какое-то содержимое веб-страницы, например, текст или картинку.

+ +

Эта метрика показывает, какое время потребуется браузеру для отображения части DOM после того, как пользователь перешел на веб-страницу. Контентом в данном случае считаются любой текст, изображения, не пустой canvas и SVG. Данный показатель не учитывает загрузку контента в iframe, но учитывает текст, шрифт которых еще загружается.

+ +

См. также:

+ + diff --git a/files/ru/glossary/first_cpu_idle/index.html b/files/ru/glossary/first_cpu_idle/index.html new file mode 100644 index 0000000000..703c2e9e2d --- /dev/null +++ b/files/ru/glossary/first_cpu_idle/index.html @@ -0,0 +1,8 @@ +--- +title: First CPU idle +slug: Словарь/First_CPU_idle +translation_of: Glossary/First_CPU_idle +--- +

First CPU Idle показывает, через какое время страница является "минимально" интерактивной, или когда основной поток достаточно свободен, чтобы обработать пользовательский ввод. Как правило, это происходит, когда большинство видимых элементов пользовательского интерфейса являются интерактивными и реагируют на события пользовательского ввода.

+ +

Этот показатель является нестандартной метрикой веб-производительности от Google и также известен как First interactive.

diff --git a/files/ru/glossary/first_input_delay/index.html b/files/ru/glossary/first_input_delay/index.html new file mode 100644 index 0000000000..fa3c87bbf8 --- /dev/null +++ b/files/ru/glossary/first_input_delay/index.html @@ -0,0 +1,15 @@ +--- +title: First input delay +slug: Словарь/First_input_delay +translation_of: Glossary/First_input_delay +--- +

Задержка первого ввода (англ. First input delay, FID) - одна из метрик производительности веб-страниц, которая описывает время, которое прошло с момента, когда пользователь впервые начал взаимодействовать с веб-страницей, т.е. нажал на ссылку, кнопку или использует элемент управления на основе JavaScript, до момента, когда веб-браузер может ответить на данное взаимодействие. Таким образом, это промежуток времени в миллисекундах между первым взаимодействием пользователя с веб-страницой и ответом браузера на это взаимодействие. Прокрутка и масштабирование не включены в этот показатель.

+ +

Время между моментом, когда содержимое отображается на странице, и моментом, когда все функциональные возможности становятся реагирующими на взаимодействие с человеком, часто варьируется в зависимости от размера и сложности JavaScript, который необходимо загрузить, проанализировать и выполнить в основном потоке. Оно зависит также и от возможности устройства, на котором выполняется JavaScript (подумайте о недорогих мобильных устройствах). Чем дольше задержка, тем хуже пользовательский опыт. Сокращение времени инициализации сайта и устранение долгих задач может помочь устранить первые задержки ввода.

+ +

См. также

+ + diff --git a/files/ru/glossary/first_interactive/index.html b/files/ru/glossary/first_interactive/index.html new file mode 100644 index 0000000000..2433ee6b7e --- /dev/null +++ b/files/ru/glossary/first_interactive/index.html @@ -0,0 +1,14 @@ +--- +title: First interactive +slug: Словарь/First_interactive +translation_of: Glossary/First_interactive +--- +

Первая интерактивность (англ. First Interactive), также известная как first CPU idle - нестандартная метрика веб-производительности, которая показывает, через какое время страница является "минимально" интерактивной, или когда основной поток достаточно свободен, чтобы обработать пользовательский ввод.

+ +

Страница является "минимально" интерактивной, когда большинство видимых элементов пользовательского интерфейса является интерактивными и реагируют на события пользовательского ввода в течение допустимого периода времени - 50 миллисекунд.

+ +

Больше информации

+ +

Первая интерактивность - вариация метрики "Time to Interactive", которая подразделяется на "First interactive" и "Consistently Interactive". Эти показатели были предложены WICG и уже используются в различных инструментах.

+ +

Начиная с Lighthouse 3.0 данный показатель называется First CPU idle.

diff --git a/files/ru/glossary/first_meaningful_paint/index.html b/files/ru/glossary/first_meaningful_paint/index.html new file mode 100644 index 0000000000..569b1ebd8d --- /dev/null +++ b/files/ru/glossary/first_meaningful_paint/index.html @@ -0,0 +1,12 @@ +--- +title: First Meaningful Paint +slug: Словарь/first_meaningful_paint +translation_of: Glossary/first_meaningful_paint +--- +

Первое значимое отображение (англ. First Meaningful Paint, FMP) - метрика, которая показывает, за какое время контент на странице становится виден пользователю. Это метрика включает в себя время от начала загрузки страницы до момента, когда на сайте отобразился основной контент.

+ +

См. также:

+ + diff --git a/files/ru/glossary/first_paint/index.html b/files/ru/glossary/first_paint/index.html new file mode 100644 index 0000000000..fec7ec3741 --- /dev/null +++ b/files/ru/glossary/first_paint/index.html @@ -0,0 +1,14 @@ +--- +title: First paint +slug: Словарь/First_paint +translation_of: Glossary/First_paint +--- +

Первое отображение - время между переходом на страницу и моментом, когда браузер отображает первые пиксели на экране. Является частью Paint Timing API.

+ +

См. также

+ + diff --git a/files/ru/glossary/flex_item/index.html b/files/ru/glossary/flex_item/index.html new file mode 100644 index 0000000000..7253e9a025 --- /dev/null +++ b/files/ru/glossary/flex_item/index.html @@ -0,0 +1,34 @@ +--- +title: Флекс-элемент +slug: Словарь/Flex_Item +tags: + - CSS + - флекс-элемент + - флексбокс +translation_of: Glossary/Flex_Item +--- +

Непосредственые дочерние элементы {{glossary("флекс-контейнера")}} (элемент для которого установлено display: flex или display: inline-flex) становятся флекс-элементами.

+ +

Непрерывные фрагменты текста внутри флекс-контейнера также становятся флекс-элементами.

+ +

Изучать далее

+ +

Ссылки на свойства

+ +
+
    +
  • {{cssxref("align-self")}}
  • +
  • {{cssxref("flex-basis")}}
  • +
  • {{cssxref("flex-grow")}}
  • +
  • {{cssxref("flex-shrink")}}
  • +
  • {{cssxref("order")}}
  • +
+
+ +

Читать далее

+ + diff --git a/files/ru/glossary/flexbox/index.html b/files/ru/glossary/flexbox/index.html new file mode 100644 index 0000000000..918997b331 --- /dev/null +++ b/files/ru/glossary/flexbox/index.html @@ -0,0 +1,44 @@ +--- +title: Flexbox +slug: Словарь/Flexbox +translation_of: Glossary/Flexbox +--- +

Flexbox это общепринятый термин для CSS Flexible Box Layout Module, модели разметки для отображения элементов в одном измерении - в виде строки или столбца.

+ +

В данной спецификации, flexbox описывается как модель разметки для проектирования пользовательского интерфейса. Ключевая особенность flexbox заключается в том, что элементы во flex-разметке могут увеличиваться и уменьшаться. Пространство может использоваться самими элементами, или распределяться между или вокруг элементов.

+ +

Flexbox также позволяет выравнивать элементы по главной или поперечной оси, таким образом предоставляя высокоуровневый контроль над размером и выравниванием группы элементов.

+ +

Смотрите также

+ +

Связанные свойства

+ +
+
    +
  • {{cssxref("align-content")}}
  • +
  • {{cssxref("align-items")}}
  • +
  • {{cssxref("align-self")}}
  • +
  • {{cssxref("flex")}}
  • +
  • {{cssxref("flex-basis")}}
  • +
  • {{cssxref("flex-direction")}}
  • +
  • {{cssxref("flex-flow")}}
  • +
  • {{cssxref("flex-grow")}}
  • +
  • {{cssxref("flex-shrink")}}
  • +
  • {{cssxref("flex-wrap")}}
  • +
  • {{cssxref("justify-content")}}
  • +
  • {{cssxref("order")}}
  • +
+
+ +

Дальнейшее чтение

+ + diff --git a/files/ru/glossary/forbidden_header_name/index.html b/files/ru/glossary/forbidden_header_name/index.html new file mode 100644 index 0000000000..059b6898c6 --- /dev/null +++ b/files/ru/glossary/forbidden_header_name/index.html @@ -0,0 +1,44 @@ +--- +title: Запрещенное имя заголовка +slug: Словарь/Forbidden_header_name +tags: + - HTTP + - Заголовки + - Словарь + - запрещенный +translation_of: Glossary/Forbidden_header_name +--- +

Запрещённое имя заголовка (Forbidden header name) это имя какого-либо HTTP заголовка, который нельзя изменить программно. 

+ +

Изменение этих заголовков запрещено, потому что пользовательский агент (браузер) удерживает полный контроль над ними. Заголовки, чьи имена начинаются с `Sec-`, зарезервированы для создания новых заголовков, безопасных (отделённых) от {{glossary("API","APIs")}}, используемого Fetch, которое даёт разработчику контроль над заголовками. Утверждение также верно и для {{domxref("XMLHttpRequest")}}.

+ +

Запрещенные имена заголовков начинаются с Proxy- или Sec-, или содержат следующие имена:

+ + + +
+

Заметка: Загловок User-Agent более не запрещён, как указано в спецификации — посмотрите список запрещённых заголовков (он был реализован в Firefox 43,) так что User-Agent может быть установлен через в объект Headers под Fetch через вызов метода setRequestHeader().

+
diff --git a/files/ru/glossary/forbidden_response_header_name/index.html b/files/ru/glossary/forbidden_response_header_name/index.html new file mode 100644 index 0000000000..a53aa15026 --- /dev/null +++ b/files/ru/glossary/forbidden_response_header_name/index.html @@ -0,0 +1,25 @@ +--- +title: Запрещённое имя заголовка ответа +slug: Словарь/Запрещённое_имя_заголовка_ответа +translation_of: Glossary/Forbidden_response_header_name +--- +

Запрещённое имя заголовка ответа это имя HTTP заголовка (`Set-Cookie` или `Set-Cookie2`), который не может быть изменён программно.

+ +

Specifications

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Fetch','#forbidden-response-header-name','forbidden-response-header-name')}}{{Spec2('Fetch')}} 
diff --git a/files/ru/glossary/fps/index.html b/files/ru/glossary/fps/index.html new file mode 100644 index 0000000000..dbb479d226 --- /dev/null +++ b/files/ru/glossary/fps/index.html @@ -0,0 +1,20 @@ +--- +title: Частота кадров (FPS) +slug: Словарь/FPS +translation_of: Glossary/FPS +--- +

Частота кадров - это скорость, с которой браузер может пересчитывать, размещать и отображать содержимое на дисплее. FPS (англ. frames per second) - количество сменяемых кадров за одну секунду.

+ +

Целевая частота кадров для компьютерной графики на веб-сайте составляет 60 кадров в секунду.

+ +

Общемировой стандарт частоты киносъёмки и проекции звукового кинематографа - 24 кадра в секунду. Для замедления или ускорения движения на экране существует ускоренная и замедленная или покадровая съёмки. 

+ +

Узнать больше

+ +

Общее представление

+ + + + diff --git a/files/ru/glossary/ftp/index.html b/files/ru/glossary/ftp/index.html new file mode 100644 index 0000000000..a14c6cacd7 --- /dev/null +++ b/files/ru/glossary/ftp/index.html @@ -0,0 +1,22 @@ +--- +title: FTP +slug: Словарь/FTP +tags: + - CodingScripting + - FTP + - Glossary + - протокол +translation_of: Glossary/FTP +--- +

FTP (англ. file transfer protocol — протокол передачи файлов) — стандартный сетевой {{glossary("protocol", "протокол")}} для передачи файлов с одного {{glossary("host", "хост")}}а на другой через Интернет по протоколу {{Glossary("TCP")}}.

+ +

Узнать больше

+ +

Общие сведения

+ + + +

 

diff --git a/files/ru/glossary/function/index.html b/files/ru/glossary/function/index.html new file mode 100644 index 0000000000..4e2698b38c --- /dev/null +++ b/files/ru/glossary/function/index.html @@ -0,0 +1,77 @@ +--- +title: Функция +slug: Словарь/Функция +tags: + - JavaScript + - Глоссарий + - КодингСкриптинг + - Функция +translation_of: Glossary/Function +--- +

Функция это отрывок кода который может быть вызван из другого кода или вызван собой, или это {{Glossary("variable")}} которая ссылается на функцию. Когда функция вызвана, {{Glossary("Argument", "аргументы")}} переданы в функцию как вход, и функция может необязательно вернуть вывод. Функция в {{glossary("JavaScript")}} это {{glossary("object")}}.

+ +

Имя функции это {{Glossary("identifier")}} объявлённый как часть объявления функции или выражения функции. Имя функции {{Glossary("scope")}} зависит от того является ли имя функции объявлением или выражением.

+ +

Различные типы функций

+ +

Анонимная функция это функция без имени:

+ +
function () {}
+ +

Именованная функция это функция с именем:

+ +
function foo() {}
+ +

Внутренняя функция это функция внутри другой функции  (square в данном случае). Внешняя функция это функция содержащая функцию (addSquares в данном случае):

+ +
+
+ +
function addSquares(a,b) {
+   function square(x) {
+      return x * x;
+   }
+   return square(a) + square(b);
+}
+ +

Рекурсивная функция это функция которая вызывает саму себя. См {{Glossary("Recursion", "recursion")}}.

+ +
function loop(x) {
+   if (x >= 10)
+      return;
+   loop(x + 1);
+}
+
+
+ +

Immediately Invoked Function Expressions (IIFE) это функция которая вызывается прямо после того как функция загружена в компилятор браузера. Способ объявления IIFE это путём размещения левых и правых круглых скобок в конце объявления функции.  В этом типе выражении функций много преимуществ, но это выходит за рамки курса. Если вы хотите узнать больше об IFFE, проверьте следующую страницу на Википедии.

+ +

https://en.wikipedia.org/wiki/Immediately-invoked_function_expression

+ +
Examples:
+
+​function foo(){
+ console.log('Здравствуй Foo');
+}();
+
+
+(function foo() {
+​ console.log('Здравствуй Foo');
+}());
+
+
+(function food(){
+    console.log('Здравствуй Foo');
+})();
+ +

 

+ +

 

+ +

Узнайте больше

+ +

Технический справочник

+ + diff --git a/files/ru/glossary/gecko/index.html b/files/ru/glossary/gecko/index.html new file mode 100644 index 0000000000..cba601e9b9 --- /dev/null +++ b/files/ru/glossary/gecko/index.html @@ -0,0 +1,31 @@ +--- +title: Gecko +slug: Словарь/Gecko +tags: + - Gecko + - Glossary + - Глоссарий +translation_of: Glossary/Gecko +--- +

Gecko - это движок обработки и рендеринга макетов веб-страниц, разработанный в рамках Mozilla Project и используемый многими приложениями и устройствами, включая {{glossary("Mozilla Firefox","Firefox")}} и {{glossary("Firefox OS")}}.

+ +

Веб-{{glossary("browser","браузеры")}} нуждаются в программах, называемых "движками рендеринга" для того, чтобы обрабатывать {{glossary("HTML")}}, {{glossary("CSS")}}, {{glossary("JavaScript")}} и другой встроенный контент (например, картинки) и всё это отрисовать на экране вашего монитора. Кроме того, Gecko создаёт четко-связанные программные {{glossary("API","API")}}, хорошо работающие в любой операционной системе (которая поддерживается Gecko), и это API разработано только для поддержки связанных с основными задачами целей. Это означает, что Gecko включает: сетевой стек, графический стек, рендеринг страниц, виртуальная машина JavaScript и другое.

+ +

Поскольку все приложения Firefox OS это веб-приложения, то Firefox OS использует Gecko как среду выполнения приложений.

+ +

Узнать больше

+ +

Общие знания

+ + + +

Технический справочник

+ + + +


+  

diff --git a/files/ru/glossary/general_header/index.html b/files/ru/glossary/general_header/index.html new file mode 100644 index 0000000000..3d2f5cb65c --- /dev/null +++ b/files/ru/glossary/general_header/index.html @@ -0,0 +1,8 @@ +--- +title: Общий заголовок +slug: Словарь/General_header +translation_of: Glossary/General_header +--- +

Общий заголовок (основной заголовок) - это {{glossary('HTTP header', 'заголовок')}}, который используется и в запросе, и в ответе (в отличие от {{glossary("Response header", "заголовка запроса")}} и {{glossary("request header", "заголовка ответа")}}), однако общий заголовок не описывает тело сообщения, как {{glossary("entity header", "заголовок сущности")}}.

+ +

Наиболее часто встречающиеся общие заголовки: {{HTTPHeader('Date')}}, {{HTTPheader("Cache-Control")}} или {{HTTPHeader("Connection")}}.

diff --git a/files/ru/glossary/git/index.html b/files/ru/glossary/git/index.html new file mode 100644 index 0000000000..0e1bda3846 --- /dev/null +++ b/files/ru/glossary/git/index.html @@ -0,0 +1,18 @@ +--- +title: Git +slug: Словарь/Git +tags: + - Словарь + - Совместная работа +translation_of: Glossary/Git +--- +

Git — это свободная с открытым исходным кодом распределённая система управления версиями (от англ. Source Code Management ({{Glossary("SCM", "SCM", 1)}}). Она облегчает написание кода с использованием распределенных команд разработчиков. Ее отличие от предшествующих систем управления версиями — способность выполнять общие операции (ветвление, фиксакция изменений, и т.д.) на вашем локальном компьютере, без необходимости изменять главный репозиторий или даже не имея прав на запись в него.

+ +

Узнать больше

+ +

Общие знания

+ + diff --git a/files/ru/glossary/global_object/index.html b/files/ru/glossary/global_object/index.html new file mode 100644 index 0000000000..402ba23ea0 --- /dev/null +++ b/files/ru/glossary/global_object/index.html @@ -0,0 +1,66 @@ +--- +title: Global object +slug: Словарь/Global_object +translation_of: Glossary/Global_object +--- +

Глобальный обьект - это {{glossary("object")}}, который всегда существует в {{glossary("global scope")}}.

+ +

В JavaScript всегда определён глобальный обьект. В веб-браузере, когда скрипты создают глобальные переменные, они создаются как свойства глобального обьекта. (В {{Glossary("Node.js")}} это не так.) {{Glossary("Interface")}} глобального обьекта зависит от контекста, в котором выполняется скрипт.К примеру:

+ + + +

Обьект window в Браузере

+ +

Обьект window - Глобальный Обьект в браузере. Доступ к любым Глобальным Переменным или функциям может быть получен как к свойствам обьекта window.

+ +

Получение доступа к Глобальным Переменным

+ +
var foo = "foobar";
+foo === window.foo; // Возвращает: true
+
+ +

После определения Глобальной Переменной foo, мы можем получить доступ к его значению прямо с обьекта window, использую имя переменной foo в качестве имени свойства Глобального Обьекта window.foo.

+ +

Обьяснение:

+ +

Глобальная Переменная foo была сохранена в обьекте window, подобно следующему примеру:

+ +
foo: "foobar"
+ +

Получение доступа к Глобальным Функциям

+ +
function greeting() {
+   console.log("Hi!");
+}
+
+window.greeting(); // Тоже самое что и обычный вызов: greeting();
+
+ +

Пример выше показывает как Глобальные Функции хранятся в качестве свойств обьекта window. Мы создали Глобальную Функцию greeting и вызвали её с помощью обьекта window.

+ +

Обьяснение:

+ +

Глобальная функция greeting была сохранена в обьекте window, подобно следующему примеру:

+ +
greeting: function greeting() {
+   console.log("Hi!");
+}
+ + diff --git a/files/ru/glossary/global_variable/index.html b/files/ru/glossary/global_variable/index.html new file mode 100644 index 0000000000..a9e4a36a5b --- /dev/null +++ b/files/ru/glossary/global_variable/index.html @@ -0,0 +1,18 @@ +--- +title: Глобальная переменная +slug: Словарь/global_variable +tags: + - Словарь +translation_of: Glossary/Global_variable +--- +

Глобальная перменная это переменная, которая была объявлена в глобальной области видимости. Иначе говоря, переменная, доступ к которой, можно получить со всех других областей видимости.

+ +

В JavaScript это свойство глобального объекта.

+ +

Материалы для обучения

+ +

Общие

+ + diff --git a/files/ru/glossary/grid/index.html b/files/ru/glossary/grid/index.html new file mode 100644 index 0000000000..2d00a835e1 --- /dev/null +++ b/files/ru/glossary/grid/index.html @@ -0,0 +1,75 @@ +--- +title: Grid +slug: Словарь/Grid +tags: + - CSS + - CSS Grids + - Glossary +translation_of: Glossary/Grid +--- +

CSS Гриды (они же сетки или CSS Grid) устанавливаются с помощью значения grid в свойстве display; вы можете определить колонки и строки в сетке с помощью свойств {{cssxref("grid-template-columns")}} и {{cssxref("grid-template-rows")}} соответственно.

+ +

Сетка, которую вы создаете, используя эти свойства, является явной сеткой.

+ +

If you place content outside of this explicit grid, or if you are relying on auto-placement and the grid algorithm needs to create additional row or column {{glossary("grid tracks", "tracks")}} to hold {{glossary("grid item", "grid items")}}, then extra tracks will be created in the implicit grid. The implicit grid is the grid created automatically due to content being added outside of the tracks defined.

+ +

В примере ниже отображена точная сетка из трех колонок и двух рядов. The third row on the grid is an implicit grid row track, formed due to their being more than the six items which fill the explicit tracks.

+ +
+ + +
.wrapper {
+  display: grid;
+  grid-template-columns: 1fr 1fr 1fr;
+  grid-template-rows: 100px 100px;
+}
+
+ +
<div class="wrapper">
+   <div>One</div>
+   <div>Two</div>
+   <div>Three</div>
+   <div>Four</div>
+   <div>Five</div>
+   <div>Six</div>
+   <div>Seven</div>
+   <div>Eight</div>
+</div>
+
+ +

{{ EmbedLiveSample('example', '500', '330') }}

+ +

Дополнительные материалы

+ +

Руководство по свойствам

+ +
    +
  • {{cssxref("grid-template-columns")}}
  • +
  • {{cssxref("grid-template-rows")}}
  • +
  • {{cssxref("grid")}}
  • +
  • {{cssxref("grid-template")}}
  • +
+ +

Что почитать еще

+ + +
diff --git a/files/ru/glossary/grid_column/index.html b/files/ru/glossary/grid_column/index.html new file mode 100644 index 0000000000..ca5ed8bd59 --- /dev/null +++ b/files/ru/glossary/grid_column/index.html @@ -0,0 +1,30 @@ +--- +title: Grid Column +slug: Словарь/Grid_Column +tags: + - CSS + - grid +translation_of: Glossary/Grid_Column +--- +

Столбец сетки (grid column) — это вертикальный элемент в CSS Grid Layout, а также пространство между двумя вертикальными линиями сетки. Он определяется свойством {{cssxref("grid-template-columns")}}, либо в сокращенном виде {{cssxref("grid")}} или {{cssxref("grid-template")}}.

+ +

Кроме того, столбцы могут быть созданы в неявном виде (implicit grid), когда элементы расположены за пределами столбцов, созданных в явно-заданной сетке (explicit grid). Размер этих столбцов будет подобран автомтически, либо задан с помощью свойства {{cssxref("grid-auto-columns")}}.

+ +

При работе с выравниванием в CSS Grid Layout, ось, идущая вниз, вдоль которой идут столбцы, также называется осью блоков или столбцов.

+ +

Смотрите также

+ +

Связанные свойства

+ + + +

Дальнейшая информация

+ + diff --git a/files/ru/glossary/hash/index.html b/files/ru/glossary/hash/index.html new file mode 100644 index 0000000000..9084e9ed64 --- /dev/null +++ b/files/ru/glossary/hash/index.html @@ -0,0 +1,14 @@ +--- +title: Хеш +slug: Словарь/хеш +translation_of: Glossary/hash +--- +

Хеш-функция получает на вход текстовое сообщение произвольной длины и выдает хеш фиксированной длины. Как правило, в форме 128-битного "отпечатка пальцев" или "дайджеста сообщения". Хеши очень полезны для {{glossary("криптографии")}} — они обеспечивают целостность передаваемых данных. Это служит основой для {{glossary("HMAC's")}}, которые обеспечивают идентификацию сообщений.

+ +

Дополнительно

+ +

Общие сведения

+ + diff --git a/files/ru/glossary/head/index.html b/files/ru/glossary/head/index.html new file mode 100644 index 0000000000..5fef76a367 --- /dev/null +++ b/files/ru/glossary/head/index.html @@ -0,0 +1,15 @@ +--- +title: Head (Заголовок) +slug: Словарь/Заголовок +translation_of: Glossary/Head +--- +

Head (заголовок) это часть {{glossary("HTML")}} документа, которая содержит {{glossary("metadata")}} о документе, такие как автор, описание, ссылки на {{glossary("CSS")}} или {{glossary("JavaScript")}} файлы, которые должны быть применены в HTML.

+ +

Смотрите также

+ +

HTML head

+ + diff --git a/files/ru/glossary/high-level_programming_language/index.html b/files/ru/glossary/high-level_programming_language/index.html new file mode 100644 index 0000000000..b6fa171131 --- /dev/null +++ b/files/ru/glossary/high-level_programming_language/index.html @@ -0,0 +1,10 @@ +--- +title: Высокоуровневый язык программирования +slug: Словарь/Высокоуровневый_язык_программированияprogramming_language +tags: + - Словарь +translation_of: Glossary/High-level_programming_language +--- +

Высокоуровневый язык программирования имеет существенную абстракцию от деталей работы компьютера. Он предназначен для простого понимания людьми и поэтому должен быть переведен другим программным обеспечением. В отличие от низкоуровневых языков программирования, он может использовать элементы естественного языка или может автоматизировать (или даже полностью скрыть) важные области вычислительных систем, делая процесс разработки более простым и более понятным по сравнению с языком более низкого уровня. Количество предоставляемой абстракции определяет, насколько "высокоуровневым является" язык программирования.

+ +

Идея языка, автоматически переводимого в машинный код, но ближе к человеческой логике, была внедрена в компьютерные науки в 1950-х годах, особенно благодаря работе Джона Бэкуса (IBM), который руководил командой разработавшей первый высокоуровневый язык программирования: Фортран. За это нововведение Бэкус был удостоен премии Тьюринга.

diff --git a/files/ru/glossary/hoisting/index.html b/files/ru/glossary/hoisting/index.html new file mode 100644 index 0000000000..ef0cdfb1be --- /dev/null +++ b/files/ru/glossary/hoisting/index.html @@ -0,0 +1,74 @@ +--- +title: Поднятие +slug: Словарь/Поднятие +translation_of: Glossary/Hoisting +--- +

Поднятие (hoisting) — термин, который вы не встретите в документации JavaScript. Поднятие задумывалось как общий способ мышления о том, как контекст исполнения (в частности, фазы создания и исполнения) работает в JavaScript. Однако, hoisting может привести и к недоразумениям. Например, hoisting учит, что объявление переменной или функции физически перемещается в начало вашего кода, хотя в действительности этого не происходит. На самом же деле, объявления переменных и функций попадают в память в процессе фазы компиляции, но остаются в коде на том месте, где вы их объявили.

+ +

Узнаем больше

+ +

Пример:

+ +

Одним из преимуществ помещения в память объявлений функций до выполнения кода то, что можно использовать функцию до ее объявления. Например:

+ +
function catName(name) {
+  console.log("Мою кошку зовут " + name);
+}
+
+catName("Тигр");
+/*
+Результатом будет вывод строки: "Мою кошку зовут Тигр"
+*/
+
+ +

Предыдущий пример демонстрирует ожидаемый рабочий код. Теперь давайте посмотрим, что происходит, когда мы вызываем функцию в коде до ее объявления:

+ +
catName("Раиса");
+
+function catName(name) {
+  console.log("Мою кошку зовут " + name);
+}
+/*
+Результатом будет вывод строки: "Мою кошку зовут Раиса"
+*/
+
+ +

Даже если мы вызываем функцию до ее объявления, код работает. Это происходит благодаря тому, как работает контекст выполнения в JavaScript.

+ +

 

+ +

Hoisting хорошо работает и с другими типами данных и переменными. Переменные могут быть инициализированы и использованы до их объявления. Однако, они не могут быть использованы без инициализации.

+ +

Пример:
+  

+ +
num = 6;
+num + 7;
+var num;
+/* не генерирует ошибку, так как num объявлен */
+
+
+ +

JavaScript "поднимает" только объявление, но не инициализацию. Если вы используете переменную, объявленную и проинициализированную после ее использования, то значение будет undefined. Два примера ниже демонстрируют это поведение.
+  

+ +
var x = 1; // Инициализируем x
+console.log(x + " " + y);  // '1 undefined'
+var y = 2;
+//код выше и код ниже одинаковые
+
+var x = 1; // Инициализируем x
+var y; // Объявляем y
+console.log(x + " " + y);  // '1 undefined'
+y = 2; // Инициализируем y
+
+ +

 

+ +

Technical reference

+ + diff --git a/files/ru/glossary/host/index.html b/files/ru/glossary/host/index.html new file mode 100644 index 0000000000..667e65ab28 --- /dev/null +++ b/files/ru/glossary/host/index.html @@ -0,0 +1,20 @@ +--- +title: Host +slug: Словарь/Host +tags: + - Glossary + - Intermediate + - Web + - WebMechanics + - Словарь +translation_of: Glossary/Host +--- +

Хост - это устройство, подключенное к {{glossary("Internet", "Интернет")}} (или локальной сети). Некоторые хосты, называемые {{glossary("server", "сервер", "серверами")}}, предлагают дополнительные услуги, такие как обслуживание веб-страниц или хранение файлов и электронных писем.

+ +

Подробнее

+ +

Базовые знания

+ + diff --git a/files/ru/glossary/html/index.html b/files/ru/glossary/html/index.html new file mode 100644 index 0000000000..560c7101c3 --- /dev/null +++ b/files/ru/glossary/html/index.html @@ -0,0 +1,47 @@ +--- +title: HTML +slug: Словарь/HTML +tags: + - Glossary + - HTML +translation_of: Glossary/HTML +--- +

HTML (от англ. HyperText Markup Language — «язык гипертекстовой разметки») — язык разметки, определяющий структуру веб-страниц.

+ +

Краткая история

+ +

В 1990 году, как часть видения о {{glossary("World Wide Web","Вебе")}}, Тим Бернс-Ли определил понятие {{glossary("Hypertext","гипертекста")}}, которое он оформил с помощью разметки, главным образом основанной на приложении SGML. Группа {{glossary("IETF")}} начала формировать спецификацию HTML в 1993, и после нескольких набросков выпустила версию 2.0 в 1995. В 1994 Бернс-Ли основал {{glossary("W3C")}} для развития Веба. В 1996, W3C взяло на себя работу над HTML и опубликовало "HTML 3.2 Recommendation" годом позже. HTML 4.0 был выпущен в 1999 и стал стандартом {{glossary("ISO")}} в 2000.

+ +

В настоящее время, W3C почти забросили работу над HTML в пользу {{glossary("XHTML")}}, что побудило в 2004 году основание независимой группы, названной {{glossary("WHATWG")}}. Благодаря WHATWG, работа над {{glossary("HTML5")}} продолжилась: две организации выпустили первый черновик в 2008 и финальный стандарт в 2014.

+ +

Концепция и синтаксис

+ +

Документ HTML - это простой текст, поделенный на {{glossary("element","элементы")}}. Элементы окружены одинаковыми открывающимися и закрывающимися {{glossary("Tag","тегами")}}. Каждый тег начинается и заканчивается с угловых скобок (<>). Также есть теги, которые созданы не для добавления текста, например {{htmlelement("img")}}.

+ +

Вы можете дополнить HTML теги с помощью {{Glossary("attribute","атрибутов")}}, которые дают дополнительную информацию и затрагивают то, как браузер интерпретирует элемент:

+ +

Detail of the structure of an HTML element

+ +

HTML принято сохранять с расширением .htm или .html, которые обслуживаются {{Glossary("Server","сервером")}}, и могут воспроизводиться любым {{Glossary("Browser","браузером")}}.

+ +

Узнайте больше

+ +

Общие сведения

+ + + +

Изучаем HTML

+ + + +

Техническая справка

+ + diff --git a/files/ru/glossary/html5/index.html b/files/ru/glossary/html5/index.html new file mode 100644 index 0000000000..b081f5c053 --- /dev/null +++ b/files/ru/glossary/html5/index.html @@ -0,0 +1,19 @@ +--- +title: HTML5 +slug: Словарь/HTML5 +tags: + - CodingScripting + - HTML + - HTML5 + - Глоссарий + - Разметка + - Словарь +translation_of: Glossary/HTML5 +--- +

Последний стабильный релиз {{Glossary("HTML")}}, HTML5 преобразовывает HTML из простого языка для разметки документа в платформу для разработки полноценных приложений. Среди других особенностей, HTML5 включает в себя новые элементы и {{glossary("JavaScript")}} {{glossary("API")}} для улучшения доступа к хранилищу, мультимедиа и аппаратным средствам.

+ +

Узнайте больше

+ + diff --git a/files/ru/glossary/http/index.html b/files/ru/glossary/http/index.html new file mode 100644 index 0000000000..2d9b3f539b --- /dev/null +++ b/files/ru/glossary/http/index.html @@ -0,0 +1,25 @@ +--- +title: HTTP +slug: Словарь/HTTP +tags: + - HTTP + - Глоссарий + - Начинающий + - инфраструктура + - протокол передачи гипертекста +translation_of: Glossary/HTTP +--- +

Протокол передачи гипертекста (HTTP) является базовым сетевым {{glossary("protocol")}}, который позволяет передавать гипермедиа документы в {{glossary("World Wide Web","Web")}}, обычно между браузером и сервером, таким образом, что бы люди могли их читать. Текущая версия спецификации HTTP называется HTTP/2.
+
+ Как часть URI, «http://» называется «
schema» и обычно стоит в начале адреса, например, в «https://developer.mozilla.org», чтобы указать браузеру запросить документ с использованием протокола HTTP. Https в этом случае относится к защищенной версии протокола HTTP, {{glossary("SSL")}} (также называемый TLS).
+
+ HTTP является текстовым (все сообщения осуществляются в виде простого текста), без запоминания состояния (нет информации о предыдущих сообщениях). Это свойство делает его идеальным для чтения людьми документов (веб-сайтов) во всемирной паутине. Однако HTTP также можно использовать в качестве основы веб-сервисов REST для передачи сообщений от сервера к серверу или запросов AJAX на веб-сайтах, чтобы сделать их более динамичными.

+ +
+

Изучите больше

+ +
    +
  • HTTP на сайте MDN
  • +
  • {{interwiki("wikipedia", "Hypertext Transfer Protocol", "HTTP")}} на Википедии
  • +
+
diff --git a/files/ru/glossary/http_2/index.html b/files/ru/glossary/http_2/index.html new file mode 100644 index 0000000000..3423133e8d --- /dev/null +++ b/files/ru/glossary/http_2/index.html @@ -0,0 +1,31 @@ +--- +title: HTTP/2 +slug: Словарь/HTTP_2 +tags: + - Glossary + - HTTP + - Infrstructure + - Reference + - Web Performance +translation_of: Glossary/HTTP_2 +--- +

HTTP/2 это старшая версия сетевого протокола HTTP. Основным назначеним HTTP/2 является снижение задержки({{glossary("latency")}})  путём реализации полного мультиплексирования запросов и ответов, уменьшения перегруженности протокола при помощи эффективного сжатия заголовков HTTP, а также добавления поддержки приоритетов запроса и "server push"("серверне проталкивание" - сервер имея правила, может проявить инициативу, которые инициируют отправку контента до его запроса, зная о том, что может поступить запрос на их отправку).

+ +

HTTP/2 никоим образом не изменяет семантику применяемую HTTP. Все основные концепции HTTP 1.1, такие как методы HTTP, коды статусов, URI, и поля заголовков останутся прежними. Вместо этого HTTP/2 изменит порядок(форму) данных и способ их передачи между клиентом и сервером, которые управляют всем процессом, и скроет сложность применения в новом обрамляющем слое. Это позволит использовать существующие приложения без изменений.

+ + diff --git a/files/ru/glossary/https/index.html b/files/ru/glossary/https/index.html new file mode 100644 index 0000000000..21c860794a --- /dev/null +++ b/files/ru/glossary/https/index.html @@ -0,0 +1,17 @@ +--- +title: HTTPS +slug: Словарь/https +tags: + - HTTPS + - Безопасность +translation_of: Glossary/https +--- +

HTTPS (HTTP Secure) является зашифрованной версией {{Glossary("HTTP")}} протокола. Обычно он использует {{Glossary("SSL")}} или {{Glossary("TLS")}} для шифрования соединения между клиентом и сервером. Это безопасное соединение позволяет клиентам безопасно обмениваться конфиденциальными данными с сервером, например, для банковских операций или онлайн-покупок.

+ +

Узнать больше

+ +

Общая информация

+ + diff --git a/files/ru/glossary/hypertext/index.html b/files/ru/glossary/hypertext/index.html new file mode 100644 index 0000000000..75e77edbf5 --- /dev/null +++ b/files/ru/glossary/hypertext/index.html @@ -0,0 +1,27 @@ +--- +title: Гипертекст +slug: Словарь/Гипертекст +tags: + - Веб + - Глоссарий + - Механика Веба + - гипертекст +translation_of: Glossary/Hypertext +--- +

Гипертекст - это текст, содержащий ссылки на другие тексты.

+ +

Термин был придуман Теодором Нельсоном в 1965 году.

+ +

Изучите больше

+ +

Общие знания

+ + + +

Техническое руководство

+ + diff --git a/files/ru/glossary/iana/index.html b/files/ru/glossary/iana/index.html new file mode 100644 index 0000000000..3e2b4fc33e --- /dev/null +++ b/files/ru/glossary/iana/index.html @@ -0,0 +1,13 @@ +--- +title: IANA +slug: Словарь/IANA +translation_of: Glossary/IANA +--- +

IANA (Internet Assigned Numbers Authority) является дочерней компанией {{glossary("ICANN")}}, задача которой записывать и/или назначать {{glossary("domain name","domain names")}}, {{glossary("IP address","IP addresses")}}, и другие имена и номера, используемые Интернетом {{glossary("protocol","protocols")}}.

+ +

Смотрите также:

+ + diff --git a/files/ru/glossary/icann/index.html b/files/ru/glossary/icann/index.html new file mode 100644 index 0000000000..e67e2d4b6f --- /dev/null +++ b/files/ru/glossary/icann/index.html @@ -0,0 +1,13 @@ +--- +title: ICANN +slug: Словарь/ICANN +translation_of: Glossary/ICANN +--- +

ICANN (Internet Corporation of Assigned Names and Numbers) является международной некоммерческой организацией, которая поддерживает {{glossary("DNS","domain name system")}} и запись {{glossary("IP address","IP addresses")}}.

+ +

Смотрите также:

+ + diff --git a/files/ru/glossary/idempotent/index.html b/files/ru/glossary/idempotent/index.html new file mode 100644 index 0000000000..569dbc0168 --- /dev/null +++ b/files/ru/glossary/idempotent/index.html @@ -0,0 +1,49 @@ +--- +title: Идемпотентный метод +slug: Словарь/Idempotent +tags: + - Glossary + - HTTP +translation_of: Glossary/Idempotent +--- +

Метод HTTP является идемпотентным, если повторный идентичный запрос, сделанный один или несколько раз подряд, имеет один и тот же эффект, не изменяющий состояние сервера. Другими словами, идемпотентный метод не должен иметь никаких побочных эффектов (side-effects), кроме сбора статистики или подобных операций. Корректно реализованные методы {{HTTPMethod("GET")}}, {{HTTPMethod("HEAD")}}, {{HTTPMethod("PUT")}} и {{HTTPMethod("DELETE")}} идемпотентны, но не метод {{HTTPMethod("POST")}}. Также все {{glossary("safe", "безопасные")}} методы являются идемпотентными.

+ +

Для идемпотентности нужно рассматривать только изменение фактического внутреннего состояния сервера, а возвращаемые запросами коды статуса могут отличаться: первый вызов {{HTTPMethod("DELETE")}} вернёт код {{HTTPStatus("200")}}, в то время как последующие вызовы вернут код {{HTTPStatus("404")}}. Из идемпотентности {{HTTPMethod("DELETE")}} неявно следует, что разработчики не должны использовать метод {{HTTPMethod("DELETE")}} при реализации RESTful API с функциональностью удалить последнюю запись.

+ +

Обратите внимание, что идемпотентность метода не гарантируется сервером, и некоторые приложения могут нарушать ограничение идемпотентности.

+ +

GET /pageX HTTP/1.1 идемпотентен. Вызвавший несколько раз подряд этот запрос, клиент получит тот же результат:

+ +
GET /pageX HTTP/1.1
+GET /pageX HTTP/1.1
+GET /pageX HTTP/1.1
+GET /pageX HTTP/1.1
+
+ +

POST /add_row HTTP/1.1 не идемпотентен; если его вызвать несколько раз, то он добавит несколько строк:

+ +
POST /add_row HTTP/1.1
+POST /add_row HTTP/1.1   -> Adds a 2nd row
+POST /add_row HTTP/1.1   -> Adds a 3rd row
+
+ +

DELETE /idX/delete HTTP/1.1 идемпотентен, даже если возвращаемый код отличается:

+ +
DELETE /idX/delete HTTP/1.1   -> Returns 200 if idX exists
+DELETE /idX/delete HTTP/1.1   -> Returns 404 as it just got deleted
+DELETE /idX/delete HTTP/1.1   -> Returns 404
+ +

Материалы для изучения

+ +

Общие

+ + + +

Технические

+ + diff --git a/files/ru/glossary/identifier/index.html b/files/ru/glossary/identifier/index.html new file mode 100644 index 0000000000..ea244035d4 --- /dev/null +++ b/files/ru/glossary/identifier/index.html @@ -0,0 +1,19 @@ +--- +title: Идентификатор +slug: Словарь/Identifier +tags: + - Глоссарий + - начальный уровень +translation_of: Glossary/Identifier +--- +

Последовательность символов в коде, которые определяют {{glossary("variable")}}, {{glossary("function")}} или {{glossary("property")}}.

+ +

В {{glossary("JavaScript")}}, идентификаторы могут содержать только буквы, цифры (а также «$» или «_»), и не могут начинаться с цифры. Идентификатор отличается от строки (string) в том, что строка — это данные, в то время как идентификатор является частью кода. В JavaScript нет способа сконтвертировать идентификаторы в строки, но иногда можно преобразовать (парсить) строки в идентификаторы.

+ +

Узнайте больше

+ +

Общие знания

+ + diff --git a/files/ru/glossary/ietf/index.html b/files/ru/glossary/ietf/index.html new file mode 100644 index 0000000000..538f7a6df0 --- /dev/null +++ b/files/ru/glossary/ietf/index.html @@ -0,0 +1,21 @@ +--- +title: IETF +slug: Словарь/IETF +tags: + - IETF + - Глоссарий + - Интернет + - Словарь + - инфраструктура +translation_of: Glossary/IETF +--- +

Инженерный совет Интернета (IETF) это всемирная организация, которая разрабатывает спецификации регулирующие механизмы, лежащие в основе {{glossary("Internet", "интернета")}}, особенно {{glossary("TCP")}}/{{glossary("IPv6","IP")}} илипакет {{glossary("Protocol","протоколов")}} интернета. IETF это открытое сообщество, управляется добровольцами и спонсируется интернет-сообществом.

+ +

Узнать больше

+ +

Основные сведения

+ + diff --git a/files/ru/glossary/iife/index.html b/files/ru/glossary/iife/index.html new file mode 100644 index 0000000000..7c764f6f71 --- /dev/null +++ b/files/ru/glossary/iife/index.html @@ -0,0 +1,61 @@ +--- +title: IIFE +slug: Словарь/IIFE +tags: + - IIFE + - JavaScript + - Глоссарий + - КодингСкриптинг +translation_of: Glossary/IIFE +--- +

IIFE (Immediately Invoked Function Expression) это {{glossary("JavaScript")}} {{glossary("функция")}}, которая выполняется сразу же после того, как она была определена.

+ + + +
(function () {
+    statements
+})();
+ +

Это тип выражений, также известный как {{glossary("Self-Executing Anonymous Function")}}, который состоит из двух основных частей. Первая - это сама анонимная функция с лексическим скоупом, заключеннным внутри {{jsxref("Operators/Grouping", "Оператора группировки")}} (). Благодаря этому переменные IIFE замыкаются в его пределах, и глобальная область видимости ими не засоряется.

+ +

Вторая часть создает мгновенно выполняющееся функциональное выражение  () , благодаря которому JavaScript-движок выполняет функцию напрямую.

+ + + +

Примеры

+ +

Функция становится мгновенно выполняющимся функциональным выражением. Переменные внутри функции не могут быть использованы за пределами ее области видимости.

+ +
(function () {
+    var aName = "Barry";
+})();
+// Variable name is not accessible from the outside scope
+aName // throws "Uncaught ReferenceError: aName is not defined"
+ +

Переменная, которой присвоено IIFE, хранит в себе результат выполнения функции, но не саму функцию.

+ +
var result = (function () {
+    var name = "Barry";
+    return name;
+})();
+// Immediately creates the output:
+result; // "Barry"
+ + + + + +

Узнать больше

+ +

Материалы

+ + + +

Основные понятия

+ + diff --git a/files/ru/glossary/index.html b/files/ru/glossary/index.html new file mode 100644 index 0000000000..758dfb9000 --- /dev/null +++ b/files/ru/glossary/index.html @@ -0,0 +1,24 @@ +--- +title: Словарь +slug: Словарь +tags: + - Глоссарий + - Новичку + - Словарь +translation_of: Glossary +--- +
{{LearnBox({"title":"Узнайте новый термин:"})}}
+ +

Веб-технологии содержат длинные списки жаргона и аббревиатур которые используются в документации и программировании. Этот словарь представляет собой определения слов и аббревиатур, которые понадобятся вам для успешного понимания и созданы для Веб.

+ +

{{GlossaryList({"split":"h3", "css":"multiColumnList"})}}

+ +

Внести вклад в словарь

+ +

Этот словарь никогда не заканчивает работу. Вы можете помочь улучшить его написав новые записи или сделав описание уже существующих лучше. Самый простой способ начать это нажать следующую кнопку или снизу выбрать одно из предложенных условий.

+ +

Добавить новую статью в словарь

+ +

{{GlossaryList({"terms":[], "filter":"notdefined", "css":"multiColumnList"})}}

+ +

Если вы хотите узнать больше о том, как внести вклад в словарь, посмотрите статус документации словаря.

diff --git a/files/ru/glossary/indexeddb/index.html b/files/ru/glossary/indexeddb/index.html new file mode 100644 index 0000000000..e4aee4fc0a --- /dev/null +++ b/files/ru/glossary/indexeddb/index.html @@ -0,0 +1,19 @@ +--- +title: IndexedDB +slug: Словарь/IndexedDB +tags: + - API + - CodingScripting + - Database + - Glossary + - Sql +translation_of: Glossary/IndexedDB +--- +

IndexedDB это Web {{glossary("API")}} интерфейс, который позволяет хранить большие данные внутри браузера. Также используется индексирование для поддержания высоко-производительного поиска по данным. Подобно {{glossary("SQL")}}-основанным RDBMS, IndexedDB это транзакционная система базы данных. Но в отличие от RDBMS, которая для хранения использует таблицы с фиксированными колонками, IndexedDB использует {{glossary("JavaScript")}} объекты.

+ +

Смотрите также

+ + diff --git a/files/ru/glossary/information_architecture/index.html b/files/ru/glossary/information_architecture/index.html new file mode 100644 index 0000000000..884c1a85e4 --- /dev/null +++ b/files/ru/glossary/information_architecture/index.html @@ -0,0 +1,14 @@ +--- +title: Архитектура данных +slug: Словарь/Information_architecture +translation_of: Glossary/Information_architecture +--- +

Архитектура данных, относящаяся к веб-дизайну и веб-разработке,является методом организации данных / контента / функционала веб-сайта,со всеми данными и сервисами,доступ и непосредственное использование которых не представляет трудностей,и таким образом дающим пользователю максимальное удобство в использовании данного веб-ресурса.

+ +

Дополнительная информация

+ +

Общие сведения

+ + diff --git a/files/ru/glossary/internet/index.html b/files/ru/glossary/internet/index.html new file mode 100644 index 0000000000..950220263c --- /dev/null +++ b/files/ru/glossary/internet/index.html @@ -0,0 +1,31 @@ +--- +title: Интернет +slug: Словарь/Internet +tags: + - Beginner + - Glossary + - Guide + - Intro + - NeedsContent + - Tutorial + - Web + - WebMechanics + - Введение + - Веб + - Глоссарий + - Начинающий + - Руководство + - Словарь + - Учебник + - туториал +translation_of: Glossary/Internet +--- +

Интернет — это всемирная сеть сетей, в которой используется набор интернет-протоколов (называемый также {{glossary("TCP")}}/{{glossary("IPv6","IP")}} по двум наиболее важным {{glossary("protocol","протоколам")}}).

+ +

Подробнее

+ +

Читать об этом

+ + diff --git a/files/ru/glossary/ip_address/index.html b/files/ru/glossary/ip_address/index.html new file mode 100644 index 0000000000..b3752b53a2 --- /dev/null +++ b/files/ru/glossary/ip_address/index.html @@ -0,0 +1,22 @@ +--- +title: IP Address +slug: Словарь/IP_Address +tags: + - Основы + - Словарь + - инфраструктура + - сеть + - терминология +translation_of: Glossary/IP_Address +--- +

IP адрес - это число, назначенное каждому устройству, подключённому к сети, которая использует Интернет-протокол. 

+ +

Термин "IP адрес" обычно означает 32-разрядные IPv4 адреса, но до тех пор, пока IPv6 не получит более широкое применение.

+ +

Learn more

+ +

General knowledge

+ + diff --git a/files/ru/glossary/iso/index.html b/files/ru/glossary/iso/index.html new file mode 100644 index 0000000000..98d2226829 --- /dev/null +++ b/files/ru/glossary/iso/index.html @@ -0,0 +1,19 @@ +--- +title: ISO +slug: Словарь/ISO +tags: + - ISO + - Глоссарий + - Стандарты веб + - инфраструктура +translation_of: Glossary/ISO +--- +

ISO (Международная организация по стандартизации) - это глобальная ассоциация, которая разрабатывает единые критерии, координирующие деятельность компаний в каждой крупной отрасли.

+ +

Узнать больше

+ +

Основные сведения

+ + diff --git a/files/ru/glossary/isp/index.html b/files/ru/glossary/isp/index.html new file mode 100644 index 0000000000..11d9b86957 --- /dev/null +++ b/files/ru/glossary/isp/index.html @@ -0,0 +1,20 @@ +--- +title: Интернет-провайдер +slug: Словарь/Интернет-провайдер +tags: + - ISP + - Веб + - Интернет-провайдер + - Словарь +translation_of: Glossary/ISP +--- +

ISP (Интернет-провайдер) продает доступ к интернету, а иногда и электронную почту, веб-хостинг и VoIP, либо путем установления соединения по телефонной линии (которая раньше была распространена), либо через широкополосное соединение, такое как кабельный модем или DSL-сервис. 

+ +

Узнайте больше

+ +

Общие знания

+ + diff --git a/files/ru/glossary/java/index.html b/files/ru/glossary/java/index.html new file mode 100644 index 0000000000..6aa04149f8 --- /dev/null +++ b/files/ru/glossary/java/index.html @@ -0,0 +1,22 @@ +--- +title: Java +slug: Словарь/Java +tags: + - Java + - Глоссарий + - Язык программирования +translation_of: Glossary/Java +--- +

Java — {{glossary("Compile", "компилируемый")}}, {{glossary("OOP", "объектно-ориентированный")}} и легко переносимый язык {{Glossary("computer programming", "программирования")}}.

+ +

Java {{glossary("Static typing", "статически типизирован")}} и имеет C-подобный синтаксис. Содержит большую библиотеку полезных функций — инструменты разработчика Java (Java Software Development Kit, SDK).

+ +

Программы {{glossary("Compile", "компилируются")}} единоразово до запуска в проприетарный байт-код определённого формата, который выполняется в виртуальной машине Java (Java Virtual Machine, JVM). JVM существует для множества платформ, что позволяет программам на Java запускаться почти везде без необходимости перекомпиляции или пересборки. Благодаря этому Java широко используется в приложениях предприятий с гетерогенной средой, при этом часто считается тяжеловесным решением.

+ +

Узнать больше

+ +

Общая информация

+ + diff --git a/files/ru/glossary/javascript/index.html b/files/ru/glossary/javascript/index.html new file mode 100644 index 0000000000..330e6ad88a --- /dev/null +++ b/files/ru/glossary/javascript/index.html @@ -0,0 +1,45 @@ +--- +title: JavaScript +slug: Словарь/JavaScript +tags: + - Glossary + - JavaScript + - Глоссарий +translation_of: Glossary/JavaScript +--- +

JavaScript (JS) это язык программирования, который в основном используется для создания динамических скриптов на веб-страницах, но он так же часто применяется на стороне {{Glossary("Server", "сервера")}}, используя пакеты, такие как Node.JS.

+ +

JavaScript не следует путать с {{interwiki("wikipedia", "Java", "Java")}}. «Java» и «JavaScript» являются товарными знаками или зарегистрированными товарными знаками Oracle в США и других странах. Тем не менее, два языка программирования существенно различаются по синтаксису, семантике и использованию.

+ +

Задуманный Бренданом Эйхом (тогда работал в Netscape Corporation) как серверный язык, Javascript вскоре появился в Netscape Navigator 2.0 в сентябре 1995 года. JavaScript сразу же добился успеха и {{glossary("Microsoft Internet Explorer", "Internet Explorer 3.0")}} представил поддержку JavaScript под названием JScript в августе 1996 года.

+ +

В ноябре 1996 года Netscape начала сотрудничать с ECMA International, чтобы сделать JavaScript отраслевым стандартом. С тех пор стандартизированный JavaScript называется ECMAScript и изложен в ECMA-262, чье последнее (девятое, ES2018) издание доступно с июня 2018 года.

+ +

JavaScript в основном используется в браузере, что позволяет разработчикам манипулировать содержимым веб-страницы с помощью {{Glossary("DOM")}}, данными с помощью {{Glossary("AJAX")}} и {{Glossary("IndexedDB")}}, рисовать графику с помощью {{Glossary("canvas")}}, взаимодействовать с устройством под управлением браузера через различные {{Glossary("API","APIs")}} и т.д. JavaScript является одним из наиболее часто используемых языков в мире благодаря недавнему росту и повышению производительности доступных в браузерах {{Glossary ("API", "APIs")}}.

+ +

В последнее время популярность JavaScript расширилась еще больше благодаря успешной платформе Node.js - самой популярной кроссплатформенной среде выполнения JavaScript вне браузера. Node.js позволяет разработчикам использовать JavaScript в качестве языка сценариев для автоматизации работы на ПК и создания полнофункциональных {{Glossary ("HTTP")}} и {{Glossary ("WebSockets")}} серверов.

+ +

Узнай больше

+ +

Общие сведения

+ + + +

Изучение JavaScript

+ + + +

Технический справочник

+ + diff --git a/files/ru/glossary/jpeg/index.html b/files/ru/glossary/jpeg/index.html new file mode 100644 index 0000000000..19218f558f --- /dev/null +++ b/files/ru/glossary/jpeg/index.html @@ -0,0 +1,17 @@ +--- +title: JPEG +slug: Словарь/jpeg +tags: + - Изображения + - Словарь +translation_of: Glossary/jpeg +--- +

JPEG (произносится «джейпег», англ. Joint Photographic Experts Group, по названию организации-разработчика) — является широко используемым методом сжатия с потерями данных для цифровых изображений.

+ +

Узнать больше

+ +

General knowledge

+ + diff --git a/files/ru/glossary/jquery/index.html b/files/ru/glossary/jquery/index.html new file mode 100644 index 0000000000..666d9a3fc1 --- /dev/null +++ b/files/ru/glossary/jquery/index.html @@ -0,0 +1,35 @@ +--- +title: jQuery +slug: Словарь/jQuery +translation_of: Glossary/jQuery +--- +

jQuery это  {{Glossary("JavaScript")}} {{Glossary("Библиотека")}} сфокусированная на  управлении {{Glossary("DOM")}} , вызовах {{Glossary("AJAX")}} , и  {{Glossary("событиях")}} обработки.

+ +

jQuery синтаксис использования $(selector).action() позволяет выбранному селектору совершить действие.Пример:

+ +
$(document).ready(function(){
+  alert("Hello World!");
+});
+
+ +

JQuery имеет аналогичный эффект, что и следующий код JavaScript:

+ +
window.onload = function() {
+  alert( "Hello World!" );
+};
+
+ +

Изучите больше

+ +

База знаний

+ + + +

Техническая информация

+ + diff --git a/files/ru/glossary/json/index.html b/files/ru/glossary/json/index.html new file mode 100644 index 0000000000..9993de4e8f --- /dev/null +++ b/files/ru/glossary/json/index.html @@ -0,0 +1,29 @@ +--- +title: JSON +slug: Словарь/JSON +tags: + - JSON + - Введение + - Глоссарий + - Написание скриптов +translation_of: Glossary/JSON +--- +

JavaScript Object Notation (JSON) это формат обмена данными.  Несмотря на то, что JSON не является строгим подмножеством, он напоминает синтаксис {{Glossary("JavaScript")}}. Хотя много языков программирования поддерживают JSON, он особенно полезен для JavaScript-приложений, таких как веб-сайты и расширения для браузера.

+ +

JSON может представлять числа, булевы значения, строки, null, массивы (упорядоченные последовательности значений) и объекты (состоят из пар ключ-значение). Ключом является строка, значением может выступать любой примитив, массив или объект.  JSON изначально не предоставляет поддержки более сложных типов данных, таких как функции, регулярные выражения, даты и так далее.  Объекты дат по умолчанию сериализируются в строки, содержащие дату в ISO-формате, поэтому данные не будут утеряны. Если вам нужен JSON для представления дополнительных типов данных, преобразуйте значения в строку в том формате, в котором вы позже хотите его десереализировать.

+ +

Как и XML, JSON имеет возможность хранить иерархические данные (в отличие от более традиционного CSV формата). Существует много инструментов для переходов между этими форматами. Например,  конвертер JSON в CSV.

+ +

Узнать больше

+ +

Общие знания

+ + + +

Техническая информация

+ + diff --git a/files/ru/glossary/loop/index.html b/files/ru/glossary/loop/index.html new file mode 100644 index 0000000000..95c17d0620 --- /dev/null +++ b/files/ru/glossary/loop/index.html @@ -0,0 +1,88 @@ +--- +title: Loop +slug: Словарь/loop +tags: + - Glossary + - control flow + - Программирование + - Словарь + - контроль потока +translation_of: Glossary/loop +--- +

Цикл - это последовательность инструкций, которая постоянно повторяется до тех пор, пока в {{Glossary('computer programming', 'программе')}} не будет выполнено определенное условие. Примером может служить процесс получения элемента данных, его последующего изменения, а затем проверки некоторых {{Glossary ('conditional', 'условий')}}, например, что счетчик достиг заданного числа.

+ +

Примеры

+ +

Цикл for

+ +

Синтаксис:

+ +
for (statement 1; statement 2; statement 3){
+ execute code block
+}
+ + + +

Пример:

+ +
for(var i = 0; i < 10; i++){
+    console.log(i)
+}
+//Этот цикл будет печатать числа 0-9 и остановится, когда условие будет выполнено (i = 10)
+
+ +

Для приведенного выше примера синтаксис выглядит следующим образом:

+ + + +

Цикл while

+ +

Синтаксис:

+ +
while (condition){
+ execute code block
+}
+
+ + + +

Пример:

+ +
var i = 0;
+while(i < 5){
+    console.log(i)
+    i++
+}
+//Этот цикл выведет числа 0-4 и остановится, когда условие станет ложным (i >=5)
+
+ +

Для приведенного выше примера синтаксис выглядит следующим образом:

+ + + + diff --git a/files/ru/glossary/main_axis/index.html b/files/ru/glossary/main_axis/index.html new file mode 100644 index 0000000000..02c5f99ae3 --- /dev/null +++ b/files/ru/glossary/main_axis/index.html @@ -0,0 +1,46 @@ +--- +title: Главная ось +slug: Словарь/Main_Axis +translation_of: Glossary/Main_Axis +--- +

Главная ось в {{glossary("flexbox")}} определяется направлением, установленным в свойстве {{cssxref("flex-direction")}}. Это свойство может принимать одно из четырёх значений:

+ + + +

Если вы выберите row или row-reverse, то главная ось будет проходить вдоль направления строк.

+ +

In this image the flex-direction is row which forms the main axis

+ +

Выберите column или column-reverse, и главная ось будет проходить сверху вниз в направлении блоков.

+ +

+ +

На главной оси вы можете контролировать размеры flex элементов, добавляя к ним свободное простанство с помощью свойства flex на самих элементах. Также, вы можете контролировать пространство между и вокруг элементов свойством justify-content.

+ +

Узнать больше

+ +

Связанные свойства

+ +
+
    +
  • {{cssxref("flex-basis")}}
  • +
  • {{cssxref("flex-direction")}}
  • +
  • {{cssxref("flex-grow")}}
  • +
  • {{cssxref("flex-shrink")}}
  • +
  • {{cssxref("justify-content")}}
  • +
  • {{cssxref("flex")}}
  • +
+
+ +

Дальнейшее чтение

+ + diff --git a/files/ru/glossary/mathml/index.html b/files/ru/glossary/mathml/index.html new file mode 100644 index 0000000000..0b4c5caaca --- /dev/null +++ b/files/ru/glossary/mathml/index.html @@ -0,0 +1,26 @@ +--- +title: MathML +slug: Словарь/MathML +tags: + - CodingScripting + - Glossary + - MathML + - Mathematical Markup Language + - XML +translation_of: Glossary/MathML +--- +

MathML ({{glossary("XML")}} приложение) - это открытый стандарт для представления математических выражений на веб-страницах.  В 1998 году W3C впервые рекомендовал MathML для представления математических выражений в {{glossary("browser")}}. MathML имеет и другие применения, включающие научный контент и синтез голоса.

+ +

Для дополнительного изучения 

+ +

Общие сведения

+ + + +

Техническая справка

+ + diff --git a/files/ru/glossary/metadata/index.html b/files/ru/glossary/metadata/index.html new file mode 100644 index 0000000000..75122f3bf4 --- /dev/null +++ b/files/ru/glossary/metadata/index.html @@ -0,0 +1,20 @@ +--- +title: Метаданные +slug: Словарь/Метаданные +translation_of: Glossary/Metadata +--- +

Метаданные - это, в самом простом определении, данные, что описывают данные. Например, {{ glossary("HTML") }}-документ - это данные, но HTML также может содержать метаданные в элементе {{ htmlelement("head") }}, который описывает документ, например кто его написал и его резюме.

+ +

Смотрите также

+ +

Общие знания

+ + + +

Метаданные в HTML

+ + diff --git a/files/ru/glossary/method/index.html b/files/ru/glossary/method/index.html new file mode 100644 index 0000000000..775570fb71 --- /dev/null +++ b/files/ru/glossary/method/index.html @@ -0,0 +1,43 @@ +--- +title: Метод +slug: Словарь/Method +tags: + - JavaScript + - Словарь +translation_of: Glossary/Method +--- +

Метод это {{glossary("function","функция")}}, являющаяся {{glossary("property","свойством")}} {{glossary("object","объекта")}}. Существует два типа методов: Методы Экземпляра которые являются встроенными задачами, выполняемыми экземпляром объекта, или {{Glossary("static method", "Статические Методы")}} которые являются задачами, вызываемыми непосредственно в конструкторе объекта.

+ +
+

Заметка: В JavaScript функции сами по себе являются объектами, поэтому в этом контексте метод фактически является {{glossary("object reference","ссылкой на объект")}} для функции.

+
+ +

Узнать больше

+ +

Узнайте об этом

+ + + +

Техническая информация

+ + + + diff --git a/files/ru/glossary/microsoft_internet_explorer/index.html b/files/ru/glossary/microsoft_internet_explorer/index.html new file mode 100644 index 0000000000..1770cb13d7 --- /dev/null +++ b/files/ru/glossary/microsoft_internet_explorer/index.html @@ -0,0 +1,41 @@ +--- +title: Microsoft Internet Explorer +slug: Словарь/Microsoft_Internet_Explorer +tags: + - Microsoft + - Microsoft Internet Explorer + - Windows +translation_of: Glossary/Microsoft_Internet_Explorer +--- +

Internet Explorer (или IE) - это бесплатный графический {{glossary("browser", "браузер")}}, созданный Microsoft для использования внутри компании. {{glossary("Microsoft Edge")}} - на данный момент Windows браузер по умолчанию.

+ +

Microsoft впервые выпустила IE в сборке вместе с Windows в 1995 как часть пакета "Microsoft Plus!". Примерно в 2002 году Internet Explorer стал самым испольуемым браузером в мире, но с тех пор утратил свои популярность, уступив свои позиции Chrome, Firefox, Edge и Safari. 

+ +

IE прошёл через огромное количество релизов, и сейчас его текущая версия 11.0.12. Он доступен на персональных компьютерах, телефонах и консоле Xbox. Прежде был доступен на Mac и UNIX, но Microsoft прекратили поддержку этих версий в 2003 и 2001 соответственно.

+ +

См. также

+ +

Основная информация

+ + + +

Изучение Internet Explorer

+ + + +

Технические ссылки

+ + diff --git a/files/ru/glossary/mime_type/index.html b/files/ru/glossary/mime_type/index.html new file mode 100644 index 0000000000..7995c6400e --- /dev/null +++ b/files/ru/glossary/mime_type/index.html @@ -0,0 +1,26 @@ +--- +title: MIME-тип +slug: Словарь/MIME_type +tags: + - MIME-тип + - Media-тип + - Медиа тип +translation_of: Glossary/MIME_type +--- +

MIME-тип (называемый "media type", а иногда "content type") - это строка, отправляемая вместе с файлом, которая указывает тип файла. (например, передаваемый аудиофайл может быть помечен как audio/ogg тип, а изображение - image/png). MIME-тип играет точно такую же роль, как и расширение файла в системе Windows. Когда HTTP-сообщение содержит Content-type заголовок, тело запроса будет парситься в соответствии с MIME-типом, указанным в заголовке.  

+ +

Узнать больше

+ +

Основная информация

+ + + +

Технические справки 

+ + diff --git a/files/ru/glossary/mixin/index.html b/files/ru/glossary/mixin/index.html new file mode 100644 index 0000000000..8f0e369515 --- /dev/null +++ b/files/ru/glossary/mixin/index.html @@ -0,0 +1,24 @@ +--- +title: Миксин +slug: Словарь/Mixin +tags: + - Интерфейс + - Класс + - Свойство + - метод + - миксин +translation_of: Glossary/Mixin +--- +

Миксин (дословно: "примесь) - класс ({{Glossary("class")}}) или интерфейс, в котором некоторые или все его методы ({{Glossary("method", "methods")}}) и/или свойства ({{Glossary("property", "properties")}}) не реализованы, требуя, чтобы другой класс или интерфейс обеспечивал недостающие реализации. Новый класс или интерфейс затем включает в себя как свойства и методы из миксина, так и те, которые он определяет сам. Все методы и свойства используются совершенно одинаково, независимо от того, реализованы ли они в миксине, интерфейсе или классе, реализующем миксин.

+ +

Преимущество миксинов заключается в том, что они могут быть использованы для упрощения проектирования API, в которых несколько интерфейсов должны включать одни и те же методы и свойства.

+ +

Например, миксин {{domxref("WindowOrWorkerGlobalScope")}} используется для предоставления методов и свойств, которые должны быть доступны как в интерфейсах {{domxref("Window")}}, так и в интерфейсах {{domxref("WorkerGlobalScope")}}. Миксин осуществляется с помощью обоих этих интерфейсов.

+ +

Узнать больше

+ +

General knowledge

+ + diff --git a/files/ru/glossary/node.js/index.html b/files/ru/glossary/node.js/index.html new file mode 100644 index 0000000000..7204c8f02c --- /dev/null +++ b/files/ru/glossary/node.js/index.html @@ -0,0 +1,29 @@ +--- +title: Node.js +slug: Словарь/Node.js +tags: + - Glossary + - Infrastructure + - JavaScript + - node.js +translation_of: Glossary/Node.js +--- +

Node.js является межплатформенной средой выполнения, созданной на {{Glossary("JavaScript")}}, которая позволяет разработчикам создавать серверные и сетевые приложения с помощью JavaScript.

+ +

Узнать больше

+ +

Общая информация

+ + + +

Техническая информация

+ + + +

 

diff --git a/files/ru/glossary/null/index.html b/files/ru/glossary/null/index.html new file mode 100644 index 0000000000..5b2520923b --- /dev/null +++ b/files/ru/glossary/null/index.html @@ -0,0 +1,28 @@ +--- +title: 'Null' +slug: Словарь/Null +tags: + - CodingScripting + - Glossary +translation_of: Glossary/Null +--- +

В информатике, значение null представляет ссылку, которая указывает, обычно намеренно, на несуществующий или некорректный {{glossary("object")}} или адрес. Смысл null-ссылки различается от языка к языку.

+ +

В {{Glossary("JavaScript")}}, null – это значение, специально обозначенное как {{Glossary("Primitive", "примитив")}}, так как по поведению это в самом деле видимый примитив. Но при этом от null унаследованы все остальные Объекты, поэтому, несмотря на то, что null возвращает примитивное значение, его тип это объект:

+ +
typeof null === 'object'
+ +

Узнать больше

+ +

Общая информация

+ + + +

Техническая информация

+ + diff --git a/files/ru/glossary/number/index.html b/files/ru/glossary/number/index.html new file mode 100644 index 0000000000..07f67d2729 --- /dev/null +++ b/files/ru/glossary/number/index.html @@ -0,0 +1,25 @@ +--- +title: Number (Числовой тип данных) +slug: Словарь/Number +tags: + - JavaScript + - Типы данных +translation_of: Glossary/Number +--- +

В {{Glossary("JavaScript")}}, Number - числовой тип данных в формате 64-битного числа двойной точности с плавающей запятой. В других языках программирования может существовать несколько чиловых типов данных, например: Integer, Float, Double или Bignum.

+ +

См. также

+ +

Общие сведения

+ + + +

Техничекая справка

+ + diff --git a/files/ru/glossary/object/index.html b/files/ru/glossary/object/index.html new file mode 100644 index 0000000000..4bb269fa22 --- /dev/null +++ b/files/ru/glossary/object/index.html @@ -0,0 +1,26 @@ +--- +title: Объект +slug: Словарь/Object +tags: + - CodingScripting + - Glossary + - Intro + - Object + - Введение + - Объект + - Словарь +translation_of: Glossary/Object +--- +

Объект относится к структуре данных, содержит в себе данные и инструкции по работе с ними. Объекты могут обозначать реальные вещи, например: машину, яблоко, человека или даже карту к сокровищам с ее координатами и инструкциями о том, как добраться до этих сокровищ.
+
+ {{glossary("JavaScript")}}, Java, C++, Python, и Ruby это языки программирования которые относятся к объектно ориентированным языкам (ООП)

+ +

Подробнее

+ +

Общие сведения

+ + diff --git a/files/ru/glossary/oop/index.html b/files/ru/glossary/oop/index.html new file mode 100644 index 0000000000..f90b31c18c --- /dev/null +++ b/files/ru/glossary/oop/index.html @@ -0,0 +1,21 @@ +--- +title: OOП +slug: Словарь/OOP +tags: + - Beginner + - CodingScripting + - Glossary +translation_of: Glossary/OOP +--- +

OOП (Объектно-Ориентированное Программирование) это подход в программировании, согласно которому, данные инкапсулированы внутри {{glossary("object","objects")}}, а сам объект существует как составная часть целого.

+ +

{{glossary("JavaScript")}} сильно объекто-ориентирован. Он следует модели, базирующейся на прототипах (в отличии от модели, базирующейся на классах).

+ +

Смотреть также

+ +

Общие знания

+ + diff --git a/files/ru/glossary/opengl/index.html b/files/ru/glossary/opengl/index.html new file mode 100644 index 0000000000..c6aa1376be --- /dev/null +++ b/files/ru/glossary/opengl/index.html @@ -0,0 +1,16 @@ +--- +title: OpenGL +slug: Словарь/OpenGL +translation_of: Glossary/OpenGL +--- +

OpenGL (Open Graphics Library) -  Это кроссплатформеный программный интерфейс, использующийся разными языками для обработки векторной(2D, 3D) графики.Обычно используется для взаимодействия с графическим процессором(GPU), чтобы добиться аппаратно-ускоренного рендеринга.

+ +

+ +

Learn more

+ +

General knowledge

+ + diff --git a/files/ru/glossary/origin/index.html b/files/ru/glossary/origin/index.html new file mode 100644 index 0000000000..4b95d3a888 --- /dev/null +++ b/files/ru/glossary/origin/index.html @@ -0,0 +1,52 @@ +--- +title: Первичные данные +slug: Словарь/origin +translation_of: Glossary/Origin +--- +

Браузер отправляет серверу первичные данные - протокол, хистинг, домен, порт соединения через {{Glossary("URL")}}. Два объекта одинаковые если протокол, хост, домен и порт одинаковые.

+ +

Некоторые данные могут не передаваться источником, для их получения необходимо использовать CORS.

+ +

Примеры первичных данных

+ + + + + + + + + + + + +
http://example.com/app1/index.html
+ http://example.com/app2/index.html
данные протокола (http) и хостинга (example.com)
http://Example.com:80
+ http://example.com
первичные данные для сервера- соединения HTTP, номер порта 80
+ +

Пример других первичных данных

+ + + + + + + + + + + + + + + + +
http://example.com/app1
+ https://example.com/app2
другие протоколы
http://example.com
+ http://www.example.com
+ http://myapp.example.com
разные хостинги
http://example.com
+ http://example.com:8080
другой порт
+ +

Больше информации

+ +

Смотрите Same-origin policy.

diff --git a/files/ru/glossary/php/index.html b/files/ru/glossary/php/index.html new file mode 100644 index 0000000000..626e15310a --- /dev/null +++ b/files/ru/glossary/php/index.html @@ -0,0 +1,16 @@ +--- +title: PHP +slug: Словарь/PHP +translation_of: Glossary/PHP +--- +
+
PHP, расшифровывающийся как "PHP: Hypertext Preprocessor" - «PHP: Препроцессор Гипертекста», является распространенным интерпретируемым языком общего назначения с открытым исходным кодом. PHP создавался специально для ведения web-разработок и код на нем может внедряться непосредственно в HTML-код. Синтаксис языка берет начало из C, Java и Perl, и является легким для изучения. Основной целью PHP является предоставление web-разработчикам возможности быстрого создания динамически генерируемых web-страниц, однако область применения PHP не ограничивается только этим.
+
+ +

Узнать больше

+ + diff --git a/files/ru/glossary/pixel/index.html b/files/ru/glossary/pixel/index.html new file mode 100644 index 0000000000..dbe4aa4eb6 --- /dev/null +++ b/files/ru/glossary/pixel/index.html @@ -0,0 +1,19 @@ +--- +title: Pixel +slug: Словарь/Pixel +tags: + - Glossary + - Graphics +translation_of: Glossary/Pixel +--- +

Пиксель (англ. Pixel) - маленький строительный блок графического дисплея экрана компьютера.

+ +

Разрешение дисплея выражено в пикселях, например:  “800 x 600” пикселей, значит, что дисплей может отображать 800 пикселей в ширину и 600 пикселей в высоту.

+ +

Узнайте больше

+ +

Технические ссылки

+ + diff --git a/files/ru/glossary/polifill/index.html b/files/ru/glossary/polifill/index.html deleted file mode 100644 index caffde4878..0000000000 --- a/files/ru/glossary/polifill/index.html +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: Полифил -slug: Glossary/Polifill -tags: - - Glossary - - Глоссарий - - Словарь ---- -

Полифил (англ. "polyfill") — это фрагмент кода, предоставляющий функционал необходимой технологии, которая будет нативным образом представлена браузером. Другими словами, код будет работать в точности так, как технология, которую он, собственно, и предназначен представлять. Подделка архитектуры API интерфейса, если вам угодно.

- -

Ссылки

- -

Что такое полифил? http://webknowledge.ru/chto-takoe-polyfill/

diff --git a/files/ru/glossary/polymorphism/index.html b/files/ru/glossary/polymorphism/index.html new file mode 100644 index 0000000000..bea130b908 --- /dev/null +++ b/files/ru/glossary/polymorphism/index.html @@ -0,0 +1,24 @@ +--- +title: Полиморфизм +slug: Словарь/Polymorphism +tags: + - CodingScripting + - Glossary +translation_of: Glossary/Polymorphism +--- +

Полиморфизм - это представление одного интерфейса для разных типов данных.
+
+ Например, целые числа(integers), числа с плавающей запятой(floats) и числа с плавающей точкой двойной точности(doubles) полностью полиморфны: независимо от их отличающихся типов, их можно складывать, вычитать, перемножать, и так далее.

+ +

В случае {{glossary("OOP")}}, возлогая ответственность на {{glossary("class")}} за его код так же, как свои собственные данные, полиморфизм может быть достигнут в том, что у каждого класса есть своя {{glossary("function")}}, которая (при вызове) выполняется корректно для любого {{glossary("object")}}.

+ + + +

Изучить больше

+ +

Общие знания

+ + diff --git a/files/ru/glossary/port/index.html b/files/ru/glossary/port/index.html new file mode 100644 index 0000000000..d4443e736e --- /dev/null +++ b/files/ru/glossary/port/index.html @@ -0,0 +1,22 @@ +--- +title: Порт +slug: Словарь/Порт +tags: + - Glossary + - Intro + - Security + - computer network + - port +translation_of: Glossary/Port +--- +

Для подключенного к сети компьютера с {{Glossary("IP address")}}, порт это конечная точка входа для коммуникаций. Порты обозначаются числами, и до 1024 каждому порту по умолчанию назначен некоторый протокол.

+ +

Например, порт по умолчанию для протокола {{Glossary("HTTP")}} 80, а порт для протокола HTTPS – 443, таким образом {{Glossary("HTTP")}}-сервер ожидает входящие запросы на данных портах. Каждый интернет протокол имеет порт по умолчанию: {{Glossary("SMTP")}} (25), {{Glossary("POP3")}} (110), {{Glossary("IMAP")}} (143), {{Glossary("IRC")}} (194) и так далее.

+ +

Узнать больше

+ +

Общая информация

+ + diff --git a/files/ru/glossary/primitive/index.html b/files/ru/glossary/primitive/index.html new file mode 100644 index 0000000000..cdeff2610a --- /dev/null +++ b/files/ru/glossary/primitive/index.html @@ -0,0 +1,105 @@ +--- +title: Primitive +slug: Словарь/Primitive +tags: + - CodingScripting + - Glossary + - JavaScript +translation_of: Glossary/Primitive +--- +

Примитив (значение примитивного типа, примитивный тип данных) это данные, которые не являются {{glossary("object", "объектом")}} и не имеют {{glossary("method","методов")}}. В {{Glossary("JavaScript")}} 7 простых типов данных: {{Glossary("string")}}, {{Glossary("number")}}, {{Glossary("boolean")}}, {{Glossary("null")}}, {{Glossary("undefined")}}, {{Glossary("symbol")}} (новое в {{Glossary("ECMAScript")}} 2015), {{Glossary("bigint")}}.

+ +

Чаще всего значение примитивного типа представлено в низкоуровневой реализации языка.

+ +

Все примитивы неизменяемы (immutable), то есть они не могут быть изменены. Важно не путать сам примитив с переменной, которой присвоено значение примитивного типа. Переменной может быть переприсвоено новое значение, но существующее значение примитивного типа не может быть изменено подобно объектам, массивам и функциям.

+ +

Пример

+ +

Этот пример поможет понять, что значения примитивных типов неизменяемы (immutable).

+ +

JavaScript

+ +
// Using a string method doesn't mutate the string
+var bar = "baz";
+console.log(bar);               // baz
+bar.toUpperCase();
+console.log(bar);               // baz
+
+// Using an array method mutates the array
+var foo = [];
+console.log(foo);               // []
+foo.push("plugh");
+console.log(foo);               // ["plugh"]
+
+// Assignment gives the primitive a new (not a mutated) value
+bar = bar.toUpperCase();       // BAZ
+
+ +

Примитив может быть заменен, но он не может быть напрямую изменен.

+ +

Другой пример [ Step-by-step ]

+ +

Следующий пример поможет разобраться как JavaScript работает с примитивами.

+ +

JavaScript

+ +
// The Primitive
+let foo = 5;
+
+// Defining a function that should change the Primitive value
+function addTwo(num) {
+   num += 2;
+}
+// Another function trying to do the same thing
+function addTwo_v2(foo) {
+   foo += 2;
+}
+
+// Calling our first function while passing our Primitive as an argument
+addTwo(foo);
+// Getting the current Primitive value
+console.log(foo);   // 5
+
+// Trying again with our second function...
+addTwo_v2(foo);
+console.log(foo);   // 5
+
+ +

Вы ожидали, что будет 7 вместо 5? Если так, тогда прочитайте, как работает этот код:

+ + + +

Вот почему примитивы неизменяемы (immutable). Потому что мы не работаем над ними напрямую. Мы создаем копию и продолжаем работать с ней, не касаясь исходных значений.

+ +

Обертки примитивных типов в JavaScript

+ +

За исключением null и undefined, все примитивные значения имеют объектный аналог, который оборачивает значение примитивного типа:

+ + + +

Метод valueOf() типа обертки возвращает значение примитивного типа.

+ +

См. также

+ +

Общие сведения

+ + diff --git a/files/ru/glossary/privileged_code/index.html b/files/ru/glossary/privileged_code/index.html new file mode 100644 index 0000000000..c8f7e0c484 --- /dev/null +++ b/files/ru/glossary/privileged_code/index.html @@ -0,0 +1,10 @@ +--- +title: Привилегированный код +slug: Словарь/privileged_code +tags: + - privileged +translation_of: Glossary/privileged_code +--- +

Привилегированный код (Privileged code) - Javascript-код расширения, например, скриптов content scripts.

+ +

Непривилегированный код - обычный Javascript на веб-странице

diff --git a/files/ru/glossary/progressive_web_apps/index.html b/files/ru/glossary/progressive_web_apps/index.html new file mode 100644 index 0000000000..d839ddf725 --- /dev/null +++ b/files/ru/glossary/progressive_web_apps/index.html @@ -0,0 +1,18 @@ +--- +title: Прогрессивные веб приложения +slug: Словарь/Progressive_web_apps +tags: + - Глоссарий + - Прогрессивные веб-приложения +translation_of: Glossary/Progressive_web_apps +--- +

Прогрессивные веб-приложения — это термин, используемый для описания современного состояния разработки веб-приложений. Включает в себя использование стандартов веб-сайтов/приложений, которые используют все лучшие части Интернета, такие как возможность обнаружения поисковыми системами, возможность ссылки через {{Glossary("URL")}}  работу с различными форм-факторами, и их усиление с современными API-интерфейсами (такими как Service Workers и Push) и функциями, которые предоставляют другие преимущества, обычно присущие нативным приложениям.

+ +

Эти функции включают в себя возможность установки, работу в автономном режиме, а также простоту синхронизации и повторного подключения пользователя с сервера.

+ +

Узнать больше

+ + diff --git a/files/ru/glossary/promise/index.html b/files/ru/glossary/promise/index.html new file mode 100644 index 0000000000..23ed273c40 --- /dev/null +++ b/files/ru/glossary/promise/index.html @@ -0,0 +1,32 @@ +--- +title: Promise +slug: Словарь/Promise +tags: + - Словарь + - асинхронный +translation_of: Glossary/Promise +--- +

A {{jsxref("Promise")}} - это {{Glossary("Object")}}, возвращаемый {{Glossary("function")}}, которая еще не завершила свою работу. Promise буквально представляет собой 'обещание' функции в итоге вернуть результат через объект промиса.

+ +

Когда вызванная функция {{Glossary("asynchronous", "asynchronously")}} завершает работу, вызывается функция объекта промиса, называемая обработчиком решения (или выполнения, или завершения) чтобы исходный объект вызова знал, что задача выполнена

+ +

 

+ +

 

+ +

Узнать больше

+ +

Чтобы узнать больше, пройдите по ссылкам

+ +

General knowledge

+ + + +

Technical reference

+ + diff --git a/files/ru/glossary/property/index.html b/files/ru/glossary/property/index.html new file mode 100644 index 0000000000..92f27a9b35 --- /dev/null +++ b/files/ru/glossary/property/index.html @@ -0,0 +1,12 @@ +--- +title: Свойство +slug: Словарь/property +tags: + - Глоссарий + - Неоднозначность + - Словарь терминов +translation_of: Glossary/property +--- +

Термин свойство может иметь разное значение, в зависимости от контекста. Он может указывать на:

+ +

{{GlossaryDisambiguation}}

diff --git a/files/ru/glossary/protocol/index.html b/files/ru/glossary/protocol/index.html new file mode 100644 index 0000000000..86ad7407af --- /dev/null +++ b/files/ru/glossary/protocol/index.html @@ -0,0 +1,21 @@ +--- +title: Протокол +slug: Словарь/Протокол +tags: + - Глоссарий + - инфраструктура + - протокол +translation_of: Glossary/Protocol +--- +

Протокол - это система правил, определяющая, как данные обмениваются внутри или между компьютерами.  Для связи между устройствами требуется согласование формата данных, которые будут использоваться для обмена. Набор правил, определяющих формат, называется протоколом.

+ +

Смотрите также

+ +

Основная информация

+ + + +

 

diff --git a/files/ru/glossary/prototype-based_programming/index.html b/files/ru/glossary/prototype-based_programming/index.html new file mode 100644 index 0000000000..78e3828363 --- /dev/null +++ b/files/ru/glossary/prototype-based_programming/index.html @@ -0,0 +1,17 @@ +--- +title: Прототипно-ориентированное программирование +slug: Словарь/Prototype-based_programming +tags: + - Glossary + - Глоссарий +translation_of: Glossary/Prototype-based_programming +--- +

Прототипно-ориентированный стиль объектно-ориентированного программирования тот, в котором классы определены неявно, а производные классы получаются добавлением свойств и методов в экземпляр другого класса или, значительно реже, к пустому объекту.

+ +

Узнать больше

+ +

Общее представление

+ + diff --git a/files/ru/glossary/prototype/index.html b/files/ru/glossary/prototype/index.html new file mode 100644 index 0000000000..cd248a94a9 --- /dev/null +++ b/files/ru/glossary/prototype/index.html @@ -0,0 +1,18 @@ +--- +title: Прототип +slug: Словарь/Прототип +tags: + - прототип +translation_of: Glossary/Prototype +--- +

Прототип — модель, отображающая внешний вид и поведение приложения или продукта в начале цикла разработки.

+ +

См. в разделе Наследование и цепочка прототипов

+ +

Узнать больше

+ +

Общие сведения

+ + diff --git a/files/ru/glossary/proxy_server/index.html b/files/ru/glossary/proxy_server/index.html new file mode 100644 index 0000000000..e545c3b1b0 --- /dev/null +++ b/files/ru/glossary/proxy_server/index.html @@ -0,0 +1,24 @@ +--- +title: Прокси сервер +slug: Словарь/Прокси_сервер +tags: + - Прокси + - Сервер + - Термин +translation_of: Glossary/Proxy_server +--- +

Прокси-сервер - это промежуточная программа или компьютер, используемый при навигации по разным сетям Интернета. Они облегчают доступ к контенту во всемирной паутине. Прокси-сервер перехватывает запросы и возвращает ответы; он может пересылать запросы или нет (например, в случае кеша), и он может изменять его (например, изменяя его заголовки на границе между двумя сетями).

+ +

Прокси-сервер может находиться на локальном компьютере пользователя или в любом месте между компьютером пользователя и конечным сервером в Интернете. Cуществует два основных типа прокси-серверов:

+ + + +

Узнать подробнее

+ + diff --git a/files/ru/glossary/pseudo-element/index.html b/files/ru/glossary/pseudo-element/index.html new file mode 100644 index 0000000000..24edc01fe7 --- /dev/null +++ b/files/ru/glossary/pseudo-element/index.html @@ -0,0 +1,18 @@ +--- +title: Псевдоэлемент +slug: Словарь/Pseudo-element +tags: + - CSS + - CodingScripting + - Glossary +translation_of: Glossary/Pseudo-element +--- +

Селектор псевдоэлемента в CSS применяет стили к частям содержимого вашего документа в тех случаях, когда нет конкретного HTML-элемента для выбора. Например, вместо того, чтобы помещать первую букву каждого абзаца в отдельный элемент, вы можете оформить их все с помощью p{{ Cssxref("::first-letter") }}.

+ +

Смотрите также

+ +

Техническая справка

+ + diff --git a/files/ru/glossary/pseudocode/index.html b/files/ru/glossary/pseudocode/index.html new file mode 100644 index 0000000000..df42e78eaa --- /dev/null +++ b/files/ru/glossary/pseudocode/index.html @@ -0,0 +1,17 @@ +--- +title: Псевдокод +slug: Словарь/Pseudocode +tags: + - Написание кода + - Псевдокод +translation_of: Glossary/Pseudocode +--- +

Псевдокод относится к кодоподобному синтаксису, который обычно используется для указания людям, как работает некоторый синтаксис кода, или для иллюстрации конструкции элемента архитектуры кода. Он не сработает, если вы попытаетесь запустить его как код. 

+ +

Узнать подробнее

+ +

База знаний

+ + diff --git a/files/ru/glossary/reflow/index.html b/files/ru/glossary/reflow/index.html new file mode 100644 index 0000000000..34546c1ab3 --- /dev/null +++ b/files/ru/glossary/reflow/index.html @@ -0,0 +1,12 @@ +--- +title: Пересчет (Reflow) +slug: Словарь/Reflow +translation_of: Glossary/Reflow +--- +

Пересчет (Reflow) происходит, когда {{glossary("браузер")}} должен снова обработать и отрисовать часть или всю веб-страницу, например, после изменения размера какого-нибудь блока или изменения его позиции на интерактивном сайте.

+ +

Learn more

+ + diff --git a/files/ru/glossary/regular_expression/index.html b/files/ru/glossary/regular_expression/index.html new file mode 100644 index 0000000000..c087ec1115 --- /dev/null +++ b/files/ru/glossary/regular_expression/index.html @@ -0,0 +1,26 @@ +--- +title: Регулярные выражения +slug: Словарь/Regular_expression +tags: + - регулярные выражения +translation_of: Glossary/Regular_expression +--- +

Регулярные выражения (regex) - это правила, определяющие, какие последовательности символов появляются в поиске.
+
+ Регулярные выражения реализованы в разных языках, но наиболее известной является реализация в Perl, которая породила собственную экосистему реализаций, называемых PCRE (Perl Compatible Regular Expression). В Интернете {{glossary("JavaScript")}} предоставляет еще одну реализацию регулярных выражений через объект {{jsxref("RegExp")}}.

+ +

Материалы для изучения

+ +

Общие

+ + + +

Технические

+ + diff --git a/files/ru/glossary/request_header/index.html b/files/ru/glossary/request_header/index.html new file mode 100644 index 0000000000..b5a8b82dad --- /dev/null +++ b/files/ru/glossary/request_header/index.html @@ -0,0 +1,43 @@ +--- +title: Заголовок запроса +slug: Словарь/Request_header +tags: + - Словарь +translation_of: Glossary/Request_header +--- +

Заголовок запроса - {{Glossary("header", "HTTP header")}} который используется в  HTTP-запросе и который не относиться к содержимому сообщения. Заголовки запроса, такие как {{HTTPHeader("Accept")}}, {{HTTPHeader("Accept-Language", "Accept-*")}} или {{HTTPHeader("If-Modified-Since", "If-*")}} позволяют выполнять условные запросы; другие, такие как {{HTTPHeader("Cookie")}}, {{HTTPHeader("User-Agent")}} или {{HTTPHeader("Referer")}} уточняют контекст, чтобы сервер мог адаптировать ответ.

+ +

Не все заголовки, появляющиеся в запросе, являются заголовками запроса. Например, {{HTTPHeader("Content-Length")}}, появляющийся в запросе {{HTTPMethod("POST")}}, на самом деле является {{Glossary("entity header", "заголовки сущности")}}, ссылающимся на размер тела сообщения запроса. Однако в таком контексте эти заголовки сущности часто называют заголовками запроса.

+ +

Кроме того, CORS определяет подмножество заголовков запросов как {{Glossary("simple header", "простой заголовок")}}, заголовки запросов, которые всегда считаются авторизованными и не указаны явно в ответах на {{Glossary("preflight request","preflight")}} запросов.

+ +

Несколько заголовков запроса после запроса {{HTTPMethod("GET")}}:

+ +
GET /home.html HTTP/1.1
+Host: developer.mozilla.org
+User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
+Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
+Accept-Language: en-US,en;q=0.5
+Accept-Encoding: gzip, deflate, br
+Referer: https://developer.mozilla.org/testpage.html
+Connection: keep-alive
+Upgrade-Insecure-Requests: 1
+If-Modified-Since: Mon, 18 Jul 2016 02:36:04 GMT
+If-None-Match: "c561c68d0ba92bbeb8b0fff2a9199f722e3a621a"
+Cache-Control: max-age=0
+ +

Строго говоря, заголовок {{HTTPHeader("Content-Length")}} в этом примере является не заголовком запроса, как другие, а представляет {{Glossary("entity header", "заголовок сущности")}}:

+ +
POST /myform.html HTTP/1.1
+Host: developer.mozilla.org
+User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
+Content-Length: 128
+
+ +

Узнать больше

+ +

Технические знания

+ + diff --git a/files/ru/glossary/responsive_web_design/index.html b/files/ru/glossary/responsive_web_design/index.html new file mode 100644 index 0000000000..6c0c3bc240 --- /dev/null +++ b/files/ru/glossary/responsive_web_design/index.html @@ -0,0 +1,20 @@ +--- +title: Responsive web design +slug: Словарь/Responsive_web_design +tags: + - Глоссарий + - Дизайн + - адаптивный дизайн +translation_of: Glossary/Responsive_web_design +--- +

Адаптивный веб-дизайн ( RWD ) - это концепция веб-разработки, направленная на то, чтобы сайты выглядели и вели себя оптимально на всех персональных вычислительных устройствах, от настольных компьютеров до мобильных.

+ +

См. также

+ +

Общая информация

+ + diff --git a/files/ru/glossary/round_trip_time_(rtt)/index.html b/files/ru/glossary/round_trip_time_(rtt)/index.html new file mode 100644 index 0000000000..f81a2077b9 --- /dev/null +++ b/files/ru/glossary/round_trip_time_(rtt)/index.html @@ -0,0 +1,28 @@ +--- +title: Round Trip Time (RTT) +slug: Словарь/Round_Trip_Time_(RTT) +translation_of: Glossary/Round_Trip_Time_(RTT) +--- +

Время приема-передачи (англ. Round Trip Time, RTT) - это время, которое требуется для отправки пакета данных в пункт назначения, плюс время, которое требуется для подтверждения того, что этот пакет был получен обратно. RTT между сетью и сервером может быть определен с помощью команды ping.

+ +
+
$ ping google.com
+PING google.com (216.58.194.174): 56 data bytes
+64 bytes from 216.58.194.174: icmp_seq=0 ttl=55 time=25.050 ms
+64 bytes from 216.58.194.174: icmp_seq=1 ttl=55 time=23.781 ms
+64 bytes from 216.58.194.174: icmp_seq=2 ttl=55 time=24.287 ms
+64 bytes from 216.58.194.174: icmp_seq=3 ttl=55 time=34.904 ms
+64 bytes from 216.58.194.174: icmp_seq=4 ttl=55 time=26.119 ms
+--- google.com ping statistics ---
+5 packets transmitted, 5 packets received, 0.0% packet loss
+round-trip min/avg/max/stddev = 23.781/26.828/34.904/4.114 ms
+ +

В приведенном выше примере среднее время приема-передачи, как показано в последней строке, равно 26,8 мс.

+
+ +

См. также

+ + diff --git a/files/ru/glossary/safe/index.html b/files/ru/glossary/safe/index.html new file mode 100644 index 0000000000..4351bd9fee --- /dev/null +++ b/files/ru/glossary/safe/index.html @@ -0,0 +1,43 @@ +--- +title: Безопасный метод +slug: Словарь/safe +tags: + - Glossary + - HTTP +translation_of: Glossary/safe +--- +

Метод HTTP является безопасным, если он не меняет состояние сервера. Другими словами, безопасный метод проводит операции "только чтение" (read-only). Несколько следующих методов HTTP безопасные: {{HTTPMethod("GET")}}, {{HTTPMethod("HEAD")}} или {{HTTPMethod("OPTIONS")}}. Все безопасные методы являются также {{glossary("idempotent", "идемпотентными")}}, как и некоторые другие, но при этом небезопасные, такие как {{HTTPMethod("PUT")}} или {{HTTPMethod("DELETE")}}.

+ +

Даже если безопасные методы являются по существу "только для чтения", сервер всё равно может сменить своё состояние: например, он может сохранять статистику. Что существенно, так то, когда клиент вызывает безопасный метод, то он не запрашивает никаких изменений на сервере, и поэтому не создаёт дополнительную нагрузку на сервер. Браузеры могут вызывать безопасные методы, не опасаясь причинить вред серверу: это позволяет им выполнять некоторые действия, например, предварительная загрузка без риска. Поисковые роботы также полагаются на вызовы безопасных методов.

+ +

Безопасные методы не обязательно должны обрабатывать только статичные файлы; сервер может генерировать ответ "на-лету", пока скрипт, генерирующий ответ, гарантирует безопасность: он не должен вызывать внешних эффектов, таких как формирование заказов, отправка писем и др..

+ +

Правильная реализация безопасного метода - это ответственность серверного приложения, потому что сам веб-сервер, будь то Apache, nginx, IIS это соблюсти не сможет. В частности, приложение не должно разрешать изменение состояния сервера запросами {{HTTPMethod("GET")}}.

+ +

Вызов безопасного метода, не меняющего состояния сервера:

+ +
GET /pageX.html HTTP/1.1
+
+ +

Вызов небезопасного метода, который может поменять состояние сервера:

+ +
POST /pageX.html HTTP/1.1 
+ +

Вызов идемпотентного, но небезопасного метода:

+ +
DELETE /idX/delete HTTP/1.1
+ +

Материалы для изучения

+ +

Общие

+ + + +

Технические

+ + diff --git a/files/ru/glossary/scroll_container/index.html b/files/ru/glossary/scroll_container/index.html new file mode 100644 index 0000000000..4ea91d5582 --- /dev/null +++ b/files/ru/glossary/scroll_container/index.html @@ -0,0 +1,25 @@ +--- +title: Scroll-контейнер +slug: Словарь/Scroll_container +translation_of: Glossary/Scroll_container +--- +

Scroll-контейнер создаётся путём применения к элементу свойства overflow: scroll или overflow: auto, при условии, что содержимого достаточно много для появления переполнения.

+ +

Scroll-контейнер позволяет пользователю с помощью прокрутки достигать участков переполняющего содержимого, которые в ином случае были бы обрезаны и поэтому недоступны для просмотра. Видимая часть scroll-контейнера называется {{glossary("Scrollport", "scrollport")}}.

+ + diff --git a/files/ru/glossary/sdp/index.html b/files/ru/glossary/sdp/index.html new file mode 100644 index 0000000000..d1044fb171 --- /dev/null +++ b/files/ru/glossary/sdp/index.html @@ -0,0 +1,31 @@ +--- +title: SDP +slug: Словарь/SDP +translation_of: Glossary/SDP +--- +

SDP (Session Description {{glossary("Protocol")}} - протокол описания сессии) - это текстовый формат для описания {{Glossary("P2P","peer-to-peer")}}-соединения. SDP содержит описание {{Glossary("кодеков")}}, адрес источника и информацию для синхронизации аудио и видео.

+ +

Here is a typical SDP message:

+ +
   v=0
+   o=alice 2890844526 2890844526 IN IP4 host.anywhere.com
+   s=
+   c=IN IP4 host.anywhere.com
+   t=0 0
+   m=audio 49170 RTP/AVP 0
+   a=rtpmap:0 PCMU/8000
+   m=video 51372 RTP/AVP 31
+   a=rtpmap:31 H261/90000
+   m=video 53000 RTP/AVP 32
+   a=rtpmap:32 MPV/90000
+ +

SDP is never used alone, but by protocols like {{Glossary("RTP")}} and {{Glossary("RTSP")}}. SDP is also as component of {{Glossary("WebRTC")}}, which uses SDP as a way of describing a session.

+ +

Learn more

+ +

General knowledge

+ + diff --git a/files/ru/glossary/self-executing_anonymous_function/index.html b/files/ru/glossary/self-executing_anonymous_function/index.html new file mode 100644 index 0000000000..104fef094b --- /dev/null +++ b/files/ru/glossary/self-executing_anonymous_function/index.html @@ -0,0 +1,8 @@ +--- +title: Self-Executing Anonymous Function +slug: Словарь/Self-Executing_Anonymous_Function +translation_of: Glossary/Self-Executing_Anonymous_Function +--- +

{{glossary("JavaScript")}} {{glossary("функция")}}, которая выполняется сразу после определения. Также известна как IIFE (Immediately Invoked Function Expression).

+ +

См. страницу о IIFE для подробной информации.

diff --git a/files/ru/glossary/semantics/index.html b/files/ru/glossary/semantics/index.html new file mode 100644 index 0000000000..b64469506d --- /dev/null +++ b/files/ru/glossary/semantics/index.html @@ -0,0 +1,98 @@ +--- +title: Semantics +slug: Словарь/Semantics +translation_of: Glossary/Semantics +--- +

В программировании, Семантика означает значение фрагмента кода - например, «к какому результату приведет выполнение этой строки JavaScript?», или «каково предназначение или какая роль у этого элемента HTML» (а не «как он выглядит ?».)

+ +

Семантика в JavaScript

+ +

Для JavaScript, рассмотрим функцию, которая принимает строку в качестве параметра, и возвращает элемент {{htmlelement("li")}} с этой строкой в качестве свойства textContent. Нужно ли вам смотреть на код, чтобы понять, что делает функция build('Peach'), или createLiWithContent('Peach')?

+ +

Семантика в CSS

+ +

Для CSS, рассмотрим стилизацию списка элементов li, в которых содержаться разные виды фруктов. Вы бы поняли, какая часть DOM выбрана с помощью селектора div > ul > li, или .fruits__item?

+ +

Семантика в HTML

+ +

В HTML, например, элемент {{htmlelement("h1")}} является семантическим, что дает тексту внутри него роль (или значение) "заголовка первого уровня на вешей странице".

+ +
<h1>This is a top level heading</h1>
+ +

По умолчанию, стандартные стили большинства браузеров зададут {{htmlelement("h1")}} большой размер шрифта, чтобы он выглядел как заголовок (хотя вы можете стилизировать его так, как сочтете нужным).

+ +

С другой стороны, вы можете сделать любой элемент похожим на заголовок первого уровня. Рассмотрим следующее:

+ +
<span style="font-size: 32px; margin: 21px 0;">Is this a top level heading?</span>
+ +

Эти стили сделают элемент похожим на заголовок первого уровня, но он не будет иметь семантического значения, поэтому не получит никаких дополнительных преимуществ, описанных выше. Поэтому хорошей практикой является выбор подходящего элемента HTML для каждого отдельного случая.

+ +

HTML должен предоставлять структуру информации, которой он будет наполняться, и не должен полагаться на стандартные свойтва стилей. Стилизация (то, как эта информация должна выглядеть), полностью ложиться на плечи CSS.

+ +

Некоторые из преимуществ использования семантической разметки:

+ + + +

Принимая решение об использовании той или иной разметки, спросите себя: «Какой элемент (элементы) лучше всего описывает / представляет данные, которые я собираюсь использовать?» Например, это список данных ?; упорядоченный, неупорядоченный ?; это статья с разделами и дополнительной информацией ?; в ней перечислены определения ?; это рисунок или изображение, которое требует подписи ?; должен ли он иметь собственные header и footer?; и т.п.

+ +

Семантические элементы

+ +

Вот некоторые из примерно 100 доступных семантических элементов:

+ + + +

Learn more

+ + + + diff --git a/files/ru/glossary/seo/index.html b/files/ru/glossary/seo/index.html new file mode 100644 index 0000000000..b8222c6577 --- /dev/null +++ b/files/ru/glossary/seo/index.html @@ -0,0 +1,35 @@ +--- +title: SEO +slug: Словарь/SEO +translation_of: Glossary/SEO +--- +

SEO (Search Engine Optimization) Поисковая оптимизация - это комплекс мер по оптимизации, для поднятия сайта в рейтингах поисковых систем. Её еще называют "Повышением поискового рейтинга" 

+ +

Поисковые системы исследуют интернет, переходят по ссылкам со страницы на страницу и индексируют найденый контент. Когда вы ищищте что то в интернете, поисковые системы отображают индексированный контент.  Сканнеры пользуются определенными алгоритмами. Если вы будете знать и внимательно следовать  этим правилам, когда внедряете SEO для сайта, у такого сайта будут более высокие шансы оказаться в числе первых результатов поискового запроса, а следовательно - более высокий трафик и, как следствие - доход (дляя интернет продаж и рекламы).

+ +

Поисковые системы дают некоторые рекомендации для SEO, но большие поисковые системы сохраняют алгоритмы и результаты поиска как коммерческую тайну. SEO объединяет в себе рекомендации поисковых систем содержащиеся в свободном доступе, эмпирический опыт и теоретические знания, подчерпываемые из научных статей и патентов.

+ +

Методы SEO делятся на три объемных класса:

+ +
+
технический
+
Создание тегов контента, используя семантику HTML. Сканируя сайт, алгоритмы поиска находят только тот коонтент, который вы хотите проиндексировать.
+
копирайтинг
+
Создавайте контент, используя словарь ваших потенциальных посетителей. Используйте тексты и изображения, которые помогли бы помочь алгоритмам поисковой симтемы понять суть предмета представленного на вашем ресурсе.
+
популяризация
+
Вы можете значительно увеличить поток трафика, если ссылки на ваш сайт будут размещены на других развитых ресурсах.
+
+ +

Изучить больше

+ +

Основной источник

+ + + +

Learn SEO

+ + diff --git a/files/ru/glossary/server/index.html b/files/ru/glossary/server/index.html new file mode 100644 index 0000000000..61c783485f --- /dev/null +++ b/files/ru/glossary/server/index.html @@ -0,0 +1,25 @@ +--- +title: Server +slug: Словарь/Server +translation_of: Glossary/Server +--- +

A server is a software or hardware offering a service to a user, usually referred to as client.  A hardware server is a shared computer on a network, usually powerful and housed in a data center.  A software server (often running on a hardware server) is a program that provides services to client programs or a {{glossary("UI","user interface")}} to human clients.

+ +

Services are provided generally over local area networks or wide area networks such as the internet. A client program and server program traditionally connect by passing messages encoded using a {{glossary("protocol")}} over an {{glossary("API")}}.

+ +

For example:

+ + + +

Learn More

+ +

General knowledge

+ + diff --git a/files/ru/glossary/sgml/index.html b/files/ru/glossary/sgml/index.html new file mode 100644 index 0000000000..7e00336c25 --- /dev/null +++ b/files/ru/glossary/sgml/index.html @@ -0,0 +1,18 @@ +--- +title: SGML +slug: Словарь/SGML +tags: + - SGML + - Словарь +translation_of: Glossary/SGML +--- +

Стандартный обобщённый язык разметки (SGML) это спецификация {{Glossary("ISO")}} для определения декларативных языков разметки.

+ +

В вебе, {{Glossary("HTML")}} 4, {{Glossary("XHTML")}}, и {{Glossary("XML")}} популярные языки SGML-типа. Стоит отметить, что с момента своего пятого издания HTML больше не основан на SGML и имеет свои собственные правила синтаксического анализа.

+ +

Узнать больше

+ + diff --git a/files/ru/glossary/simple_header/index.html b/files/ru/glossary/simple_header/index.html new file mode 100644 index 0000000000..c90db6fd05 --- /dev/null +++ b/files/ru/glossary/simple_header/index.html @@ -0,0 +1,39 @@ +--- +title: Простой заголовок +slug: Словарь/Простой_заголовок +tags: + - CORS + - HTTP + - Определения + - инфраструктура +translation_of: Glossary/Simple_header +--- +

Простой заголовок (или заголовок запроса с поддержкой безопасности CORS) - это один из следующих HTTP заголовков:

+ + + +

Или один из этих клиентских заголовков:

+ + + +

Если они содержат только простые заголовки, запросы считаются простыми и не нужно отправлять {{glossary("preflight request")}} в контексте CORS.

+ +

Смотрите также

+ + diff --git a/files/ru/glossary/simple_response_header/index.html b/files/ru/glossary/simple_response_header/index.html new file mode 100644 index 0000000000..7cddde385f --- /dev/null +++ b/files/ru/glossary/simple_response_header/index.html @@ -0,0 +1,6 @@ +--- +title: Simple response header +slug: Словарь/Simple_response_header +translation_of: Glossary/Simple_response_header +--- +

Old term for {{Glossary("CORS-safelisted response header")}}.

diff --git a/files/ru/glossary/sloppy_mode/index.html b/files/ru/glossary/sloppy_mode/index.html new file mode 100644 index 0000000000..ae8eba54e3 --- /dev/null +++ b/files/ru/glossary/sloppy_mode/index.html @@ -0,0 +1,21 @@ +--- +title: Грязный режим +slug: Словарь/Sloppy_mode +tags: + - Glossary + - JavaScript + - Sloppy + - Глоссарий +translation_of: Glossary/Sloppy_mode +--- +

{{Glossary("ECMAScript")}} 5 и более поздние версии выполняют скрипты в Строгом режиме, который определенным образом изменяет семантику JavaScript для улучшения стабильности, и который упрощает понимание того, что происходит в программе при возникновении проблем.

+ +

Обычный, нестрогий, режим выполнения JavaScript иногда называется Грязным режимом (Sloppy mode). Это неофициальное название, но вы, вероятно, сталкивались с ним при серьёзной разработке на JavaScript.

+ +

См. также

+ +

Общие знания

+ + diff --git a/files/ru/glossary/specification/index.html b/files/ru/glossary/specification/index.html new file mode 100644 index 0000000000..5c1abe1dd5 --- /dev/null +++ b/files/ru/glossary/specification/index.html @@ -0,0 +1,23 @@ +--- +title: Спецификация +slug: Словарь/Specification +tags: + - Словарь + - Стандартизация +translation_of: Glossary/Specification +--- +

Спецификация - документ, детально описывающий функции и параметры, которые должен предоставлять продукт перед тем, как быть доставлен (опубликован). В случае описания Веба, термин "спецификация" (часто сокращают до "spec") в основном означает документ, описывающй язык, технологи или {{Glossary("API")}}, которые составляют целостный набор открытх Web технологий.

+ +

Узнайте больше

+ +

Основная информация

+ + + +

Technical reference

+ + diff --git a/files/ru/glossary/speculative_parsing/index.html b/files/ru/glossary/speculative_parsing/index.html new file mode 100644 index 0000000000..0b3418772f --- /dev/null +++ b/files/ru/glossary/speculative_parsing/index.html @@ -0,0 +1,33 @@ +--- +title: Оптимизация Ваших страниц для рискованного парсинга +slug: Web/HTML/Optimizing_Your_Pages_for_Speculative_Parsing +tags: + - HTML + - HTML5 + - Веб-разработка + - Продвинутый +translation_of: Glossary/speculative_parsing +--- +

Традиционно, HTML-парсер в браузерах работает на главной ветке и блокируется после тега </script>, пока скрипт не загрузится и не выполнится. HTML-парсер в Firefox 4 и новее поддерживает рискованный парсинг вне главной ветки. Он продолжает парсить, пока скрипты загружаются и выполняются. В Firefox 3.5 и 3.6 парсер начинает рискованную загрузку скриптов, стилей и изображений, когда он находит их. Однако, в Firefox 4 и новее HTML-парсер также рискованно загружает алгоритм постройки дерева HTML. С одной стороны, когда риск оправдался, нет необходимости в репарсинге части, которая уже была просканирована на скрипты, стили и изображения. С другой стороны, когда риск не оправдался, HTML-парсеру достаётся больше работы.

+ +

Эта статья поможет избежать некоторых проблем, которые замедляют загрузку страницы.

+ +

Делаем рискованную загрузку успешной

+ +

Есть только одно правило, чтобы сделать рискованную загрузку скриптов, стилей и изображений успешной:

+ + + +

Как избежать перестройки дерева страницы

+ +

Рискованное построение дерева терпит неудачу в случае, когда функция document.write() изменяет состояния построителя дерева так, что то рискованное состояние после тега </script> более не остаётся прежним после того, как весь контент, добавленный через document.write(), будет распарсен. Только несколько необычных применений document.write() вызывают эту проблему. Вот, чего необходимо избегать:

+ + diff --git a/files/ru/glossary/statement/index.html b/files/ru/glossary/statement/index.html new file mode 100644 index 0000000000..cd9163c964 --- /dev/null +++ b/files/ru/glossary/statement/index.html @@ -0,0 +1,27 @@ +--- +title: Инструкция +slug: Словарь/Выражение +tags: + - Глоссарий + - Инструкция + - Новичку +translation_of: Glossary/Statement +--- +

В компьютерном языке программирования инструкция — строка кода, выполняющая задачу. Каждая программа состоит из последовательности инструкций.

+ +

Узнать больше

+ +

Общие сведения

+ + + +

Техническая справка

+ + + + diff --git a/files/ru/glossary/static_typing/index.html b/files/ru/glossary/static_typing/index.html new file mode 100644 index 0000000000..f2336fb220 --- /dev/null +++ b/files/ru/glossary/static_typing/index.html @@ -0,0 +1,17 @@ +--- +title: Статическая типизация +slug: Словарь/Статическая_типизация +tags: + - Глоссарий + - Тип +translation_of: Glossary/Static_typing +--- +

Статически типизированный язык — это язык, где типы переменных известны во время компиляции (н-р {{glossary("Java", "Java")}}, C, C++). В большинстве таких языков типы переменных должны быть явно заданы разработчиком. В остальных статически типизированных языках вывод типов (type inference) позволяет не задавать их (н-р OCaml).

+ +

Узнать больше

+ +

Общая информация

+ + diff --git a/files/ru/glossary/string/index.html b/files/ru/glossary/string/index.html new file mode 100644 index 0000000000..43aa69f04a --- /dev/null +++ b/files/ru/glossary/string/index.html @@ -0,0 +1,20 @@ +--- +title: Строка +slug: Словарь/Строка +tags: + - Начальный + - Строка +translation_of: Glossary/String +--- +

В любом языке программирования компьютера, строка представляет собой последовательность {{Glossary("character","символов")}}, используемых для представления текста.

+ +

В {{Glossary("JavaScript")}}, String - это один из {{Glossary("Primitive", "примитивных типов")}} и {{jsxref("String")}} объект - это {{Glossary("wrapper")}} над примитивной строкой.

+ +

См. также

+ +

Общие сведения

+ + diff --git a/files/ru/glossary/svg/index.html b/files/ru/glossary/svg/index.html new file mode 100644 index 0000000000..1f4bd4ba6b --- /dev/null +++ b/files/ru/glossary/svg/index.html @@ -0,0 +1,41 @@ +--- +title: SVG +slug: Словарь/SVG +tags: + - SVG + - Глоссарий + - Графика + - Начинающий + - Программирование +translation_of: Glossary/SVG +--- +

Масштабируемая векторная графика ( SVG ) - это формат двумерного векторного изображения на основе синтаксиса {{Glossary("XML")}}.

+ +

{{Glossary("W3C")}} начал работу над SVG в конце 1990 - х годов, но SVG стал популярным, когда {{Glossary("Microsoft Internet Explorer", "Internet Explorer")}} 9 вышел с поддержкой SVG. Все основные, {{Glossary("browser","браузеры")}} теперь поддерживают SVG.

+ +

На основе синтаксиса {{Glossary("XML")}}, SVG можно стилизовать с помощью {{Glossary("CSS")}} и сделать интерактивным с использованием {{Glossary("JavaScript")}}. HTML5 теперь позволяет прямое встраивание {{Glossary("Tag","тегов")}} SVG в {{Glossary("HTML")}} документ.

+ +

В качестве формата векторного изображения графика SVG может масштабироваться бесконечно, делая их неоценимыми в адаптивном дизайне , поскольку вы можете создавать элементы интерфейса и графику, масштабируемые для любого размера экрана. SVG также предоставляет полезный набор инструментов, таких как обрезание, маскирование, фильтры и анимации.

+ +

 

+ +

См. также

+ +

Общая информация

+ + + +

Изучение SVG

+ + + +

Техническая документация

+ + diff --git a/files/ru/glossary/symbol/index.html b/files/ru/glossary/symbol/index.html new file mode 100644 index 0000000000..daa0202fd5 --- /dev/null +++ b/files/ru/glossary/symbol/index.html @@ -0,0 +1,24 @@ +--- +title: Symbol (Символ) +slug: Словарь/Symbol +translation_of: Glossary/Symbol +--- +

На этой странице описывается тип данных «символ» и функция «{{jsxref("Symbol")}}()», которая (среди прочего) создает экземпляры типа «символ».

+ +

Symbol​ (Символ) — примитивный тип данных, экземпляры которого уникальны и неизменяемы. В некоторых языках программирования символы также называются атомами.

+ +

В среде выполнения JavaScript значение «символа» создается путем вызова функции Symbol (), которая динамически создает анонимное и уникальное значение. Единственное разумное использование — сохранить символ, а затем использовать сохраненное значение для создания свойства объекта. Следующий пример хранит символ в «var».

+ +
var  myPrivateMethod  = Symbol();
+this[myPrivateMethod] = function() {...};
+ +

Когда символ используется как идентификатор в присваивании свойства, свойство (например, символ) является анонимным; а также не исчислимым. Поскольку свойство не исчислимо, оно не будет отображаться в цикле «for (... in ...)», и поскольку свойство является анонимным, оно не будет отображаться в массиве результатов "Object.getOwnPropertyNames ()". Доступ к этому свойству можно получить с помощью исходного значения символа, создавшего его, или путем итерирования в массиве результатов «Object.getOwnPropertySymbols ()». В предыдущем примере кода доступ к свойству будет осуществляться через значение, которое было сохранено в переменной myPrivateMethod.

+ +

Узнать больше

+ +

Общие сведения

+ + diff --git a/files/ru/glossary/synchronous/index.html b/files/ru/glossary/synchronous/index.html new file mode 100644 index 0000000000..f939717e05 --- /dev/null +++ b/files/ru/glossary/synchronous/index.html @@ -0,0 +1,23 @@ +--- +title: Синхронный +slug: Словарь/Синхронный +tags: + - Веб + - Веб механика + - Глоссарий +translation_of: Glossary/Synchronous +--- +

Синхронный относится к среде связи где каждый участник получает (и если нужно обрабатывает и/или отвечает) сообщения немедленно (или настолько быстро, на сколько это возможно).

+ +

Примером из жизни является телефон — во время телефонного разговора вы можете отвечать собеседнику незамедлительно.

+ +

Множество комманд так же синхронны — например когда вы вводите значения в поле при каком-либо вычислении, результат может быть мгновенно рассчитан и выведен в поле с результатом.

+ +

Больше информации

+ +

Техническая документация

+ + diff --git a/files/ru/glossary/tag/index.html b/files/ru/glossary/tag/index.html new file mode 100644 index 0000000000..f018fa052b --- /dev/null +++ b/files/ru/glossary/tag/index.html @@ -0,0 +1,28 @@ +--- +title: Тег +slug: Словарь/Тег +tags: + - HTML + - Вступление + - Словарь + - Тег +translation_of: Glossary/Tag +--- +

В {{Glossary("HTML")}} теги используются для создания {{Glossary("Элемент", "элементов")}}. Имя HTML элемента - это имя заключенное в угловые скобки, как например <p> для "абзаца". Обратите внимание, что концу имени предшествует символ косой черты (слэша), "</p>", и что в пустых элементах закрывающий тег не требуется и не допускается. Если атрибуты не указаны, то для них применяются значения по умолчанию. 

+ +

Узнать больше

+ +

Общие знания

+ + + +

Техническое руководство

+ + + +

 

diff --git a/files/ru/glossary/tcp/index.html b/files/ru/glossary/tcp/index.html new file mode 100644 index 0000000000..9576c824cc --- /dev/null +++ b/files/ru/glossary/tcp/index.html @@ -0,0 +1,23 @@ +--- +title: TCP +slug: Словарь/TCP +tags: + - TCP + - Transmission Control Protocol + - Протокол Управления Передачей + - Словарь + - инфраструктура +translation_of: Glossary/TCP +--- +

TCP (Протокол Управления Передачей) - важный {{Glossary("protocol", "протокол")}} сети интернет, который позволяет двум хостам создать соединение и обмениваться потоками данных. TCP гарантирует доставку данных и пакетов в том же порядке, в котором они были отправлены. Винт Серф и Боб Кан, которые в то время были учеными DARPA, разработали TCP в 1970-х годах.

+ +

Роль TCP заключается в обеспечении надёжной доставки пакетов без ошибок. TCP имеет контроль перегрузки, что означает, что первые пакеты начинаются с небольшого размера, увеличиваясь в размерах до уровней пропускной способности, которую могут поддерживать компьютеры, серверы и сеть.

+ +

Смотрите также

+ +

Общая информация

+ + diff --git a/files/ru/glossary/time_to_first_byte/index.html b/files/ru/glossary/time_to_first_byte/index.html new file mode 100644 index 0000000000..e7110fe8b6 --- /dev/null +++ b/files/ru/glossary/time_to_first_byte/index.html @@ -0,0 +1,18 @@ +--- +title: Time to first byte +slug: Словарь/time_to_first_byte +translation_of: Glossary/time_to_first_byte +--- +

Время до первого байта (англ. Time to First Byte, TTFB) - одна из метрик производительности веб-страниц, которая описывает время, которое прошло с момента отправления браузером запроса страницы до момента, когда он получил первый байт информации с сервера. Это время включает в себя поиск DNS-сервера и установление соединия с использованием TCP-рукопожатия и SSL-рукопожатия, если запрос выполняется через https.

+ +

TTFB - время между началом запроса и началом ответа в миллисекундах:

+ +
TTFB = responseStart - requestStart
+ +

См. также

+ + diff --git a/files/ru/glossary/time_to_interactive/index.html b/files/ru/glossary/time_to_interactive/index.html new file mode 100644 index 0000000000..8d89b8fc0d --- /dev/null +++ b/files/ru/glossary/time_to_interactive/index.html @@ -0,0 +1,20 @@ +--- +title: Time to interactive +slug: Словарь/Time_to_interactive +translation_of: Glossary/Time_to_interactive +--- +

Время до интерактивности (англ. Time to Interactive, TTI) - это нестандартизированная метрика веб-производительности, которая определяется как момент времени, когда завершилась последняя долгая задача, после которой следовало 5 секунд бездействия сети и основного потока.

+ +

TTI, предложенный WICG в 2018 году, был предназначен для предоставления показателя, описывающей состояние, когда страница или приложение содержит полезный контент, а основной поток простаивает и может свободно реагировать на взаимодействия с пользователем, включая регистрацию обработчиков событий.

+ +

Предостережение

+ +

TTI получается путем использования информации из {{domxref("Long Tasks API")}}. Несмотря на то, что TTI доступен в некоторых инструментах мониторинга производительности, на момент написания этой статьи он не является частью какой-либо официальной веб-спецификации.

+ +

См.также

+ + diff --git a/files/ru/glossary/tls/index.html b/files/ru/glossary/tls/index.html new file mode 100644 index 0000000000..a39a18bd66 --- /dev/null +++ b/files/ru/glossary/tls/index.html @@ -0,0 +1,24 @@ +--- +title: TLS +slug: Словарь/TLS +translation_of: Glossary/TLS +--- +

Transport Layer Security (TLS) - Безопасность Транспортного Уровня ({{Glossary("протокол")}}), ранее известный как Secure Sockets Layer (SSL) - Уровень Защищённых Соединений используется приложениями для организации защищённой передачи данных через интернет, предотвращая взлом и прослушивание электронной почты, просмотра сайтов, переписки и прочих протоколов.

+ +

Все современные браузеры поддерживают TLS протокол, требуя у сервера предоставить действующий "цифровой сертификат", подтверждающий подлинность в порядке обеспечения безопасного соединения. Это осуществляется для обоих - клиента и сервера, для обоюдной проверки подлинности каждого, если обе стороны обмена данных обеспечены их собственными цифровыми сертификатами.

+ +

 

+ +

General knowledge

+ + + +

Specifications

+ + diff --git a/files/ru/glossary/truthy/index.html b/files/ru/glossary/truthy/index.html new file mode 100644 index 0000000000..a99cf53cf9 --- /dev/null +++ b/files/ru/glossary/truthy/index.html @@ -0,0 +1,39 @@ +--- +title: Truthy +slug: Словарь/Truthy +tags: + - Glossary + - JavaScript + - truthy + - Словарь +translation_of: Glossary/Truthy +--- +

В {{Glossary("JavaScript")}}, истинное значение - это значение, которое считается true, когда встречается в контексте {{Glossary("Boolean")}}. Все значения истинные, если они не определены как {{Glossary("Falsy", "falsy")}} (кроме false, 0, -0, 0n, "", null, undefined, и NaN).

+ +

{{Glossary("JavaScript")}} использует {{Glossary("Type_coercion", "приведение типов")}} в Boolean контекстах.

+ +

Примеры истинных значений в JavaScript (которые будут приведены к true в булевых выражениях, и таким образом выполниться блок if):

+ +
if (true)
+if ({})
+if ([])
+if (42)
+if ("0")
+if (new Date())
+if (-42)
+if (12n)
+if (3.14)
+if (-3.14)
+if (Infinity)
+if (-Infinity)
+
+ +

Смотри также

+ + + +
{{QuickLinksWithSubpages("/en-US/docs/Glossary")}}
diff --git a/files/ru/glossary/type/index.html b/files/ru/glossary/type/index.html new file mode 100644 index 0000000000..0e596241d9 --- /dev/null +++ b/files/ru/glossary/type/index.html @@ -0,0 +1,23 @@ +--- +title: Type (тип) +slug: Словарь/Type +tags: + - Data Type + - Glossary + - JavaScript + - Type + - тип данных +translation_of: Glossary/Type +--- +

Тип является характеристикой {{glossary('value', 'значения')}}, влияющей на то, какой вид данных или структур оно может хранить — например, в JavaScript {{domxref("Boolean")}} содержит только значения true/false, тогда как {{domxref("String")}} содержит текстовые строки, а {{domxref("Number")}} содержит числа любого типа и т.д. При этом для Структурных типов мы в целом можем опираться на то, какой конструктор был использован для создания данной структуры.

+ +

Тип данных значения также влияет на то, какие операции допустимы для этого значения. Например, целое число может быть умножено на целое число, но не на строку. Это так же полезно знать для операций сравнения меду типами данных. В тоже время сравнение между структурными типами является отдельной весьма сложной задачей, так как даже несмотря на то, что структуры могут быть идентичны по типам данных и набору полей, в глубине своей Цепочки Прототипов они могут различаться.

+ +

Узнать больше

+ +

Общие сведения

+ + diff --git a/files/ru/glossary/type_coercion/index.html b/files/ru/glossary/type_coercion/index.html new file mode 100644 index 0000000000..d8a4add38c --- /dev/null +++ b/files/ru/glossary/type_coercion/index.html @@ -0,0 +1,44 @@ +--- +title: Type coercion +slug: Словарь/Type_coercion +tags: + - Beginner + - Glossary + - JavaScript + - Type coercion + - Начинающим + - приведение типа +translation_of: Glossary/Type_coercion +--- +

Приведение типов (type coercion) - это автоматическое или неявное преобразование значений из одного типа данных в другой (например, строки в число). {{Glossary('Type conversion', 'Преобразование типа')}} похоже на приведение типа, потому что они оба преобразуют значения из одного типа данных в другой с одним ключевым различием — приведение типа является неявным, тогда как преобразование типа может быть неявным или явным.

+ +

Примеры

+ +
const value1 = '5';
+const value2 = 9;
+let sum = value1 + value2;
+
+console.log(sum);
+ +

В приведённом выше примере JavaScript приводит число 9 в строку, а затем объединяет два значения вместе, в результате получается строка 59. JavaScript имел выбор между строкой или числом и решил использовать строку.

+ +

Компилятор мог привести строку 5 к числу и вернуть сумму 14, но он этого не сделал. Чтобы получить этот результат, вам нужно явно преобразовать строку 5 в число, используя метод {{jsxref("Global_Objects/Number", "Number()")}}:

+ +
sum = Number(value1) + value2;
+ + diff --git a/files/ru/glossary/type_conversion/index.html b/files/ru/glossary/type_conversion/index.html new file mode 100644 index 0000000000..534f66d01d --- /dev/null +++ b/files/ru/glossary/type_conversion/index.html @@ -0,0 +1,30 @@ +--- +title: Type conversion +slug: Словарь/Type_Conversion +tags: + - Beginner + - Glossary + - Type casting + - Type conversion + - Начинающим + - Преобразование типов +translation_of: Glossary/Type_Conversion +--- +

Преобразование типов (type conversion) означает передачу данных из одного типа данных в другой. Неявное преобразование происходит, когда компилятор автоматически присваивает (назначает) типы данных, но исходный код также может явно требовать преобразования для завершения. Например, в случае инструкции 5+2.0, число с плавающей точкой 2.0 неявно преобразуется в целое число, но в случае инструкции Number("0x11") строка "0x11" явно преобразуется в типизированное число 17.

+ + diff --git a/files/ru/glossary/ui/index.html b/files/ru/glossary/ui/index.html new file mode 100644 index 0000000000..eb16ea20c3 --- /dev/null +++ b/files/ru/glossary/ui/index.html @@ -0,0 +1,19 @@ +--- +title: UI +slug: Словарь/UI +tags: + - Дизайн + - Словарь + - доступность +translation_of: Glossary/UI +--- +

Пользовательский Интерфейс (UI) — это всё, что облегчает взаимодействие пользователя с компьютером. В мире компьютеров это может быть что угодно: клавиатура, джойстик, монитор, программа. Если мы рассматриваем компьютерное ПО - это ввод и вывод командной строки, веб-страница, форма ввода или интерфейс любого приложения.

+ +

Узнайте больше

+ +

Общие знания

+ + diff --git a/files/ru/glossary/undefined/index.html b/files/ru/glossary/undefined/index.html new file mode 100644 index 0000000000..c73dbb8ada --- /dev/null +++ b/files/ru/glossary/undefined/index.html @@ -0,0 +1,8 @@ +--- +title: undefined +slug: Словарь/undefined +translation_of: Glossary/undefined +--- +
+
{{Glossary("primitive", "Примитивное")}} значение. Автоматически присваивается переменным, которые были только объявлены или {{Glossary("Argument","аргументам")}}, для которых не были установлены значения.
+
diff --git a/files/ru/glossary/url/index.html b/files/ru/glossary/url/index.html new file mode 100644 index 0000000000..acaddff749 --- /dev/null +++ b/files/ru/glossary/url/index.html @@ -0,0 +1,30 @@ +--- +title: URL (Единый указатель ресурса) +slug: Словарь/URL +tags: + - URL + - Глоссарий + - Ссылки + - веб-адреса + - урлы +translation_of: Glossary/URL +--- +

Единый указатель ресурса (Uniform Resource Locator, URL) — строка, однозначно определяющая, где в интернете находится ресурс.

+ +

В контексте {{Glossary("HTTP")}}, URL называют "адрес" (web address)" или "ссылку" (link). В браузере URL отображается в адресной строке , например,  https://developer.mozilla.org.

+ +

Кроме того, URL используют при передаче файлов через {{Glossary("FTP")}} , в электронной почте через ({{Glossary("SMTP")}}) и других местах.

+ +

См. также

+ +

Основная информация

+ + + +

Узнайте об этом

+ + diff --git a/files/ru/glossary/user_agent/index.html b/files/ru/glossary/user_agent/index.html new file mode 100644 index 0000000000..d0b87d42eb --- /dev/null +++ b/files/ru/glossary/user_agent/index.html @@ -0,0 +1,28 @@ +--- +title: Агент пользователя +slug: Словарь/User_agent +translation_of: Glossary/User_agent +--- +

Пользовательский агент (user agent, UA), или агент пользователя, это компьютерная программа, представляющая пользователя и выполняющая действия от его лица, например, {{Glossary("Browser","браузер")}} в контексте {{Glossary("World Wide Web", "Всемирной паутины")}}.

+ +

Агентом пользователя может быть не только браузер, но и бот, удаляющий веб-страницы, менеджер закачек или другое приложение, использующее Веб. Выполняя запросы к серверу, браузеры, чтобы была возможность их идентифицировать, снабжают каждый запрос так называемой строкой пользовательского агента (UA-строкой), завернутой в {{Glossary("HTTP")}}-заголовок User-Agent. Это строка идентифицирует браузер, сообщает номер его версии и информацию об операционной системе.

+ +

Спам-боты, менеджеры закачек и некоторые браузеры нередко шлют подложные UA-строки, чтобы выдать себя за другие клиенты. Эта ситуация известна под названием подмена или подделка пользовательского агента (user agent spoofing).

+ +

Строчку пользовательского агента можно прочитать на стороне клиента с помощью {{Glossary("JavaScript")}}, обратившись к свойству navigator.userAgent.

+ +

Типичная UA-строка выглядит так: "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:35.0) Gecko/20100101 Firefox/35.0"

+ +

Смотрите также

+ +

Общие сведения

+ + + +

Техническая справка

+ + diff --git a/files/ru/glossary/variable/index.html b/files/ru/glossary/variable/index.html new file mode 100644 index 0000000000..8afe021e2d --- /dev/null +++ b/files/ru/glossary/variable/index.html @@ -0,0 +1,14 @@ +--- +title: Переменная +slug: Словарь/Variable +tags: + - Словарь +translation_of: Glossary/Variable +--- +

Переменная — именованная часть памяти, в которую могут помещаться разные значения переменной. Причем в каждый момент времени переменная имеет единственное значение.

+ +

Подробнее:

+ + diff --git a/files/ru/glossary/vendor_prefix/index.html b/files/ru/glossary/vendor_prefix/index.html new file mode 100644 index 0000000000..b9d0c149ba --- /dev/null +++ b/files/ru/glossary/vendor_prefix/index.html @@ -0,0 +1,75 @@ +--- +title: Vendor Prefix +slug: Словарь/Vendor_Prefix +translation_of: Glossary/Vendor_Prefix +--- +

Browser vendors sometimes add prefixes to experimental or nonstandard CSS properties and JavaScript APIs, so developers can experiment with new ideas while—in theory—preventing their experiments from being relied upon and then breaking web developers' code during the standardization process. Developers should wait to include the unprefixed property until browser behavior is standardized.

+ +
+

Browser vendors are working to stop using vendor prefixes for experimental features. Web developers have been using them on production Web sites, despite their experimental nature. This has made it more difficult for browser vendors to ensure compatibility and to work on new features; it's also been harmful to smaller browsers who wind up forced to add other browsers' prefixes in order to load popular web sites.

+ +

Lately, the trend is to add experimental features behind user-controlled flags or preferences, and to create smaller specifications which can reach a stable state much more quickly.

+
+ +

CSS prefixes

+ +

The major browsers use the following prefixes:

+ + + +

Sample usage:

+ +
-webkit-transition: all 4s ease;
+-moz-transition: all 4s ease;
+-ms-transition: all 4s ease;
+-o-transition: all 4s ease;
+transition: all 4s ease; 
+ +

API prefixes

+ +

Historically, vendors have also used prefixes for experimental APIs. If an entire interface is experimental, then the interface's name is prefixed (but not the properties or methods within). If an experimental property or method is added to a standardized interface, then the individual method or property is prefixed.

+ +

Interface prefixes

+ +

Prefixes for interface names are upper-cased:

+ + + +

Property and method prefixes

+ +

The prefixes for properties and methods are lower-case:

+ + + +

Sample usage:

+ +
var requestAnimationFrame = window.requestAnimationFrame ||
+                            window.mozRequestAnimationFrame ||
+                            window.webkitRequestAnimationFrame ||
+                            window.oRequestAnimationFrame ||
+                            window.msRequestAnimationFrame;
+ +

Learn more

+ +

General knowledge

+ + + +
{{QuickLinksWithSubpages("/en-US/docs/Glossary")}}
diff --git a/files/ru/glossary/viewport/index.html b/files/ru/glossary/viewport/index.html new file mode 100644 index 0000000000..075b8fbf69 --- /dev/null +++ b/files/ru/glossary/viewport/index.html @@ -0,0 +1,110 @@ +--- +title: Viewport +slug: Словарь/Viewport +translation_of: Glossary/Viewport +--- +

Viewport - это видимая пользователю область веб-страницы, то, что может увидеть пользователь, не прибегая к прокрутке.

+ +

Окно просмотра представляет собой многоугольную (обычно прямоугольную) область в компьютерной графике, которая в настоящее время просматривается. В терминах веб-браузера это относится к той части просматриваемого документа, которая в данный момент отображается в ее окне (или на экране, если документ просматривается в полноэкранном режиме).
+ Содержимое вне окна просмотра не отображается на экране до тех пор, пока оно не будет просмотрено.

+ + + +

Meta-тег viewport сообщает браузеру о том, как именно обрабатывать размеры страницы, и изменять её масштаб. Этот тег необходимо добавлять в секцию HEAD.

+ + + +

Пример:

+ +
<meta name="viewport" content="width=device-width, initial-scale=1">
+ +

Атрибуты метатега viewport

+ +

Meta-тег viewport может иметь следующие атрибуты, указанные через запятую (,):

+ +

width – ширина области просмотра.

+ +

Значением атрибута является целое неотрицательное число от 200 до 10000 пикселей или константа device-width, которая задаёт ширину страницы в соответствии с размером экрана.

+ +

Если значение не задано, по умолчанию устанавливается – в мобильном Safari = 980px, Opera = 850px, Android WebKit = 800px, IE = 974px.

+ +
Примечание: для сайтов с адаптивным дизайном рекомендуется использовать: width=device-width.
+ +

height – высота области просмотра.

+ +

Значением атрибута является целое неотрицательное число от 233 до 10000 пикселей или константа device-height, которая задаёт высоту страницы в соответствии с размером экрана.

+ +
Примечание: если указан атрибут width, указывать атрибут height не обязательно.
+ +

initial-scale – начальный масштаб страницы.

+ +

Значением атрибута является вещественное число от 0.1 до 1.0. Значение 1.0 определяет масштаб 1:1, т.е. «не масштабировать».

+ +
+

Примечание: в некоторых операционных системах (iOS, Windows Phone и т.д.) ширина страницы, при повороте, остаётся неизменной. Вместо перераспределения контента выполняется его масштабирование. Поэтому рекомендуется использовать: initial-scale=1.0.

+
+ +

user-scalable – доступность масштабирования страницы пользователем.

+ +

Значение атрибута является логическое «yes» (1) – можно масштабировать или «no» (0)– нельзя масштабировать.

+ +
Примечание: рекомендуется использовать значение «yes» , а т.к. оно установлено по умолчанию, то user-scalable можно и не указывать.
+ +

minimum-scale – минимальный масштаб области просмотра.

+ +

Значением атрибута является вещественное число от 0.1 до 1.0. В мобильном браузере Safari по умолчанию 0.25. Значение 1.0 определяет масштаб 1:1, т.е. «не масштабировать».

+ +

maximum-scale – максимальный масштаб области просмотра.

+ +

Значением атрибута является вещественное число от 0.1 до 1.0 . В мобильном браузере Safari по умолчанию 1.6. Значение 1.0 определяет масштаб 1:1, т.е. «не масштабировать».

+ +
Примечание: избегайте атрибутов user-scalableminimum-scale и maximum-scale, т.к. они отрицательно сказываются на доступности содержания.
+ + + + + +

Дополнительные и полезные метатеги

+ +

Meta-тег HandheldFriendly определяет оптимизирована ли страница сайта под мобильные устройства на Palm и Blackberry, в таком браузере как AvantGo. Сейчас распознаётся и многими другими мобильными браузерами.

+ +

Пример:

+ +
<meta name="HandheldFriendly" content="true">
+ +

Meta-тег MobileOptimized (http://goo.gl/ZpLjZz) задаёт ширину области просмотра в мобильных браузеров IE Mobile или Pocket IE. Является аналогом атрибута width в meta-теге viewport.

+ +

Пример:

+ +
<!-- фиксированная ширина в 320 пикселей -->
+<meta name="MobileOptimized" content="320">
+<!-- ширина страницы в соответствии с размером экрана, аналог device-width -->
+<meta name="MobileOptimized" content="width">
+ +

Meta-тег apple-mobile-web-app-capable (http://goo.gl/VGDYQC) позволяет странице работать в полноэкранном режиме, актуален для мобильных устройств Apple.

+ +

Пример:

+ +
<meta name="apple-mobile-web-app-capable" content="yes">
+ +

Рекомендованный набор метатегов

+ +

Используемый мной набор meta-тегов для сайтов с адаптивным дизайном, заточенным под мобильные устройства:

+ +
<meta name='viewport' content='width=device-width,initial-scale=1'/>
+<meta content='true' name='HandheldFriendly'/>
+<meta content='width' name='MobileOptimized'/>
+<meta content='yes' name='apple-mobile-web-app-capable'/>
+ +

Читать больше

+ +

General Knowledge

+ + diff --git a/files/ru/glossary/w3c/index.html b/files/ru/glossary/w3c/index.html new file mode 100644 index 0000000000..6c8de54e86 --- /dev/null +++ b/files/ru/glossary/w3c/index.html @@ -0,0 +1,26 @@ +--- +title: W3C +slug: Словарь/W3C +tags: + - W3C + - Введение + - Веб консорциум + - Консорциум + - Словарь + - Сообщество +translation_of: Glossary/W3C +--- +

The World Wide Web Consortium (W3C) is an international body that maintains {{Glossary("World Wide Web", "Web-related")}} rules and frameworks.

+ +

W3C объединяет более 350 организаций-участников, присоединившихся для разработки стандартов Веба, run outreach programs, and maintain an open forum for talking about the Web. W3C координирует компании в инстрии, чтобы быть уверенными в едином понимании W3C стандартов.

+ +

Каждый стандарт проиходит чере 4 этапа of maturity: Working Draft (WD), Candidate Recommendation (CR), Proposed Recommendation (PR), and W3C Recommendation (REC).

+ +

Узнайте больше

+ +

Основная информация

+ + diff --git a/files/ru/glossary/wai/index.html b/files/ru/glossary/wai/index.html new file mode 100644 index 0000000000..6c9ed57dda --- /dev/null +++ b/files/ru/glossary/wai/index.html @@ -0,0 +1,15 @@ +--- +title: WAI +slug: Словарь/WAI +translation_of: Glossary/WAI +--- +

WAI или Web Accessibility Initiative (англ. Инициатива доступности веб-сайтов)  это попытка Консорциума World Wide Web (W3C) улучшить доступность для людей с различными проблемами, которым могут понадобиться нестандартные {{glossary ("browser", "браузер")}} или устройства.

+ +

Узнай больше

+ +

Базовые знания

+ + diff --git a/files/ru/glossary/webkit/index.html b/files/ru/glossary/webkit/index.html new file mode 100644 index 0000000000..cbe8ed17d7 --- /dev/null +++ b/files/ru/glossary/webkit/index.html @@ -0,0 +1,24 @@ +--- +title: WebKit +slug: Словарь/WebKit +translation_of: Glossary/WebKit +--- +

WebKit это framework который показывает правильно отформатированные веб-страницы на основе их разметки. {{Glossary("Apple Safari")}} и большинство мобильных браузеров зависят от Webkit (Webkit это очень портативный и легко настраиваемый framework).

+ +

WebKit начал жизнь как разветвление библеотек KDE's KHTML and KJS , и с тех пор много частных лиц и компаний внесли свой вклад в его развитие (включая : KDE, Apple, Google, и Nokia).

+ +

WebKit это торговая марка Apple, который распространяется под лицензией BSD-form. Однако , 2 важные составляющие попадают под лицензию {{Glossary("LGPL")}}: это WebCore - визуальная библиотека и движок JavaScriptCore.

+ +

Читайте также

+ +

Весь материал

+ + + +

Технический справочник

+ + diff --git a/files/ru/glossary/websockets/index.html b/files/ru/glossary/websockets/index.html new file mode 100644 index 0000000000..e3dff1b176 --- /dev/null +++ b/files/ru/glossary/websockets/index.html @@ -0,0 +1,35 @@ +--- +title: WebSockets +slug: Словарь/WebSockets +tags: + - Web + - WebSocket + - Протоколы + - Словарь + - инфраструктура +translation_of: Glossary/WebSockets +--- +

WebSocket - это {{Glossary("protocol", "протокол")}}, который позволяет создать постоянное {{Glossary("TCP")}} соединение между сервером и клиентом, чтобы они могли обмениваться данными в любое время.

+ +

Любые приложения могут использовать WebSocket, но обычно подразумевается {{Glossary("Browser", "браузер")}} и веб-сервер. При использовании WebSocket сервер может передать данные клиенту без запроса от последнего, что позволяет реализовать динамическое обновление содержимого.

+ +

Узнать больше

+ +

Общие сведения

+ + + +

Техническая справка

+ + + +

Примеры использования

+ + diff --git a/files/ru/glossary/whatwg/index.html b/files/ru/glossary/whatwg/index.html new file mode 100644 index 0000000000..8a062129fe --- /dev/null +++ b/files/ru/glossary/whatwg/index.html @@ -0,0 +1,26 @@ +--- +title: WHATWG +slug: Словарь/WHATWG +tags: + - Community + - DOM + - HTML + - HTML5 + - WHATWG + - Web + - Веб + - Глоссарий + - Сообщество + - Стандарты +translation_of: Glossary/WHATWG +--- +

WHATWG (Рабочая группа по вебу, гипертексту, приложениям и технологиям) (англ. Web Hypertext Application Technology Working Group) сообщество, которое поддерживает и разрабатывает веб стандарты, включая {{Glossary("DOM")}}, Fetch и {{Glossary("HTML")}}. Сотрудники Apple, Mozilla и Opera основали WHATWG в 2004.

+ +

Узнать больше

+ +

Общие знания

+ + diff --git a/files/ru/glossary/whitespace/index.html b/files/ru/glossary/whitespace/index.html new file mode 100644 index 0000000000..737429d465 --- /dev/null +++ b/files/ru/glossary/whitespace/index.html @@ -0,0 +1,36 @@ +--- +title: Пробельные символы +slug: Словарь/Пробельные_символы +translation_of: Glossary/Whitespace +--- +

Пробельные символы — это множество {{Glossary("Character", "символов")}}  использующихся для горизонтального или вертикалного разделения остальных символов. Они используются для разделения токенов в {{Glossary("HTML")}}, {{Glossary("CSS")}}, {{Glossary("JavaScript")}} и других компьютерных языках.

+ +

В HTML

+ +

Текущий стандарт HTML описывает как пробельные 5 символов из таблицы ASCII: U+0009 TAB, U+000A LF, U+000C FF, U+000D CR и U+0020 SPACE. В тексте они будут отображены как обычные пробелы, а последовательность пробельных символов, в большинстве случаев, будет схлопнута в один пробел (это поведение можно изменить CSS-свойством {{cssxref("white-space")}}). Они могут быть использованы как разделители между названием элемента и его атрибутами, между названиями классов и т. д.

+ + diff --git a/files/ru/glossary/world_wide_web/index.html b/files/ru/glossary/world_wide_web/index.html new file mode 100644 index 0000000000..14d223cd89 --- /dev/null +++ b/files/ru/glossary/world_wide_web/index.html @@ -0,0 +1,40 @@ +--- +title: World Wide Web +slug: Словарь/World_Wide_Web +tags: + - WWW + - World Wide Web + - инфраструктура +translation_of: Glossary/World_Wide_Web +--- +

Всемирная сеть — сокращенно: WWW, W3, или Web; Сетьпаутина или веб — всемирная система публичных веб-страниц в сети {{Glossary("Интернет")}}. Сеть не является Интернетом: Сеть лишь использует Интернет как среду передачи информации и данных.

+ +

Тим Бернерз-Ли предложил архитектуру, которая стала известна под названием World Wide Web. В 1990 году в ЦЕРН (в своей лаборатории физ. исследований) он создал первый веб-{{Glossary("Server","сервер")}},  {{Glossary("Browser","браузер")}} и веб-страницу на своем компьютере. В 1991 году он обьявил про свое творение в группе новостей alt.hypertext, тем самым, обозначив момент, когда Web стал достоянием общества.

+ +

Система, которую мы называем Web состоит из нескольких компонентов:

+ + + +

Связь страниц с помощью {{Glossary("Hyperlink","гиперссылок")}} является главной концепцией Web.

+ +

Незадолго после создания Web, Тим Бернерз-Ли основал {{Glossary("W3C")}} (World Wide Web Consortium) для стандартизации и последующего развития интернета. Этот консорциум состоит из: разработчиков браузеров, гос. учереждения, исследователи и университеты. Его цель - образование и распространение.

+ +

Узнать больше

+ +

Обучение

+ + + +

Общие ведомости

+ + diff --git a/files/ru/glossary/wrapper/index.html b/files/ru/glossary/wrapper/index.html new file mode 100644 index 0000000000..b5d33ac99c --- /dev/null +++ b/files/ru/glossary/wrapper/index.html @@ -0,0 +1,16 @@ +--- +title: Обертка +slug: Словарь/Wrapper +tags: + - CodingScripting + - Glossary + - Wrapper +translation_of: Glossary/Wrapper +--- +

В языках программирования, таких как JavaScript , обертка является функцией, которая предназначена для вызова одного или более других функций , иногда исключительно для удобства , а иногда адаптируя их чтобы сделать немного отличающийся задачу в процессе.

+ +

Узнать больше

+ +

Общие знания

+ +

{{Interwiki("wikipedia", " Wrapper function")}} в Википедии

diff --git a/files/ru/glossary/xhr_(xmlhttprequest)/index.html b/files/ru/glossary/xhr_(xmlhttprequest)/index.html new file mode 100644 index 0000000000..1fda8a238a --- /dev/null +++ b/files/ru/glossary/xhr_(xmlhttprequest)/index.html @@ -0,0 +1,23 @@ +--- +title: XHR (XMLHttpRequest) +slug: Словарь/XHR_(XMLHttpRequest) +translation_of: Glossary/XHR_(XMLHttpRequest) +--- +

{{domxref("XMLHttpRequest")}} (XHR) это {{Glossary("JavaScript")}} {{Glossary("API")}} для создания {{Glossary("AJAX")}} запросов. Методы этого объекта предоставляют возможность отправки сетевых запросов между {{Glossary("browser")}} и {{Glossary("server")}}.

+ +

Узнать больше

+ +

Общие знания

+ + + +

Техническая информация

+ + diff --git a/files/ru/glossary/xhtml/index.html b/files/ru/glossary/xhtml/index.html new file mode 100644 index 0000000000..ced26ea14b --- /dev/null +++ b/files/ru/glossary/xhtml/index.html @@ -0,0 +1,32 @@ +--- +title: XHTML +slug: Словарь/XHTML +translation_of: Glossary/XHTML +--- +

XHTML по отношению к XML - это так же, как HTML по отношению к SGML. Таким образом, XHTML - язык разметки который подобен HTML, но с более строгим синтаксисом. Две версии XHTML были закончены (окончательно сформулированы) W3C:

+ +

Третья версия, XHTML 2 - содержит существенные изменения словаря элементов (has significant changes to the element vocabulary).

+

Для получения дополнительной информации о XHTML, см.:

+ + +

Смотри также

+
+ Edit section
+ diff --git a/files/ru/glossary/xml/index.html b/files/ru/glossary/xml/index.html new file mode 100644 index 0000000000..14568728d3 --- /dev/null +++ b/files/ru/glossary/xml/index.html @@ -0,0 +1,17 @@ +--- +title: XML +slug: Словарь/XML +tags: + - Glossary + - XML +translation_of: Glossary/XML +--- +

eXtensible Markup Language (XML) - расширяемый язык разметки, рекомендованный Консорциумом Всемирной паутины (W3C). В отрасли информационных технологий (ИТ) используется множество языков на основе XML в качестве языков описания данных.

+ +

Тэги XML напоминают тэги HTML, но XML гораздо более гибкий, поскольку он позволяет пользователям определять свои собственные тэги. Таким образом, XML действует как мета-язык, то есть его можно применить для определения других языков, например {{Glossary("RSS")}}. Кроме того, HTML является языком презентации, тогда как XML является языком описания данных. Это означает, что XML имеет гораздо более широкое применение, чем просто веб-интерфейс. Например, веб-службы могут использовать XML для обмена запросами и ответами. 

+ +

Узнать больше

+ + diff --git a/files/ru/html/html5/constraint_validation/index.html b/files/ru/html/html5/constraint_validation/index.html deleted file mode 100644 index 5a5fccec8c..0000000000 --- a/files/ru/html/html5/constraint_validation/index.html +++ /dev/null @@ -1,343 +0,0 @@ ---- -title: Constraint validation -slug: HTML/HTML5/Constraint_validation -tags: - - Селекторы -translation_of: Web/Guide/HTML/HTML5/Constraint_validation ---- -

Создание веб форм всегда было комплексной задачей. В то время как сама по себе разметка формы - задача не сложная, проверка каждого поля на валидность - сложнее, а информирование юзера о проблеме - может стать головной болью. Стандарт HTML5 предоставил новые механизмы для форм: были добавлены новые семантические типы для элемента {{ HTMLElement("input") }} и обязательная валидация, чтобы облегчить работу по проверке содержимого формы на стороне браузера. Проще говоря, обычная проверка может быть выполнена без JavaScript, простой установкой новых аттрибутов; более сложные ограничения могут быть реализованы через HTML5 Constraint Validation API.

- -
Внимание: HTML5 Constraint validation не отменяет валидацию на стороне сервера. Несмотря на то что на сервер будет отправляться меньше запросов с невалидными данными, такие запросы всё ещё могут быть отправлены менее "сговорчивыми" браузерами (например, браузерами без поддержки HTML5 и без JavaScript) или плохими парнями, пытающимися взломать ваше веб-приложение. Следовательно, как и в случае с HTML4, вам всё ещё нужно проверять ввод на стороне сервера, таким образом, чтобы это было согласовано с валидацией на стороне клиента.
- -

Внутренние и базовые ограничения

- -

В HTML5, базовые ограничения описываются двумя способами:

- - - -

Семантические типы input-ов

- -

Аттрибуты, присущие элементам {{ htmlattrxref("type", "input") }}:

- - - - - - - - - - - - - - - - - - - - - -
Input typeОпределение ограниченияСвязанное с этим нарушение
<input type="URL">Значение должно быть абсолютным URL, одним из: -
    -
  • валидным URI (как описано в RFC 3986)
  • -
  • валидным IRI, без query сомпонента (как описано в RFC 3987)
  • -
  • валидным IRI, без query сомпонента и без неэкранированных не-ASCII символов (как описано в RFC 3987)
  • -
  • валидным IRI, при условии, что кодировка документа UTF-8 или UTF-16 (как описано в RFC 3987)
  • -
-
Type mismatch constraint violation
 <input type="email">Значение должно следовать ABNF: 1*( atext / "." ) "@" ldh-str 1*( "." ldh-str ) где: -
    -
  • atext (описан в RFC 5322) - US-ASCII символ (A to Z and a-z), цифра (от 0 до 9) или один из следующих: 
    - ! # $ % & ' * + - / = ? ` { } | ~ специальных символов,
  • -
  • ldh-str (описан в RFC 1034) - US-ASCII символы, цифры и "-", сгруппированы по словам и разделённые точкой (.).
  • -
- -
Внимание: если установлен аттрибут {{ htmlattrxref("multiple", "input") }}, в поле могут быть вписаны несколько e-mail адресов, разделённых запятыми. Если любое из этих условий не выполнено, будет вызвано Type mismatch constraint violation.
-
Type mismatch constraint violation
- -

Следует учесть, что большинство типов input не имеют "нативных" ограничений, а некоторые из них просто лишены валидации или имеют автоматическую корректировку невалидных значений по умолчанию. 

- -

Аттрибуты валидации

- -

Ниже перечислены аттрибуты, которые описывают базовые ограничения:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
АттрибутТипы input с поддержкой аттрибутаВозможные значенияОписание ограниченияСвязанное нарушение
{{ htmlattrxref("pattern", "input") }}text, search, url, tel, email, passwordРегулярное выражение JavaScript (по стандарту ECMAScript 5, флаги global, ignoreCase, и multiline отключены)Значение должно подходить под паттернPattern mismatch constraint violation
{{ htmlattrxref("min", "input") }}range, numberВалидное числоЗначение поля должно быть больше или равно значению аттрибутаUnderflow constraint violation
date, month, weekВалидная дата
datetime, datetime-local, timeВалидная дата и время
{{ htmlattrxref("max", "input") }}range, numberВалидное числоЗначение поля должно быть меньше или равно значению аттрибутаOverflow constraint violation
date, month, weekВалидная дата
datetime, datetime-local, timeВалидная дата и время
{{ htmlattrxref("required", "input") }}text, search, url, tel, email, password, date, datetime, datetime-local, month, week, time, number, checkbox, radio, file; also on the {{ HTMLElement("select") }} and {{ HTMLElement("textarea") }} elementsникакое так как это Boolean аттрибут: его присутствие означает true, а отсутствие - falseЗначение должно быть не пустым (если установлено).Missing constraint violation
{{ htmlattrxref("step", "input") }}dateЦелое число днейПока в аттрибут step не установлен любой литерал, значение может быть min + любое число, крастное шагу.Step mismatch constraint violation
monthЦелое число месяцев
weekЦелое число недель
datetime, datetime-local, timeЦелое число секунд
range, numberЦелое число
{{ htmlattrxref("maxlength", "input") }}text, search, url, tel, email, password; также на элементе {{ HTMLElement("textarea") }}Длина (целое число)Количество символов (знаков) не должно превышать значение аттрибута.Too long constraint violation
- -

Процесс валидации ограничений

- -

Constraint validation is done through the Constraint Validation API either on a single form element or at the form level, on the {{ HTMLElement("form") }} element itself. The constraint validation is done in the following ways:

- - - -
Note: - -
    -
  • If the {{ htmlattrxref("novalidate", "form") }} attribute is set on the {{ HTMLElement("form") }} element, interactive validation of the constraints doesn't happen.
  • -
  • Calling the send() method on the HTMLFormElement interface doesn't trigger a constraint validation. In other words, this method sends the form data to the server even if doesn't satisfy the constraints.
  • -
-
- -

Complex constraints using HTML5 Constraint API

- -

Using JavaScript and the Constraint API, it is possible to implement more complex constraints, for example, constraints combining several fields, or constraints involving complex calculations.

- -

Basically, the idea is to trigger JavaScript on some form field event (like onchange) to calculate whether the constraint is violated, and then to use the method field.setCustomValidity() to set the result of the validation: an empty string means the constraint is satisfied, and any other string means there is an error and this string is the error message to display to the user.

- -

Constraint combining several fields: Postal code validation

- -

The postal code format varies from one country to another. Not only do most countries allow an optional prefix with the country code (like D- in Germany, F- in France or Switzerland), but some countries have postal codes with only a fixed number of digits; others, like the UK, have more complex structures, allowing letters at some specific positions.

- -
-

Note: This is not a comprehensive postal code validation library, but rather a demonstration of the key concepts. 

-
- -

As an example, we will add a script checking the constraint validation for this simple form:

- -
<form>
-    <label for="ZIP">ZIP : </label>
-    <input type="text" id="ZIP">
-    <label for="Country">Country : </label>
-    <select id="Country">
-      <option value="ch">Switzerland</option>
-      <option value="fr">France</option>
-      <option value="de">Germany</option>
-      <option value="nl">The Netherlands</option>
-    </select>
-    <input type="submit" value="Validate">
-</form>
- -

This displays the following form: 

- -

- -

First, we write a function checking the constraint itself:

- -
function checkZIP() {
-  // For each country, defines the pattern that the ZIP has to follow
-  var constraints = {
-    ch : [ '^(CH-)?\\d{4}$', "Switzerland ZIPs must have exactly 4 digits: e.g. CH-1950 or 1950" ],
-    fr : [ '^(F-)?\\d{5}$' , "France ZIPs must have exactly 5 digits: e.g. F-75012 or 75012" ],
-    de : [ '^(D-)?\\d{5}$' , "Germany ZIPs must have exactly 5 digits: e.g. D-12345 or 12345" ],
-    nl : [ '^(NL-)?\\d{4}\\s*([A-RT-Z][A-Z]|S[BCE-RT-Z])$',
-                    "Nederland ZIPs must have exactly 4 digits, followed by 2 letters except SA, SD and SS" ]
-  };
-
-  // Read the country id
-  var country = document.getElementById("Country").value;
-
-  // Get the NPA field
-  var ZIPField = document.getElementById("ZIP");
-
-  // Build the constraint checker
-  var constraint = new RegExp(constraints[country][0], "");
-    console.log(constraint);
-
-
-  // Check it!
-  if (constraint.test(ZIPField.value)) {
-    // The ZIP follows the constraint, we use the ConstraintAPI to tell it
-    ZIPField.setCustomValidity("");
-  }
-  else {
-    // The ZIP doesn't follow the constraint, we use the ConstraintAPI to
-    // give a message about the format required for this country
-    ZIPField.setCustomValidity(constraints[country][1]);
-  }
-}
-
- -

Then we link it to the onchange event for the {{ HTMLElement("select") }} and the oninput event for the {{ HTMLElement("input") }}:

- -
window.onload = function () {
-    document.getElementById("Country").onchange = checkZIP;
-    document.getElementById("ZIP").oninput = checkZIP;
-}
- -

You can see a live example of the postal code validation.  

- -

Limiting the size of a file before its upload

- -

Another common constraint is to limit the size of a file to be uploaded. Checking this on the client side before the file is transmitted to the server requires combining the Constraint API, and especially the field.setCustomValidity() method, with another JavaScript API, here the HTML5 File API.

- -

Here is the HTML part:

- -
<label for="FS">Select a file smaller than 75 kB : </label>
-<input type="file" id="FS">
- -

This displays:

- -

- -

 

- -

The JavaScript reads the file selected, uses the File.size() method to get its size, compares it to the (hard coded) limit, and calls the Constraint API to inform the browser if there is a violation:

- -
function checkFileSize() {
-  var FS = document.getElementById("FS");
-  var files = FS.files;
-
-  // If there is (at least) one file selected
-  if (files.length > 0) {
-     if (files[0].size > 75 * 1024) { // Check the constraint
-       FS.setCustomValidity("The selected file must not be larger than 75 kB");
-       return;
-     }
-  }
-  // No custom constraint violation
-  FS.setCustomValidity("");
-}
- -

 

- -

Finally we hook the method with the correct event:

- -
window.onload = function () {
-  document.getElementById("FS").onchange = checkFileSize;
-}
- -

You can see a live example of the File size constraint validation.

- -

Visual styling of constraint validation

- -

Apart from setting constraints, web developers want to control what messages are displayed to the users and how they are styled.

- -

Controlling the look of elements

- -

The look of elements can be controlled via CSS pseudo-classes.

- -

:required and :optional CSS pseudo-classes

- -

The :required and :optional pseudo-classes allow writing selectors that match form elements that have the {{ htmlattrxref("required") }} attribute, or that don't have it.

- - -

:-moz-placeholder CSS pseudo-class

- -

See :-moz-placeholder.

- -

:valid :invalid CSS pseudo-classes

- -

The :valid and :invalid pseudo-classes are used to represent <input> elements whose content validates and fails to validate respectively according to the input's type setting. These classes allow the user to style valid or invalid form elements to make it easier to identify elements that are either formatted correctly or incorrectly.

- -

Default styles

- -

Controlling the text of constraints violation

- -

The x-moz-errormessage attribute

- -

The x-moz-errormessage attribute is a Mozilla extension that allows you to specify the error message to display when a field does not successfully validate.

- -
-

Note: This extension is non-standard.

-
- -

Constraint API's element.setCustomValidity()

- -

The element.setCustomValidity(error) method is used to set a custom error message to be displayed when a form is submitted. The method works by taking a string parameter error. If error is a non-empty string, the method assumes validation was unsuccessful and displays error as an error message. If error is an empty string, the element is considered validated and resets the error message.

- -

Constraint API's ValidityState object

- -

The DOM ValidityState interface represents the validity states that an element can be in, with respect to constraint validation. Together, they help explain why an element's value fails to validate, if it's not valid.

- -

Examples of personalized styling

- -

HTML4 fallback

- -

Trivial fallback

- -

JS fallback

- -

Conclusion

diff --git a/files/ru/html/html5/index.html b/files/ru/html/html5/index.html deleted file mode 100644 index dca2e39993..0000000000 --- a/files/ru/html/html5/index.html +++ /dev/null @@ -1,171 +0,0 @@ ---- -title: HTML5 -slug: HTML/HTML5 -tags: - - HTML5 -translation_of: Web/Guide/HTML/HTML5 ---- -

HTML5 — последняя версия стандарта HTML. Термин имеет два определения:

- - - -

Эта страница создана в помощь всем разработчикам Open Web и ссылается на множество материалов, сгруппированных по функциям:

- - - - - - - - - - -
-

СЕМАНТИКА

- -
-
Секции и контуры в HTML5
-
Контурные и секционные элементы в HTML5: {{ HTMLElement("section") }}, {{ HTMLElement("article") }}, {{ HTMLElement("nav") }}, {{ HTMLElement("header") }}, {{ HTMLElement("footer") }}, {{ HTMLElement("aside") }} and {{ HTMLElement("hgroup") }}.
-
Использование HTML5 audio и video
-
{{ HTMLElement("audio") }} и {{ HTMLElement("video") }} элементы вставляют и позволяют управлять мультимедиа контентом.
-
Формы в HTML5
-
Взгляд на улучшение форм в HTML5: API валидации, несколько новых атрибутов, новые значения для аттрибута {{ htmlattrxref("type", "input") }} тега {{ HTMLElement("input") }} и новый элемент {{ HTMLElement("output") }}.
-
Новые семантические элементы
-
Кроме секций, медиа и форм, множество новых тегов, такие как {{ HTMLElement("mark") }}, {{ HTMLElement("figure") }}, {{ HTMLElement("figcaption") }}, {{ HTMLElement("data") }}, {{ HTMLElement("time") }}, {{ HTMLElement("output") }}, {{ HTMLElement("progress") }} и {{ HTMLElement("meter") }}, увеличено количество валидных HTML5 элементов.
-
Улучшение {{HTMLElement("iframe")}}
-
Использование атрубутов {{htmlattrxref("sandbox", "iframe")}}, {{htmlattrxref("seamless", "iframe")}}, and {{htmlattrxref("srcdoc", "iframe") }}, разработчики могут задать нужный уровень безопасности и осуществивить рендеринг тега {{HTMLElement("iframe")}}.
-
MathML
-
Позволяет вставлять математические формулы.
-
Введение в HTML5
-
Эта статья знакомит вас с тем, как указать на то, что вы используете HTML5 в вашем веб-дизайне или веб-приложении.
-
HTML5-совместимый парсер
-
Анализатор, который превращает байты HTML документа в DOM, был расширен и точно определяет поведение, чтобы даже в случае неверного HTML, исход был предсказуемым и одинаков во всех HTML5-совместимых браузерах.
-
-
- -

СВЯЗЬ

- -
-
Web Sockets
-
Позволяет создать постоянное соединение между страницей и сервером и обмениваться данными через него.
-
Server-sent события
-
Позволяет серверу отправлять события клиенту, а не по классической парадигме, где сервер может передавать данные только в ответ на запрос клиента.
-
WebRTC
-
Эта технология, где RTC создает возможость общения в реальном времени, позволяет подключаться к другим людям и контролировать видеоконференции непосредственно в браузере, без необходимости плагинов и внешний приложений.
-
- -

ОФФЛАЙН И ХРАНИЛИЩЕ

- -
-
Оффлайн ресурсы: кеш приложения
-
Firefox полностью поддерживает спецификацию HTML5 по оффлайн ресурсам. Другие браузеры также имеют поддержку спецификации на должном уровне
-
Online and offline events
-
Firefox 3 поддерживает WHATWG online и offline события, которые позволяют приложениям и расширениям обнаружить есть ли активное подключение к Интернет, а также определить, когда соединение портится или улучшается.
-
WHATWG сессионное или постоянное хранилище (aka DOM Storage)
-
Постоянное или сессионое храилище позволяет веб-приложениям хранить структурированны данные на стороне клиента.
-
IndexedDB
-
Веб-стандарт для хранения значительных количеств структурированных данных в браузере и для быстрого их поиска, используя индексы.
-
Using files from web applications
-
Поддержка HTML5 File API была добавлена в Gecko, сделав возможным веб-приложениям иметь доступ к файлам, выбираемых пользователем. Это включает поддержку множества файлов, используя {{ HTMLElement("input") }} с типом file, имеющих атрибут multiple. Ещё это FileReader.
-
- -

МУЛЬТИМЕДИА

- -
-
Использование HTML5 audio и video
-
{{ HTMLElement("audio") }} и {{ HTMLElement("video") }} элементы вставляют и позволяют управлять мультимедиа контентом.
-
WebRTC
-
Эта технология, где RTC создает возможость общения в реальном времени, позволяет подключаться к другим людям и контролировать видеоконференции непосредственно в браузере, без необходимости плагинов и внешний приложений.
-
Использование Camera API
-
Позволяет контролировать, манипулировать и хранить изображения с камеры устройства.
-
- -

ГРАФИКА И ЭФФЕКТЫ

- -
-
Canvas Tutorial
-
Узнайте о элементе {{ HTMLElement("canvas") }} и узнайте, как рисовать графику и другие элементы в Firefox.
-
HTML5 text API для <canvas>
-
HTML5 text API сейчас поддерживается в {{ HTMLElement("canvas") }}.
-
WebGL
-
WebGL приносит 3D в веб, соответстсвует OpenGL ES 2.0, может использоваться в HTML5 через {{ HTMLElement("canvas") }}.
-
SVG
-
Основанный на XML формат векторных изображений, который может быть непосредственно вставлен в HTML.
-
- -
-
-
-
-

производительность и интеграция

- -
-
Web Workers
-
Позволяет делегировать выполнение JavaScript в фоновые потоки, это позволит предотвратить замедление интерактивных событий.
-
XMLHttpRequest Level 2
-
Позволяет извлечь асинхронно некоторые части страницы, что позволяет отобразить динамический контент, изменяющейся время от времени или от действий пользователя. Это технология, лежащая в основе AJAX.
-
JIT-компилирование движков JavaScript
-
Новое поколение движков JavaScript гораздо более мощных, приводящих к большей производительности.
-
History API
-
Позволяет управлять историей браузера. Это особенно полезно страниц, интерактивно загружающих новую информацию.
-
contentEditable атрибут: трансформируйте свой сайт в википедию!
-
HTML5 стандартизировал атрибут contentEditable. Узнайте больше об этой фиче.
-
Drag and drop
-
HTML5 drag and drop API позволяет перетаскивать элементы по сайту или на него. Также простейшее API для использования расширениями или иными приложениями.
-
Управление фокусом в HTML
-
Поддержка новый атрибутов HTML5 activeElement and hasFocus.
-
Обработчики протоколов для Web
-
Вы можете зарегистровать веб-приложения, как обработчики протоколов, используя метод navigator.registerProtocolHandler().
-
requestAnimationFrame
-
Контролирует анимации для обеспечения оптимальной производительности.
-
Fullscreen API
-
Позволяет использовать весь экран для веб-приложения, без отображения UI браузера.
-
Pointer Lock API
-
Позволяет блокировать курсор, так чтобы игры и подобные приложения не теряли фокус, когда указатель достигает предела окна.
-
Online and offline events
-
Для того, чтобы построить хорошую оффлайн-совместимые веб-приложения, вы должны знать, когда ваше приложение без сети. Также, вы должны знать, когда ваше приложение снова вернется в сеть.
-
- -

доступ к устройствам

- -
-
Использование Camera API
-
Позволяет контролировать, манипулировать и хранить изображения с камеры устройства.
-
Touch события
-
Обрабатывает события, создаваемые нажатиями пользователя по тач скрину.
-
Геолокация
-
Позволяет браузерам получать местоположение пользователя.
-
Определение ориентации устройства
-
Позволяет среагировать, когда устройство, на котором работает браузер, меняет ориентацию. Это может быть использовано в качестве устройства ввода (например, чтобы сделать игры, которые реагируют на положение устройства) или адаптировать компоновку страницы с ориентацией экрана (вертикальная или горизонтальная).
-
Pointer Lock API
-
Позволяет блокировать курсор, так чтобы игры и подобные приложения не теряли фокус, когда указатель достигает предела окна.
-
- -

стилизация

- -

CSS был расширен, чтобы дать возможность стилизировать элементы наиболее оптимальным способом. Его часто называют CSS3, хотя CSS больше не является монолитной спецификацией и различные модули, не все на уровне 3: некоторые на уровне 1, а некоторые на уровне 4, с промежуточными уровнями.

- -
-
Новые способы стилизирования фона
-
Новая возможность задать тень элемента, используя {{ cssxref("box-shadow") }} или установление множественных фонов.
-
Лучшие границы
-
Не только изображения можно использовать для стилизирования границы, используя {{ cssxref("border-image") }} или его длинные формы записи, а скруглить уголки можно свойством {{ cssxref("border-radius") }}.
-
Анимируйте свой стиль
-
Используйте CSS Переходы, чтобы анимировать изменение состояния элемента или CSS Анимации для анимации частей страницы без запуска событий, вы теперь можете контролировать мобильные элементы на вашей странице.
-
Улучшение типографии
-
Авторы могут лучше контролировать типографию. Например, они могут контролировать {{ cssxref("text-overflow") }} и перенос слов, а также тень текста и его декорированиe. Могут загрузить и применить другой шрифт правилом {{ cssxref("@font-face") }}.
-
Новые презентационные макеты
-
Для того, чтобы улучшить гибкость дизайна, добавили: CSS мульти-колоночный макет и CSS отзывчивый блочный макет.
-
-
diff --git "a/files/ru/html/html5/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html5/index.html" "b/files/ru/html/html5/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html5/index.html" deleted file mode 100644 index 28b8138f0e..0000000000 --- "a/files/ru/html/html5/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html5/index.html" +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: Введение в HTML5 -slug: HTML/HTML5/Введение_в_HTML5 -tags: - - DOCTYPE - - HTML5 - - HTML5 парсер -translation_of: Web/Guide/HTML/HTML5/Introduction_to_HTML5 ---- -

HTML5 - пятая редакция и самая новая версия стандарта HTML. Она предлагает новые возможности, которые предоставляют не только богатую поддержку медиа, но и также расширяет возможности для создания веб-приложений, которые могут взаимодействовать с пользователем, его локальными данными, и серверами проще и эффективнее, чем это было раньше.

-

Because HTML5 is still being developed, changes to the specifications are inevitable. Therefore, not all of its features are supported by all browsers yet. However, Gecko, and by extension, Firefox, has very good initial support for HTML5, and work continues toward supporting more of its features. Gecko began supporting some HTML5 features in version 1.8.1. You can find a list of all of the HTML5 features that Gecko currently supports on the main HTML5 page. For detailed information about multiple browsers' support of HTML5 features, refer to the CanIUse website.

-

Declaring that the document contains HTML5 mark-up with the HTML5 doctype

-

The doctype for HTML5 is very simple. To indicate that your HTML content uses HTML5, simply use:

-
<!DOCTYPE html>
-
-

Doing so will cause even browsers that don't presently support HTML5 to enter into standards mode, which means that they'll interpret the long-established parts of HTML in an HTML5-compliant way while ignoring the new features of HTML5 they don't support.

-

This is much simpler than the former doctypes, and shorter, making it easier to remember and reducing the amount of bytes that must be downloaded.

-

Декларация кодировки с помощью <meta charset>

-

The first thing done on a page is usually indicating the character set that is used. In previous versions of HTML, it was done using a very complex {{HTMLElement("meta")}} element. Now, it is very simple:

-
<meta charset="UTF-8">
-

Place this right after your {{HTMLElement("head") }}, as some browsers restart the parsing of an HTML document if the declared charset is different from what they had anticipated. Also, if you are not currently using UTF-8, it's recommended that you switch to it in your Web pages, as it simplifies character handling in documents using different scripts.

-

Note that HTML5 restricts the valid charset to that compatible with ASCII and using at least 8 bits. This was done to tighten security and prevent some types of attacks.

-

Использование нового HTML5 парсера

-

The parsing rule of HTML5, which analyzes the meaning of mark-up, has been more precisely defined in HTML5. Until the introduction of HTML5, only the meaning of valid mark-up was defined, meaning that as soon as one small error was made in the mark-up (most Web sites have at least one), the behavior was undefined. Essentially, it meant that all browsers behaved differently, which is no longer the case. Now, faced with errors in the mark-up, all compliant browsers must behave exactly in the same way.

-

This requirement helps Web developers quite a bit. While it is true that all modern browsers now use these HTML5 parsing rules, non-HTML5-compliant browsers are still used by some. Keep in mind that it's still highly recommended that one write valid mark-up, as such code is easier to read and maintain, and it greatly decreases the prominence of incompatibilities that exists in various older browsers.

-

Не волнуйтесь - вам не придется ничего менять на вашем веб-сайте - разработчики веб-браузерах сделали все для вас!

diff --git a/files/ru/introduction_(alternate)/index.html b/files/ru/introduction_(alternate)/index.html deleted file mode 100644 index 206d60c40d..0000000000 --- a/files/ru/introduction_(alternate)/index.html +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: Введение (альтернативные проекты) -slug: Introduction_(alternate) -translation_of: Mozilla/Developer_guide/Introduction -translation_of_original: Introduction_(alternate) ---- -

Хотя Firefox в значительной степени написан на C++, есть много способов помочь сообществу, не зная C++.

-

Firefox/Thunderbird/ и др.

-

Хотя Firefox и другие продукты Mozilla, построенные на базе кода Mozilla, написаны на C++, у них есть много компонентов, написанных на других языках:

- -

Для начала ознакомьтесь с основным руководством - почти всё написанное в нём можно применить и к вышеупомянутым проблемам, в том числе поиск багов, с фикса которых можно начать, а также описание системы наставников.

-

Веб сайты

-

Mozilla имеет более 100 различных веб-проектов и инструментов, почти все из которых - проекты с открытым кодом. Есть ресурсы getting started with Mozilla's main web sites, а также mostly-up-to-date list of web development projects с участием Mozilla, и мы постоянно стремимся расширять этот список. В этих списках Вы найдете много интересных проектов и узнаете, как помочь их развитию.

-

Проекты на гитхабе

-

Mozilla github страница содержит более 100 проектов, в которых Вы можете принять участие. Эти проекты разрабатываются с использованием обычной GitHub практики, так что для начала работы над каким-либо проектом Вам нужно лишь форкнуть его. Мы с нетерпением ждем Ваших запросов на мёрдж! Среди этих проектов есть и такие высоко-профильные, как Jetpack и многие другие.

-

Mozilla Mercurial репозитории

-

Многие Mozilla-проекты лежат в своих собственных репозиториях на hg.mozilla.org. Там можно увидеть иерархию директорий проектов, а также какие из них в настоящее время поддерживается (подсказка - не все из них!). В числе таких проектов - многие основные сферы деятельности Mozilla, такие как QA, RelEng, localization, webtools, core developers' user repos и другие.

-

Другие способы принять участие

-

Есть много способов внести свой вклад в сообщество Mozilla, помимо программирования. Если вы хотите принять участие в дизайне, поддержке, переводе, тестировании или в других видах вспомогательной деятельности, см. страницу волонтеров.

diff --git a/files/ru/learn/accessibility/accessibility_troubleshooting/index.html b/files/ru/learn/accessibility/accessibility_troubleshooting/index.html new file mode 100644 index 0000000000..d47abae869 --- /dev/null +++ b/files/ru/learn/accessibility/accessibility_troubleshooting/index.html @@ -0,0 +1,101 @@ +--- +title: Устранение проблем доступности +slug: Learn/Доступность/Accessibility_troubleshooting +translation_of: Learn/Accessibility/Accessibility_troubleshooting +--- +
{{LearnSidebar}}
+ +
{{PreviousMenu("Learn/Accessibility/Mobile", "Learn/Accessibility")}}
+ +

In the assessment for this module, we present to you a simple site with a number of accessibility issues that you need to diagnose and fix.

+ + + + + + + + + + + + +
Prerequisites:Basic computer literacy, a basic understanding of HTML, CSS, and JavaScript, an understanding of the previous articles in the course.
Objective:To test basic knowledge of accessibility fundamentals.
+ +

Starting point

+ +

To get this assessment started, you should go and grab the ZIP containing the files that comprise the example. Decompress the contents into a new directory somewhere on your local computer.

+ +

The finished assessment site should look like so:

+ +

+ +

You will see some differences/issues with the display of the starting state of the assessment — this is mainly due to the differences in the markup, which in turn cause some styling issues as the CSS is not applied properly. Don't worry — you'll be fixing these problems in the upcoming sections!

+ +

Project brief

+ +

For this project, you are presented with a fictional nature site displaying a "factual" article about bears. As it stands, it has a number of accessibility issues — your task is to explore the existing site and fix them to the best of your abilities, answering the questions given below.

+ +

Color

+ +

The text is difficult to read because of the current color scheme. Can you do a test of the current color contrast (text/background), report the results of the test, and then fix it by changing the assigned colors?

+ +

Semantic HTML

+ +
    +
  1. The content is still not very accessible — report on what happens when you try to navigate it using a screenreader.
  2. +
  3. Can you update the article text to make it easier for screenreader users to navigate?
  4. +
  5. The navigation menu part of the site (wrapped in <div class="nav"></div>) could be made more accessible by putting it in a proper HTML5 semantic element. Which one should it be updated to? Make the update.
  6. +
+ +
+

Note: You'll need to update the CSS rule selectors that style the tags to their proper equivalents for the semantic headings. Once you add paragraph elements, you'll notice the styling looking better.

+
+ +

The images

+ +

The images are currently inaccessible to screenreader users. Can you fix this?

+ +

The audio player

+ +
    +
  1. The <audio> player isn't accessible to hearing impaired (deaf) people — can you add some kind of accessible alternative for these users?
  2. +
  3. The <audio> player isn't accessible to those using older browsers that don't support HTML5 audio. How can you allow them to still access the audio?
  4. +
+ +

The forms

+ +
    +
  1. The <input> element in the search form at the top could do with a label, but we don't want to add a visible text label that would potentially spoil the design and isn't really needed by sighted users. How can you add a label that is only accessible to screenreaders?
  2. +
  3. The two <input> elements in the comment form have visible text labels, but they are not unambiguously associated with their labels — how do you achieve this? Note that you'll need to update some of the CSS rule as well.
  4. +
+ +

The show/hide comment control

+ +

The show/hide comment control button is not current keyboard-accessible. Can you make it keyboard accessible, both in terms of focusing it using the tab key, and activating it using the return key?

+ +

The table

+ +

The data table is not currently very accessible — it is hard for screenreader users to associate data rows and columns together, and the table also has no kind of summary to make it clear what it shows. Can you add some features to your HTML to fix this problem?

+ +

Other considerations?

+ +

Can you list two more ideas for improvements that would make the website more accessible?

+ +

Assessment

+ +

If you are following this assessment as part of an organized course, you should be able to give your work to your teacher/mentor for marking. If you are self-learning, then you can get the marking guide fairly easily by asking on the discussion thread for this exercise, or in the #mdn IRC channel on Mozilla IRC. Try the exercise first — there is nothing to be gained by cheating!

+ +

{{PreviousMenu("Learn/Accessibility/Mobile", "Learn/Accessibility")}}

+ +

В этом модуле

+ + diff --git a/files/ru/learn/accessibility/css_and_javascript/index.html b/files/ru/learn/accessibility/css_and_javascript/index.html new file mode 100644 index 0000000000..31ed1cb106 --- /dev/null +++ b/files/ru/learn/accessibility/css_and_javascript/index.html @@ -0,0 +1,357 @@ +--- +title: CSS и JavaScript доступность - лучшие практики +slug: Learn/Доступность/CSS_and_JavaScript +tags: + - CSS + - JavaScript +translation_of: Learn/Accessibility/CSS_and_JavaScript +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Accessibility/HTML","Learn/Accessibility/WAI-ARIA_basics", "Learn/Accessibility")}}
+ +

CSS и JavaScript, при правильном использовании, появляется возможность получить доступный web - опыт ... или же они могут значительно навредить доступности если не правильно используются. Это статья в общих очертаниях описывает рекомендации по использованию CSS и JavaScript , это является лучшей практикой, поэтому следует учитывать для обеспечения того, чтобы даже сложное содержание было максимально доступным

+ + + + + + + + + + + + +
необходимые условия:Базовая компьютерная грамотность, базовое понимание HTML, CSS, и JavaScript, и понимать (что такое доступность) what accessibility is.
Цели:Приобрести хорошую осведомленность при использовании CSS и JavaScript в ваших web документах для максимального увелечения доступности и (not detract from it)-(привет я не понял как переводится эти слова так что помогите если понимаете).
+ +

CSS и JavaScript доступны?

+ +

CSS и JavaScript не имеют такого же непосредственного значения для доступности как HTML, но они остаются способными для помощи или для повреждения доступности, в зависимости от того как их использовать. Другими словами, важно чтобы вы рассмотрели некоторые рекомендации для лучшей практики,чтобы убедится, что CSS JavaScript не разрушат доступность ваших документов.

+ +

CSS

+ +

Let's start off by looking at CSS.

+ +

Correct semantics and user expectation

+ +

It is possible to use CSS to make any HTML element look like anything, but this doesn't mean that you should. As we frequently mentioned in our HTML: A good basis for accessibility article, you should use the appropriate semantic element for the job, whenever possible. If you don't, it can cause confusion and usability issues for everyone, but particularly users with disabilities. Using correct semantics has a lot to do with user expectations — elements look and behave in certain ways, according to their functionality, and these common conventions are expected by users.

+ +

As an example, a screen reader user can't navigate a page via heading elements if the developer hasn't appropriately used heading elements to markup the content. By the same token, a heading loses its visual purpose if you style it so it doesn't look like a heading.

+ +

The rule of thumb is that you can update the styling of a page feature to fit in your design, but don't change it so much that it no longer looks or behaves as expected. The following sections summarize the main HTML features to consider.

+ +

"Standard" text content structure

+ +

Headings, paragraphs, lists — the core text content of your page:

+ +
<h1>Heading</h1>
+
+<p>Paragraph</p>
+
+<ul>
+  <li>My list</li>
+  <li>has two items.</li>
+</ul>
+ +

Some typical CSS might look like this:

+ +
h1 {
+  font-size: 5rem;
+}
+
+p, li {
+  line-height: 1.5;
+  font-size: 1.6rem;
+}
+ +

You should:

+ + + +

See HTML text fundamentals and Styling text for more information.

+ +

Emphasised text

+ +

Inline markup that confers specific emphasis to the text that it wraps:

+ +
<p>The water is <em>very hot</em>.</p>
+
+<p>Water droplets collecting on surfaces is called <strong>condensation</strong>.</p>
+ +

You might want to add some simple coloring to your emphasised text:

+ +
strong, em {
+  color: #a60000;
+}
+ +

You will however rarely need to style emphasis elements in any significant way. The standard conventions of bold and italic text are very recognisable, and changing the style can cause confusion. For more on emphasis, see Emphasis and importance.

+ +

Abbreviations

+ +

An element that allows an abbreviation, acronym, or initialization to be associated with its expansion:

+ +
<p>Web content is marked up using <abbr title="Hypertext Markup Language">HTML</abbr>.</p>
+ +

Again, you might want to style it in some simple way:

+ +
abbr {
+  color: #a60000;
+}
+ +

The recognised styling convention for abbreviations is a dotted underline, and it is unwise to significantly deviate from this. For more on abbreviations, see Abbreviations.

+ + + +

Hyperlinks — the way you get to new places on the web:

+ +
<p>Visit the <a href="https://www.mozilla.org">Mozilla homepage</a>.</p>
+ +

Some very simple link styling is shown below:

+ +
a {
+  color: #ff0000;
+}
+
+a:hover, a:visited, a:focus {
+  color: #a60000;
+  text-decoration: none;
+}
+
+a:active {
+  color: #000000;
+  background-color: #a60000;
+}
+ +

The standard link conventions are underlined and a different color (default: blue) in their standard state, another color variation when the link has previously been visited (default: purple), and yet another color when the link is activated (default: red). In addition, the mouse pointer changes to a pointer icon when links are moused over, and the link receives a highlight when focused (e.g. via tabbing) or activated. The following image shows the highlight in both Firefox (a dotted outline) and Chrome (a blue outline):

+ +

+ +

+ +

You can be creative with link styles, as long as you keep giving users feedback when they interact with the links. Something should definitely happen when states change, and you shouldn't get rid of the pointer cursor or the outline — both are very important accessibility aids for those using keyboard controls.

+ +

Form elements

+ +

Elements to allow users to input data into websites:

+ +
<div>
+  <label for="name">Enter your name</label>
+  <input type="text" id="name" name="name">
+</div>
+ +

You can see some good example CSS in our form-css.html example (see it live also).

+ +

Most of the CSS you'll write for forms will be for sizing the elements, lining up labels and inputs, and getting them looking neat and tidy.

+ +

You shouldn't however deviate too much from the expected visual feedback form elements receive when they are focused, which is basically the same as links (see above). You could style form focus/hover states to make this behaviour more consistent across browsers or fit in better with your page design, but don't get rid of it altogether — again, people rely on these clues to help them know what is going on.

+ +

Tables

+ +

Tables for presenting tabular data.

+ +

You can see a good, simple example of table HTML and CSS in our table-css.html example (see it live also).

+ +

Table CSS generally serves to make the table fit better into your design and look less ugly. It is a good idea to make sure the table headers stand out (normally using bold), and use zebra striping to make different rows easier to parse.

+ +

Color and color contrast

+ +

When choosing a color scheme for your website, make sure that the text (foreground) color contrasts well with the background color. Your design might look cool, but it is no good if people with visual impairments like color blindness can't read your content.

+ +

There is an easy way to check whether your contrast is large enough to not cause problems. There are a number of contrast checking tools online that you can enter your foreground and background colors into, to check them. For example WebAIM's Color Contrast Checker is simple to use, and provides an explanation of what you need to conform to the WCAG criteria around color contrast.

+ +
+

Note: A high contrast ratio will also allow anyone using a smartphone or tablet with a glossy screen to better read pages when in a bright environment, such as sunlight.

+
+ +

Another tip is to not rely on color alone for signposts/information, as this will be no good for those who can't see the color. Instead of marking required form fields in red, for example, mark them with an asterisk and in red.

+ +

Hiding things

+ +

There are many instances where a visual design will require that not all content is shown at once. For example, in our Tabbed info box example (see source code) we have three panels of information, but we are positioning them on top of one another and providing tabs that can be clicked to show each one (it is also keyboard accessible — you can alternatively use Tab and Enter/Return to select them).

+ +

+ +

Screen reader users don't care about any of this — they are happy with the content as long as the source order makes sense, and they can get to it all. Absolute positioning (as used in this example) is generally seen as one of the best mechanisms of hiding content for visual effect, because it doesn't stop screen readers from getting to it.

+ +

On the other hand, you shouldn't use {{cssxref("visibility")}}:hidden or {{cssxref("display")}}:none, because they do hide content from screen readers. Unless of course, there is a good reason why you want this content to be hidden from screen readers.

+ +
+

Note: Invisible Content Just for Screen Reader Users has a lot more useful detail surrounding this topic.

+
+ +

Accept that users can override styles

+ +

Accept that users can override your styles

+ +

It is possible for users to override your styles with their own custom styles, for example:

+ + + +

Users might do this for a variety of reasons. A visually impaired user might want to make the text bigger on all websites they visit, or a user with severe color deficiency might want to put all websites in high contrast colors that are easy for them to see. Whatever the need, you should be comfortable with this, and make your designs flexible enough so that such changes will work in your design. As an example, you might want to make sure your main content area can handle bigger text (maybe it will start to scroll to allow it all to be seen), and won't just hide it, or break completely.

+ +

JavaScript

+ +

JavaScript can also break accessibility, depending on how it is used.

+ +

Modern JavaScript is a powerful language, and we can do so much with it these days, from simple content and UI updates to fully-fledged 2D and 3D games. There is no rule that says all content has to be 100% accessible to all people — you just need to do what you can, and make your apps as accessible as possible.

+ +

Simple content and functionality is arguably easy to make accessible — for example text, images, tables, forms and push button that activate functions. As we looked at in our HTML: A good basis for accessibility article, the key considerations are:

+ + + +

We also looked at an example of how to use JavaScript to build in functionality where it is missing — see Building keyboard accessibility back in. This is not ideal — really you should just use the right element for the right job — but it shows that it is possible in situations where for some reason you can't control the markup that is used. Another way to improve accessibility for non-semantic JavaScript-powered widgets is to use WAI-ARIA to provide extra semantics for screen reader users. The next article will also cover this in detail.

+ +

Complex functionality like 3D games are not so easy to make accessible — a complex 3D game created using WebGL will be rendered on a {{htmlelement("canvas")}} element, which has no facility at this time to provide text alternatives or other information for severely visually impaired users to make use of. It is arguable that such a game doesn't really have this group of people as a part of its main target audience, and it would be unreasonable to expect you to make it 100% accessible to blind people, however you could implement keyboard controls so it is usable by non-mouse users, and make the color scheme contrasting enough to be usable by those with color deficiencies.

+ +

The problem with too much JavaScript

+ +

The problem often comes when people rely on JavaScript too much. Sometimes you'll see a website where everything has been done with JavaScript — the HTML has been generated by JavaScript, the CSS has been generated by JavaScript, etc. This has all kinds of accessibility and other issues associated with it, so it is not advised.

+ +

As well as using the right element for the right job, you should also make sure you are using the right technology for the right job! Think carefully about whether you need that shiny JavaScript-powered 3D information box, or whether plain old text would do. Think carefully about whether you need a complex non-standard form widget, or whether a text input would do. And don't generate all your HTML content using JavaScript if at all possible.

+ +

Keeping it unobtrusive

+ +

You should keep unobtrusive JavaScript in mind when creating your content. The idea of unobtrusive JavaScript is that it should be used wherever possible to enhance functionality, not build it in entirely — basic functions should ideally work without JavaScript, although it is appreciated that this is not always an option. But again, a large part of it is using built-in browser functionality where possible.

+ +

Good example uses of unobtrusive JavaScript include:

+ + + +

As an example, we've written a quick and dirty client-side form validation example — see form-validation.html (also see the demo live). Here you'll see a simple form; when you try to submit the form with one or both fields left empty, the submit fails, and an error message box appears to tell you what is wrong.

+ +

This kind of form validation is unobtrusive — you can still use the form absolutely fine without the JavaScript being available, and any sensible form implementation will have server-side validation active as well, because it is too easy for malicious users to bypass client-side validation (for example, by turning JavaScript off in the browser). The client-side validation is still really useful for reporting errors — users can know about mistakes they make instantly, rather than having to wait for a round trip to the server and a page reload. This is a definite usability advantage.

+ +
+

Note: Server-side validation has not been implemented in this simple demo.

+
+ +

We've made this form validation pretty accessible too. We've used {{htmlelement("label")}} elements to make sure the form labels are unambiguously linked to their inputs, so screen readers can read them out alongside:

+ +
<label for="name">Enter your name:</label>
+<input type="text" name="name" id="name">
+ +

We only do the validation when the form is submitted — this is so that we don't update the UI too often and potentially confuse screen reader (and possibly other) users:

+ +
form.onsubmit = validate;
+
+function validate(e) {
+  errorList.innerHTML = '';
+  for(var i = 0; i < formItems.length; i++) {
+    var testItem = formItems[i];
+    if(testItem.input.value === '') {
+      errorField.style.left = '360px';
+      createLink(testItem);
+    }
+  }
+
+  if(errorList.innerHTML !== '') {
+    e.preventDefault();
+  }
+}
+ +
+

Note: In this example, we are hiding and showing the error message box using absolute positioning rather than another method such as visibility or display, because it doesn't interfere with the screen reader being able to read content from it.

+
+ +

Real form validation would be much more complex than this — you'd want to check that the entered name actually looks like a name, the entered age is actually a number and is realistic (e.g. not a minus number, or four digits). Here we've just implemented a simple check that a value has been filled in to each input field (if(testItem.input.value === '')).

+ +

When the validation has been performed, if the tests pass then the form is submitted. If there are errors (if(errorList.innerHTML !== '')) then we stop the form submitting (using preventDefault()), and display any error messages that have been created (see below). This mechanism means that the errors will only be shown if there are errors, which is better for usability.

+ +

For each input that doesn't have a value filled in when the form is submitted, we create a list item with a link and insert it in the errorList.

+ +
function createLink(testItem) {
+  var listItem = document.createElement('li');
+  var anchor = document.createElement('a');
+  anchor.textContent = testItem.input.name + ' field is empty: fill in your ' + testItem.input.name + '.';
+  anchor.href = '#' + testItem.input.name;
+  anchor.onclick = function() {
+    testItem.input.focus();
+  };
+  listItem.appendChild(anchor);
+  errorList.appendChild(listItem);
+}
+ +

Each link serves a dual purpose — it tells you what the error is, plus you can click on it/activate it to jump straight to the input element in question and correct your entry.

+ +
+

Note: The focus() part of this example is a bit tricky. Chrome and Edge (and newer versions of IE) will focus the element when the link is clicked, without needing the onclick/focus() block. Safari will only highlight the form element with the link on its own, so needs the onclick/focus() block to actually focus it. Firefox doesn't focus the inputs properly at all in this context, so Firefox users can't take advantage of this at present (although everything else works fine). The Firefox issue should be fixed soon — work is being done to give Firefox behaviour parity with other browsers (see {{bug(277178)}}).

+
+ +

In addition, the errorField is placed at the top of the source order (although it is positioned differently in the UI using CSS), meaning that users can find out exactly what's wrong with their form submissions and get to the input elements in question by going back up to the start of the page.

+ +

As a final note, we have used some WAI-ARIA attributes in our demo to help solve accessibility problems caused by areas of content constantly updating without a page reload (screen readers won't pick this up or alert users to it by default):

+ +
<div class="errors" role="alert" aria-relevant="all">
+  <ul>
+  </ul>
+</div>
+ +

We will explain these attributes in our next article, which covers WAI-ARIA in much more detail.

+ +
+

Note: Some of you will probably be thinking about that fact that HTML5 forms have built-in validation mechanisms like the required, min/minlength, and max/maxlength attributes (see the {{htmlelement("input")}} element reference for more information). We didn't end up using these in the demo because cross-browser support for them is patchy (for example IE10 and above only, no Safari support).

+
+ +
+

Note: WebAIM's Usable and Accessible Form Validation and Error Recovery provides some further useful information about accessible form validation.

+
+ +

Other JavaScript accessibility concerns

+ +

There are other things to be aware of when implementing JavaScript and thinking about accessibility. We will add more as we find them.

+ +

mouse-specific events

+ +

As you will be aware, most user interactions are implemented in client-side JavaScript using event handlers, which allow us to run functions in response to certain events happening. Some events can have accessibility issues. The main example you'll come across is mouse-specific events like mouseover, mouseout, dblclick, etc. Functionality that runs in response to these events will not be accessible using other mechanisms, like keyboard controls.

+ +

To mitigate such problems, you should double up these events with similar events that can be activated by other means (so-called device-independent event handlers) — focus and blur would provide accessibility for keyboard users.

+ +

Let's look at an example that highlights when this could be useful. Maybe we want to provide a thumbnail image that shows a larger version of the image when it is moused over or focused (like you'd see on an e-commerce product catalog.)

+ +

We've made a very simple example, which you can find at mouse-and-keyboard-events.html (see also the source code). The code features two functions that show and hide the zoomed-in image; these are run by the following lines that set them as event handlers:

+ +
imgThumb.onmouseover = showImg;
+imgThumb.onmouseout = hideImg;
+
+imgThumb.onfocus = showImg;
+imgThumb.onblur = hideImg;
+ +

The first two lines run the functions when the mouse pointer hovers over and stops hovering over the thumbnail, respectively. This won't allow us to access the zoomed view by keyboard though — to allow that, we've included the last two lines, which run the functions when the image is focused and blurred (when focus stops). This can be done by tabbing over the image, because we've included tabindex="0" on it.

+ +

The click event is interesting — it sounds mouse-dependent, but most browsers will activate onclick event handlers after Enter/Return is pressed on a link or form element that has focus, or when such an element is tapped on a touchscreen device. This doesn't work by default however when you allow a non-default-focusable event to have focus using tabindex — in such cases you need to detect specifically when that exact key is pressed (see Building keyboard accessibility back in).

+ +

Summary

+ +

We hope this article has given you a good amount of detail and understanding about the accessibility issues surrounding CSS and JavaScript use on web pages.

+ +

Next up, WAI-ARIA!

+ +
{{PreviousMenuNext("Learn/Accessibility/HTML","Learn/Accessibility/WAI-ARIA_basics", "Learn/Accessibility")}}
+ +
+

В этом модуле

+ + +
diff --git a/files/ru/learn/accessibility/html/index.html b/files/ru/learn/accessibility/html/index.html new file mode 100644 index 0000000000..64c19fd4d6 --- /dev/null +++ b/files/ru/learn/accessibility/html/index.html @@ -0,0 +1,537 @@ +--- +title: 'HTML: Хорошая основа для доступности' +slug: Learn/Доступность/HTML +tags: + - HTML + - a11y + - Клавиатура + - Кнопки + - Начинающий + - Семантика + - Ссылки + - Формы + - вспомагательные технологии + - доступность +translation_of: Learn/Accessibility/HTML +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Accessibility/What_is_Accessibility","Learn/Accessibility/CSS_and_JavaScript", "Learn/Accessibility")}}
+ +

Большая часть содержимого интернета может быть сделана доступной просто благодаря использованию правильных HTML элементов по назначению. В этой статье подробно рассмотрено как HTML может быть использован для обеспечения максимальной доступности.

+ + + + + + + + + + + + +
Необходимые знания:Базовая компьютерная грамотность, базовое понимание HTML (смотрите Введение в HTML), и понимания, что такое доступность.
Цель: +

Познакомиться с тем, какие особенности HTML способствуют доступности, и как использовать их на ваших веб-страницах должным образом.

+
+ +

HTML и доступность

+ +

По мере изучения HTML: чтения статей, просмотра примеров и т.д., вы заметите одну общую тему — важность использования семантического HTML (иногда называемого POSH (Plain Old Semantic HTML), или «старый добрый семантический HTML»). Это означает использование HTML элементов по назначению насколько это возможно.

+ +

Вы спросите, почему это так важно?  В конце концов, можно использовать комбинацию CSS и JavaScript, чтобы заставить почти любой HTML элемент вести себя так, как вы захотите. Например, кнопка для воспроизведения видео на вашем сайте может быть обозначена вот так:

+ +
<div>Воспроизвести видео</div>
+ +

Но, как вы увидите далее, в данном случае намного логичнее использовать правильный элемент:

+ +
<button>Воспроизвести видео</button>
+ +

HTML элементы <button> не только имеют соответствующие кнопке стили по-умолчанию (которые вы скорее всего захотите переписать), они также имеют встроенную доступность с клавиатуры: между ними можно передвигаться с помощью кнопки Tab и активировать, используя Enter.

+ +

Вёрстка с помощью семантического HTML не займёт больше времени, чем с помощью не семантического (плохого) HTML, если делать это последовательно с самого начала проекта, и это также имеет другие преимущества помимо доступности:

+ +
    +
  1. Легче разрабатывать — как сказано выше, вы получаете функционал «из коробки», плюс проще для восприятия.
  2. +
  3. Лучше для мобильных — семантический HTML легче по размеру, чем не семантический спаггети-код, и его легче сделать адаптивным.
  4. +
  5. Хорошо для SEO — поисковики уделяют больше внимания ключевым словам внутри заголовков, ссылок и т.д., чем ключевым словам, помещённым в не семантический <div> и т.д., поэтому клиентам будет проще найти ваш сайт.
  6. +
+ +

Давайте рассмотрим доступный HTML более детально.

+ +
+

Примечание: Желательно, чтобы у вас был установлен скринридер, чтобы вы могли тестировать примеры, приведённые ниже. Посмотрите наше Руководство по скринридерам для более подробной информации.

+
+ +

Хорошая семантика

+ +

Мы уже говорили о важности хорошей семантики, и почему нам стоит использовать HTML элементы по назначению. Это нельзя игнорировать, поскольку это одно из основных мест, где ломается доступность из-за плохой семантики, если должным образом не уделять внимания.

+ +

В интернете люди делают очень странные вещи с HTML разметкой. Некоторые злоупотребляют HTML, используя устаревшие практики, которые не были полностью забыты, а некоторые просто не знают. В любом случае, вам стоит заменить по возможности плохой код, где бы вы его не увидели.

+ +

У вас не всегда есть возможность избавиться от плохой вёрстки: ваши страницы могут быть сгенерированы каким-нибудь фреймворком на стороне сервера, над которым у вас нет полного контроля, или на страницах есть сторонний контент (такой как рекламные баннеры), которые вы также не контролируете.

+ +

Цель не «всё или ничего», однако — каждое улучшение, которое вам под силу сделать, поможет обеспечить доступность.

+ +

Текстовый контент

+ +

Одно из самых лучших вспомогательных средств доступности для пользователя скринридера — хорошая структура заголовков, параграфов, список и т.д. Пример хорошей семантики может выглядеть так:

+ +
<h1>Мой заголовок</h1>
+
+<p>Это первый раздел моей страницы.</p>
+
+<p>Я добавлю ещё один параграф тут.</p>
+
+<ol>
+  <li>Это</li>
+  <li>список для</li>
+  <li>чтения</li>
+</ol>
+
+<h2>Мой подзаголовок</h2>
+
+<p>Это первый подраздел моей страницы. Я бы хотела, чтобы люди могли найти этот контент!</p>
+
+<h2>Мой второй подзаголовок</h2>
+
+<p>Это второй подраздел. Думаю, он намного интереснее, чем предыдущий.</p>
+ +

Мы подготовили версию с длинными текстом, чтобы вы попробовали со скринридером (смотрите good-semantics.html). Если вы попробуете поперемещаться, то увидите, как легко ориентироваться на странице:

+ +
    +
  1. Скринридер озвучивает каждый заголовок по мере перемещения, оповещая вас, что является заголовком, а что параграфом. 
  2. +
  3. Он останавливается после каждого элемента, позволяя вам переместиться в любое другое место, которое вам надо.
  4. +
  5. Во многих скринридерах Вы можете перемещаться к следующему/предыдущему заголовкам.
  6. +
  7. Во многих скринридерах Вы также можете вызвать список всех заголовков, который можно использовать как содержание, чтобы найти определённую информацию. 
  8. +
+ +

Иногда люди используют презентационные элементы HTML и перенос строки, чтобы написать заголовки или параграфы:

+ +
<font size="7">Мой заголовок</font>
+<br><br>
+Это первый раздел моей страницы.
+<br><br>
+Я добавлю ещё один параграф тут.
+<br><br>
+1. Это
+<br><br>
+2. список для
+<br><br>
+3. чтения
+<br><br>
+<font size="5">Мой подзаголовок</font>
+<br><br>
+Это первый подраздел моей страницы. Я бы хотела, чтобы люди могли найти этот контент!
+<br><br>
+<font size="5">Мой второй подзаголовок</font>
+<br><br>
+Это второй подраздел. Думаю, он намного интереснее, чем предыдущий.
+ +

Если вы попробуете полную версию с помощью скринридера (смотрите bad-semantics.html), вам не слишком это понравится: скринридеру нечего использовать как ориентир, поэтому вы не сможете получить содержание, а вся страница для скринридера — это один большой блок, поэтому он озвучит всё за один раз, без остановок. 

+ +

Есть и другие проблемы, помимо доступности — сложнее стилизовать контент, используя CSS, или манипулировать им с помощью JavaScript, например, потому что  там нет элементов, которые можно использовать как селекторы.

+ +

Использование понятного языка

+ +

Язык, который вы используете, также может влиять на доступность. В целом, лучше использовать понятный язык, который не слишком сложный, и который не использует ненужные жаргоны и сленг. Это помогает не только людям с когнитивными или другими нарушениями, но и читателям, для которых текст написан не на родном языке, молодым людям... на самом деле всем! Кроме этого, стоит избегать использование языка и символов, которые не могут быть чётко озвучено скринридером. Например:

+ + + +

Вёрстка

+ +

В старые недобрые времена, люди верстали с помощью HTML-таблиц: использовали различные табличные ячейки для размещения шапки, подвала, боковую панель, колонку с основным контентом и т.д. Это плохая идея, потому что скринридер, скорее всего, выдаст непонятную озвучку, особенно, если раскладка сложная и имеет много вложенных таблиц.

+ +

Посмотрите пример табличной вёрстки, открыв table-layout.html, которая выглядит примерно так:

+ +
<table width="1200">
+      <!-- main heading row -->
+      <tr id="heading">
+        <td colspan="6">
+
+          <h1 align="center">Шапка</h1>
+
+        </td>
+      </tr>
+      <!-- nav menu row  -->
+      <tr id="nav" bgcolor="#ffffff">
+        <td width="200">
+          <a href="#" align="center">Главная</a>
+        </td>
+        <td width="200">
+          <a href="#" align="center">Наша команда</a>
+        </td>
+        <td width="200">
+          <a href="#" align="center">Проекты</a>
+        </td>
+        <td width="200">
+          <a href="#" align="center">Контакты</a>
+        </td>
+        <td width="300">
+          <form width="300">
+            <input type="search" name="q" placeholder="Поиск" width="300">
+          </form>
+        </td>
+        <td width="100">
+          <button width="100">Вперёд!</button>
+        </td>
+      </tr>
+      <!-- spacer row -->
+      <tr id="spacer" height="10">
+        <td>
+
+        </td>
+      </tr>
+      <!-- main content and aside row -->
+      <tr id="main">
+        <td id="content" colspan="4" bgcolor="#ffffff">
+
+          <!-- основной контент -->
+        </td>
+        <td id="aside" colspan="2" bgcolor="#ff80ff" valign="top">
+          <h2>Связанный контент</h2>
+
+          <!-- второстепенный контент -->
+
+        </td>
+      </tr>
+      <!-- spacer row -->
+      <tr id="spacer" height="10">
+        <td>
+
+        </td>
+      </tr>
+      <!-- footer row -->
+      <tr id="footer" bgcolor="#ffffff">
+        <td colspan="6">
+          <p>© 2050 никто. Все права защищены.</p>
+        </td>
+      </tr>
+    </table>
+ +

Если вы попробуете поперемещаться с помощью скринридера, вероятно, он скажет вам, что перед вами таблица (хотя некоторые скринридеры могу различать табличную вёрстку от таблиц данных). После этого, скорее всего (в зависимости от того, какой скринридер вы используете), вам придётся переместиться в таблицу как в объект, посмотрев каждый элемент по отдельности, затем выйти из таблицы, чтобы продолжить перемещение по контенту.

+ +

Табличная вёрстка — пережиток прошлого, который имел смысл, когда поддержка CSS не была сильно распространена среди браузеров, но она создаёт путаницу среди пользователей скринридеров, и плоха по многим другим причинам (злоупотребление таблицами, пожалуй, требует больше разметки, делает дизайн менее гибким). Не делайте так!

+ +

Вы можете проверить эти утверждения, сравнив предыдущий опыт с более современной структурой веб-сайта, которая выглядит так:

+ +
<header>
+  <h1>Шапка</h1>
+</header>
+
+<nav>
+  <!-- основная навигация -->
+</nav>
+
+<!-- Основной контент нашей страницы -->
+<main>
+
+  <!-- На ней есть статьи -->
+  <article>
+    <h2>Заголовок статьи</h2>
+
+    <!-- сама статья -->
+  </article>
+
+  <aside>
+    <h2>Связанный контент</h2>
+
+    <!-- второстепенный контент -->
+  </aside>
+
+</main>
+
+<!-- А здесь наш основной подвал, который используется на всех страницах нашего сайта -->
+
+<footer>
+  <!-- здесь содержимое подвала -->
+</footer>
+ +

Если вы попробуете нашу более современную структуру с помощью скринридера, вы увидите, что разметка больше не сбивает с толку скринридер. Она также более компактная с точки зрения размера кода, что означает, его легче поддерживать, а пользователям меньше скачивать (особенно для тех, у кого медленный интенет).

+ +

На что ещё стоит обратить внимание при вёрстке — это использование семантических HTML5 элементов, которые можно увидеть в примере выше (смотрите секционирование содержания): вы можно верстать, используя только вложенные {{htmlelement("div")}} элементы, но лучше использовать соответствующие секционные элементы, чтобы обернуть вашу основную навигацию ({{htmlelement("nav")}}), футер ({{htmlelement("footer")}}), повторяющийся контент ({{htmlelement("article")}}) и т.д. Эти элементы предоставляют дополнительную семантику для скринридеров (и других инструментов), чтобы давать пользователю дополнительную информацию о контенте, по которому они перемещаются (смотрите статью Screen Reader Support for new HTML5 Section Elements для представления поддержки этих элементов с помощью скринридеров).

+ +
+

Примечание: Помимо того, что ваш контент имеет семантическую и красивую разметку, он должен иметь логический порядок в его исходном коде — позже вы всегда можете разместить элементы там, где хотите, с помощью CSS, но располагать элементы в правильном порядке нужно в самом начале, чтобы то, что зачитывает пользователям скринридер, имело смысл.

+
+ +

Элементы интерфейса

+ +

Под элементами интерфейса мы подразумеваем основные элементы веб-страниц, с которыми взаимодействует пользователь, в основном это кнопки, ссылки и элементы форм. В этом разделе мы рассмотрим основные проблемы доступности, которые стоит учитывать при создании таких элементов. В следующих статьях про WAI-ARIA и мультимедиа мы рассмотрим другие аспекты доступности пользовательского интерфейса.

+ +

Одним из ключевых аспектов доступуности элементов интерфейса является то, что браузеры по-умолчанию позволяют управлять ими с помощью клавиатуры. Вы можете проверить это, открыв в новой вкладке native-keyboard-accessibility.html (смотрите исходный код). Попробуйте понажимать клавишу Tab, после нескольких нажатий вы заметите, что фокус перемещается по всем фокусируемым элементам. Сфокусированные элеметы подсвечиваются браузерными стилями по-умолчанию (в зависимости от браузера они немного разные), чтобы можно было понять, какой элемент в фокусе.

+ +

+ +

Вы можете нажать Enter, чтобы перейти по сфокусированной ссылке или нажать кнопку (мы добавили немного JavaScript, чтобы кнопки выводили окно с сообщением), или начать печатать в текстовом поле (другие элементы формы имеют разное управление, например, у элемента {{htmlelement("select")}} можно отобразить опции и переключаться между ними, используя клавиши-стрелки вверх и вниз).

+ +
+

Примечание: Различные браузеры могут иметь разное управление с клавиатуры. Для более подробной информации смотрите Using native keyboard accessibility.

+
+ +

Такое поведение вы получаете сразу по-умолчанию, просто используя правильные элементы, например:

+ +
<h1>Ссылки</h1>
+
+<p>Это ссылка ведёт на сайт <a href="https://www.mozilla.org">Mozilla</a>.</p>
+
+<p>Другая ссылка на <a href="https://developer.mozilla.org">Mozilla Developer Network</a>.</p>
+
+<h2>Кнопки</h2>
+
+<p>
+  <button data-message="Это из первой кнопки">Нажми меня!</button>
+  <button data-message="Это из второй кнопки">Меня тоже нажми!</button>
+  <button data-message="Это из третьей кнопки">И меня!</button>
+</p>
+
+<h2>Форма</h2>
+
+<form>
+  <div>
+    <label for="name">Укажите ваше имя:</label>
+    <input type="text" id="name" name="name">
+  </div>
+  <div>
+    <label for="age">Укажите ваш возраст:</label>
+    <input type="text" id="age" name="age">
+  </div>
+  <div>
+    <label for="mood">Выберите ваше настроение:</label>
+    <select id="mood" name="mood">
+      <option>Счастливый</option>
+      <option>Грустный</option>
+      <option>Злой</option>
+      <option>Обеспокоенный</option>
+    </select>
+  </div>
+</form>
+ +

Это предполагает использование соответствующим образом ссылок, кнопок, элементов форм и меток (включая элемент {{htmlelement("label")}} для элементов форм).

+ +

Однако, опять же, люди иногда делают странные вещи с HTML. Например, иногда вы видите кнопки, размеченные с помощью элемента {{htmlelement("div")}}:

+ +
<div data-message="Это из первой кнопки">Нажми меня!</div>
+<div data-message="Это из второй кнопки">Меня тоже нажми!</div>
+<div data-message="Это из третьей кнопки">И меня!</div>
+ +

Такой код не советуется использовать: вы сразу же теряете нативную доступность с клавиатуры, которая у вас была бы, если просто использовать элемент {{htmlelement("button")}}, к тому же {{htmlelement("div")}} по-умолчанию не имеет кнопочных стилей.

+ +

Добавление доступности с клавиатуры

+ +

Для добавления доступности с клавиатуры несоответствующим элементам придётся немного поработать (вы можете посмотреть пример, открыв  fake-div-buttons.html, а также исходный код). Мы дали нашим поддельным <div>-кнопкам возможность фокусироваться (в том числе через Tab), указав аттрибут tabindex="0":

+ +
<div data-message="Это из первой кнопки" tabindex="0">Кликни меня!</div>
+<div data-message="Это из второй кнопки" tabindex="0">Меня тоже кликни!</div>
+<div data-message="Это из третьей кнопки" tabindex="0">И меня!</div>
+ +

Аттрибут {{htmlattrxref("tabindex")}} в первую очередь предназначен для того, чтобы менять порядок фокусируемых элементов в последовательной навигации (указанный в виде положительного целого числа). Это почти всегда — плохая идея, которая может вызвать большую путаницу. Используйте его, если он правда необходим, например, если визуальный порядок сильно отличается от исходного, и вы хотите более логичную последовательную навигацию. Есть два варианта значений tabindex:

+ + + +

Хотя дополнение, которые мы сделали, позволяет нам перемещаться по кнопкам с помощью Tab, оно не позволяет нам активировать их кнопкой Enter. Для этого нам необходимо добавить хитрый кусочек JavaScript:

+ +
document.onkeydown = function(e) {
+  if(e.keyCode === 13) { // Кнопка Enter
+    document.activeElement.click();
+  }
+};
+ +

Мы навешиваем обработчик событий на document для обнаружения нажатий с клавиатуры. Далее, через свойство объекта события keyCode, проверяем, какая кнопка была нажата. Если код клавиши совпадает с кодом клавиши Enter, мы выполняем функцию, которая хранится в обработчике кнопки onclick, используя document.activeElement.click(). activeElement возвращает текущий сфокусированный элемент.

+ +

Слишком много дополнительной мороки с добавлением такой функциональности. И обязательно будут ещё проблемы. Лучше просто сразу использовать правильные элементы по назначению.

+ +

Содержательные текстовые метки

+ +

Текстовые метки (описания) для элементов интерфейса полезны всем пользователям, но их правильное описание — особенно важно для пользователей с ограниченными способностями.

+ +

Вы должны следить за тем, чтобы кнопки и ссылки имели понятные и уникальные текстовые описания. Не используйте фразу «Кликните здесь», потому что пользователи скринридеров иногда вызывают список кнопок и элементов форм. В примере ниже можно увидеть такой список, вызванный из VoiceOver на Mac.

+ +

+ +

Удостоверьтесь, что описания вне контекста имеют смысл, так же как и в контексте параграфа, в котором они содержаться. Например, вот хороший текст для ссылки:

+ +
<p>Киты очень классные существа. <a href="whales.html">Узнай больше о китах</a>.</p>
+ +

а это плохой текст для ссылки:

+ +
<p>Киты очень классные существа. Чтобы узнать больше о китах, <a href="whales.html">нажмите здесь</a>.</p>
+ +
+

Примечание: Более подробно о создании ссылок и лучших практиках можно почитать в статье «Создание ссылок». Также посмотреть на примеры хороших и плохих ссылок можно на good-links.html и bad-links.html

+
+ +

Описания форм также важны для понимания, что нужно вводить в каждое текстовое поле. Следующий пример кажется достаточно разумным:

+ +
Укажите ваше имя: <input type="text" id="name" name="name">
+ +

Однако, это не совсем удобно для пользователей с ограниченными возможностями. В примере нет ничего, что могло бы однозначно связать описание текстового поля с самим текстовым полем, и чётко указать, как его заполнить, если вы не можете видеть. Если бы вы воспользовались скринридером, скорее всего он озвучил описание примерно как «редактировать текст».

+ +

Следующий пример намного лучше:

+ +
<div>
+  <label for="name">Укажите ваше имя:</label>
+  <input type="text" id="name" name="name">
+</div>
+ +

С такой разметкой описание будет явно связано с текстовым полем, и будет звучать как «Укажите ваше имя: редактировать текст».

+ +

+ +

Как бонус, в большинстве браузеров привязка описания к полю ввода означает, что вы можете щелкнуть по описанию, чтобы выбрать/активировать элемент формы. Это облегчает нажатие на элемент формы из-за увеличенной зоны нажатия.

+ +
+

Примечание: Посмотреть на хорошие и плохие пример форм можно на good-form.html и bad-form.html.

+
+ +

Доступные таблицы

+ +

Обычные таблицы с данными можно сверстать очень простой разметкой, например:

+ +
<table>
+  <tr>
+    <td>Имя</td>
+    <td>Возраст</td>
+    <td>Пол</td>
+  </tr>
+  <tr>
+    <td>Гавриил</td>
+    <td>13</td>
+    <td>Мужской</td>
+  </tr>
+  <tr>
+    <td>Эвелина</td>
+    <td>8</td>
+    <td>Женский</td>
+  </tr>
+  <tr>
+    <td>Фрида</td>
+    <td>5</td>
+    <td>Женский</td>
+  </tr>
+</table>
+ +

Но есть проблемы — пользователи скринридера никак не смогут связать вместе строки или столбцы в группу данных. Чтобы это сделать, нужно знать какие из строк являются заголовками, и озаглавливают ли они строки, столбцы и т.д. Для таблицы выше это можно определить только визуально (попробуйте сами на примере, открыв bad-table.html).

+ +

Теперь посмотрим на пример таблицы с панк-группами, где можно увидеть несколько вспомогательных средств:

+ + + +
+

Примечание: Более подробную информацию о доступных таблицах можно узнать в статье HTML-таблицы: продвинутые возможности и доступность.

+
+ +

Альтернативный текст

+ +

В то время как текстовый контент доступен по-умолчанию, этого нельзя сказать о мультимедийном контенте — изображения/видео-контент не может быть просмотрен людьми с нарушениями зрения, а аудио контент не может быть услышан людьми с нарушениями слуха. Мы подробно рассмотрим видео и аудио контент в статье о доступности мультимедиа позже, но в этой статье мы рассмотрим доступность для простого элемента {{htmlelement("img")}}.

+ +

У нас есть простой пример, accessible-image.html, который содержит четыре копии одного и того же изображения:

+ +
<img src="dinosaur.png">
+
+<img src="dinosaur.png"
+     alt="Красный тираннозавр Рекс: стоящий как человек двуногий динозавр, с маленькими передними лапами и большой головой с большим количеством острых зубов.">
+
+<img src="dinosaur.png"
+     alt="Красный тираннозавр Рекс: стоящий как человек двуногий динозавр, с маленькими передними лапами и большой головой с большим количеством острых зубов."
+     title="Красный динозавр Mozilla">
+
+
+<img src="dinosaur.png" aria-labelledby="dino-label">
+
+<p id="dino-label">Красный тираннозавр Рекс Mozilla: стоящий как человек двуногий динозавр, с маленькими передними лапами и большой головой с большим количеством острых зубов.</p>
+
+ +

Первое изображение, когда оно просматривается программой чтения с экрана, не очень помогает пользователю — например, VoiceOver озвучивает его как «/dinosaur.png, image». Он озвучивает имя файла, чтобы попытаться помочь. В этом примере пользователь, по крайней мере, будет знать, что это какой-то динозавр, но часто файлы могут загружаться с программно-генерируемыми именами (например, с цифровой камеры), и эти имена файлов, скорее всего, не обеспечат контекста для содержимого изображения.

+ +
+

Примечание: Вот почему вы никогда не должны включать текстовое содержимое в изображение — скринридеры просто не могут получить к нему доступ.Есть и другие недостатки — вы не можете выбрать его и скопировать/вставить. Просто не делайте этого!

+
+ +

Когда скринридер встретит второе изображение, он озвучит аттрибут alt полностью: «Красный тираннозавр Рекс: стоящий как человек двуногий динозавр, с маленькими передними лапами и большой головой с большим количеством острых зубов».

+ +

Это подчёркивает важность не только использования содержательных файловых имён в случаях отсутствия, так называемого, альтернативного текста, но также важность предоставления альтернативного текста в аттрибуте alt, где это возможно. Заметьте, что содержание аттрибута alt должно всегда предоставлять прямое представление изображения и то, что оно визуально передаёт. Любые личные знания или дополнительное описание не должны быть включены, так как это не принесёт пользы людям, которые не видели изображение ранее.

+ +

Также стоит учитывать, имеют ли изображения значение внутри вашего контента, или они исключительно для украшения без смысла. Если они декоративные, лучше оставить значение аттрибута alt пустым (смотрите «Пустые аттрибуты alt») или просто вставить их как фон с помощью CSS.

+ +
+

Примечание: Для более подробной информации об изображениях и лучших практиках читайте «Изображения в HTML» и «Адаптивные изображения».

+
+ +

Если вы всё же хотите предоставить дополнительную контекстуальную информацию, поместите её в тексте рядом с изображением или внутри аттрибута title, как показано ниже. В этом случае большинство скринридеров озвучат альтернативный текст, аттрибут title и имя файла. Дополнительно, при наведении мышкой браузеры отобразят текст из аттрибута title как всплывающую подсказку.

+ +

+ +

Давайте взглянем на четвёртый способ:

+ +
<img src="dinosaur.png" aria-labelledby="dino-label">
+
+<p id="dino-label">Красный тираннозавр Mozilla ... </p>
+ +

В этом случае мы вообще не используем аттрибут alt. Вместо этого мы представили наше описание изображения как обычный параграф, указали id, и потом использовали аттрибут aria-labelledby, сославшись на тот id. Это вынуждает скринридеры использовать параграф как альтернативный текст/описание изображения. Это особенно удобно, если вы хотите использовать один текст как описание для нескольких изображений, что невозомжно с помощью аттрибута alt.

+ +
+

Примечание: aria-labelledby — часть спецификации WAI-ARIA, которая позволяет разработчиками добавлять, где требуется, дополнительную семантику разметке для улучшения доступности при использовании скринридеров. Чтобы узнать больше о том, как это работает, читайте статью «Основы WAI-ARIA».

+
+ +

Другие механизмы альтернативного текста

+ +

У изображений есть ещё один механизм для предоставления описательного текста. Например, есть аттрибут longdesc, который предназначен для указания отдельной веб-страницы, содержащей расширенное описание изображения:

+ +
<img src="dinosaur.png" longdesc="dino-info.html">
+ +

Звучит, как хорошая идея, особенно для такой инфографики как диаграммы с большим количеством информации, которую, в качестве альтернативы, можно представить в виде доступной таблицы с данными (смотрите предыдущий раздел). Однако, longdesc нестабильно поддерживается скринридерами, и контент полностью недоступен пользователям, которые не используют скринридеры. Пожалуй, намного лучше будет вставить длинное описание на страницу вместе с изображением, или указать обычную ссылку.

+ +

HTML5 содержит два новых элемента — {{htmlelement("figure")}} и {{htmlelement("figcaption")}}, которые, как предполагается, должны связывать какую-любо фигуру (всё что угодно, необязательно изображение) с заголовком фигуры:

+ +
<figure>
+  <img src="dinosaur.png" alt="Тираннозавр организации Mozilla">
+  <figcaption>Красный тираннозавр Рекс: стоящий как человек двуногий динозавр, с маленькими передними лапами и большой головой с большим количеством острых зубов.</figcaption>
+</figure>
+ +

К сожалению, большинство скринридеров, кажется, пока ещё не умеют связывать заголовки фигур с  самими фигурами, но такая структура элементов удобна для CSS стилизации, к тому же, она предоставляет способ расположить описание рядом с изображением в исходнике.

+ +

Пустые аттрибуты alt

+ +
<h3>
+  <img src="article-icon.png" alt="">
+  Тираннозавр Рекс: король динозвров
+</h3>
+ +

Бывает, что  в дизайне страницы присутствуют изображения, но они исполняют декоративную роль. В примере выше вы можете заметить, что у изображения пустой аттрибут alt — это сделано, чтобы скринридер опознал изображение, но не стал озвучивать её описание (вместо этого, он бы озвучил её как «изображение», или аналогично).

+ +

Причина, по которой стоит использовать пустой аттрибут alt, вместо того, чтобы просто его не указывать в том, что большинство скринридеров объявят весь URL-адрес изображения, если не указан alt. В пример выше изображение используется как украшение для связанного с ним заголовка. В таких случаях и случаях, когда изображение является украшением и не имеет ценное содержание, вы должны использовать пустой аттрибут alt. Другой вариант — использовать aria роль role="presentation". Это также предотвратит озвучивание скринридером альтернативного текста.

+ +
+

Примечание: По возможности для отображения декоративных изображений вы должны использовать CSS.

+
+ +

Заключение

+ +

Теперь вы должны хорошо разбираться в написании доступного HTML для большинства случаев. Наша статья про основы WAI-ARIA также заполнит пробелы в знаниях, но эта статья посвящена основам. Далее мы рассмотрим CSS и JavaScript, и как хорошое или плохое их использование влияет на доступность. 

+ +

{{PreviousMenuNext("Learn/Accessibility/What_is_Accessibility","Learn/Accessibility/CSS_and_JavaScript", "Learn/Accessibility")}}

+ + + +

В этом модуле

+ + diff --git a/files/ru/learn/accessibility/index.html b/files/ru/learn/accessibility/index.html new file mode 100644 index 0000000000..422bead1d7 --- /dev/null +++ b/files/ru/learn/accessibility/index.html @@ -0,0 +1,55 @@ +--- +title: Доступность +slug: Learn/Доступность +tags: + - CSS + - HTML + - JavaScript + - Удобство + - доступность +translation_of: Learn/Accessibility +--- +
{{LearnSidebar}}
+ +

Изучение HTML, CSS, и JavaScript полезно, если вы хотите стать веб-разработчиком, но ваши знания должны быть глубже обычного использования технологий — вы должны быть ответственны и максимизировать доступность ваших веб-приложений, не лишая никого возможности их использования. Чтобы достигнуть этого, вы можете следовать общепринятым лучшим практикам (которые демонстрируются в статьях посвященных HTML, CSS и JavaScript), проводить кросс-браузерное тестирование и обращать внимание на доступность с самого начала. В этом модуле мы рассмотрим эту тему в деталях.

+ +

Прежде чем начать

+ +

Чтобы разобраться с большей частью материалов этого модуля, хорошей идеей будет проходить одновременно один или несколько из модулей других тем (HTML, CSS или JavaScript), или, что ещё лучше, пройти соответствующие части данного модуля во время изучения этих технологий.

+ +
+

Примечание: Если вы работаете на компьютере/планшете/другом устройстве, на котором у вас нет возможности создавать файлы, вы можете попробовать большую часть примеров кода в онлайн программах, таких как JSBin или Thimble.

+
+ +

Справочники

+ +
+
Что такое доступность?
+
Данная статья открывает модуль, в котором рассматривается, что такое доступность на самом деле — она включает в себя группы людей, которые нам нужно учитывать и почему, какие инструменты используют разные пользователи для взаимодействия с вебом, и как мы можем сделать доступность частью нашего рабочего процесса веб-разработки.
+
HTML: Хорошая основа для доступности
+
Большая часть содержимого интернета может быть сделана доступной просто благодаря использованию HTML элементов по назначению. В этой статье подробно рассмотрено как HTML может быть использован для обеспечения максимальной доступности.
+
Лучшие практики CSS и JavaScript для обеспечения доступности
+
CSS и JavaScript, при правильном использовании, также имеют потенциал для обеспечения доступности, но при неправильном использовании они могут существенно ухудшить доступность. Эта статья раскрывает некоторые из лучших практик CSS и JavaScript которые должны помочь сделать даже очень сложное содержимое как можно более доступным.
+
Основы WAI-ARIA
+
Web Accessibility Initiative - Accessible Rich Internet Applications — это технологический стандарт для предоставления возможности полноценного использования Интернета людьми с физическими ограничениями.
+ Исходя из предыдущей статьи, иногда создание сложных элементов управления пользовательским интерфейсом, которые включают в себя не семантический HTML и динамический контент, обновляемый с помощью JavaScript, может быть затруднено. WAI-ARIA — это технология, которая может помочь в решении таких проблем, добавляя дополнительную семантику, которую браузеры и вспомогательные технологии могут распознавать и использовать, чтобы пользователи знали, что происходит. Здесь мы покажем, как использовать его на базовом уровне для улучшения доступности.
+
Доступный мультимедиа контент
+
Другая категория контента, которая может создавать проблемы с доступностью, это мультимедиа — видео, аудио и изображения, которые должны быть предоставлены с надлежащей текстовой альтернативой, чтобы их могли понять с помощью вспомогательных технологий и их пользователи. В этой статье показано, как это можно сделать.
+
Доступность на мобильных устройствах
+
Поскольку веб-доступ на мобильных устройствах является настолько популярным, и на популярных платформах, таких как iOS и Android, есть полноценные средства обеспечения доступности, важно учитывать доступность вашего веб-контента для этих платформ. В этой статье рассматриваются соображения доступности для мобильных устройств.
+
+ +

Проверка знаний

+ +
+
Найди недочеты в доступности
+
В этом блоке представлен достаточно простой сайт, в котором, однако, есть множество недочетов в доступности. Необходимо найти их и починить.
+
+ +

Также советуем посмотреть

+ + diff --git a/files/ru/learn/accessibility/mobile/index.html b/files/ru/learn/accessibility/mobile/index.html new file mode 100644 index 0000000000..bbdc7f0e1d --- /dev/null +++ b/files/ru/learn/accessibility/mobile/index.html @@ -0,0 +1,304 @@ +--- +title: Мобильная доступность +slug: Learn/Доступность/Mobile +tags: + - Mobile +translation_of: Learn/Accessibility/Mobile +--- +
+
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Accessibility/Multimedia","Learn/Accessibility/Accessibility_troubleshooting", "Learn/Accessibility")}}
+ +

With web access on mobile devices being so popular, and popular platforms such as iOS and Android having fully fledged accessibility tools, it is important to consider the accessibility of your web content on these platforms. This article looks at mobile-specific accessibility considerations.

+ + + + + + + + + + + + +
Prerequisites:Basic computer literacy, a basic understanding of HTML, CSS, and JavaScript, and an understanding of the previous articles in the course.
Objective:To understand what problems exist with accessibility on mobile devices, and how to overcome them.
+ +

Accessibility on mobile devices

+ +

The state of accessibility — and support for web standards in general — is good in modern mobile devices. Long gone are the days when mobile devices ran completely different web technologies to desktop browsers, forcing developers to use browser sniffing and serve them completely separate sites (although quite a few companies still detect usage of mobile devices and serve them a separate mobile domain).

+ +

These days, mobile devices in general can handle "full fat" websites, and the main platforms even have screenreaders built in to enable visually impaired users to use them successfully. Modern mobile browsers tend to have good support for WAI-ARIA, too.

+ +

To make a website accessible and usable on mobile, you just need to follow general good web design and accessibility best practices.

+ +

There are some exceptions that need special consideration for mobile; the main ones are:

+ +
    +
  • Control mechanisms — Make sure interface controls such as buttons are accessible on mobiles (i.e., mainly touchscreen), as well as desktops/laptops (mainly mouse/keyboard).
  • +
  • User input — Make user input requirements as painless as possible on mobile (e.g., in forms, keep typing to a minimum).
  • +
  • Responsive design — Make sure layouts work on mobile, conserve image download sizes, and think about provision of images for high-resolution screens.
  • +
+ +

Summary of screenreader testing on Android and iOS

+ +

The most common mobile platforms have fully functional screenreaders. These function in much the same way as desktop screenreaders, except they are largely operated using touch gestures rather than key combinations.

+ +

Let's look at the main two: TalkBack on Android and VoiceOver on iOS.

+ +

Android TalkBack

+ +

The TalkBack screenreader is built into the Android operating system.

+ +

To turn it on, select Settings > Accessibility > TalkBack, and then press the slider switch to turn it on. Follow any additional on-screen prompts that you are presented with.

+ +

Note: Older versions of TalkBack are turned on in slightly different ways.

+ +

When TalkBack is turned on, your Android device's basic controls will be a bit different. For example:

+ +
    +
  1. Single-tapping an app will select it, and the device will read out what the app is.
  2. +
  3. Swiping left and right will move between apps, or buttons/controls if you are in a control bar. The device will read out each option.
  4. +
  5. Double-tapping anywhere will open the app/select the option.
  6. +
  7. You can also "explore by touch" — hold your finger down on the screen and drag it around, and your device will read out the different apps/items you move across.
  8. +
+ +

If you want to turn TalkBack off:

+ +
    +
  1. Navigate to your Settings app using the above gestures.
  2. +
  3. Navigate to Accessibility > TalkBack.
  4. +
  5. Navigate to the slider switch and activate it to turn it off.
  6. +
+ +

Note: You can get to your homescreen at any time by swiping up and left in a smooth motion. If you have more than one homescreen, you can move between them by swiping two fingers left and right.

+ +

For a more complete list of TalkBack gestures, see Use TalkBack gestures.

+ +

Unlocking the phone

+ +

When TalkBack is turned on, unlocking the phone is a bit different.

+ +

You can do a two-finger swipe up from the bottom of the lock screen. If you've set a passcode or pattern for unlocking your device, you will then be taken to the relevant entry screen to enter it.

+ +

You can also explore by touch to find the Unlock button at the bottom middle of the screen, and then double-tap.

+ +

Global and local menus

+ +

TalkBack allows you to access global and local context menus, wherever you have navigated to on the device. The former provides global options relating to the device as a whole, and the latter provides options relating just to the current app/screen you are in.

+ +

To get to these menus:

+ +
    +
  1. Access the global menu by quickly swiping down, and then right.
  2. +
  3. Access the local menu by quickly swiping up, and then right.
  4. +
  5. Swipe left and right to cycle between the different options.
  6. +
  7. Once you've selected the option you want, double-click to choose that option.
  8. +
+ +

For details on all the options available under the global and local context menus, see Use global and local context menus.

+ +

Browsing web pages

+ +

You can use the local context menu while in a web browser to find options to navigate web pages using just the headings, form controls, or links, or navigate line by line, etc.

+ +

For example, with TalkBack turned on:

+ +
    +
  1. Open your web browser.
  2. +
  3. Activate the URL bar.
  4. +
  5. Enter a web page that has a bunch of headings on it, such as the front page of bbc.co.uk. To enter the text of the URL: +
      +
    • Select the URL bar by swiping left/right till you get to it, and then double-tapping.
    • +
    • Hold your finger down on the virtual keyboard until you get the character you want, and then release your finger to type it. Repeat for each character.
    • +
    • Once you've finished, find the Enter key and press it.
    • +
    +
  6. +
  7. Swipe left and right to move between different items on the page.
  8. +
  9. Swipe up and right with a smooth motion to enter the local content menu.
  10. +
  11. Swipe right until you find the "Headings and Landmarks" option.
  12. +
  13. Double-tap to select it. Now you'll be able to swipe left and right to move between headings and ARIA landmarks.
  14. +
  15. To go back to the default mode, enter the local context menu again by swiping up and right, select "Default", and then double-tap to activate.
  16. +
+ +

Note: See Get started on Android with TalkBack for more complete documentation.

+ +

iOS VoiceOver

+ +

A mobile version of VoiceOver is built into the iOS operating system.

+ +

To turn it on, go to Your Settings app and select General > Accessibility > VoiceOver. Press the VoiceOver slider to enable it (you'll also see a number of other options related to VoiceOver on this page).

+ +

Once VoiceOver is enabled, the iOS's basic control gestures will be a bit different:

+ +
    +
  1. A single tap will cause the item you tap on to be selected; your device will speak the item you've tapped on.
  2. +
  3. You can also navigate the items on the screen by swiping left and right to move between them, or by sliding your finger around on the screen to move between different items (when you find the item you want, you can remove your finger to select it).
  4. +
  5. To activate the selected item (e.g., open a selected app), double-tap anywhere on the screen.
  6. +
  7. Swipe with three fingers to scroll through a page.
  8. +
  9. Tap with two fingers to perform a context-relevant action — for example, taking a photo while in the camera app.
  10. +
+ +

To turn it off again, navigate back to Settings > General > Accessibility > VoiceOver using the above gestures, and toggle the VoiceOver slider back to off.

+ +

Unlock phone

+ +

To unlock the phone, you need to press the home button (or swipe) as normal. If you have a passcode set, you can select each number by swiping/sliding (as explained above) and then double-tapping to enter each number when you've found the right one.

+ +

Using the Rotor

+ +

When VoiceOver is turned on, you have a navigation feature called the Rotor available to you, which allows you to quickly choose from a number of common useful options. To use it:

+ +
    +
  1. Twist two fingers around on the screen like you are turning a dial. Each option will be read aloud as you twist further around. You can go back and forth to cycle through the options.
  2. +
  3. Once you've found the option you want: +
      +
    • Release your fingers to select it.
    • +
    • If it is an option you can iterate the value of (such as Volume or Speaking Rate), you can do a swipe up or down to increase or decrease the value of the selected item.
    • +
    +
  4. +
+ +

The options available under the Rotor are context-sensitive — they will differ depending on what app or view you are in (see below for an example).

+ +

Browsing web pages

+ +

Let's have a go at web browsing with VoiceOver:

+ +
    +
  1. Open your web browser.
  2. +
  3. Activate the URL bar.
  4. +
  5. Enter a web page that has a bunch of headings on it, such as the front page of bbc.co.uk. To enter the text of the URL: +
      +
    • Select the URL bar by swiping left/right until you get to it, and then double-tapping.
    • +
    • For each character, hold your finger down on the virtual keyboard until you get the character you want, and then release your finger to select it. Double-tap to type it.
    • +
    • Once you've finished, find the Enter key and press it.
    • +
    +
  6. +
  7. Swipe left and right to move between items on the page. You can double-tap an item to select it (e.g., follow a link).
  8. +
  9. By default, the selected Rotor option will be Speaking Rate; you can currently swipe up and down to increase or decrease the speaking rate.
  10. +
  11. Now turn two fingers around the screen like a dial to show the rotor and move between its options. Here are a few examples of the options available: +
      +
    • Speaking Rate: Change the speaking rate.
    • +
    • Containers: Move between different semantic containers on the page.
    • +
    • Headings: Move between headings on the page.
    • +
    • Links: Move between links on the page.
    • +
    • Form Controls: Move between form controls on the page.
    • +
    • Language: Move between different translations, if they are available.
    • +
    +
  12. +
  13. Select Headings. Now you'll be able to swipe up and down to move between headings on the page.
  14. +
+ +

Note: For a more complete reference covering the VoiceOver gestures available and other hints on accessibility testing on iOS, see Test Accessibility on Your Device with VoiceOver.

+ +

Control mechanisms

+ +

In our CSS and JavaScript accessibility article, we looked at the idea of events that are specific to a certain type of control mechanism (see Mouse-specific events). To recap, these cause accessibility issues because other control mechanisms can't activate the associated functionality.

+ +

As an example, the click event is good in terms of accessibility — an associated event handler can be invoked by clicking the element the handler is set on, tabbing to it and pressing Enter/Return, or tapping it on a touchscreen device. Try our simple-button-example.html example (see it running live) to see what we mean.

+ +

Alternatively, mouse-specific events such as mousedown and mouseup create problems — their event handlers cannot be invoked using non-mouse controls.

+ +

If you try to control our simple-box-drag.html (see example live) example with keyboard or touch, you'll see the problem. This occurs because we are using code such as the following:

+ +
div.onmousedown = function() {
+  initialBoxX = div.offsetLeft;
+  initialBoxY = div.offsetTop;
+  movePanel();
+}
+
+document.onmouseup = stopMove;
+ +

To enable other forms of control, you need to use different, yet equivalent events — for example, touch events work on touchscreen devices:

+ +
div.ontouchstart = function(e) {
+  initialBoxX = div.offsetLeft;
+  initialBoxY = div.offsetTop;
+  positionHandler(e);
+  movePanel();
+}
+
+panel.ontouchend = stopMove;
+ +

We've provided a simple example that shows how to use the mouse and touch events together — see multi-control-box-drag.html (see the example live also).

+ +

Note: You can also see fully functional examples showing how to implement different control mechanisms at Implementing game control mechanisms.

+ +

Responsive design

+ +

Responsive design is the practice of making your layouts and other features of your apps dynamically change depending on factors such as screen size and resolution, so they are usable and accessible to users of different device types.

+ +

In particular, the most common problems that need to be addressed for mobile are:

+ +
    +
  • Suitability of layouts for mobile devices. A multi-column layout won't work as well on a narrow screen, for example, and the text size may need to be increased so it is legible. Such issues can be solved by creating a responsive layout using technologies such as media queriesviewport, and flexbox.
  • +
  • Conserving image sizes downloaded. In general, small screen devices won't need images that are as large as their desktop counterparts, and they are more likely to be on slow network connections. Therefore, it is wise to serve smaller images to narrow screen devices as appropriate. You can handle this using responsive image techniques.
  • +
  • Thinking about high resolutions. Many mobile devices have high-resolution screens, and therefore need higher-resolution images so that the display can continue to look crisp and sharp. Again, you can serve images as appropriate using responsive image techniques. In addition, many image requirements can be fulfilled using the SVG vector images format, which is well-supported across browsers today. SVG has a small file size and will stay sharp regardless of whatever size is being displayed  (see Adding vector graphics to the web for more details).
  • +
+ +

Note: We won't provide a full discussion of responsive design techniques here, as they are covered in other places around MDN (see above links).

+ +

Specific mobile considerations

+ +

There are other important issues to consider when making sites more accessible on mobile. We have listed a couple here, but we will add more when we think of them.

+ +

Not disabling zoom

+ +

Using viewport, it is possible to disable zoom, using code like this in your {{htmlelement("head")}}:

+ +
<meta name="viewport" content="user-scalable=no">
+ +

You should never do this if at all possible — many people rely on zoom to be able to see the content of your website, so taking this functionality away is a really bad idea. There are certain situations where zooming might break the UI; in such cases, if you feel that you absolutely need to disable zoom, you should provide some other kind of equivalent, such as a control for increasing the text size in a way that doesn't break your UI.

+ +

Keeping menus accessible

+ +

Because the screen is so much narrower on mobile devices, it is very common to use media queries and other technologies to make the navigation menu shrink down to a tiny icon at the top of the display — which can be pressed to reveal the menu only if it's needed — when the site is viewed on mobile. This is commonly represented by a "three horizontal lines" icon, and the design pattern is consequently known as a "hamburger menu".

+ +

When implementing such a menu, you need to make sure that the control to reveal it is accessible by appropriate control mechanisms (normally touch for mobile), as discussed in {{anch("Control mechanisms")}} above, and that the rest of the page is moved out of the way or hidden in some way while the menu is being accessed, to avoid confusion with navigating it.

+ +

Click here for a good hamburger menu example.

+ +

User input

+ +

On mobile devices, inputting data tends to be more annoying for users than the equivalent experience on desktop computers. It is more convenient to type text into form inputs using a desktop or laptop keyboard than a touchscreen virtual keyboard or a tiny mobile physical keyboard.

+ +

For this reason, it is worth trying to minimize the amount of typing needed. As an example, instead of getting users to fill out their job title each time using a regular text input, you could instead offer a {{htmlelement("select")}} menu containing the most common options (which also helps with consistency in data entry), and offer an "Other" option that displays a text field to type any outliers into. You can see a simple example of this idea in action in common-job-types.html (see the common jobs example live).

+ +

It is also worth considering the use of HTML5 form input types such as date on mobile platforms as they handle them well — both Android and iOS, for example, display usable widgets that fit well with the device experience. See html5-form-examples.html for some examples (see the HTML5 form examples live) — try loading these and manipulating them on mobile devices. For example:

+ +
    +
  • Types numbertel, and email display suitable virtual keyboards for entering numbers/telephone numbers.
  • +
  • Types time and date display suitable pickers for selecting times and dates.
  • +
+ +

If you want to provide a different solution for desktops, you could always serve different markup to your mobile devices using feature detection. See input types for raw information on detecting different input types, and also check out our feature detection article for much more information.

+ +

Summary

+ +

In this article we have provided you with some details about common mobile accessibility-specific issues and how to overcome them. We also took you through usage of the most common screenreaders to aid you in accessibility testing.

+ +

See also

+ + + +
{{PreviousMenuNext("Learn/Accessibility/Multimedia","Learn/Accessibility/Accessibility_troubleshooting", "Learn/Accessibility")}}
+ +
+

В этом модуле

+ + +
+
diff --git a/files/ru/learn/accessibility/multimedia/index.html b/files/ru/learn/accessibility/multimedia/index.html new file mode 100644 index 0000000000..e07550ba5e --- /dev/null +++ b/files/ru/learn/accessibility/multimedia/index.html @@ -0,0 +1,360 @@ +--- +title: Доступность мультимедиа +slug: Learn/Доступность/Multimedia +tags: + - JavaScript +translation_of: Learn/Accessibility/Multimedia +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Accessibility/WAI-ARIA_basics","Learn/Accessibility/Mobile", "Learn/Accessibility")}}
+ +

Another category of content that can create accessibility problems is multimedia — video, audio, and image content need to be given proper textual alternatives so they can be understood by assistive technologies and their users. This article shows how.

+ + + + + + + + + + + + +
Prerequisites:Basic computer literacy, a basic understanding of HTML, CSS, and JavaScript, an understanding of what accessibility is.
Objective:To understand the accessibility issues behind multimedia, and how to overcome them.
+ +

Multimedia and accessibility

+ +

So far in this module we have looked at a variety of content and what needs to be done to ensure its accessibility, ranging from simple text content to data tables, images, native controls such as form elements and buttons, and even more complex markup structures (with WAI-ARIA attributes).

+ +

This article on the other hand looks at another general class of content that arguably isn't as easy to ensure accessibility for — multimedia. Images, videos, {{htmlelement("canvas")}} elements, Flash movies, etc., aren't as easily understood by screenreaders or navigated by the keyboard, and we need to give them a helping hand.

+ +

But don't despair — here we will help you navigate through the techniques available for making multimedia more accessible.

+ +

Simple images

+ +

We already covered simple text alternatives for HTML images in our HTML: A good basis for accessibility article — you can refer back to there for the full details. In short, you should ensure that where possible visual content has an alternative text available for screenreaders to pick up and read to their users.

+ +

For example:

+ +
<img src="dinosaur.png"
+     alt="A red Tyrannosaurus Rex: A two legged dinosaur standing upright like a human, with small arms, and a large head with lots of sharp teeth.">
+
+ +

Accessible audio and video controls

+ +

Implementing controls for web-based audio/video shouldn't be a problem, right? Let's investigate.

+ +

The problem with native HTML5 controls

+ +

HTML5 video and audio instances even come with a set of inbuilt controls that allow you to control the media straight out of the box. For example (see native-controls.html source code and live):

+ +
<audio controls>
+  <source src="viper.mp3" type="audio/mp3">
+  <source src="viper.ogg" type="audio/ogg">
+  <p>Your browser doesn't support HTML5 audio. Here is a <a href="viper.mp3">link to the audio</a> instead.</p>
+</audio>
+
+<br>
+
+<video controls>
+  <source src="rabbit320.mp4" type="video/mp4">
+  <source src="rabbit320.webm" type="video/webm">
+  <p>Your browser doesn't support HTML5 video. Here is a <a href="rabbit320.mp4">link to the video</a> instead.</p>
+</video>
+ +

The controls attribute provides play/pause buttons, seek bar, etc. — the basic controls you'd expect from a media player. It looks like so in Firefox and Chrome:

+ +

Screenshot of Video Controls in Firefox

+ +

Screenshot of Video Controls in Chrome

+ +

However, there are problems with these controls:

+ + + +

To remedy this, we can create our own custom controls. Let's look at how.

+ +

Creating custom audio and video controls

+ +

HTML5 video and audio share an API — HTML Media Element — which allows you to map custom functionality to buttons and other controls — both of which you define yourself.

+ +

Let's take the video example from above and add custom controls to them.

+ +

Basic setup

+ +

First, grab a copy of our custom-controls-start.html, custom-controls.css, rabbit320.mp4, and rabbit320.webm files and save them in a new directory on your hard drive.

+ +

Create a new file called main.js and save it in the same directory.

+ +

First of all, let's look at the HTML for the video player, in the HTML:

+ +
<section class="player">
+  <video controls>
+    <source src="rabbit320.mp4" type="video/mp4">
+    <source src="rabbit320.webm" type="video/webm">
+    <p>Your browser doesn't support HTML5 video. Here is a <a href="rabbit320.mp4">link to the video</a> instead.</p>
+  </video>
+
+  <div class="controls">
+    <button class="playpause">Play</button>
+    <button class="stop">Stop</button>
+    <button class="rwd">Rwd</button>
+    <button class="fwd">Fwd</button>
+    <div class="time">00:00</div>
+  </div>
+</section>
+ +

JavaScript basic setup

+ +

We've inserted some simple control buttons below our video. These controls of course won't do anything by default; to add functionality, we will use JavaScript.

+ +

We will first need to store references to each of the controls — add the following to the top of your JavaScript file:

+ +
var playPauseBtn = document.querySelector('.playpause');
+var stopBtn = document.querySelector('.stop');
+var rwdBtn = document.querySelector('.rwd');
+var fwdBtn = document.querySelector('.fwd');
+var timeLabel = document.querySelector('.time');
+ +

Next, we need to grab a reference to the video/audio player itself — add this line below the previous lines:

+ +
var player = document.querySelector('video');
+ +

This holds a reference to a {{domxref("HTMLMediaElement")}} object, which has several useful properties and methods available on it that can be used to wire up functionality to our buttons.

+ +

Before moving onto creating our button functionality, let's remove the native controls so they don't get in the way of our custom controls. Add the following, again at the bottom of your JavaScript:

+ +
player.removeAttribute('controls');
+ +

Doing it this way round rather than just not including the controls attribute in the first place has the advantage that if our JavaScript fails for any reason, the user still has some controls available.

+ +

Wiring up our buttons

+ +

First, let's set up the play/pause button. We can get this to toggle between play and pause with a simple conditional function, like the following. Add it to your code, at the bottom:

+ +
playPauseBtn.onclick = function() {
+  if(player.paused) {
+    player.play();
+    playPauseBtn.textContent = 'Pause';
+  } else {
+    player.pause();
+    playPauseBtn.textContent = 'Play';
+  }
+};
+ +

Next, add this code to the bottom, which controls the stop button:

+ +
stopBtn.onclick = function() {
+  player.pause();
+  player.currentTime = 0;
+  playPauseBtn.textContent = 'Play';
+};
+ +

There is no stop() function available on {{domxref("HTMLMediaElement")}}s, so instead we pause() it, and at the same time set the currentTime to 0.

+ +

Next, our rewind and fast forward buttons — add the following blocks to the bottom of your code:

+ +
rwdBtn.onclick = function() {
+  player.currentTime -= 3;
+};
+
+fwdBtn.onclick = function() {
+  player.currentTime += 3;
+  if(player.currentTime >= player.duration || player.paused) {
+    player.pause();
+    player.currentTime = 0;
+    playPauseBtn.textContent = 'Play';
+  }
+};
+ +

These are very simple, just adding or subtracting 3 seconds to the currentTime each time they are clicked. In a real video player, you'd probably want a more elaborate seeking bar, or similar.

+ +

Note that we also check to see if the currentTime is more than the total media duration, or if the media is not playing, when the Fwd button is pressed. If either conditions are true, we simply stop the video, to avoid the user interface going wrong if they attempt to fast forward when the video is not playing, or fast forward past the end of the video.

+ +

Last of all, add the following to the end of the code, to control the time elapsed display:

+ +
player.ontimeupdate = function() {
+  var minutes = Math.floor(player.currentTime / 60);
+  var seconds = Math.floor(player.currentTime - minutes * 60);
+  var minuteValue;
+  var secondValue;
+
+  if (minutes<10) {
+    minuteValue = "0" + minutes;
+  } else {
+    minuteValue = minutes;
+  }
+
+  if (seconds<10) {
+    secondValue = "0" + seconds;
+  } else {
+    secondValue = seconds;
+  }
+
+  mediaTime = minuteValue + ":" + secondValue;
+  timeLabel.textContent = mediaTime;
+};
+ +

Each time the time updates (once per second), we fire this function. It works out the number of minutes and seconds from the given currentTime value that is just in seconds, adds a leading 0 if either the minute or second value is less than 10, and then create the display readout and adds it to the time label.

+ +

Further reading

+ +

This gives you a basic idea of how to add custom player functionality to video/audio player instances. For more information on how to add more complex features to video/audio players, including Flash fallbacks for older browsers, see:

+ + + +

We've also created an advanced example to show how you could create an object-oriented system that finds every video and audio player on the page (no matter how many there are) and adds our custom controls to it. See custom-controls-oojs (also see the source code).

+ +

Audio transcripts

+ +

To provide deaf people with access to audio content, you really need to create text transcripts. These can either be included on the same page as the audio in some way, or included on a separate page and linked to.

+ +

In terms of actually creating the transcript, your options are:

+ + + +

As with most things in life, you tend to get what you pay for; different services will vary in accuracy and time taken to produce the transcript. If you pay a reputable company or AI service to do the transcription, you will probably get it done rapidly and to a high quality. If you don't want to pay for it, you are likely to get it done at a lower quality, and/or slowly.

+ +

It is not OK to publish an audio resource but promise to publish the transcript later on — such promises often aren't kept, which will erode trust between you and your users. If the audio you are presenting is something like a face to face meeting or live spoken performance, it would be acceptable to take notes during the performance, publish them in full along with the audio, then seek help in cleaning up the notes afterwards.

+ +

Transcript examples

+ +

If you use an automated service, then you'll probably have to use the user interface that the tool provides. For example, take a look at Audio Transcription Sample 1 and choose More > Transcript.

+ +

If you are creating your own user interface to present your audio and associated transcript, you can do it however you like, but it might make sense to include it in a showable/hideable panel; see our audio-transcript-ui example (also see the source code).

+ +

Audio descriptions

+ +

On occasions where there are visuals accompanying your audio, you'll need to provide audio descriptions of some kind to describe that extra content.

+ +

In many cases this will simply take the form of video, in which case you can implement captions using the techniques described in the next section of the article.

+ +

However, there are some edge cases. You might for example have an audio recording of a meeting that refers to an accompanying resource such as a spreadsheet or chart. In such cases, you should make sure that the resources are provided along with the audio + transcript, and specifically link to them in the places where they are referred to in the transcript. This of course will help all users, not just people who are deaf.

+ +
+

Note: An audio transcript will in general help multiple user groups. As well as giving deaf users access to the information contained in the audio, think about a user with a low bandwidth connection, who would find downloading the audio inconvenient. Think also about a user in a noisy environment like a pub or bar, who is trying to access the information but can't hear it over the noise.

+
+ +

Video text tracks

+ +

To make video accessible for deaf, blind, or even other groups of users (such as those on low bandwidth, or who don't understand the language the video is recorded in), you need to include text tracks along with your video content.

+ +
+

Note: text tracks are also useful for potentially any user, not just those with disabilities. for example, some users may not be able to hear the audio because they are in noisy environments (like a crowded bar when a sports game is being shown) or might not want to disturb others if they are in a quiet place (like a library.)

+
+ +

This is not a new concept — television services have had closed captioning available for quite a long time:

+ +

Frame from an old-timey cartoon with closed captioning "Good work, Goldie. Keep it up!"

+ +

Whereas many countries offer English films with subtitles written in their own native languages, and different language subtitles are often available on DVDs, for example

+ +

An English film with German subtitles "Emo, warum erkennst du nicht die Schonheit dieses Ortes?"

+ +

There are different types of text track with different purposes. The main ones you'll come across are:

+ + + +

Implementing HTML5 video text tracks

+ +

Text tracks for displaying with HTML5 video need to be written in WebVTT, a text format containing multiple strings of text along with metadata such as what time in the video you want each text string to be displayed, and even limited styling/positioning information. These text strings are called cues.

+ +

A typical WebVTT file will look something like this:

+ +
WEBVTT
+
+1
+00:00:22.230 --> 00:00:24.606
+This is the first subtitle.
+
+2
+00:00:30.739 --> 00:00:34.074
+This is the second.
+
+  ...
+ +

To get this displayed along with the HTML media playback, you need to:

+ + + +

Here's an example:

+ +
<video controls>
+    <source src="example.mp4" type="video/mp4">
+    <source src="example.webm" type="video/webm">
+    <track kind="subtitles" src="subtitles_en.vtt" srclang="en">
+</video>
+ +

This will result in a video that has subtitles displayed, kind of like this:

+ +

Video player with standard controls such as play, stop, volume, and captions on and off. The video playing shows a scene of a man holding a spear-like weapon, and a caption reads "Esta hoja tiene pasado oscuro."

+ +

For more details, please read Adding captions and subtitles to HTML5 video. You can find the example that goes along with this article on Github, written by Ian Devlin (see the source code too.) This example uses some JavaScript to allow users to choose between different subtitles. Note that to turn the subtitles on, you need to press the "CC" button and select an option — English, Deutsch, or Español.

+ +
+

Note: Text tracks and transcriptions also help you with {{glossary("SEO")}}, since search engines especially thrive on text. Text tracks even allow search engines to link directly to a spot partway through the video.

+
+ +

Other multimedia content

+ +

The above sections don't cover all types of multimedia content that you might want to put on a web page. You might also need to deal with games, animations, slideshows, embedded video, and content created using other available technologies such as:

+ + + +

For such content, you need to deal with accessibility concerns on a case by case basis. In some cases it is not so bad, for example:

+ + + +

However, other multimedia is not so easy to make accessible. If for example you are dealing with an immersive 3D game or virtual reality app, it really is quite difficult to provide text alternatives for such an experience, and you might argue that blind users are not really in the target audience bracket for such apps.

+ +

You can however make sure that such an app has good enough color contrast and clear presentation so it is perceivable to those with low vision/color blindness, and also make it keyboard accessible. Remember that accessibility is about doing as much as you can, rather than striving for 100% accessibility all the time, which is often impossible.

+ +

Summary

+ +

This chapter has provided a summary of accessibility concerns for multimedia content, along with some practical solutions.

+ +

{{PreviousMenuNext("Learn/Accessibility/WAI-ARIA_basics","Learn/Accessibility/Mobile", "Learn/Accessibility")}}

+ +

 

+ +

В этом модуле

+ + + +

 

diff --git a/files/ru/learn/accessibility/wai-aria_basics/index.html b/files/ru/learn/accessibility/wai-aria_basics/index.html new file mode 100644 index 0000000000..d04c4fd483 --- /dev/null +++ b/files/ru/learn/accessibility/wai-aria_basics/index.html @@ -0,0 +1,416 @@ +--- +title: Основы WAI-ARIA +slug: Learn/Доступность/WAI-ARIA_basics +tags: + - JavaScript +translation_of: Learn/Accessibility/WAI-ARIA_basics +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Accessibility/CSS_and_JavaScript","Learn/Accessibility/Multimedia", "Learn/Accessibility")}}
+ +

Исходя из предыдущей статьи, иногда создание сложных элементов UI, которые включают в себя неcемантичный HTML и динамически обновляемый с помощью JavaScript контент, может быть затруднено. WAI-ARIA - это технология, которая может помочь в решении таких проблем, добавляя дополнительную разметку, которую браузеры и вспомогательные технологии могут распознавать и использовать, чтобы пользователи знали, что происходит. В этой статье мы покажем, как использовать эту технологию на базовом уровне для улучшения доступности.

+ + + + + + + + + + + + +
Необходимые знания:Базовая компьютерная грамотность, базовое понимание HTML, CSS и JavaScript, понимание предыдущей статьи курса.
Цель:Ознакомиться с WAI-ARIA и узнать, как эту технологию можно использовать для включения полезной дополнительной семантики в целях повышения доступности.
+ +

Что такое WAI-ARIA?

+ +

Давайте начнем с рассмотрения того, что такое WAI-ARIA и чем она может быть полезна.

+ +

Новый набор проблем

+ +

С тех пор как веб-приложения стали более сложными и динамичными, появились новые специальные возможности и проблемы.

+ +

Например, HTML5 ввел ряд семантических элементов, чтобы определить общую разметку страниц ( <nav><footer>и т.д.). До того как они были доступны, разработчики просто использовали <div> с идентификаторами или классами, например <div class="nav">, но это создавало проблемы, так как не было никакого простого способа найти определенный раздел страницы программным способом.

+ +

Первоначальным решением было добавить одну или несколько скрытых ссылок вверху страницы для ссылки на навигацию (или на что-то еще), например:

+ +
<a href="#hidden" class="hidden">Skip to navigation</a>
+ +

Но это все еще не очень точно, и может использоваться только тогда, когда программа чтения с экрана читает сверху страницы.

+ +

В качестве другого примера, в приложения стали использовать сложные элементы управления, такие как поля выбора даты, ползунки для выбора значений и т.д. HTML5 предоставляет специальные типы ввода для отображения таких элементов управления:

+ +
<input type="date">
+<input type="range">
+ +

Они не очень хорошо поддерживаются в разных браузерах, и их очень сложно стилизовать, что делает их не очень полезными для интеграции с дизайном сайтов. В результате разработчики нередко используют библиотеки JavaScript, которые генерируют такие элементы управления, как последовательность вложенных <div>элементов или ячеек таблиц с именами классов, которые затем стилизуются с помощью CSS и управляют с помощью JavaScript.

+ +

The problem here is that visually they work, but screenreaders can't make any sense of what they are at all, and their users just get told that they can see a jumble of elements with no semantics to describe what they mean.

+ +

Enter WAI-ARIA

+ +

WAI-ARIA is a specification written by the W3C, defining a set of additional HTML attributes that can be applied to elements to provide additional semantics and improve accessibility wherever it is lacking. There are three main features defined in the spec:

+ + + +

An important point about WAI-ARIA attributes is that they don't affect anything about the web page, except for the information exposed by the browser's accessibility APIs (where screenreaders get their information from). WAI-ARIA doesn't affect webpage structure, the DOM, etc., although the attributes can be useful for selecting elements by CSS.

+ +
+

Note: You can find a useful list of all the ARIA roles and their uses, with links to futher information, in the WAI-ARIA spec — see Definition of Roles.

+ +

The spec also contains a list of all the properties and states, with links to further information — see Definitions of States and Properties (all aria-* attributes).

+
+ +

Where is WAI-ARIA supported?

+ +

This is not an easy question to answer. It is difficult to find a conclusive resource that states what features of WAI-ARIA are supported, and where, because:

+ +
    +
  1. There are a lot of features in the WAI-ARIA spec.
  2. +
  3. There are many combinations of operating system, browser, and screenreader to consider.
  4. +
+ +

This last point is key — To use a screenreader in the first place, your operating system needs to run browsers that have the necessary accessibility APIs in place to expose the information screenreaders need to do their job. Most popular OSes have one or two browsers in place that screenreaders can work with. The Paciello Group has a fairly up-to-date post that provides data for this — see Rough Guide: browsers, operating systems and screen reader support updated.

+ +

Next, you need to worry about whether the browsers in question support ARIA features and expose them via their APIs, but also whether screenreaders recognise that information and present it to their users in a useful way.

+ +
    +
  1. Browser support is generally quite good — at the time of writing, caniuse.com stated that global browser support for WAI-ARIA was around 88%.
  2. +
  3. Screenreader support for ARIA features isn't quite at this level, but the most popular screenreaders are getting there. You can get an idea of support levels by looking at Powermapper's WAI-ARIA Screen reader compatibility article.
  4. +
+ +

In this article, we won't attempt to cover every WAI-ARIA feature, and its exact support details. Instead, we will cover the most critical WAI-ARIA features for you to know about; if we don't mention any support details, you can assume that the feature is well-supported. We will clearly mention any exceptions to this.

+ +
+

Note: Some JavaScript libraries support WAI-ARIA, meaning that when they generate UI features like complex form controls, they add ARIA attributes to improve the accessibility of those features. If you are looking for a 3rd party JavaScript solution for rapid UI development, you should definitely consider the accessibility of its UI widgets as an important factor when making your choice. Good examples are jQuery UI (see About jQuery UI: Deep accessibility support), ExtJS, and Dojo/Dijit.

+
+ +

When should you use WAI-ARIA?

+ +

We talked about some of the problems that prompted WAI-ARIA to be created earlier on, but essentially, there are four main areas that WAI-ARIA is useful in:

+ +
    +
  1. Signposts/Landmarks: ARIA's role attribute values can act as landmarks that either replicate the semantics of HTML5 elements (e.g. {{htmlelement("nav")}}), or go beyond HTML5 semantics to provide signposts to different functional areas, e.g search, tabgroup, tab, listbox, etc.
  2. +
  3. Dynamic content updates: Screenreaders tend to have difficulty with reporting constantly changing content; with ARIA we can use aria-live to inform screenreader users when an area of content is updated, e.g. via XMLHttpRequest, or DOM APIs.
  4. +
  5. Enhancing keyboard accessibility: There are built-in HTML elements that have native keyboard accessibility; when other elements are used along with JavaScript to simulate similar interactions, keyboard accessibility and screenreader reporting suffers as a result. Where this is unavoidable, WAI-ARIA provides a means to allow other elements to receive focus (using tabindex).
  6. +
  7. Accessibility of non-semantic controls: When a series of nested <div>s along with CSS/JavaScript is used to create a complex UI-feature, or a native control is greatly enhanced/changed via JavaScript, accessibility can suffer — screenreader users will find it difficult to work out what the feature does if there are no semantics or other clues. In these situations, ARIA can help to provide what's missing with a combination of roles like button, listbox, or tabgroup, and properties like aria-required or aria-posinset to provide further clues as to functionality.
  8. +
+ +

One thing to remember though — you should only use WAI-ARIA when you need to! Ideally, you should always use native HTML features to provide the semantics required by screenreaders to tell their users what is going on. Sometimes this isn't possible, either because you have limited control over the code, or because you are creating something complex that doesn't have an easy HTML element to implement it. In such cases, WAI-ARIA can be a valuable accessibility enhancing tool.

+ +

But again, only use it when necessary!

+ +
+

Note: Also, try to make sure you test your site with a variety of real users — non-disabled people, people using screenreaders, people using keyboard navigation, etc. They will have better insights than you about how well it works.

+
+ +

Practical WAI-ARIA implementations

+ +

In the next section we'll look at the four areas in more detail, along with practical examples. Before you continue, you should get a screenreader testing setup put in place, so you can test some of the examples as you go through.

+ +

See our section on testing screenreaders for more information.

+ +

Signposts/Landmarks

+ +

WAI-ARIA adds the role attribute to browsers, which allows you to add extra semantic value to elements on your site wherever they are needed. The first major area in which this is useful is providing information for screenreaders so that their users can find common page elements. Let's look at an example — our website-no-roles example (see it live) has the following structure:

+ +
<header>
+  <h1>...</h1>
+  <nav>
+    <ul>...</ul>
+    <form>
+      <!-- search form  -->
+    </form>
+  </nav>
+</header>
+
+<main>
+  <article>...</article>
+  <aside>...</aside>
+</main>
+
+<footer>...</footer>
+ +

If you try testing the example with a screenreader in a modern browser, you'll already get some useful information. For example, VoiceOver gives you the following:

+ + + +

If you go to VoiceOver's landmarks menu (accessed using VoiceOver key + U and then using the cursor keys to cycle through the menu choices), you'll see that most of the elements are nicely listed so they can be accessed quickly.

+ +

+ +

However, we could do better here. the search form is a really important landmark that people will want to find, but it is not listed in the landmarks menu or treated like a notable landmark, beyond the actual input being called out as a search input (<input type="search">). In addition, some older browsers (most notably IE8) don't recognise the semantics of the HTML5 elements.

+ +

Let's improve it by the use of some ARIA features. First, we'll add some role attributes to our HTML structure. You can try taking a copy of our original files (see index.html and style.css), or navigating to our website-aria-roles example (see it live), which has a structure like this:

+ +
<header>
+  <h1>...</h1>
+  <nav role="navigation">
+    <ul>...</ul>
+    <form role="search">
+      <!-- search form  -->
+    </form>
+  </nav>
+</header>
+
+<main>
+  <article role="article">...</article>
+  <aside role="complementary">...</aside>
+</main>
+
+<footer>...</footer>
+ +

We've also given you a bonus feature in this example — the {{htmlelement("input")}} element has been given the attribute aria-label, which gives it a descriptive label to be read out by a screenreader, even though we haven't included a {{htmlelement("label")}} element. In cases like these, this is very useful — a search form like this one is a very common, easily recognised feature, and adding a visual label would spoil the page design.

+ +
<input type="search" name="q" placeholder="Search query" aria-label="Search through site content">
+ +

Now if we use VoiceOver to look at this example, we get some improvements:

+ + + +

Beyond this, the site is more likely to be accessible to users of older browsers such as IE8; it is worth including ARIA roles for that purpose. And if for some reason your site is built using just <div>s, you should definitely include the ARIA roles to provide these much needed semantics!

+ +

The improved semantics of the search form have shown what is made possible when ARIA goes beyond the semantics available in HTML5. You'll see a lot more about these semantics and the power of ARIA properties/attributes below, especially in the {{anch("Accessibility of non-semantic controls")}} section. For now though, let's look at how ARIA can help with dynamic content updates.

+ +

Dynamic content updates

+ +

Content loaded into the DOM can be easily accessed using a screenreader, from textual content to alternative text attached to images. Traditional static websites with largely text content are therefore easy to make accessible for people with visual impairments.

+ +

The problem is that modern web apps are often not just static text — they tend to have a lot of dynamically updating content, i.e. content that updates without the entire page reloading via a mechanism like XMLHttpRequest, Fetch, or DOM APIs. These are sometimes referred to as live regions.

+ +

Let's look at a quick example — see aria-no-live.html (also see it running live). In this example we have a simple random quote box:

+ +
<section>
+  <h1>Random quote</h1>
+  <blockquote>
+    <p></p>
+  </blockquote>
+</section>
+ +

Our JavaScript loads a JSON file via XMLHttpRequest containing a series of random quotes and their authors. Once that is done, we start up a setInterval() loop that loads a new random quote into the quote box every 10 seconds:

+ +
var intervalID = window.setInterval(showQuote, 10000);
+ +

This works OK, but it is not good for accessibility — the content update is not detected by screenreaders, so their users would not know what is going on. This is a fairly trivial example, but just imagine if you were creating a complex UI with lots of constantly updating content, like a chat room, or a strategy game UI, or a live updating shopping cart display — it would be impossible to use the app in any effective way without some kind of way of alerting the user to the updates.

+ +

WAI-ARIA fortunately provides a useful mechanism to provide these alerts — the aria-live property. Applying this to an element causes screenreaders to read out the content that is updated. How urgently the content is read out depends on the attribute value:

+ + + +

We'd like you to take a copy of aria-no-live.html and quotes.json, and update your <section> tag as follows:

+ +
<section aria-live="assertive">
+ +

This will cause a screenreader to read out the content as it is updated.

+ +
+

Note: Most browsers will throw a security exception if you try to do an XMLHttpRequest call from a file:// URL, e.g. if you just load the file by loading it directly into the browser (via double clicking, etc.). To get it to run, you will need to upload it to a web server, for example using GitHub, or a local web server like Python's SimpleHTTPServer.

+
+ +

There is an additional consideration here — only the bit of text that updates is read out. It might be nice if we always read out the heading too, so the user can remember what is being read out. To do this, we can add the aria-atomic property to the section. Update your <section> tag again, like so:

+ +
<section aria-live="assertive" aria-atomic="true">
+ +

The aria-atomic="true" attribute tells screenreaders to read out the entire element contents as one atomic unit, not just the bits that were updated.

+ +
+

Note: You can see the finished example at aria-live.html (see it running live).

+
+ +
+

Note: The aria-relevant property is also quite useful for controlling what gets read out when a live region is updated. You can for example only get content additions or removals read out.

+
+ +

Enhancing keyboard accessibility

+ +

As discussed in a few other places in the module, one of the key strengths of HTML with respect to accessibility is the built-in keyboard accessibility of features such as buttons, form controls, and links. Generally, you are able to use the tab key to move between controls, the Enter/Return key to select or activate controls, and occasionally other controls as needed (for example the up and down cursor to move between options in a <select> box).

+ +

However, sometimes you will end up having to write code that either uses non-semantic elements as buttons (or other types of control), or uses focusable controls for not quite the right purpose. You might be trying to fix some bad code you've inherited, or you might be building some kind of complex widget that requires it.

+ +

In terms of making non-focusable code focusable, WAI-ARIA extends the tabindex attribute with some new values:

+ + + +

We discussed this in more detail and showed a typical implementation back in our HTML accessibility article — see Building keyboard accessibility back in.

+ +

Accessibility of non-semantic controls

+ +

This follows on from the previous section — when a series of nested <div>s along with CSS/JavaScript is used to create a complex UI-feature, or a native control is greatly enhanced/changed via JavaScript, not only can keyboard accessibility suffer, but screenreader users will find it difficult to work out what the feature does if there are no semantics or other clues. In such situations, ARIA can help to provide those missing semantics.

+ +

Form validation and error alerts

+ +

First of all, let's revisit the form example we first looked at in our CSS and JavaScript accessibility article (read Keeping it unobtrusive for a full recap). At the end of this section we showed that we have included some ARIA attributes on the error message box that appears when there are validation errors when you try to submit the form:

+ +
<div class="errors" role="alert" aria-relevant="all">
+  <ul>
+  </ul>
+</div>
+ + + +

We could go further with our ARIA usage, and provide some more validation help. How about indicating whether fields are required in the first place, and what range the age should be?

+ +
    +
  1. At this point, take a copy of our form-validation.html and validation.js files, and save them in a local directory.
  2. +
  3. Open them both in a text editor and have a look at how the code works.
  4. +
  5. First of all, add a paragraph just above the opening <form> tag, like the one below, and mark both the form <label>s with an asterisk. This is normally how we mark required fields for sighted users. +
    <p>Fields marked with an asterisk (*) are required.</p>
    +
  6. +
  7. This makes visual sense, but it isn't as easy to understand for screenreader users. Fortunately, WAI-ARIA provides the aria-required attribute to give screenreaders hints that they should tell users that form inputs need to be filled in. Update the <input> elements like so: +
    <input type="text" name="name" id="name" aria-required="true">
    +
    +<input type="number" name="age" id="age" aria-required="true">
    +
  8. +
  9. If you save the example now and test it with a screenreader, you should hear something like "Enter your name star, required, edit text".
  10. +
  11. It might also be useful if we give screenreader users and sighted users an idea of what the age value should be. This is often presented as a tooltip, or placeholder inside the form field perhaps. WAI-ARIA does include aria-valuemin and aria-valuemax properties to specify min and max values, but these currently don't seem very well supported; a better supported feature is the HTML5 placeholder attribute, which can contain a message that is shown in the input when no value is entered, and is read out by a number of screenreaders. Update your number input like this: +
    <input type="number" name="age" id="age" placeholder="Enter 1 to 150" aria-required="true">
    +
  12. +
+ +
+

Note: You can see the finished example live at form-validation-updated.html.

+
+ +

WAI-ARIA also enables some advanced form labelling techniques, beyond the classic {{htmlelement("label")}} element. We already talked about using the aria-label property to provide a label where we don't want the label to be visible to sighted users (see the {{anch("Signposts/Landmarks")}} section, above). There are some other labelling techniques that use other properties such as aria-labelledby if you want to designate a non-<label> element as a label or label multiple form inputs with the same label, and aria-describedby, if you want to associate other information with a form input and have it read out as well. See WebAIM's Advanced Form Labeling article for more details.

+ +

There are many other useful properties and states too, for indicating the status of form elements. For example, aria-disabled="true" can be used to indicate that a form field is disabled. Many browsers will just skip past disabled form fields, and they won't even be read out by screenreaders, but in some cases they will be perceived, so it is a good idea to include this attribute to let the screenreader know that a disabled input is in fact disabled.

+ +

If the disabled state of an input is likely to change, then it is also a good idea to indicate when it happens, and what the result is. For example, in our form-validation-checkbox-disabled.html demo there is a checkbox that when checked, enables another form input to allow further information be entered. We've set up a hidden live region:

+ +
<p class="hidden-alert" aria-live="assertive"></p>
+ +

which is hidden from view using absolute positioning. When this is checked/unchecked, we update the text inside the hidden live region to tell screenreader users what the result of checking this checkbox is, as well as updating the aria-disabled state, and some visual indicators too:

+ +
function toggleMusician(bool) {
+  var instruItem = formItems[formItems.length-1];
+  if(bool) {
+    instruItem.input.disabled = false;
+    instruItem.label.style.color = '#000';
+    instruItem.input.setAttribute('aria-disabled', 'false');
+    hiddenAlert.textContent = 'Instruments played field now enabled; use it to tell us what you play.';
+  } else {
+    instruItem.input.disabled = true;
+    instruItem.label.style.color = '#999';
+    instruItem.input.setAttribute('aria-disabled', 'true');
+    instruItem.input.removeAttribute('aria-label');
+    hiddenAlert.textContent = 'Instruments played field now disabled.';
+  }
+}
+ +

Describing non-semantic buttons as buttons

+ +

A few times in this course already, we've mentioned the native accessibilty of (and the accessibility issues behind using other elements to fake) buttons, links, or form elements (see UI controls in the HTML accessibility article, and {{anch("Enhancing keyboard accessibility")}}, above). Basically, you can add keyboard accessibility back in without too much trouble in many cases, using tabindex and a bit of JavaScript.

+ +

But what about screenreaders? They still won't see the elements as buttons. If we test our fake-div-buttons.html example in a screenreader, our fake buttons will be reported using phrases like "Click me!, group", which is obviously confusing.

+ +

We can fix this using a WAI-ARIA role. Make a local copy of fake-div-buttons.html, and add role="button" to each button <div>, for example:

+ +
<div data-message="This is from the first button" tabindex="0" role="button">Click me!</div>
+ +

Now when you try this using a screenreader, you'll have buttons be reported using phrases like "Click me!, button" — much better.

+ +
+

Note: Don't forget however that using the correct semantic element where possible is always better. If you want to create a button, and can use a {{htmlelement("button")}} element, you should use a {{htmlelement("button")}} element!

+
+ +

Guiding users through complex widgets

+ +

There are a whole host of other roles that can identify non-semantic element structures as common UI features that go beyond what's available in standard HTML, for example combobox, slider, tabpanel, tree. You can see a number of userful examples in the Deque university code library, to give you an idea of how such controls can be made accessible.

+ +

Let's go through an example of our own. We'll return to our simple absolutely-positioned tabbed interface (see Hiding things in our CSS and JavaScript accessibility article), which you can find at Tabbed info box example (see source code).

+ +

This example as-is works fine in terms of keyboard accessibility — you can happily tab between the different tabs and select them to show the tab contents. It is also fairly accessible too — you can scroll through the content and use the headings to navigate , even if you can't see what is happening on screen. It is however not that obvious what the content is — a screenreader currently reports the content as a list of links, and some content with three headings. It doesn't give you any idea of what the relationship is between the content. Giving the user more clues as to the structure of the content is always good.

+ +

To improve things, we've created a new version of the example called aria-tabbed-info-box.html (see it running live). We've updated the structure of the tabbed interface like so:

+ +
<ul role="tablist">
+  <li class="active" role="tab" aria-selected="true" aria-setsize="3" aria-posinset="1" tabindex="0">Tab 1</li>
+  <li role="tab" aria-selected="false" aria-setsize="3" aria-posinset="2" tabindex="0">Tab 2</li>
+  <li role="tab" aria-selected="false" aria-setsize="3" aria-posinset="3" tabindex="0">Tab 3</li>
+</ul>
+<div class="panels">
+  <article class="active-panel" role="tabpanel" aria-hidden="false">
+    ...
+  </article>
+  <article role="tabpanel" aria-hidden="true">
+    ...
+  </article>
+  <article role="tabpanel" aria-hidden="true">
+    ...
+  </article>
+</div>
+ +
+

Note: The most striking change here is that we've removed the links that were originally present in the example, and just used the list items as the tabs — this was done because it makes things less confusing for screenreader users (the links don't really take you anywhere; they just change the view), and it allows the setsize/position in set features to work better — when these were put on the links, the browser kept reporting "1 of 1" all the time, not "1 of 3", "2 of 3", etc.

+
+ +

The new features are as follows:

+ + + +

In our tests, this new structure did serve to improve things overall. The tabs are now recognised as tabs (e.g. "tab" is spoken by the screenreader), the selected tab is indicated by "selected" being read out with the tab name, and the screenreader also tells you which tab number you are currently on. In addition, because of the aria-hidden settings (only the non-hidden tab ever has aria-hidden="false" set), the non-hidden content is the only one you can navigate down to, meaning the selected content is easier to find.

+ +
+

Note: If there is anything you explicitly don't want screen readers to read out, you can give them the aria-hidden="true"  attribute.

+
+ +

Summary

+ +

This article has by no means covered all that's available in WAI-ARIA, but it should have given you enough information to understand how to use it, and know some of the most common patterns you will encounter that require it.

+ +

See also

+ + + +

{{PreviousMenuNext("Learn/Accessibility/CSS_and_JavaScript","Learn/Accessibility/Multimedia", "Learn/Accessibility")}}

+ +

В этом модуле

+ + diff --git a/files/ru/learn/accessibility/what_is_accessibility/index.html b/files/ru/learn/accessibility/what_is_accessibility/index.html new file mode 100644 index 0000000000..1a6e11f73e --- /dev/null +++ b/files/ru/learn/accessibility/what_is_accessibility/index.html @@ -0,0 +1,210 @@ +--- +title: Что такое доступность? +slug: Learn/Доступность/What_is_accessibility +tags: + - CSS + - HTML + - JavaScript + - Изучение + - Клавиатура + - Написание скриптов + - Начинающий + - Программные средства + - Статья + - Считыватель экрана + - вспомогательная технология + - доступность +translation_of: Learn/Accessibility/What_is_accessibility +--- +
{{LearnSidebar}}
+ +
{{NextMenu("Learn/Accessibility/HTML", "Learn/Accessibility")}}
+ +

Данная статья открывает модуль, в котором рассматривается, что такое доступность на самом деле — она включает в себя группы людей, которые нам нужно учитывать и почему, какие инструменты используют разные пользователи для взаимодействия с вебом, и как мы можем сделать доступность частью нашего рабочего процесса веб-разработки.

+ + + + + + + + + + + + +
Необходимые знания:Базовая компьютерная грамотность, базовое понимание HTML и CSS.
Цель:Узнать, что такое доступность, и как она влияет на вас как на веб-разработчика.
+ +

Итак, что такое доступность?

+ +

Доступность — это практика, позволяющая использовать ваши сайты как можно большему числу людей. Мы традиционно думаем об этом как о доступности для людей с ограниченными возможностями, но на самом деле, в это число входят и другие группы пользователей, которые используют мобильные устройства либо имеют медленное сетевое соединение.

+ +

Вы также можете думать о доступности как о способе предоставления равных прав и одинаковых возможностей, независимо от способностей или обстоятельств. Точно так же, как не правильно лишать человека права посещать разнообразные места, только потому что он перемещается в инвалидном кресле (общественные здания в наши дни обычно имеют пандусы для инвалидных колясок или лифты), так и не правильно исключать кого-либо из веб-пространства из-за того, что у них слабое зрение или они используют мобильный телефон. Мы все разные, но все мы люди, и поэтому имеем одинаковые (человеческие) права.

+ +

Помимо того, что доступность это просто хороший тон, она также регулируется законодательством в некоторых странах и может поспособствовать открытию важных рынков, которые в противном случае не смогут использовать ваши услуги, покупать ваши продукты и т. д.

+ +

Доступность и опыт её применения принесут пользу всем:

+ + + +

Какие виды ограниченных возможностей мы рассматриваем?

+ +

Люди с ограниченными возможностями так же разнообразны, как и люди без них, так и своими недостатками. Ключевой урок заключается в том, чтобы думать за пределами вашего собственного компьютера и того, как вы используете Интернет, и начать изучать как его используют другие — вы не ваши пользователи. Ниже разъясняются основные виды инвалидности, а также любые специализированные инструменты, которые  используются для доступа к веб-контенту (известные как вспомогательные технологии).

+ +
+

Примечание: в информационном бюллетене Всемирной организации здравоохранения по вопросам Инвалидности и Здоровья говорится, что "Более 1 миллиарда людей, около 15% населения мира, имеют какую-либо форму инвалидности" и "От 110 до 190 миллионов взрослых испытывают значительные трудности в функционировании."

+
+ +

Люди с нарушениями зрения

+ +

Сюда относятся люди со слепотой, слабым зрением, дальтонизмом и другие. Многие из этих людей используют экранные лупы (либо физические лупы, либо программные возможности масштабирования — большинство браузеров и операционных систем в наши дни имеют возможности масштабирования), а некоторые будут использовать программы чтения с экрана, то есть программное обеспечение, которое читает цифровой текст вслух:

+ + + +

Хорошая идея ознакомиться с экранными дикторами; вы можете настроить экранный считыватель и поиграть с ним, чтобы получить представление о том, как это работает. Более подробную информацию об их использовании см. в руководстве по кросс-браузерному тестированию. Видео ниже предоставляет краткий пример взаимодействия с экранными читателями.

+ +

{{EmbedYouTube("IK97XMibEws")}}

+ +

 

+ +

Что касается статистики: по оценкам Всемирной Организации Здравоохранения: "285 миллионов человек во всем мире страдают нарушениями зрения: 39 миллионов слепы и 246 имеют слабовидение." (см. Нарушения зрения и слепота). Это большая и значительная группа пользователей, которые просто упущены, потому что ваш сайт не закодирован должным образом — почти такой же размер, как и население Соединенных Штатов Америки.

+ +

Люди с нарушениями слуха

+ +

Эта группа людей либо имеет низкий уровень слуха, либо вообще не слышит. Люди с нарушениями слуха используют ATs (см. Вспомогательные устройства для людей с нарушениями слуха, голоса, речи или языка), но на самом деле нет специальных ATs, специфичных для использования на компьютере или в интернете.

+ +

Однако существуют специальные техники, которые следует учитывать для предоставления текстовых альтернатив аудиоконтенту, который люди смогут читать, от простых текстовых транскриптов до текстовых дорожек (т.е. подписей), которые могут отображаться вместе с видео. Об этом будет рассказано в статье позже.

+ +

Люди с нарушениями слуха представляют значительную базу пользователей — "360 миллионов человек в мире страдают от инвалидизирующей потери слуха", — говорится в информационном бюллетене Всемирной Организации Здравоохранения о Глухоте и потере слуха.

+ +

Люди с ограниченными физическими возможностями 

+ +

Это группа людей, которые имеют инвалидность в отношении движения, которая может включать в себя чисто физические проблемы (такие как потеря конечности или паралич), или неврологические/генетические расстройства, которые приводят к слабости или потере контроля в конечностях. Некоторые люди могут испытывать трудности с выполнением точных движений рук, необходимых для использования мыши, в то время как другие могут быть более серьезно затронуты, возможно, значительно парализованы до такой степени, что им нужно использовать указатель головы для взаимодействия с компьютером.

+ +

Этот вид инвалидности также может быть результатом старости, а не какой-либо конкретной травмы или состояния, а также может быть результатом аппаратных ограничений — у некоторых пользователей может не быть мыши.

+ +

Управление элементами с помощью клавиатуры является обычным требованием, которое влияет на процесс веб-разработки — мы обсудим доступ с клавиатруы в последующих статьях модуля. Хорошая идея, чтобы попробовать пользоваться веб-сайтами, только с помощью клавиатуры, чтобы увидеть, что из этого выйдет и как это работает. Например, можно ли использовать клавишу Tab для перемещения между различными элементами управления веб-формы? Вы можете найти больше деталей об использовании клавиатуры в нашей секции Cross browser testing Using native keyboard accessibility.

+ +

С точки зрения статистики, значительное количество людей имеют нарушения мобильности. Центры США по контролю и профилактике заболеваний Инвалидности и Функционирования (Неинституционализированные взрослые в возрасте 18 лет и старше) сообщают, что в США "Процент взрослых с любым физическим нарушением функционирования: 16,1%".

+ +

Люди с когнитивными нарушениями

+ +

Вероятно, самый широкий спектр инвалидности можно увидеть в этой категории — когнитивные нарушения в широком смысле могут относиться к инвалидности от психических заболеваний до трудностей в обучении, трудности в понимании и концентрации, такие как СДВГ (синдром дефицита внимания и гиперактивности), людям аутистического спектра, людям с шизофренией, и множество других типов нарушений. Такие недостатки могут повлиять на многие детали повседневной жизни из-за проблем с памятью, решением, пониманием, вниманием и т. д.

+ +

Наиболее распространенные способы, вызванные когнитивными нарушениями, которые могут повлиять на использование веб-сайта — трудности с пониманием того, как выполнить задачу; вспомнить, как сделать что-то, что было ранее выполнено; повышенное разочарование в запутанных рабочих процессах или непоследовательных макетах/навигации/других функциях страницы.

+ +

В отличие от других проблем доступности интернета, невозможно назначить быстрые исправления для многих проблем доступности, связанных с когнитивными нарушениями; лучшее решение, которое у вас есть — это проектировать веб-сайты таким образом, чтобы они были логичными, последовательными и удобными для использования настолько, насколько это возможно. Например, убедитесь, что:

+ + + +

Это не "методы доступности" как таковые — это хорошая практика проектирования. Они принесут пользу всем, кто использует ваши сайты, и должны быть стандартной частью вашей работы.

+ +

С точки зрения статистики, опять же цифры значительны. Отчет Корнелльского университета О состоянии инвалидности за 2014 год (PDF, 511 КБ)(en) показывает, что в 2014 году 4,5% людей в США в возрасте 21-64 лет имели ту или иную форму когнитивной инвалидности.

+ +
+

Примечание: Страница о когнитивных расстройствах на WebAIM обепечивает полезное распространение этих идей, и это, безусловно, стоит прочитать.

+
+ +

Реализация доступности в проекте

+ +

Распространенный миф о доступности заключается в том, что доступность является дорогостоящим "дополнением" для реализации проекта. Этот миф на самом деле может быть правдой, если:

+ + + +

Если вы рассматриваете доступность с самого начала проекта, то стоимость создания доступного контента должна быть весьма небольшой.

+ +

При планировании проекта учитывайте тестирование доступности в своём режиме тестирования, как при тестировании любого другого важного сегмента целевой аудитории (например, настольный или мобильный браузер). Тестируйте на ранних этапах и часто, выполняя автоматические тесты, чтобы выявить программно обнаруживаемые отсутствующие функции (такие как отсутствующий альтернативный текст изображения или неправильная ссылка — см. Element relationships and context), и тестируйте с некоторыми нетрудоспособными групами пользователей, чтобы увидеть, насколько хорошо для них работают более сложные функции сайта. Например:

+ + + +

Вы можете и должны хранить заметку о потенциальных проблемных местах в контенте, которые будут нуждаться в доработке, чтобы сделать их доступыми, убедитесь, что они тщательно протестированы, и подумайте о решениях/альтернативах. Текстовый контент (как вы увидите в следующей статье) довольно прост, но как насчет вашего мультимедийного контента, и красивой 3D-графики? Вы должны смотреть на свой бюджет проекта и реально думать о том, какие решения у вас есть, чтобы сделать такой контент доступным? Вы можете заплатить за расшифровку всего вашего мультимедийного контента, это может быть дорогостоящим, но будет сделано.

+ +

Кроме того, будьте реалистами. "100% доступность" является недостижимым идеалом — вы всегда столкнетесь с каким-то случаем, который приводёт к тому, что определенный пользователь найдёт определенный контент трудным в использовании, но вы должны сделать столько, сколько сможете. Если вы планируете использовать трехмерную круговую диаграмму, созданную с помощью WebGL, вы можете включить таблицу данных в качестве доступного альтернативного представления данных. Или, вы можете просто включить таблицу и избавиться от 3D круговой диаграммы-таблица доступна для всех, быстрее кодировать, меньше ресурсов процессора, и проще в обслуживании.

+ +

С другой стороны, если вы работаете на веб-сайте галереи с интересным трехмерным искусством, было бы неразумно ожидать, что каждое произведение искусства будет идеально доступно для людей с нарушениями зрения, учитывая, что это полностью визуальная среда.

+ +

Чтобы показать, что вы заботитесь о доступности и думали о ней, опубликуйте на своем сайте заявление о доступности, в котором подробно излагается, какова ваша политика в отношении доступности, и какие шаги вы предприняли для обеспечения доступности сайта. Если кто-то жалуется, что у вашего сайта есть проблема с доступностью, начните с ним диалог, проявите сочувствие и примите разумные меры, чтобы попытаться устранить проблему.

+ +
+

Note: В нашей статье «Об общих проблемах доступности» рассматриваются особенности доступности, которые необходимо протестировать более подробно.

+
+ +

Подведём итоги:

+ + + +

Руководство по доступности и закон

+ +

Существует множество чеклистов и наборов руководств, на которых можно основываться при тестировании доступности, которые на первый взгляд могут показаться ошеломляющими. Наш совет — ознакомиться с основными областями, о которых вам необходимо позаботиться, а также понять структуры руководящих принципов, которые наиболее актуальны для вас.

+ + + +

Поэтому, хотя WCAG представляет собой набор руководств, в вашей стране, вероятно, будут приняты законы, регулирующие доступность веба или, по крайней мере, доступность обществественных услуг (которые могут включать в себя веб-сайты, телевидение, физические пространства и т.д.). Это хорошая идея — узнать, каковы ваши законы. Если вы не предпримете никаких усилий, чтобы проверить, что ваш контент доступен, у вас могут возникнуть проблемы с законом, если люди с ограниченными возможностями жалуются на это.

+ +

Это звучит серьезно, но на самом деле вам просто нужно рассматривать доступность в качестве основного приоритета вашей практики веб-разработки, как описано выше. В случае сомнений обратитесь за советом к квалифицированному юристу. Мы не собираемся предлагать больше советов, чем эти, потому что мы не юристы.

+ +

Специальные API доступа

+ +

Веб-браузеры используют специальные API доступа (предоставляемые базовой операционной системой)  которые предоставляют информацию, полезную для вспомогательных технологий (AT). AT обычно используют семантическую информацию, поэтому эта информация не включает такие вещи, как информация о стилях или JavaScript. Эта информация структурирована в дереве информации, которое называется деревом доступности.

+ +

Различные операционные системы имеют разные API доступа:

+ + + +

Там, где нативная семантическая информация, предоставляемая элементами HTML в ваших веб-приложениях, падает, вы можете дополнить ее функциями из спецификации WAI-ARIA, которые добавляют семантическую информацию в дерево доступности для улучшения доступности. Вы можете узнать больше о WAI-ARIA в нашей статье основы WAI-ARIA.

+ +

Заключение

+ +

Эта статья должна была дать вам полезный обзор специальных возможностей, показать, почему это так важно, и посмотреть, как вы можете вписать его в свой рабочий процесс. Теперь у вас также должна быть жажда узнать о деталях реализации, которые помогут сделать сайты доступными, и мы начнем с этого в следующем разделе, рассматривая, почему HTML является хорошей основой для доступности.

+ +

{{NextMenu("Learn/Accessibility/HTML", "Learn/Accessibility")}}

+ +

В этом модуле

+ + diff --git a/files/ru/learn/common_questions/how_does_the_internet_work/index.html b/files/ru/learn/common_questions/how_does_the_internet_work/index.html new file mode 100644 index 0000000000..19230a4042 --- /dev/null +++ b/files/ru/learn/common_questions/how_does_the_internet_work/index.html @@ -0,0 +1,102 @@ +--- +title: Как работает Интернет +slug: Learn/How_the_Internet_works +tags: + - Начинающий + - Руководство + - Учебник + - туториал +translation_of: Learn/Common_questions/How_does_the_Internet_work +--- +
{{LearnSidebar}}
+ +
+

Эта статья о том, что такое Интернет, и как он работает.

+
+ + + + + + + + + + + + +
Необходимые знания:Отсутствуют, но мы будем признательны, если вы сначала прочтете Материал о там как начать разрабатывать свой сайт
Цель: +

Вы изучите основы технической инфраструктуры Веба и поймете разницу между Вебом и интернетом. 

+
+ +

Резюме

+ +

Интернет является основой сети (the Web), технической инфраструктурой, благодаря которой и существует Всемирная Паутина. По своей сути, интернет - очень большая сеть компьютеров, которые могут взаимодействовать друг с другом.

+ +

История интернета не до конца ясна. Проект по созданию интернета был начат в 60-х годах как исследовательский проект при поддержке министерства обороны США, но уже в 80-е годы вырос в сеть, которую поддерживали и развивали множество университетов и частных компаний. Технологии, лежащие в основе интернета, также продолжали развиваться со временем, но основной принцип работы не сильно изменился: Интернет - это способ подключить компьютеры в единую сеть и убедиться, что даже при серьезных сбоях, они все равно найдут способ связаться друг с другом.

+ +

Активное изучение

+ + + +

Погружаемся глубже

+ +

Простая сеть

+ +

Когда нужно связать между собой два компьютера, вы должны связать их в сеть либо проводным (обычно с помощью Ethernet кабеля), либо беспроводным способом (например, с помощью WiFi или Bluetooth). Современные компьютеры поддерживают любой из этих способов связи.

+ +
+

Примечание: До конца этой статьи мы будем говорить только о физическом (проводном) способе подключения, но беспроводные сети работают аналогичным образом.

+
+ +

Two computers linked together

+ +

Таким способом Вы можете подключить более двух компьютеров, но с каждым новым это становится все сложнее. Если хочется подключить, скажем, 10 компьютеров, вам понадобится 45 кабелей и 9 сетевых плат в каждом компьютере!

+ +

Ten computers all together

+ +

Чтобы решить эту проблему, каждый компьютер в сети подключается к специальному маленькому компьютеру. Этот компьютер называют маршрутизатором. Маршрутизатор исполняет только одну роль: как сигнальщик на железной дороге он следит за тем, чтобы пакет, отправленный одним компьютером — источником — достиг пункта назначения. Чтобы отправить сообщение компьютеру B, компьютер A сначала должен отправить его маршрутизатору, который перенаправит его компьютеру B и проконтролирует, чтобы данные не попали компьютеру C.

+ +

С добавлением маршрутизатора наша сеть здорово упрощается: чтобы соединить 10 компьютеров нам требуется только 10 кабелей (каждый кабель соединяет маршрутизатор с одним из компьютеров).

+ +

Ten computers with a router

+ +

Сеть сетей

+ +

Пока все нормально. Но что нам делать, если нужно объединить в сеть сотни, тысячи или миллиарды компьютеров? Конечно, один маршрутизатор не справится с этой задачей, но если вы внимательно читали, то помните, что маршрутизатор — это обычный компьютер, и ничто не мешает нам соединить друг с другом 2 маршрутизатора. Давайте сделаем это.

+ +

Two routers linked together

+ +

Подключая компьютеры к маршрутизатору, а затем — маршрутизатор к другому маршрутизатору, мы можем увеличивать нашу сеть до сколь угодно больших размеров.

+ +

Routers linked to routers

+ +

Такая сеть уже очень похожа на то, что мы называем интернетом, но мы что-то упустили. Наша сеть построена для решения только наших задач. Но кроме нее есть и другие сети: наши друзья, соседи — кто угодно может создать свою сеть. Как же нам их объединить? Мы не можем протянуть кабели между нашим домом и всеми остальными сетями в мире. Чтобы решить эту проблему, мы можем воспользоваться уже существующими кабельными сетями. Ведь у нас дома уже есть кабели, например, электрические или телефонные. Телефонный провод уже соединяет ваш дом со всем остальным миром, так что он идеально подходит для решения нашей задачи. Чтобы подключить нашу сеть к глобальной сети с помощью телефонного провода, нам понадобится специальное оборудование, которое называется модем. Модем перекодирует информацию, поступающую из нашей сети в формат, который можно передавать через телефонную сеть, и наоборот, декодируют информацию из телефонной сети в формат, который распознают наши компьютеры.

+ +

A router linked to a modem

+ +

Итак, мы подключились к телефонной сети. Следующий шаг — передать сообщение из нашей сети в сеть, с которой мы хотим связаться. Чтобы сделать это, мы должны подключить нашу сеть к провайдеру услуг интернета (Internet Service Provider (ISP)). Провайдер — компания, которая обслуживает специальные маршрутизаторы, которые не только подключены друг к другу (объединяют в единую сеть всех клиентов провайдера), но также связаны с маршрутизаторами других провайдеров. Таким образом, наше сообщение, пройдя транзитом через сеть нескольких провайдеров, достигнет сеть назначения. Интернет — это сеть сетей, которая объединяет в себе всю вышеперечисленную инфраструктуру.

+ +

Full Internet stack

+ +

Поиск компьютера

+ +

Чтобы послать сообщение какому-то компьютеру, необходимо как-то обратиться к нему, выделить среди других. Поэтому каждый компьютер, подключенный к сети, имеет свой уникальный адрес для связи: этот адрес называют IP-адресом (IP — сокращение для Internet Protocol, протокол интернета). В зависимости от версии протокола IP этот адрес может записываться по-разному. Самая широко используемая версия интернет-протокола — версия 4. Адреса IPv4 обычно записываются в виде четырёх чисел, разделенных точками, например: 192.168.2.10.

+ +

Такие адреса отлично подходят для компьютеров, но людям очень сложно их запоминать. Чтобы упростить себе жизнь, мы можем присвоить каждому IP-адресу псевдоним с понятным для человека именем. Такой псевдоним называют доменным именем. Например, google.com — доменное имя, которое является псевдонимом IP-адреса 173.194.121.32. Использование доменного имени — самый простой способ обратиться к компьютеру в интернете.

+ +

Show how a domain name can alias an IP address

+ +

Интернет и веб

+ +

Как вы уже заметили, когда мы просматриваем Веб с помощью браузера, обычно мы используем доменное имя, чтобы обратиться к веб-сайту. Означает ли это, что Интернет и Веб — это одно и то же? Ответ не так прост. Мы уже знаем, что Интернет — это техническая основа, которая позволяет миллиардам компьютеров связываться друг с другом. Среди этих компьютеров есть небольшая группа (называемая веб-серверами), которые могут отправлять сообщения, распознаваемые браузерами. Интернет —  это инфраструктура, а Веб — это сервис, построенный на основе этой инфраструктуры. Стоит отметить, что кроме Веба есть и другие сервисы, построенные на базе Интернета. Например, электронная почта или {{Glossary("IRC")}}.

+ +

Что дальше

+ + diff --git a/files/ru/learn/common_questions/pages_sites_servers_and_search_engines/index.html b/files/ru/learn/common_questions/pages_sites_servers_and_search_engines/index.html new file mode 100644 index 0000000000..0a9b7a643f --- /dev/null +++ b/files/ru/learn/common_questions/pages_sites_servers_and_search_engines/index.html @@ -0,0 +1,118 @@ +--- +title: 'Веб-страницы, веб-сайты, веб серверы и поисковики' +slug: Learn/Pages_sites_servers_and_search_engines +tags: + - ActiveLearning + - Beginner + - WebMechanics + - Активное изучение + - Новичку + - Программисту +translation_of: Learn/Common_questions/Pages_sites_servers_and_search_engines +--- +
+

В этой статье мы расскажем о различных понятиях связанных с Веб: о веб-страницах, веб-сайтах, веб-серверах и о поисковых системах. Эти термины часто ставят в тупик как начинающих работу с Веб, так и людей, редко пользующихся сетью. Давайте же разберемся, что именно эти понятия означают!

+
+ + + + + + + + + + + + +
Необходимые знания: +

Вы должны знать,  как работает Интернет.

+
Цель:Изучить различия между веб-страницами, веб-сайтами, веб-серверами и поисковыми системами.
+ +

В двух словах

+ +

Как и любая другая область знаний, Веб полон специфичных терминов. Но не волнуйтесь, мы не хотим перегружать Вас в самом начале Вашего пути (а если любопытство всё же берёт верх, то у нас есть словарь). Однако, для начала несколько базовых терминов всё же придётся усвоить, так как Вы будете встречать их в наших статьях довольно часто. Иногда эти термины легко перепутать, так как они связаны между собой, но имеют разные функции. Вы, наверное, не раз замечали их неправильное употребление в новостях или где-либо ещё.

+ +

Мы разберём эти понятия и технологии чуть позже, а сейчас краткие определения ниже станут для Вас очень хорошим началом:

+ +
+
Веб-страница
+
Документ, который может быть отображён веб-браузерами, такими как: Firefox, Google Chrome, Microsoft Internet Explorer / Edge или Safari от Apple. Само понятие "веб-страница" для краткости будем называть просто "страница".
+
Веб-сайт
+
Коллекция веб-страниц, связанных между собой какими-либо способами. Употребление в лексике: "веб-сайт" или просто "сайт".
+
Веб-сервер
+
Компьютер, предоставляющий компьютерное и программное обеспечение, необходимое для функционирования веб-сайта.
+
Поисковая система
+
Веб-сайт, помогающий в поиске других веб-страниц, например такие как: Google, Bing или Yahoo.
+
+ +

Активное изучение

+ +

Пока что активное изучение не доступно. Если Вы можете предоставить полезную информацию, то, пожалуйста, окажите нам содействие

+ +

Погружаемся глубже

+ +

Итак, давайте копнем чуть глубже и узнаем, как эти 4 термина связаны между собой, и почему данные понятия зачастую путают друг с другом.

+ +

Веб-страница

+ +

Веб-страница - простой документ, отображаемый на экране компьютера посредством браузера. Такой документ написан языком HTML  (который мы рассмотрим более детально в других статьях). Веб-страница может содержать множество различных материалов, таких как:

+ + + +
+

Примечание: браузеры зачастую могут отображать некоторые документы в формате PDF файла или изображения, но термин веб-страница больше относится непосредственно к HTML-документам. До конца статьи, в данном случае, мы будем использовать понятие  документ.

+
+ +

Все веб-страницы в сети имеют свой уникальный адрес. Чтобы получить доступ к нужной странице просто наберите ее адрес в адресной строке Вашего браузера:

+ +

Example of a web page address in the browser address bar

+ + + + + + + + + + + + + +

Веб-сайт - это коллекция страниц, связанных между собой какими-либо способами (включая их связи с иными ресурсами), которые доступны под единым доменным именем. Каждая страница сайта содержит прямые ссылки (практически всегда выделенные части текста, по которым можно кликнуть мышью), что позволяет пользователю быстро переходить от одной страницы веб-сайта к другой.

+ +

Чтобы получить доступ к веб-сайту, наберите его доменное имя в адресной строке браузера, и Ваш браузер отобразит главную страницу сайта или, по-другому, домашнюю страницу:

+ +

Example of a web site domain name in the browser address bar

+ +

Веб-страницу и веб-сайт особенно легко спутать между собой, когда сайт содержит всего одну страницу. Такой сайт иногда называют одностраничным веб-сайтом.

+ +

Веб-сервер

+ +

Веб-сервер - это компьютер, предоставляющий в сеть один или множество веб-сайтов (хостинг). Понятие "хостинг" - означает, что все страницы и прикрепленные к ним файлы содержатся на данном компьютере. Т.е. Веб-сервер будет отправлять любую страницу с сайта по запросу любого пользователя, что и будет хостингом для браузера пользователя.

+ +

Не путайте понятия веб-сайта и веб-сервера. Например, если Вы слышите, что кто-либо говорит: "Мой веб-сайт не отвечает", на самом деле это означает, что это веб-сервер не отвечает на запрос, и поэтому недоступен и сам сайт. Более того, так как веб-сервер может разместить несколько сайтов, термин веб-сервер никогда не используется для обозначения веб-сайта, так как это могло бы привести к большой путанице. Вернемся к предыдущему примеру: если бы мы сказали: "Мой веб-сервер не отвечает", это значило бы, что на этом сервере нет доступных сайтов в данный момент.

+ +

Поисковая система

+ +

Поисковые системы являются распространенной причиной путаницы в сети. Поисковая система - это специальный вид веб-сайта, который помогает пользователям найти нужные страницы других сайтов.

+ +

Наиболее популярные поисковые системы: Google, Bing, Yandex, DuckDuckGo, и многие другие. Некоторые из них универсальны, а какие-то ориентированы на определенную область. Используйте тот поисковик, который удобен Вам.

+ +

Многие начинающие пользователи сети путают между собой поисковую систему и браузер. Давайте поясним: браузер - это программное обеспечение, которое находит и отображает веб-страницы; поисковая система - это специальный вид сайта, который помогает пользователям найти нужные страницы других сайтов. Путаница возникает из-за того, что когда кто-либо впервые запускает браузер, тот отображает домашнюю страницу поисковой системы. Это именно так, ведь первое, что Вы делаете, запуская браузер, это находите веб-страницу и открываете ее. Но не путайте инфраструктуру (т.е. браузер) с сервисом (т.е. поисковой системой). Это отличие несколько поможет Вам, но даже некоторые специалисты произвольно употребляют данные понятия, так что из-за этого не следует особо переживать. 

+ +

Ниже пример того, как браузер Firerox по умолчанию отображает окно поиска Google на стартовой (домашней) странице:

+ +

Example of Firefox nightly displaying a custom Google page as default

+ +

Смотрите также

+ + diff --git a/files/ru/learn/common_questions/what_are_browser_developer_tools/index.html b/files/ru/learn/common_questions/what_are_browser_developer_tools/index.html new file mode 100644 index 0000000000..8cd514efcd --- /dev/null +++ b/files/ru/learn/common_questions/what_are_browser_developer_tools/index.html @@ -0,0 +1,172 @@ +--- +title: Обзор инструментов разработки в браузерах +slug: Learn/Discover_browser_developer_tools +tags: + - Beginner + - Browser + - CSS + - CodingScripting + - Dev Tools + - HTML + - JavaScript + - Браузер + - Новичку + - Обучение +translation_of: Learn/Common_questions/What_are_browser_developer_tools +--- +
{{IncludeSubnav("/ru-RU/Learn")}}
+ +

{{Previous("Learn/Getting_started_with_the_web")}}

+ +
+

Каждый современный интернет-браузер оснащён мощными инструментами для веб-разработчика. Эти инструменты позволяют делать различные вещи, от изучения загруженных в настоящий момент HTML, CSS и JavaScript до отображения в каких ресурсах нуждается страница и как долго она будет загружаться. Эта статья научит Вас использовать базовые функции инструментов разработчика в Вашем браузере.

+
+ +
+

Заметка: Прежде чем начать заниматься с примерами, откройте пример сайта для начинающих, с которым мы работали на предыдущих занятиях. Вам следует держать его открытым, чтобы выполнить описанные ниже действия.

+
+ +

Как открыть инструменты веб-разработчика в Вашем браузере?

+ +

Панель разработчика находится в нижней части Вашего браузера :

+ +

+ +

Как её отобразить? Есть три варианта:

+ + + +

+ +

Inspector: DOM обозреватель и CSS редактор

+ +

По-умолчанию, в панели открывается вкладка Inspector, Вы можете увидеть это на скриншоте снизу. Этот инструмент позволяет Вам видеть, как HTML-код выглядит на странице в настоящем времени, также как CSS, который применён к каждому элементу на странице. Это также позволяет Вам в реальном времени редактировать как HTML, так и CSS. Внесённые изменения можно увидеть непосредственно в окне браузера.

+ +

+ +

Если Вы не видите Inspector,

+ + + +

Обзор DOM inspector

+ +

Для начала, попробуйте нажать правой кнопкой мыши (Ctrl+клик) по элементу HTML в DOM inspector и посмотрите на контекстное меню. Пункты меню могут различаться в разных браузерах, но важными из них являются одни и те же:

+ +

+ + + +

Попробуйте изменить что-нибудь через окно Inspector на Вашей странице прямо сейчас. Дважды кликните по элементу, или нажмите правой кнопкой мыши и выберите Править как HTML из контекстного меню. Вы можете сделать любые изменения, какие захотите, но Вы не сможете их сохранить.

+ +

Обзор CSS редактора

+ +

По-умолчанию, CSS редактор отображает CSS свойства применённые к текущему выбранному элементу:

+ +

+ +

Эти функции особенно удобны:

+ + + +

Вы должно быть уже заметили другие вкладки в  CSS редакторе:

+ + + +

Узнать больше

+ +

Узнать больше об Inspector в различных браузерах:

+ + + +

Консоль JavaScript 

+ +

Консоль JavaScript невероятно полезный инструмент для отладки JavaScript, если он не работает, как ожидалось. Она позволяет Вам загружать JavaScript вопреки порядку загрузки скрипта в браузере, и докладывает об ошибках как только браузер пытается выполнить Ваш код. Для доступа к консоли из любого браузера просто нажмите на кнопку Console. (В Internet Explorer, нажмите Ctrl + 2.) Откроется окно, как показано ниже:

+ +

+ +

Чтобы понять, что происходит, попробуйте ввести фрагменты кода в консоль один за другим (и затем нажмите Enter):

+ +
    +
  1. +
    alert('hello!');
    +
  2. +
  3. +
    document.querySelector('html').style.backgroundColor = 'purple';
    +
  4. +
  5. +
    var myImage = document.createElement('img');
    +myImage.setAttribute('src','https://farm4.staticflickr.com/3455/3372925208_e1f2aae4e3_b.jpg');
    +document.querySelector('h1').appendChild(myImage);
    +
  6. +
+ +

Теперь попробуйте ввести следующую, неправильную версию кода и посмотрите, что из этого получится.

+ +
    +
  1. +
    alert('hello!);
    +
  2. +
  3. +
    document.cheeseSelector('html').style.backgroundColor = 'purple';
    +
  4. +
  5. +
    var myImage = document.createElement('img');
    +myBanana.setAttribute('src','https://farm4.staticflickr.com/3455/3372925208_e1f2aae4e3_b.jpg');
    +document.querySelector('h1').appendChild(myImage);
    +
  6. +
+ +

Вы увидите некоторые ошибки, которые сообщит Вам браузер. Зачастую эти ошибки выглядят довольно загадочно, но они должны быть довольно простыми, чтобы можно было выяснить проблему!

+ +

Узнать больше

+ +

Узнать больше о JavaScript консоли в различных браузерах:

+ + diff --git a/files/ru/learn/common_questions/what_are_hyperlinks/index.html b/files/ru/learn/common_questions/what_are_hyperlinks/index.html new file mode 100644 index 0000000000..63a22eb949 --- /dev/null +++ b/files/ru/learn/common_questions/what_are_hyperlinks/index.html @@ -0,0 +1,102 @@ +--- +title: Разбираемся с веб ссылками +slug: Learn/Understanding_links_on_the_web +tags: + - Навигация + - инфраструктура + - начальный уровень +translation_of: Learn/Common_questions/What_are_hyperlinks +--- +
+

В данной статье мы узнаем, что такое ссылки и почему они важны.

+
+ + + + + + + + + + + + +
Предварительно:Вы должны знать как работает интернет и иметь представление о разнице между веб-страницей, веб-сайтом, веб-сервером и поисковой системой.
Цель:Изучить, что такое веб-ссылки и почему они важны.
+ +

Коротко

+ +

Гиперссылки, в народе ссылки, являются фундаментальной основой Веба. Чтобы объяснить, что такое ссылки, мы должны обратиться к основам Веб-архитектуры. 

+ +

В 1989 году Тим Бернерс-Ли (Tim Berners-Lee), создатель Веба, говорил о трёх китах, на которых стоит Веб:

+ +
    +
  1. {{Glossary("URL")}}, система адресов, которая отслеживает веб-документы. 
  2. +
  3. {{Glossary("HTTP")}}, транспортный протокол, помогающий найти документы по заданным URL
  4. +
  5. {{Glossary("HTML")}}, формат документа, позволяющий встраивать гиперссылки
  6. +
+ +

Как вы видите, все в Вебе крутится вокруг документов и способах обеспечения доступа к ним. Первоначальная цель Веба заключалась в предоставлении легкого инструмента доступа к текстовым документам, их чтения и навигации по ним. С тех пор Веб эволюционировал в инструмент обеспечения доступа к изображениям, видео и бинарным данным, но все эти улучшения врядли были бы возможны без тех самых трёх китов, о которых говорил Тим. 

+ +

До Веба было весьма сложно получить доступ к документам и перемещаться от одного к другому. Став понятными для пользователя, URL'ы уже сделали жизнь гораздо проще, но нам довольно сложно было печатать длинный URL каждый раз, когда мы хотели получить документ. Вот тут то гиперссылки и совершили революцию. Ссылка может связать любой текст с URL, так что пользователь может моментально достигнуть цели всего лишь активируя ссылку.

+ +

По умолчанию голубого цвета и подчёркнутые, ссылки выделяются из общего текста. Кликните на ссылку, чтобы активировать ее, или, если вы используете клавиатуру, перейдите на ссылку при помощи Tab и нажмите Enter.

+ +

Example of a basic display and effect of a link in a web page

+ +

Ссылки стали прорывом, который сделал Веб таким полезным и популярным. В остальной части этой статьи мы обсудим различные типы ссылок и их важность в современном Веб-дизайне. 

+ +

Активно изучаем

+ +

В данном разделе нет контента. Please, consider contributing.

+ +

Глубокое погружение

+ +

Как мы определили, ссылка это строка, которая связана с URL. Мы используем ссылки, чтобы с легкостью перепрыгивать с одного документа на другой. Здесь существуют некоторые нюансы, которые важно рассмотреть: 

+ +

Типы ссылок

+ +
+
Внутренняя ссылка
+
Ссылка между двумя веб-страницами, принадлежащими к одному веб-сайту. Без внутренных ссылок нет такого понятия как веб-сайт (конечно, если это не одностраничный сайт).
+
Внешняя ссылка
+
Ссылка с вашей веб-страницы на чью-либо другую веб-страницу. Без внешних ссылок не будет Веба, так как Веб  это сеть веб-страниц. Используйте внешние ссылки для того, чтобы предоставить информацию помимо той, что вы поддерживаете на вашем сайте. 
+
Входящие ссылки
+
Ссылка с чьей-либо веб-страницы на ваш сайт. Это внешняя ссылка наоборот. Имейте в виду, что вам не обязательно отвечать тем же кому-то, кто ссылается на ваш сайт.
+
+ +

Когда вы создаёте веб-сайт, фокусируйтесь на внутренних ссылках, так как они делают ваш сайт возможным и удобным для использования. Найдите нужный баланс между большим и недостаточным количеством ссылок. Мы поговорим о дизайне навигации сайта в другой статье, но в качестве правила, каждый раз когда вы создаете веб-страницу, убедитесь, что хотя бы одна из ваших страниц ссылается на неё. С другой стороны, если на вашем сайте более чем десять страниц, добиваться того, чтобы каждая страница ссылалась друг на друга, может быть весьма контрпродуктивно. 

+ +

Когда вы начинаете, вам не имеет смысла сильно волноваться о наличии внешних и входящих ссылок, но они важны, если вы хотите, чтобы поисковые системы находили ваш сайт. (См. более детальное объяснение ниже.)

+ +

Якоря (Anchors)

+ +

В большинстве случаев ссылки связывают две страницы вместе. Якоря (Anchors) же связывают две области одного документа. Когда вы следуете по ссылке указывающей на якорь, ваш браузер переходит с одной части текущего документа на другую, вместо загрузки нового документа. Хотя вы создаёте и используете якоря точно так же, как любые другие ссылки. 

+ +

Example of a basic display and effect of an anchor in a web page

+ +

Ссылки и поисковые системы

+ +

Ссылки важны как для ваших пользователей, так и для поисковых систем. Каждый раз когда поисковые движки проверяют страницу, они индексируют сайт следуя по доступным ссылкам. Поисковые движки не только следуют по ссылкам, чтобы обнаружить разные страницы сайта, но также используют текст ссылки, чтобы определить поисковый запрос, который позволит найти страницу. 

+ +

Итак, ссылки влияют на готовность поисковых систем сослаться на ваш сайт. Проблема в том, что активность поисковых систем сложно оценить. Компании обычно хотят, чтобы их сайты выводились первыми в результатах поиска, и многочисленные поиски решений дают нам понять, по крайней мере, следующее:

+ + + +

SEO (поисковая оптимизация) - это комплекс мер для "поднятия" позиции сайтов в поисковой выдаче. Оптимизация использования ссылок на сайте является одной из ключевых в SEO.

+ + + +

Следующие шаги

+ +

Так что теперь, конечно, Вы захотите создать несколько веб-страниц со ссылками!

+ + diff --git a/files/ru/learn/common_questions/what_is_a_domain_name/index.html b/files/ru/learn/common_questions/what_is_a_domain_name/index.html new file mode 100644 index 0000000000..fb561cf8ea --- /dev/null +++ b/files/ru/learn/common_questions/what_is_a_domain_name/index.html @@ -0,0 +1,155 @@ +--- +title: Что такое доменные имена +slug: Learn/Understanding_domain_names +tags: + - DNS + - вводная + - домен + - доменное имя + - начальный уровень +translation_of: Learn/Common_questions/What_is_a_domain_name +--- +
+

В этом материале мы обсудим доменные имена: что это такое, как они формируются и как зарегистрировать домен для себя.

+
+ + + + + + + + + + + + +
Необходимые знания:Вы должны знать как работает Интернет и понимать устройтво устройство URL.
Цель:Вы узнаете, что такое доменные имена, как они работают и почему они важны.
+ +

Summary

+ +

Доменные имена - ключевая составляющая инфраструктуры Интернета. Они предоставляют человеко-читаемые адреса веб-серверов, доступных в Интернете.

+ +

Каждый компьютер подключен к Интернету и может быть доступен через публичный {{Glossary("IP")}}-адрес, который состоит из 32 бит для IPv4 адреса (такие адреса обычно записываются в виде четырёх чисел от 0 до 255, разделённых точками (напр., 173.194.121.32) или 128 bit для IPv6 адреса (они обычно записываются в виде 8 групп по 4 шеснадцетиричных чисел, разделенных двоеточиями (напр, 2027:0da8:8b73:0000:0000:8a2e:0370:1337). Компьютеры могут легко обрабатывать эти адреса , но у живых людей уходит слишком много времени на использование таких адресов. IP-адреса также сложно запоминаются и часто меняются со временем. Для решения этой проблемы в Интернете используются человеко-читаемые адреса, называемые доменными именами.

+ +

Активно изучаем

+ +

В данный момент нет обучающего курса . Но вы можете помочь составить его.

+ +

Глубокое погружение

+ +

Структура доменных имён

+ +

Доменное имя имеет простую структуру, состояющую из нескольких частей (частей может быть бесконечное количество, но на практике число уровней обычно невелико), разделенных точками и читаемых справа налево:

+ +

Anatomy of the MDN domain name

+ +

Каждая из этих частей предоставляет специфическую информацию о доменном имени.

+ +
+
{{Glossary("TLD")}} (Корневой домен).
+
Корневой домен сообщает наиболее общую информацию. Корневой домен говорит пользователям наиболее общую информацию о службе, доступной по доменному имени. Наиболее общие корневые домены (.com, .org, .net) не требуют от веб-службы соответствия строгим критериям, но некоторые корневые домены имеют и более строгие политики. Например, локальные корневые домены, такие как .us, .fr, или .sh, могут требовать, чтобы услуги по данному адресу предоставлялись на национальном языке или физически размещались на территории страны.
+
Домены
+
Домены - это то, что следует за корневыми доменами. Домен может представлять собой что угодно, от одного знака до целого предложения. Домен сразу за корневым доменом также называют "доменом второго уровня". Доменное имя может включать неограниченное количество доменов, нет никакого ограничения только на 3 домена в составе доменного имени. Например, www.inf.ed.ac.uk - это корректное доменное имя. Тот, кто контролирует "верхнюю" часть доменного имени (например, mozilla.org), тот может создавать доменные имена более "низких" уровней (часто называемые, "поддоменами") (например, developer.mozilla.org).
+
+ +

Покупка доменного имени

+ +

Кто владеет доменным именем?

+ +

Вы не можете “купить доменное имя”. Вы платите за право использовать доменное имя в течение одного или нескольких лет. Вы можете продлить это право и ваше продление будет иметь безусловный приоритет над заявками на домен от других желающих. Но вы никогда не владете доменным именем.

+ +

Компании, называемые регистраторами, ведут реестры доменных имён, которые содержат техническую и административную информацию, связывающую вас и ваш домен.

+ +
+

Примечание: Для некоторых доменных имён регистратор может отсутстовать, реестр может не вестись. Например, все домены в зоне .fire используются компанией Amazon только в собственных нуждах.

+
+ +

Как найти свободное доменное имя

+ +

Для того, чтобы определить, свободно или нет желаемое доменное имя, сделайте следующее,

+ + + +
$ whois mozilla.org
+Domain Name:MOZILLA.ORG
+Domain ID: D1409563-LROR
+Creation Date: 1998-01-24T05:00:00Z
+Updated Date: 2013-12-08T01:16:57Z
+Registry Expiry Date: 2015-01-23T05:00:00Z
+Sponsoring Registrar:MarkMonitor Inc. (R37-LROR)
+Sponsoring Registrar IANA ID: 292
+WHOIS Server:
+Referral URL:
+Domain Status: clientDeleteProhibited
+Domain Status: clientTransferProhibited
+Domain Status: clientUpdateProhibited
+Registrant ID:mmr-33684
+Registrant Name:DNS Admin
+Registrant Organization:Mozilla Foundation
+Registrant Street: 650 Castro St Ste 300
+Registrant City:Mountain View
+Registrant State/Province:CA
+Registrant Postal Code:94041
+Registrant Country:US
+Registrant Phone:+1.6509030800
+
+ +

Как вы видите, нельзя зарегистрировать доменное имя mozilla.org потому что Mozilla Foundation уже зарегистрировало его.

+ +

Теперь давайте посмотрим, можно ли зарегистрировать доменное имя afunkydomainname.org:

+ +
$ whois afunkydomainname.org
+NOT FOUND
+
+ +

Как вы видите, домен не существует в базе данных whois (на момент написания этой статьи), соответственно, его можно зарегистрировать.

+ +

Как получить доменное имя

+ +

Процедура довольно проста:

+ +
    +
  1. Перейдите на веб-сайт регистратора доменных имён.
  2. +
  3. Обычно там есть кнопка "Зарегистрировать домен" или что-то подобное. Нажмите её.
  4. +
  5. Заполните форму требуемыми данными. Убедитесь, что вы не опечатались в названии доменного имени. Потому что, если вы оплатите его, то будет уже поздно исправлять ошибку!
  6. +
  7. Регистратор сообщит вам, когда доменное имя будет корректно зарегистрировано. Через несколько часов все DNS-сервера обновятся и ваш домен начнёт работать.
  8. +
+ +
+

Примечание: В процессе регистрации регистратор доменов спросит вас ваш реальный домашний или рабочий адрес. Обязательно заполните его корректно, потому что многие национальные регистраторы могут отменить регистрацию домена, если был указан ошибочный адрес.

+
+ +

Обновление DNS

+ +

Базы данных DNS хранятся на каждом DNS-сервере по всему миру и эти серверы обращаются за обновлениями к нескольким серверам, называемым “authoritative name server” или “корневой DNS-сервер”. Когда ваш регистратор создаёт или обновляет информацию о зарегистрированном домене, она должна обновиться во всех DNS-базах. Каждый DNS-сервер хранит информацию о домене фиксированное количество времени, а затем автоматически обновляет её (DNS-сервер запрашивает корневой сервер снова). Соответственно, обновление баз занимает какое-то время, пока информация о новых или измененных доменах распространяется по Интернету.

+ +
+

Примечание: Это время часто называется время распространения. Тем не менее эта задержка не означает, что за это время доменное имя обновит само себя на всех серверах сверху донизу. Очень часто DNS-сервер, запрашиваемый вашим компьютером не знает конкретного домена и запрашивает о нём корневые DNS-сервера по мере требования.

+
+ +

Как работает DNS-запрос?

+ +

Как мы уже увидели, когда вы хотите, чтобы веб-страница отобразилась в вашем браузере, легче напечатать доменное имя, чем IP-адрес. Давайте разберем весь процесс:

+ +
    +
  1. Напечатайте mozilla.org в адресной строке вашего браузера.
  2. +
  3. Ваш браузер спросит ваш компьютер, знает ли он уже, какому IP-адресу соответствует этот домен (используя локальный DNS-кэш). Если имя есть в кэше, оно транслируется в IP-адрес и браузер направляется к необходимому серверу. И всё.
  4. +
  5. Если же ваш компьютер не знает, какой IP-адрес соответствует доменному имени mozilla.org, он запрашивает DNS-сервер, чья задача - сообщить вашему компьютеру какой IP-адрес соответствует запрошенному доменному имени.
  6. +
  7. Теперь ваш компьютер знает соответствие и может взаимодействовать с сервером.
  8. +
+ +

Explanation of the steps needed to obtain the result to a DNS request

+ +

Следующие шаги

+ +

Итак, мы поговорили о процессах и архитектуре. Время двигаться дальше.

+ + diff --git a/files/ru/learn/common_questions/what_is_a_url/index.html b/files/ru/learn/common_questions/what_is_a_url/index.html new file mode 100644 index 0000000000..41fe5182c7 --- /dev/null +++ b/files/ru/learn/common_questions/what_is_a_url/index.html @@ -0,0 +1,161 @@ +--- +title: Что такое URL-адрес? +slug: Learn/Understanding_URLs +tags: + - URL + - Адрес + - Порт + - Ресурс + - Якорь + - домен + - протокол +translation_of: Learn/Common_questions/What_is_a_URL +--- +
+

Данная статья описывает Единый локатор ресурсов или Uniform Resource Locators (URLs), объясняет, что это такое, и опиcывает его структуру. 

+
+ + + + + + + + + + + + +
Предварительно:Вам нужно узнать как работает интернет, что такое Веб сервер and что лежит в основе веб ссылок .
Цель:Вы узнаете, что такое URL и как они работают в вебе.
+ +

Введение

+ +

Наряду с понятиями гипертекста и протокола HTTP, понятие URL является одной из основных концепций Всемирной паутины. Это механизм, используемый браузерами для получения любого опубликованного во Всемирной сети ресурса.

+ +

URL обозначает Uniform Resource Locator. URL это лишь адрес, который выдан уникальному ресурсу в интернете. В теории, каждый корректный URL ведет на уникальный ресурс. Такими ресурсами могут быть HTML-страница, CSS-файл, изображение и т.д. На практике, существуют некоторые исключения, когда, например, URL ведет на ресурс, который больше не существует или который был перемещён. Поскольку ресурс, доступный по URL, а также сам URL обрабатываются веб-сервером, его владелец должен внимательно следить за размещаемыми ресурсами и связанными с ними URL.

+ +

Активное обучение

+ +

Активного обучения пока не существует. Пожайлуста подумайте, возможно Вы сможете внести свой вклад.

+ +

Подробная информация

+ +

Основы: анатомия URL

+ +

Вот несколько примеров URL:

+ +
https://developer.mozilla.org
+https://developer.mozilla.org/ru/docs/Learn/
+https://developer.mozilla.org/ru/search?q=URL
+ +

Каждый из этих URLs могут быть напечатаны в адресной строке браузера, чтобы заставить его загрузить связанную страницу (ресурс).

+ +

URL состоит из различных частей, некоторые из которых являются обязательными, а некоторые - факультативными. Рассмотрим наиболее важные части на примере:

+ +
http://www.example.com:80/path/to/myfile.html?key1=value1&key2=value2#SomewhereInTheDocument
+ +
+
Protocol
+
http:// это протокол. Он отображает, какой протокол браузер должен использовать. Обычно это HTTP-протокол или его безопасная версия - HTTPS. Интернет требует эти 2 протокола, но браузеры часто могут использовать и другие протоколы, например mailto: (чтобы открыть почтовый клиент) или ftp: для запуска передачи файлов, так что не стоит удивляться, если вы вдруг увидите другие протоколы.
+
Domaine Name
+
www.example.com это доменное имя. Оно означает, какой веб-сервер должен быть запрошен. В качестве альтернативы может быть использован и {{Glossary("IP address", "IP-адрес")}}, но это делается редко, поскольку запоминать IP сложнее, и это не популярно в интернете.
+
Port
+
:80 это порт. Он отображает технический параметр, используемый для доступа к ресурсам на веб-сервере. Обычно подразумевается, что веб-сервер использует стандартные порты HTTP-протокола (80 для HTTP и 443 для HTTPS) для доступа к своим ресурсам. В любом случае, порт - это факультативная составная часть URL.
+
Path to the file
+
/path/to/myfile.html это адрес ресурса на веб-сервере. В прошлом, адрес отображал местоположение реального файла в реальной директории на веб-сервере. В наши дни это чаще всего абстракция, позволяющая обрабатывать адреса и отображать тот или иной контент из баз данных.
+
Parameters
+
?key1=value1&key2=value2 это дополнительные параметры, которые браузер сообщает веб-серверу. Эти параметры - список пар ключ/значение, которые разделены символом &. Веб-сервер может использовать эти параметры для исполнения дополнительных команд перед тем как отдать ресурс. Каждый веб-сервер имеет свои собственные правила обработки этих параметров и узнать их можно, только спросив владельца сервера.
+
Anchor
+
#SomewhereInTheDocument это якорь на другую часть того же самого ресурса. Якорь представляет собой вид "закладки" внутри ресурса, которая переадресовывает браузер на "заложенную" часть ресурса. В HTML-документе, например, браузер может переместиться в точку, где установлен якорь; в видео- или аудио-документе браузер может перейти к времени, на которое ссылается якорь. Важно отметить, что часть URL после #, которая также известна как идентификатор фрагмента, никогда не посылается на сервер вместе с запросом.
+
+ +

{{Note('Есть и другие составные части и правила, касающиеся URL, но обычно они не используются ни пользователями, ни разработчика. Поэтому не стоит о них беспокоиться, вам не обязательно их знать, чтобы формировать работоспособные URL.')}}

+ +

Вам стоит представлять URL как обычный почтовый адрес: протокол обозначает почтовый транспорт, который вы собираетесь использовать,доменное имя - это город, порт - это почтовый индекс; адрес - это номер дома;параметры представляют собой дополнительную информацию, как, например, номер квартиры; и, наконец, якорь представляет собой конкретного получателя, которому вы адресуете своё письмо.

+ +

Как использовать URL

+ +

Каждый URL может быть напечатан напрямую в адресной строке браузера, чтобы сразу получить запрошенный ресурс. Но это только вершина айсберга!

+ +

Язык {{Glossary("HTML")}} — который будет обсуждать позже — позволяет активно использовать URL для:

+ + + +
+

Примечание: При указании URL-адресов для загрузки ресурсов как части страницы (например, при использовании <script>, <audio>, <img>, <video>, и т.д.), следует использовать только URL-адреса HTTP и HTTPS. Использование FTP, например, не особенно безопасно и больше не поддерживается многими браузерами.

+
+ +

Другие технологии, такие как {{Glossary("CSS")}} или {{Glossary("JavaScript")}}, также активно используют URL, так что это реально основа веба.

+ +

Абсолютные и относительные URL

+ +

Все, что мы изучали выше - это абсолютные URL. Но так же существуют и относительные URL. Изучим их.

+ +

Обязательные части URL во многом зависят от контекста, в котором используется URL. В адресной строке браузера URL не имеет никакого контекста, так что приходится вводить полный (или абсолютный) URL, такие как мы рассматривали выше. Обычно вам не требуется вводить протокол (браузер подставляет HTTP по умолчанию) и порт (который нужен только в том случае, если сервер использует нестандартный порт), но остальные части URL всё равно необходимы.

+ +

Когда URL используется в документе, например в HTML-странице, ситуация отличается. Потому что браузер уже знает URL текущего документа и он может использовать эти сведения для дополнения недостающих частей любого адреса, указанного в документе. Простейший пример относительного URL - указание только адресной части URL. А если адрес в URL начинается с символа "/", браузер запросит ресурс от корня сервера, без отсылки к контексту текущего документа.

+ +

Разберем это на примерах.

+ +

Примеры абсолютных URL

+ +
+
Полный URL (такой же, как обсуждали в начале статьи)
+
+
https://developer.mozilla.org/ru/docs/Learn
+
+
Скрыт протокол
+
+
//developer.mozilla.org/ru/docs/Learn
+ +

В этом случае браузер использует тот же протокол, что использовался для загрузки текущего документа.

+
+
Скрыт домен
+
+
/ru/docs/Learn
+ +

Это наиболее частый пример использования аболютного URL в HTML-документе. Браузер использует тот же протокол и то же доменное имя, как у текущего документа. Примечание: не возможно скрыть домен, не скрывая при этом протокол, только вместе.

+
+
+ +

Примеры относительных URL

+ +

Для лучшего понимания следующих примеров, давайте договоримся, что мы обращаемся к URL из документа, который опубликован по адресу: https://developer.mozilla.org/ru/docs/Learn

+ +
+
Дочерние ресурсы
+
+
Skills/Infrastructure/Understanding_URLs
+
+
+
Поскольку URL не начинается с  /, браузер сделает попытку найти документ в поддиректории относительно текущего документа. В данном примере будет запрошен этот URL: https://developer.mozilla.org/ru/docs/Learn/Skills/Infrastructure/Understanding_URLs
+
Назад по дереву папок
+
+
../CSS/display
+ +

В этом случае, мы используем команду ../  — унаследованную из файловой системы UNIX — чтобы сказать браузеру, что он должен подняться на 1 директорию вверх. Соответственно, здесь мы хотим открыть URL: https://developer.mozilla.org/ru/docs/Learn/../CSS/display, который может быть упрощен до вида: https://developer.mozilla.org/ru/docs/CSS/display

+
+
+ +

Семантические URL

+ +

Помимо своего технического значения, URL представляют собой человеко-читаемые записи о местоположении документов на веб-ресурсе. Они могут быть запомнены и любой может ввести их в адресную строку своего браузера. Веб создавался для людей и распространённой практикой является принцип записи URL, который называется  семантические URL.  Семантические URL используют в своём составе слова, значение которых может быть понято любым человеком, даже тем, кто не разбирается в технических нюансах.

+ +

Семантика, разумеется, плохо распознаётся компьютерами. Вы наверняка видели URL, которые выглядят как куча случайных символов. Но у семантических URL есть много преимуществ:

+ + + +

Следующие шаги

+ + diff --git a/files/ru/learn/common_questions/what_is_a_web_server/index.html b/files/ru/learn/common_questions/what_is_a_web_server/index.html new file mode 100644 index 0000000000..efdc287ba9 --- /dev/null +++ b/files/ru/learn/common_questions/what_is_a_web_server/index.html @@ -0,0 +1,128 @@ +--- +title: Что такое веб-сервер +slug: Learn/Что_такое_веб_сервер +tags: + - Веб-сервер + - Динамический сайт + - Новичок + - Статический сайт +translation_of: Learn/Common_questions/What_is_a_web_server +--- +
+

В этой статье мы узнаем, что из себя представляют веб-серверы, как они работают, и почему они так важны.

+
+ + + + + + + + + + + + +
Необходимые
+ знания:
Вы должны уже знать, как работает Интернет и понимать разницу между страницей, сайтом, сервером и поисковой системой.
Цель: +

Вы узнаете, что такое веб-сервер и получите общее представление о том, как он работает.

+
+ +

Введение

+ +

Понятие «веб-сервер» может относиться как к аппаратной начинке, так и к программному обеспечению. Или даже к обеим частям, работающим совместно.

+ +
    +
  1. С точки зрения "железа", «веб-сервер» — это компьютер, который хранит файлы сайта (HTML-документы, CSS-стили, JavaScript-файлы, картинки и другие) и доставляет их на устройство конечного пользователя (веб-браузер и т.д.). Он подключен к сети Интернет и может быть доступен через доменное имя, подобное mozilla.org.
  2. +
  3. С точки зрения ПО, веб-сервер включает в себя несколько компонентов, которые контролируют доступ веб-пользователей к размещенным на сервере файлам, как минимум — это HTTP-сервер. HTTP-сервер — это часть ПО, которая понимает {{Glossary("URL","URL’ы ")}} (веб-адреса) и {{Glossary("HTTP")}} (протокол, который ваш браузер использует для просмотра веб-страниц).
  4. +
+ +

На самом базовом уровне, когда браузеру нужен файл, размещенный на веб-сервере, браузер запрашивает его через HTTP-протокол. Когда запрос достигает нужного веб-сервера ("железо"), сервер HTTP (ПО) принимает запрос, находит запрашиваемый документ (если нет, то сообщает об ошибке 404) и отправляет обратно, также через HTTP.

+ +

Basic representation of a client/server connection through HTTP

+ +

Чтобы опубликовать веб-сайт, необходим либо статический, либо динамический веб-сервер.

+ +

Статический веб-сервер, или стек, состоит из компьютера ("железо") с сервером HTTP (ПО). Мы называем это «статикой», потому что сервер посылает размещенные файлы в браузер «как есть».

+ +

Динамический веб-сервер состоит из статического веб-сервера и дополнительного программного обеспечения, чаще всего сервера приложения и базы данных. Мы называем его «динамическим», потому что сервер приложений изменяет исходные файлы перед отправкой в ваш браузер по HTTP.

+ +

Например, для получения итоговой страницы, которую вы просматриваете в браузере, сервер приложений может заполнить HTML-шаблон данными из базы данных. Такие сайты, как MDN или Википедия, состоят из тысяч веб-страниц, но они не являются реальными HTML документами — лишь несколько HTML-шаблонов и гигантские базы данных. Эта структура упрощает и ускоряет сопровождение веб-приложений и доставку контента.

+ +

Активное изучение

+ +

Активное изучение пока не доступно. Пожалуйста, рассмотрите возможность внести свой вклад.

+ +

Погружаемся глубже

+ +

Чтобы загрузить веб-страницу, как мы уже говорили, ваш браузер отправляет запрос к веб-серверу, который приступает к поиску запрашиваемого файла в своем собственном пространстве памяти. Найдя файл, сервер считывает его, обрабатывает как ему это необходимо, и отсылает в браузер. Давайте рассмотрим эти шаги более подробно.

+ +

Хостинг файлов

+ +

Прежде всего, веб-сервер должен содержать файлы веб-сайта, а именно все HTML-документы и связанные с ними ресурсы, включая изображения, CSS-стили, JavaScript-файлы, шрифты и видео.

+ +

Технически, вы можете разместить все эти файлы на своем компьютере, но гораздо удобнее хранить их на выделенном веб-сервере, который:

+ + + +

По всем этим причинам поиск хорошего хостинг-провайдера является ключевой частью создания вашего сайта. Рассмотрите многочисленные предложения компаний и выберите то, что соответствует вашим потребностям и бюджету (предложения варьируются от бесплатных до тысяч долларов в месяц). Вы можете найти подробности в этой статье.

+ +

Как только вы решили проблему с хостингом, вам понадобится только загрузить свои файлы на ваш веб-сервер.

+ +

Связь по HTTP

+ +

Во-вторых, веб-сервер обеспечивает поддержку {{Glossary("HTTP")}} (англ. Hypertext Transfer Protocol - гипертекстовый транспортный протокол). Как следует из названия, HTTP указывает, как передавать гипертекст (т.е. связанные веб-документы) между двумя компьютерами.

+ +

Протокол представляет собой набор правил для связи между двумя компьютерами. HTTP является текстовым протоколом без сохранения состояния.

+ +
+
Текстовый
+
Все команды являются простым человекочитаемым текстом.
+
Не сохраняет состояние
+
Ни клиент, ни сервер не помнят о предыдущих соединениях. Например, опираясь только на HTTP, сервер не сможет вспомнить введенный вами пароль или на каком шаге транзакции вы находитесь. Для таких задач, вам потребуется сервер приложения. (Мы остановимся на этих технологиях в следующих статьях.)
+
+ +

HTTP задает строгие правила взаимодействия клиента и сервера. Мы рассмотрим сам протокол HTTP в технической статье немного позднее. Пока достаточно знать об этих правилах:

+ + + +

The MDN 404 page as an example of such error pageНа веб-сервере HTTP-сервер отвечает за обработку входящих запросов и ответ на них.

+ +
    +
  1. При получении запроса, HTTP-сервер сначала проверяет, существует ли ресурс по данному URL.
  2. +
  3. Если это так, веб-сервер отправляет содержимое файла обратно в браузер. Если нет, сервер приложения генерирует необходимый ресурс.
  4. +
  5. Если ничто из этого не возможно, веб-сервер возвращает сообщение об ошибке в браузер, чаще всего “404 Not Found”. (Это ошибка настолько распространена, что многие веб-дизайнеры тратят большое количество времени на разработку 404 страниц об ошибках.)
  6. +
+ +

Статический и Динамический контент

+ +

Грубо говоря, сервер может отдавать статическое или динамическое содержимое. «Статическое» означает «отдается как есть». Статические веб-сайты делаются проще всего, поэтому мы предлагаем вам сделать свой первый сайт статическим.

+ +

«Динамическое» означает, что сервер обрабатывает данные или даже генерирует их на лету из базы данных. Это обеспечивает большую гибкость, но технически сложнее в реализации и обслуживании, из-за чего процесс создания сайта очень сильно усложняется.

+ +

Возьмем для примера страницу, которую вы сейчас читаете. На веб-сервере, где она хостится, есть сервер приложения, который извлекает содержимое статьи из базы данных, форматирует его, добавляет в HTML-шаблоны и отправляет вам результат. В нашем случае, сервер приложения называется Kuma, написан он на языке программирования Python (используя фреймворк Django). Команда Mozilla создала Kuma для конкретных нужд MDN, но есть множество подобных приложений, построенных совершенно на других технологиях.

+ +

Существует так много серверов приложений, что довольно трудно предложить какой-то один. Некоторые серверы приложений заточены под определенные категории веб-сайтов, такие как блоги, вики-страницы или интернет-магазины; другие, называемые {{Glossary("CMS", "CMSs")}} (системы управления контентом), более универсальны. Если вы создаете динамический сайт, потратьте немного времени на выбор инструмента, который соответствует вашим потребностям. Если вы не хотите изучать веб-программирование (хотя это увлекательно само по себе!), то вам не нужно создавать свой собственный сервер приложения. Это будет изобретением очередного велосипеда.

+ +

Следующие шаги

+ +

Теперь, когда вы познакомились с веб-серверами, вы можете:

+ + + +
+ +
diff --git a/files/ru/learn/css/building_blocks/cascade_tasks/index.html b/files/ru/learn/css/building_blocks/cascade_tasks/index.html new file mode 100644 index 0000000000..b6524f9ed3 --- /dev/null +++ b/files/ru/learn/css/building_blocks/cascade_tasks/index.html @@ -0,0 +1,51 @@ +--- +title: 'Проверьте ваши навыки: Каскад' +slug: Learn/CSS/Building_blocks/Каскад_задачи +tags: + - CSS + - Начинающий +translation_of: Learn/CSS/Building_blocks/Cascade_tasks +--- +
{{LearnSidebar}}
+ +
+ +

Цель этого задания — помочь вам проверить ваше понимание некоторых значений и элементов, которые мы рассмотрели в уроке Каскад и наследование.

+ +
+

Примечание: Вы можете проверять решения в интерактивном редакторе, расположенном ниже, но, возможно, вам будут полезны онлайн-инструменты, такие как  CodePen, jsFiddle или Glitch, которые можно использовать для работы над заданием, предварительно загрузив в них код.
+
+ Если вы зашли в тупик, обратитесь к нам за помощью — смотрите раздел {{anch("Оценка или дальнейшая помощь")}} внизу этой страницы.

+
+ +

Задание 1

+ +

В этом задании вам надо использовать одно из специальных значений, рассмотренных нами в разделе Контроль наследования,  чтобы написать в новом правиле объявление, которое восстановит белый цвет фона без использования фактического значения цвета.

+ +

Barely visible yellow links on a white background.

+ +

Посмотрите, сможете ли вы повторить эту картинку в примере ниже.

+ +

{{EmbedGHLiveSample("css-examples/learn/tasks/cascade/cascade.html", '100%', 700)}}

+ +
+

Для получения оценки или для дальнейшей работы загрузите исходный код для этого задания в ваш собственный редактор или в онлайн-редактор.

+
+ +

Оценка или дальнейшая помощь

+ +

Вы можете упражняться на этих примерах в интерактивных редакторах, упомянутых выше.

+ +

Если вы хотите, чтобы вашу работу оценили, или вы зашли в тупик и хотите попросить о помощи:

+ +
    +
  1. Поместите вашу работу в онлайн-редактор с возможностью совместного редактирования, например, CodePen, jsFiddle или Glitch. Вы можете сами написать код или использвать файлы с исходным кодом, расположенные по ссылке в предыдущем разделе.
  2. +
  3. Напишите сообщение с просьбой оценить и/или помочь на форуме в категории "Обучение": MDN Discourse forum Learning category. Ваше сообщение должно включать: +
      +
    • Описательный заголовок, например, "Необходима оценка для теста 1 Каскад" ("Assessment wanted for Cascade skill test 1").
    • +
    • Подробности того, что вы уже попытались сделать, и чего бы вы хотели от нас, т.е. или вы в тупике и нуждаетесь в помощи, или хотите оценки.
    • +
    • Ссылка на пример, который вы просите оценить или который вызвал затруднения, в онлайн-редакторе с возможностью совместного редактирования (как указано в шаге 1 выше). Это принятая практика погружения в вопрос — очень трудно помочь кому-либо решить проблему кодирования, если вы не видите его код.
    • +
    • Ссылка на страницу с заданием, чтобы мы могли найти вопрос, на который вы затрудняетесь ответить.
    • +
    +
  4. +
diff --git a/files/ru/learn/css/building_blocks/fundamental_css_comprehension/index.html b/files/ru/learn/css/building_blocks/fundamental_css_comprehension/index.html new file mode 100644 index 0000000000..9009c684d8 --- /dev/null +++ b/files/ru/learn/css/building_blocks/fundamental_css_comprehension/index.html @@ -0,0 +1,123 @@ +--- +title: Понимание основ CSS +slug: Learn/CSS/Introduction_to_CSS/Ponimanie_osnov_CSS +translation_of: Learn/CSS/Building_blocks/Fundamental_CSS_comprehension +--- +
{{LearnSidebar}}
+ +
{{PreviousMenu("Learn/CSS/Introduction_to_CSS/Debugging_CSS", "Learn/CSS/Introduction_to_CSS")}}
+ +

Вы многое прошли в этом модуле, и должно быть вас посетило это прекрасное чувство, что дошли до конца! Последний шаг перед тем, как двигаться дальше, это попытка пройти проверку по материалам модуля — это включает в себя ряд соответствующих упражнений, которые должны быть выполнены для того, чтобы создать заключительный проект — визитка, карточка игрока, профиль в социльной сети.

+ + + + + + + + + + + + +
Предварительно:Перед попыткой пройти проверку вы должны проработать все статьи в этом модуля.
Цель:Проверка понимания основной теории, синтаксиса и техник CSS.
+ +

Отправной пункт

+ +

Чтобы начать проверку, вы должны:

+ + + +
+

Примечание: Вместо этого вы можете использовать для проверки такие сайты как  JSBin или Thimble. Вы можете скопировать HTML и заполнить CSS в одном из этих онлайн редакторов и использовать этот URL чтобы указать элементу <img> файл изображения. Если используемый онлайн-редактор не имеет отдельной панели для CSS, вы можете поместить его в элемент <style> в заголовке документа.

+
+ +

Краткое описание проекта

+ +

Вам предоставили некоторый исходный HTML и изображение, и нужно написать необходимые CSS-правила, чтобы стилизовать это в маленькую онлайн-визитку, которая может, возможно, стать картой игрока или профилем в социальных сетях. Следующие разделы описывают, что вам нужно сделать.

+ +

Первоначальные настройки:

+ + + +

Позаботимся о селекторах и наборах правил, предоставленных в файле CSS:

+ + + +

Какие новые наборы правил надо написать:

+ + + +
+

Примечание: Имейте в виду, что второй набор правил устанавливает font-size: 10px; для элемента<html> — это означает, что для любых потомков <html> em будет равен 10px, а не 16px, как это задано по умолчанию. (Это, конечно, при условии, что у потомков, о которых идет речь, нет предков, находящихся в иерархии между ними и <html>, на которых установлен другой размер шрифта. Это может повлиять на необходимые значения, хотя в этом простом примере это не проблема).

+
+ +

Другие вещи для размышления:

+ + + +

Советы и подсказки

+ + + +

Образец

+ +

На следующем снимке экрана показан образец того, как должен выглядеть готовый дизайн:

+ +

A view of the finished business card, show a reader header and footer, and a darker center panel containing the main details and image.

+ +

Проверка

+ +

Если вы проходите эту проверку в рамках организованного курса, у вас должна быть возможность отдать свою работу своему учителю/наставнику для оценки. Если вы самообучаетесь, то вы можете получить руководство по оценке достаточно простым путем: спросив в теме обсуждения об этом упражнении, или в канале #mdn IRC на Mozilla IRC. Но сначала попробуйте выполнить упражнение — вы ничего не выиграете путем обмана!

+ +

{{PreviousMenu("Learn/CSS/Introduction_to_CSS/Debugging_CSS", "Learn/CSS/Introduction_to_CSS")}}

+ +

В этом модуле

+ + diff --git a/files/ru/learn/css/building_blocks/selectors/attribute_selectors/index.html b/files/ru/learn/css/building_blocks/selectors/attribute_selectors/index.html new file mode 100644 index 0000000000..9a6a2c4c07 --- /dev/null +++ b/files/ru/learn/css/building_blocks/selectors/attribute_selectors/index.html @@ -0,0 +1,160 @@ +--- +title: Селекторы атрибута +slug: Learn/CSS/Building_blocks/Селекторы/Attribute_selectors +tags: + - CSS + - Атрибут + - Начинающий + - Обучение + - Селекторы +translation_of: Learn/CSS/Building_blocks/Selectors/Attribute_selectors +--- +

{{LearnSidebar}}{{PreviousMenuNext("Learn/CSS/Building_blocks/Selectors/Type_Class_and_ID_Selectors", "Learn/CSS/Building_blocks/Selectors/Pseudo-classes_and_pseudo-elements", "Learn/CSS/Building_blocks")}}

+ +

Как вы знаете из курса о HTML, элементы могут иметь атрибуты, которые дают дополнительную информацию о размечаемом элементе. В CSS вы можете использовать селекторы атрибута для стилизации элементов с определенными атрибутами. Этот урок покажет вам, как использовать эти очень полезные селекторы.

+ + + + + + + + + + + + +
Необходимые условия:Базовая компьютерная грамотность, установка базового ПО, базовые знания о работе с файлами, основы HTML (изучите Введение в HTML) и понимание работы CSS (изучите Введение в CSS.)
Задача:Узнать, что такое селекторы атрибута и как их использовать.
+ +

Селекторы наличия и значения

+ +

Эти селекторы делают возможным выбор элемента, основанный только на наличии атрибута (например, href) или на всевозможных разного рода сочетаниях со значением атрибута.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
СелекторПримерОписание
[attr]a[title]Выбирает элементы с атрибутом attr (имя которого это значение в квадратных скобках).
[attr=value]a[href="https://example.com"]Выбирает элементы с атрибутом attr, значение которого в точности равно value строке внутри кавычек.
[attr~=value]p[class~="special"] +

Выбирает элементы с атрибутом attr, значение которого в точности равно value или содержит value в своём (разделённом пробелами) списке значений.

+
[attr|=value]div[lang|="zh"]Выбирает элементы с атрибутом attr, значение которого в точности равно value или начинается с value, за которым сразу следует дефис.
+ +

В приведённом ниже примере вы можете увидеть использование этих селекторов.

+ + + +

{{EmbedGHLiveSample("css-examples/learn/selectors/attribute.html", '100%', 800)}}

+ +

Селекторы вхождения подстроки

+ +

Эти селекторы предоставляют более широкие возможности для выявления вхождения подстроки в значение атрибута. Например, если у вас есть классы box-warning и box-error и вы хотите выбрать всё, что начинается со стороки "box-", вы можете использовать [class^="box-"], чтобы выбрать оба класса (или [class|="box"] как описано в предыдущем разделе).

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
СелекторПримерОписание
[attr^=value]li[class^="box-"]Выбирает элементы с атрибутом attr (его имя это значение в квадратных скобках), значение которого начинается с value.
[attr$=value]li[class$="-box"]Выбирает элементы с атрибутом attr, значение которого заканчивается на value.
[attr*= ]li[class*="box"]Выбирает элементы с атрибутом attr, значение которого содержит value, независимо от его положения внутри строки.
+ +

(Отступление: возможно, будет полезным заметить, что ^ и $ давно используются как якоря в так называемых регулярных выражениях и обозначают начинается с и заканчивается на.)

+ +

Следующий пример показывает, как используются эти селекторы:

+ + + +

{{EmbedGHLiveSample("css-examples/learn/selectors/attribute-substring.html", '100%', 800)}}

+ +

Чувствительность к регистру

+ +

Если вы хотите выбрать значения атрибута без учета регистра, вы можете использовать значение i перед закрывающей скобкой. Этот признак говорит браузеру, что символы ASCII должны сопоставляться без учета регистра. Без этого признака значения будут сопоставлены в соответствии с чувствительностью к регистру языка документав случае HTML такая чувствительность присутствует.

+ +

В примере ниже первый селектор выберет значение, начинающееся с aэто соответствует только первому элементу списка, потому что два других элемента списка начинаются с заглавной буквы A. Второй селектор использует признак нечувствительности к регистру и поэтому выберет все элементы списка.

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/attribute-case.html", '100%', 800)}}

+ +
+

Примечание: Существует также более новое значение s, которое вызывает сопоставление с учетом регистра в контекстах, где сопоставление обычно не учитывает регистр, однако это не так хорошо поддерживается в браузерах и не очень полезно в контексте HTML.

+
+ +

Следующие шаги

+ +

Итак, мы рассмотрели селекторы атрибута, и вы можете перейти к следующей статье, в которой рассказывается о псевдоклассах и псевдоэлементах.

+ +

{{PreviousMenuNext("Learn/CSS/Building_blocks/Selectors/Type_Class_and_ID_Selectors", "Learn/CSS/Building_blocks/Selectors/Pseudo-classes_and_pseudo-elements", "Learn/CSS/Building_blocks")}}

+ +

В этом модуле

+ +
    +
  1. Каскад и наследование
  2. +
  3. Селекторы CSS + +
  4. +
  5. Модель коробки (The box model)
  6. +
  7. Фон и границы
  8. +
  9. Обработка разных направлений текста
  10. +
  11. Переполнение содержимого
  12. +
  13. Значения и единицы измерения
  14. +
  15. Изменение размеров в CSS
  16. +
  17. Элементы изображений, форм и медиа-элементы
  18. +
  19. Стилизация таблиц
  20. +
  21. Отладка CSS
  22. +
  23. Организация вашей CSS
  24. +
diff --git a/files/ru/learn/css/building_blocks/selectors/combinators/index.html b/files/ru/learn/css/building_blocks/selectors/combinators/index.html new file mode 100644 index 0000000000..7a076e05a8 --- /dev/null +++ b/files/ru/learn/css/building_blocks/selectors/combinators/index.html @@ -0,0 +1,113 @@ +--- +title: Комбинаторы +slug: Learn/CSS/Building_blocks/Селекторы/Combinators +tags: + - CSS + - Селекторы + - комбинаторы +translation_of: Learn/CSS/Building_blocks/Selectors/Combinators +--- +

{{LearnSidebar}}{{PreviousMenuNext("Learn/CSS/Building_blocks/Selectors/Pseudo-classes_and_pseudo-elements", "Learn/CSS/Building_blocks/The_box_model", "Learn/CSS/Building_blocks")}}

+ +

Наконец мы рассмотрим селекторы, которые называются комбинаторами, поскольку они соединяют другие селекторы, создавая полезную связь селекторов друг с другом и расположением содержимого в документе.

+ + + + + + + + + + + + +
Необходимые условия:Базовая компьютерная грамотность, установленное базовое программное обеспечение, базовые знания о работе с файлами, основы HTML (изучите Введение в HTML) и понимание работы CSS (изучите Введение в CSS.)
Цель:Узнать о различных комбинаторных селекторах, которые могут быть использованы в CSS.
+ +

Комбинатор потомка

+ +

Селектор потомка — обычно представляется символом пробела ( ) — соединяет два селектора так, что элементы, соответствующие второму селектору, выбираются, если они имеют предка (родителя, родителя родителя, родителя родителя родителя и т.д.), соответствующего первому селектору. Селекторы, которые используют комбинатор потомка, называются селекторами потомка.

+ +
body article p
+ +

В приведенном ниже примере выбирается только тот элемент <p>, который находится внутри элемента с классом.box.

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/descendant.html", '100%', 500)}}

+ +

Дочерний комбинатор

+ +

Дочерний комбинатор (>) помещается между двумя селекорами CSS. При этом будут выбраны только те элементы, соответствующие второму селектору, которые являются прямыми потомками элементов, соответствующих первому селектору. Все элементы-потомки на более низких уровнях иерархии будут пропущены. Например, чтобы выбрать только те элементы <p>, которые являются дочерними элементами <article>, селетор пишется так:

+ +
article > p
+ +

Другой пример. Имеется неупорядоченный список, заключающий в себе другой, упорядоченный список. Дочерний комбинатор используется для того, чтобы выбрать только те элементы <li>, которые являются прямыми потомками <ul>, и присвоить им верхнюю границу красного цвета.

+ +

Если вы уберёте символ >, указывающий на то, что это селектор с дочерним комбинатором, селетор превратится в селектор всех потомков (комбинатор - пробел) и все элементы <li> получат верхнюю границу красного цвета.

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/child.html", '100%', 600)}}

+ +

Соседний родственный комбинатор

+ +

Соседний родственный селектор (+) используется для выбора элемента, который непосредственно следует за другим элементом и находится на одном с ним уровне иерархии. Например, чтобы выбрать все элементы <img> , которые идут сразу после элементов <p> :

+ +
p + img
+ +

Распространенный вариант использования — сделать что-то с абзацем, который следует за заголовком, как в примере ниже. Здесь мы ищем абзац, который непосредственно примыкает к <h1>, и стилизуем его.

+ +

Если вы вставите какой-то другой элемент, например <h2> между <h1> и <p>, вы обнаружите, что абзац больше не соответствует селектору и поэтому не получает цвет фона и переднего плана, применяемый, когда элемент является соседним.

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/adjacent.html", '100%', 800)}}

+ +

Общий родственный комбинатор

+ +

Если вы хотите выбрать родственные элементы, даже если они не являются непосредственными соседями, то вы можете использовать общий родственный комбинатор (~). Чтобы выбрать все элементы <img>, которые находятся в любом месте после элементов <p>, надо указать так:

+ +
p ~ img
+ +

В приведенном ниже примере мы выбираем все элементы <p>, которые идут после <h1>, и хотя в документе есть также <div>, тем не менее <p>, который идет после него, будет выбран.

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/general.html", '100%', 600)}}

+ +

Использование комбинаторов

+ +

Вы можете соединять с помощью комбинаторов любые селекторы, которые мы изучали в предыдущих уроках, чтобы выбрать часть вашего документа. Например, если мы хотим выбрать пункты списка с классом "a", которые являются прямыми потомками <ul>, можно использовать следующую комбинацию:

+ +
ul > li[class="a"]  {  }
+ +

Однако будьте осторожны при создании больших списков селекторов, которые выделяют очень конкретные части вашего документа. Будет трудно повторно использовать правила CSS, так как вы сделали селектор очень специфичным для определения местоположения этого элемента в разметке.

+ +

Часто бывает лучше создать простой класс и применить его к рассматриваемому элементу. Тем не менее, ваши знания о комбинаторах будут очень полезны, если вам нужно добраться до чего-то в вашем документе и вы не можете получить доступ к HTML, возможно, из-за того, что он генерируется CMS.

+ +

Проверьте ваши навыки!

+ +

Мы охватили много тем в этой статье. А вы можете вспомнить наиболее важную информацию? Можете пройти несколько дополнительных тестов для того чтобы убедиться в том, что вы усвоили эту информацию, прежде чем пойдёте дальше — смотрите Проверьте ваши навыки: Селекторы.

+ +

Двигаемся дальше

+ +

Это последний раздел в наших уроках по селекторам. Далее мы перейдем к другой важной части CSS — CSS модель коробки.

+ +

{{PreviousMenuNext("Learn/CSS/Building_blocks/Selectors/Pseudo-classes_and_pseudo-elements", "Learn/CSS/Building_blocks/The_box_model", "Learn/CSS/Building_blocks")}}

+ +

В этом модуле

+ +
    +
  1. Каскад и наследование
  2. +
  3. Селекторы CSS + +
  4. +
  5. Модель коробки
  6. +
  7. Фон и границы
  8. +
  9. Обработка разных направлений текста
  10. +
  11. Переполнение содержимого
  12. +
  13. Значения и единицы измерения
  14. +
  15. Изменение размеров в CSS
  16. +
  17. Элементы изображений, форм и медиа-элементы
  18. +
  19. Стилизация таблиц
  20. +
  21. Отладка CSS
  22. +
  23. Организация вашей CSS
  24. +
diff --git a/files/ru/learn/css/building_blocks/selectors/index.html b/files/ru/learn/css/building_blocks/selectors/index.html new file mode 100644 index 0000000000..3819af4207 --- /dev/null +++ b/files/ru/learn/css/building_blocks/selectors/index.html @@ -0,0 +1,235 @@ +--- +title: Селекторы CSS +slug: Learn/CSS/Building_blocks/Селекторы +tags: + - Attribute + - Beginner + - CSS + - Learn + - Pseudo-class + - Pseudo-element + - id + - Обучение + - Псевдоэлемент + - псевдокласс + - селектор +translation_of: Learn/CSS/Building_blocks/Selectors +--- +
{{LearnSidebar}}{{PreviousMenuNext("Learn/CSS/Building_blocks/Cascade_and_inheritance", "Learn/CSS/Building_blocks/Selectors/Type_Class_and_ID_Selectors", "Learn/CSS/Building_blocks")}}
+ +

В {{Glossary("CSS")}}-селекторы используются для стилизации {{glossary("HTML")}} элементов на веб-странице. Существует широкий выбор CSS-селекторов, позволяющий максимально точно отбирать элементы для стилизации. В этой статье и её подстатьях мы в мельчайших подробностях рассмотрим разные их типы и увидим, как они работают.

+ + + + + + + + + + + + +
Необходимые знания:Базовая компьютерная грамотность, основное программное обеспечение, понимание работы с файлами, базовые знания HTML (смотрите Введение в HTML), и представление о том, как работает CSS (смотрите Введение в CSS).
Цель:Узнать, как работают CSS-селекторы.
+ +

Что такое селекторы?

+ +

Вы уже встерчались с селекторами. Это выражения, которые говорят браузеру, к какому элементу HTML нужно применить те или иные свойства CSS, определённые внутри блока объявления стиля.

+ +

Some code with the h1 highlighted.

+ +

Ранее Вы встречали несколько разных селекторов и узнали, что существуют селекторы, которые по-разному относятся к документу, — например используя элемент h1 или класс .special.

+ +

В CSS селекторы определяются в спецификации CSS-селекторов; как и другие части CSS, нужно поддерживать их работу в браузерах. Большинство селекторов, которые Вы встретите, определены в Спецификации селекторов 3 уровня, где Вы сможете найти всю информацию о поддержке селекторов в браузерах.

+ +

Несколько селекторов

+ +

Несколько селекторов, использующих одни и те же таблицы стилей, можно объединить в лист селекторов: правило будет добавлено к каждому селектору. К примеру, у меня есть одинаковые правила для заголовка h1 и класса .special; я могу написать их так:

+ +
h1 {
+  color: blue;
+}
+
+.special {
+  color: blue;
+} 
+ +

А могу написать короче — просто отделив селекторы запятыми:

+ +
h1, .special {
+  color: blue;
+} 
+ +

Пробел можно вставлять до или после запятой. Ещё удобнее писать каждый селектор с новой строки:

+ +
h1,
+.special {
+  color: blue;
+} 
+ +

В упражнении ниже объедините два селектора в одном правиле. Результат должен остаться таким же.

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/selector-list.html", '100%', 1000)}} 

+ +

При объединении селекторов таким образом, при условии если хоть один селектор будет недействительным, всё правило будет пропущено.

+ +

В примере ниже правило для селектора класса не будет работать, в то время как h1 будет стилизован.

+ +
h1 {
+  color: blue;
+}
+
+..special {
+  color: blue;
+} 
+ +

Но если мы объединим селекторы, правило не применится ни к h1, ни к классу: оно считается недействительным.

+ +
h1, ..special {
+  color: blue;
+} 
+ +

Типы селекторов

+ +

Понимание того, какой именно селектор вам нужен, очень помогает подобрать подходящий элемент. Сейчас мы разберём разные виды селекторов.

+ +

Селекторы тегов, классов и идентификаторов

+ +

К этой группе относятся селекторы HTML-элементов, таких как <h1>.

+ +
h1 { }
+ +

К группе относятся и селекторы классов:

+ +
.box { }
+ +

или селекторы идентификаторов (ID):

+ +
#unique { }
+ +

Селекторы атрибутов

+ +

Эта группа селекторов позволяет выбирать селекторы, основываясь на наличии у них конкретного атрибута элемента:

+ +
a[title] { }
+ +

или основываясь на значении атрибута:

+ +
a[href="https://example.com"] { }
+ +

Псевдоклассы, псевдоэлементы

+ +

К этой группе относятся псевдоклассы, которые стилизуют определённое состояние элемента. Псевдокласс :hover, например, применяет правило, только если на элемент наведён курсор мыши

+ +
a:hover { }
+ +

К группе ещё относятся псевдоэлементы, которые выбирают определённую часть элемента (вместо целого элемента). Например, ::first-line всегда выбирает первую строку внутри элемента (абзаца <p> в нашем случае), действуя, как если бы тег <span> оборачивал первую строку, а затем был стилизован.

+ +
p::first-line { }
+ +

Комбинаторы

+ +

И последняя группа селекторов: она позволяет объединять селекторы, чтобы было легче находить конкретные элементы внутри документа. В следующем примере мы отыскали дочерний элемент <article> с помощью комбинатора дочерних элементов (>):

+ +
article > p { }
+ +

Продолжение

+ +

Ниже можно просмотреть таблицу различных видов селекторов с соответствующими ссылками, или Вы можете двинуться дальше: нас ждут селекторы тегов, классов и идентификаторов.

+ +

{{PreviousMenuNext("Learn/CSS/Building_blocks/Cascade_and_inheritance", "Learn/CSS/Building_blocks/Selectors/Type_Class_and_ID_Selectors", "Learn/CSS/Building_blocks")}}

+ +

Справка о селекторах

+ +

В таблице ниже — доступные сейчас селекторы, а также ссылки к страницам, где рассказывается, как использовать каждый из них. Я также добавил ссылки на страницы MDN для каждого селектора, чтобы вы могли проверить, поддерживаются ли они браузерами.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
СелекторПримерРуководство
Селектор по типуh1 {  }Селектор по типу
Универсальный селектор* {  }Универсальный селектор
Селектор класса.box {  }Селекторы классов
Селектор ID#unique { }Селекторы по ID
Селектор атрибутов a[title] {  }Селекторы атрибутов
Селектор псевдоклассовp:first-child { }Псевдоклассы
Селектор псевдоэлементовp::first-line { }Псевдоэлементы
Селектор потомковarticle pСелектор потомков
Селектор дочерних элементовarticle > pСелектор дочерних элементов
Смежные селекторыh1 + pСмежные селекторы
Селектор братских элементовh1 ~ pСелектор братских элементов
+ +

В этом модуле

+ +
    +
  1. Каскад и наследование
  2. +
  3. CSS-селекторы + +
  4. +
  5. Блоки в CSS
  6. +
  7. Фон и границы
  8. +
  9. Изменение направления текста
  10. +
  11. Перекрытие содержимого
  12. +
  13. Значения свойств CSS
  14. +
  15. Изменение размеров в CSS
  16. +
  17. Изображения, формы и прочие медиа-элементы
  18. +
  19. Стилизация таблиц
  20. +
  21. Отладка CSS
  22. +
  23. Организация CSS-кода
  24. +
diff --git a/files/ru/learn/css/building_blocks/selectors/pseudo-classes_and_pseudo-elements/index.html b/files/ru/learn/css/building_blocks/selectors/pseudo-classes_and_pseudo-elements/index.html new file mode 100644 index 0000000000..4fe67b8adb --- /dev/null +++ b/files/ru/learn/css/building_blocks/selectors/pseudo-classes_and_pseudo-elements/index.html @@ -0,0 +1,415 @@ +--- +title: 'Псевдоклассы, псевдоэлементы' +slug: Learn/CSS/Building_blocks/Селекторы/Pseudo-classes_and_pseudo-elements +tags: + - CSS + - Начинающий + - Обучение + - Псевдо + - Псевдоэлемент + - Селекторы + - псевдокласс +translation_of: Learn/CSS/Building_blocks/Selectors/Pseudo-classes_and_pseudo-elements +--- +

{{LearnSidebar}}{{PreviousMenuNext("Learn/CSS/Building_blocks/Selectors/Attribute_selectors", "Learn/CSS/Building_blocks/Selectors/Combinators", "Learn/CSS/Building_blocks")}}

+ +

Следующий набор селекторов, который мы рассмотрим, относится к псевдоклассам и псевдоэлементам. Их очень много, и они часто служат довольно специфическим целям. После того как вы узнаете порядок их использования, просмотрите список — не найдётся ли в нём что-либо, что поможет решить стоящую перед вами задачу. Кроме того, будет полезным заглянуть на соответствующую каждому селектору страницу MDN, чтобы прояснить, как его обрабатывает браузер.

+ + + + + + + + + + + + +
Необходимые условия:Базовая компьютерная грамотность, установка базового ПО, базовые знания о работе с файлами, основы HTML (изучите Введение в HTML) и понимание работы CSS (изучите Введение в CSS.)
Цель:Узнать о селекторах псевдокласса и псевдоэлемента.
+ +

Что такое псевдокласс?

+ +

Псевдокласс — это селектор, который выбирает элементы, находящиеся в специфическом состоянии, например, они являются первым элементом своего типа, или на них наведён указатель мыши. Они обычно действуют так, как если бы вы применили класс к какой-то части вашего документа, что часто помогает сократить избыточные классы в разметке и даёт более гибкий, удобный в поддержке код.

+ +

Псевдоклассы — это ключевые слова, которые начинаются с двоеточия:

+ +
:pseudo-class-name
+ +

Простой пример псевдокласса

+ +

Давайте рассмотрим простой пример. Если бы мы хотели сделать шрифт первого абзаца статьи более крупным и жирным, мы могли бы добавить класс к этому абзацу, а затем добавить CSS к этому классу, как показано в первом примере ниже:

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/first-child.html", '100%', 800)}}

+ +

Однако поддержка может оказаться утомительной — что если новый абзац будет добавлен в верхнюю часть документа? Тогда нам нужно будет передвинуть класс к новому абзацу. Вместо добавления класса мы могли бы использовать селектор псевдокласса {{cssxref(":first-child")}} — он всегда будет нацелен на первый дочерний элемент в статье, и нам больше не нужно будет редактировать HTML (к тому же это не всегда возможно, например, в случае если он генерируется CMS.)

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/first-child2.html", '100%', 700)}}

+ +

Все псевдоклассы ведут себя подобным образом. Они нацелены на какой-то фрагмент вашего документа, находящийся в определенном состоянии, и ведут себя так, как если бы вы добавили класс в свой HTML. Рассмотрим некоторые другие примеры в MDN:

+ + + +
+

Примечание : Правильно писать псевдоклассы и элементы без какого бы то ни было предшествующего им селектора элемента. В примере выше вы могли бы написать :first-child и правило было бы применено к любому элементу, оказавшемуся первым дочерним для <article>, не только к первому дочернему абзацу — :first-child равнозначно *:first-child. Однако обычно вы хотите большего контроля, поэтому вам нужен более специфичный селектор.

+
+ +

Псевдоклассы пользовательского действия

+ +

Некоторые псевдоклассы применяются только тогда, когда пользователь некоторым образом взаимодействует с документом. Эти псевдоклассы действий пользователя, иногда называемые динамическими псевдоклассами, действуют так, как если бы класс был добавлен к элементу в момент взаимодействия с ним пользователя. Примеры даны для:

+ + + +

{{EmbedGHLiveSample("css-examples/learn/selectors/hover.html", '100%', 500)}}

+ +

Что такое псевдоэлемент?

+ +

Псевдоэлементы ведут себя сходным образом, однако они действуют так, как если бы вы добавили в разметку целый новый HTML-элемент, а не применили класс к существующим элементам. Псевдоэлементы начинаются с двойного двоеточия ::.

+ +
::pseudo-element-name
+ +
+

Примечание: Некоторые ранние псевдоэлементы использовали синтаксис одинарного двоеточия, которое вы можете иногда видеть в коде или примерах. Современные браузеры поддерживают ранние псевдоэлементы с одинарным или двойным двоеточием синтаксиса для обратной совместимости.

+
+ +

Например, если вы хотите выбрать первую строку абзаца, вы могли бы обернуть ее в <span> и использовать селектор элемента; однако это может не сработать, если количество слов, которые вы обернули, будет больше или меньше ширины родительского элемента. Поскольку мы, как правило, не знаем, сколько слов поместится в строке — т.к. их количество меняется, если меняется ширина экрана или размер шрифта — то надёжного решения при помощи HTML нет.

+ +

Селектор псевдоэлемента ::first-line сделает это наверняка — если количество слов увеличивается или уменьшается, он всё равно будет выбирать только первую строку.

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/first-line.html", '100%', 800)}}

+ +

Он действует так, как если бы <span> волшебным образом был обёрнут вокруг этой первой отформатированной строки и обновлялся бы каждый раз при изменении длины строки.

+ +

Вы можете видеть, что селектор выбирает первую строку обоих абзацев.

+ +

Объединение псевдоклассов и псевдоэлементов

+ +

Если вы хотите сделать шрифт первой строки первого абзаца жирным, вы можете связать вместе селекторы :first-child и ::first-line. Попробуйте отредактировать предыдущий живой пример, чтобы использовалась следующая CSS. Мы говорим, что хотим выбрать первую строку первого элемента <p>, который находится внутри элемента <article>.

+ +
article p:first-child::first-line {
+  font-size: 120%;
+  font-weight: bold;
+}
+ +

Генерация контента с помощью ::before и ::after

+ +

Существует пара специальных псевдоэлементов, которые используются вместе со свойством content для вставки содержимого в документ с помощью CSS.

+ +

Вы можете использовать их для вставки строки текста, как в приведенном ниже живом примере. Попробуйте изменить текстовое значение свойства {{cssxref("content")}} и вы увидите, как изменится результат. Можете также изменить псевдоэлемент ::before на ::after и увидите, что текст вставлен в конце элемента, а не в начале.

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/before.html", '100%', 400)}}

+ +

Однако вставка строк текста из CSS в реальности происходит не слишком часто, поскольку этот текст недоступен для некоторых экранных дикторов и его будет трудно найти и отредактировать в будущем.

+ +

Более корректным использованием этих псевдоэлементов является вставка значка, например маленькой стрелки, добавленной в приведенном ниже примере, которая является визуальным указателем, не предназначенным для зачитывания с помощью экранного диктора:

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/after-icon.html", '100%', 400)}}

+ +

Эти псевдоэлементы также часто используются для вставки пустой строки, которая затем может быть стилизована так же, как и любой элемент на странице.

+ +

В следующем примере мы добавили пустую строку, используя псевдоэлемент ::before. Мы установили display: block, чтобы стилизовать его по ширине и высоте. Затем мы используем CSS, чтобы стилизовать его так же, как и любой другой элемент. Вы можете поиграть с CSS и изменить его внешний вид и поведение.

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/before-styled.html", '100%', 500)}}

+ +

Использование псевдоэлементов ::before и ::after вместе со свойством content в CSS называется "генерируемым контентом" в CSS, и вы часто будете видеть, как этот метод используется для различных задач. Отличным примером является сайт CSS Arrow Please, который помогает вам генерировать стрелку с помощью CSS. Посмотрите на CSS, когда вы создадите свою стрелку, и вы увидите использование псевдо-элементов {{cssxref("::before")}} и {{cssxref("::after")}}. Всякий раз, когда вы будете видеть эти селекторы, смотрите на свойство {{cssxref("content")}}, чтобы увидеть, что добавляется в документ..

+ +

Справочный раздел

+ +

Существует большое количество псевдоклассов и псевдоэлементов, и полезно иметь список, к которому можно обращаться. Ниже приведены таблицы, в которых они перечислены, со ссылками на их справочные страницы в MDN. Используйте эти таблицы как справочник, чтобы видеть массив доступных вам средств для нацеливания на элементы.

+ +

Псевдоклассы

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
СелекторОписание
{{ Cssxref(":active") }}Подходит, когда пользователь активирует (например, щелкает мышью) элемент.
{{ Cssxref(":any-link") }}Соответствует как состоянию :link, так и состоянию:visited ссылки.
{{ Cssxref(":blank") }}Соответствует элементу <input>, для которого значение ввода является пустым.
{{ Cssxref(":checked") }}Соответствует переключателю или флажку в выбранном состоянии.
{{ Cssxref(":current") }}Соответствует элементу или предку элемента, который в данный момент отображается.
{{ Cssxref(":default") }}Соответствует одному или нескольким элементам пользовательского интерфейса, которые являются элементами по умолчанию (обрабатывают нажатие клавиши enter) в наборе сходных элементов.
{{ Cssxref(":dir") }}Выбирает элемент на основе его направленности (значение атрибута HTML dir или свойства CSS direction ).
{{ Cssxref(":disabled") }}Соответствует элементам пользовательского интерфейса, которые находятся в отключённом состоянии.
{{ Cssxref(":empty") }}Соответствует элементу, у которого нет дочерних элементов, кроме необязательного пробела.
{{ Cssxref(":enabled") }}Соответствует элементам пользовательского интерфейса, которые находятся во включённом состоянии.
{{ Cssxref(":first") }}В постраничном носителе соответствует первой странице.
{{ Cssxref(":first-child") }}Соответствует элементу, который является первым среди других дочерних элементов одного предка.
{{ Cssxref(":first-of-type") }}Соответствует элементу, который является первым определенного типа среди других дочерних элементов одного предка.
{{ Cssxref(":focus") }}Соответствует элементу, имеющему фокус.
{{ Cssxref(":focus-visible")}}Соответствует элементу, имеющему фокус, при этом фокус должен быть виден пользователю.
{{ Cssxref(":focus-within") }}Соответствует элементу с фокусом, а также элементу с потомком, который имеет фокус.
{{ Cssxref(":future") }}Соответствует элементам после текущего элемента.
{{ Cssxref(":hover") }}Соответствует элементу, на который наведён курсор мыши.
{{ Cssxref(":indeterminate") }}Соответствует элементам пользовательского интерфейса, значение которых находится в неопределенном состоянии, обычно checkboxes.
{{ Cssxref(":in-range") }}Соответствует элементу с диапазоном, когда его значение находится в пределах диапазона.
{{ Cssxref(":invalid") }}Соответствует элементу, например <input>, в недопустимом состоянии.
{{ Cssxref(":lang") }}Соответствует элементу, основанному на языке (значение атрибута HTML lang).
{{ Cssxref(":last-child") }}Соответствует элементу, который является последним среди других дочерних элементов одного предка.
{{ Cssxref(":last-of-type") }}Соответствует элементу, который является последним определённого типа среди других дочерних элементов одного предка.
{{ Cssxref(":left") }}В постраничном носителе соответствует левосторонним страницам.
{{ Cssxref(":link")}}Соответствует непосещавшимся ссылкам.
{{ Cssxref(":local-link")}}Соответствует ссылкам, указывающим на страницы, которые расположены на том же сайте, что и текущий документ.
{{ Cssxref(":is", ":is()")}}Соответствует любому селектору из полученного списка селекторов.
{{ Cssxref(":not") }}Соответствует объектам, не входящим в список селекторов, переданный в качестве значения этому селектору.
{{ Cssxref(":nth-child") }}Соответствует элементам из списка дочерних элементов одного предка, которые подобраны по формуле вида an+b (например, 2n + 1 будет соответствовать элементам 1, 3, 5, 7 и т. д. Все нечетные числа.)
{{ Cssxref(":nth-of-type") }}Соответствует элементам из списка дочерних элементов одного предка, имеющим определенный тип (например, элементы <p>) — дочерние элементы подобраны по формуле вида an+b (например, 2n + 1 будет соответствовать элементам 1, 3, 5, 7 и т. д. Все нечетные числа.)
{{ Cssxref(":nth-last-child") }}Соответствует элементам из списка дочерних элементов одного предка, считая в обратном порядке от конца. Дочерние элементы подобраны по формуле вида an+b (например, 2n + 1 будет соответствовать последнему элементу в последовательности, затем на два элемента до него, затем ещё на два элемента назад и т. д. Все нечетные, считая с конца.)
{{ Cssxref(":nth-last-of-type") }}Соответствует элементам из списка дочерних элементов одного предка, имеющим определенный тип (например, элементы <p>), считая в обратном порядке от конца. Дочерние элементы подобраны по формуле вида an+b (например, 2n + 1 будет соответствовать последнему элементу этого типа в последовательности, затем на два элемента до него, затем ещё на два элемента назад и т. д. Все нечетные, считая с конца.)
{{ Cssxref(":only-child") }}Соответствует элементу, являющемуся единственным дочерним для своего предка.
{{ Cssxref(":only-of-type") }}Соответствует элементу, который отличается по типу от всех других дочерних элементов общего предка.
{{ Cssxref(":optional") }}Соответствует необязательным элементам формы.
{{ Cssxref(":out-of-range") }}Соответствует элементу с диапазоном, когда его значение находится вне диапазона.
{{ Cssxref(":past") }}Соответствует элементам перед текущим элементом.
{{ Cssxref(":placeholder-shown") }}Соответствует элементу input, который показывает текст-заполнитель.
{{ Cssxref(":playing") }}Соответствует элементу, представляющему аудио, видео или подобный ресурс с возможными состояниями “воспроизведён” или “приостановлен”, когда этот элемент “воспроизводится”.
{{ Cssxref(":paused") }}Соответствует элементу, представляющему аудио, видео или подобный ресурс с возможными состояниями “воспроизведён” или “приостановлен”, когда этот элемент “приостановлен”.
{{ Cssxref(":read-only") }}Соответствует элементу, который не может быть изменён пользователем.
{{ Cssxref(":read-write") }}Соответствует элементу, который может быть изменён пользователем.
{{ Cssxref(":required") }}Соответствует обязательным элементам формы.
{{ Cssxref(":right") }}В постраничном носителе соответствует правосторонним страницам.
{{ Cssxref(":root") }}Соответствует элементу, который является корнем документа.
{{ Cssxref(":scope") }}Соответствует любому элементу, который является элементом области видимости.
{{ Cssxref(":valid") }}Соответствует элементу, такому как <input>, в допустимом состоянии.
{{ Cssxref(":target") }}Соответствует элементу, если он является целью текущего URL (т. е. если у него есть ID, соответствующий текущему URL fragment).
{{ Cssxref(":visited") }}Соответствует посещённым ссылкам.
+ +

Псевдоэлементы

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
СелекторОписание
{{ Cssxref("::after") }}Соответствует элементу, который допускает стилизацию и появляется после текущего содержимого порождающего элемента.
{{ Cssxref("::before") }}Соответствует элементу, который допускает стилизацию и появляется перед текущим содержимым порождающего элемента.
{{ Cssxref("::first-letter") }}Соответствует первой букве элемента.
{{ Cssxref("::first-line") }}Соответствует первой строке содержимого порождающего элемента.
{{ Cssxref("::grammar-error") }} +

Соответствует части документа, содержащей грамматическую ошибку, отмеченную браузером.

+
{{ Cssxref("::marker") }}Соответствует полю маркера пункта списка, которое обычно содержит жирную точку или число.
+

{{ Cssxref("::selection") }}

+
Соответствует части документа, которая была выбрана.
{{ Cssxref("::spelling-error") }} +

Соответствует части документа, содержащей орфографическую ошибку, отмеченную браузером.

+
+ +

{{PreviousMenuNext("Learn/CSS/Building_blocks/Selectors/Attribute_selectors", "Learn/CSS/Building_blocks/Selectors/Combinators", "Learn/CSS/Building_blocks")}}

+ +

В этом модуле

+ +
    +
  1. Каскад и наследование
  2. +
  3. Селекторы CSS + +
  4. +
  5. Модель коробки
  6. +
  7. Фон и границы
  8. +
  9. Обработка разных направлений текста
  10. +
  11. Переполнение содержимого
  12. +
  13. Значения и единицы измерения
  14. +
  15. Изменение размеров в CSS
  16. +
  17. Элементы изображений, форм и медиа-элементы
  18. +
  19. Стилизация таблиц
  20. +
  21. Отладка CSS
  22. +
  23. Организация вашей CSS
  24. +
diff --git a/files/ru/learn/css/building_blocks/selectors/selectors_tasks/index.html b/files/ru/learn/css/building_blocks/selectors/selectors_tasks/index.html new file mode 100644 index 0000000000..b8f36063c2 --- /dev/null +++ b/files/ru/learn/css/building_blocks/selectors/selectors_tasks/index.html @@ -0,0 +1,137 @@ +--- +title: 'Проверьте ваши навыки: Селекторы' +slug: Learn/CSS/Building_blocks/Селекторы/Селекторы_Задачи +tags: + - CSS + - Начинающий +translation_of: Learn/CSS/Building_blocks/Selectors/Selectors_Tasks +--- +
{{LearnSidebar}}
+ +
+ +

Цель этой задачи — помочь вам проверить ваше понимание селекторов в CSS.

+ +
+

Примечание: Вы можете проверять решения в интерактивном редакторе, расположенном ниже, но, возможно, вам будут полезны онлайн-инструменты, такие как  CodePen, jsFiddle или Glitch, которые можно использовать для работы над заданием, предварительно загрузив в них код.
+
+ Если вы зашли в тупик, обратитесь к нам за помощью — смотрите раздел Оценка или дальнейшая помощь внизу этой страницы.

+
+ +

Selectors One

+ +

Without changing the HTML, use CSS to do the following things:

+ + + +

Text with the CSS applied for the solution to task 1.

+ +

Try updating the live code below to recreate the finished example:

+ +

{{EmbedGHLiveSample("css-examples/learn/tasks/selectors/type.html", '100%', 700)}}

+ +
+

For assessment or further work purposes, download the starting point for this task to work in your own editor or in an online editor.

+
+ +

Selectors Two

+ +

Without changing the HTML, make the following changes to the look of the content in this example:

+ + + +

Text with the CSS applied for the solution to task 2.

+ +

Try updating the live code below to recreate the finished example:

+ +

{{EmbedGHLiveSample("css-examples/learn/tasks/selectors/class-id.html", '100%', 800)}}

+ +
+

For assessment or further work purposes, download the starting point for this task to work in your own editor or in an online editor.

+
+ +

Selectors Three

+ +

In this example, try making the following changes without adding to the HTML.

+ + + +

Text with the CSS applied for the solution to task 3.

+ +

Try updating the live code below to recreate the finished example:

+ +

{{EmbedGHLiveSample("css-examples/learn/tasks/selectors/pseudo.html", '100%', 800)}}

+ +
+

For assessment or further work purposes, download the starting point for this task to work in your own editor or in an online editor.

+
+ +

Selectors Four

+ +

In this task try the following:

+ + + +

Text with the CSS applied for the solution to task 4.

+ +

Try updating the live code below to recreate the finished example:

+ +

{{EmbedGHLiveSample("css-examples/learn/tasks/selectors/combinators.html", '100%', 800)}}

+ +
+

For assessment or further work purposes, download the starting point for this task to work in your own editor or in an online editor.

+
+ +

Selectors Five

+ +

In this final task add CSS using attribute selectors to do the following:

+ + + +

Four links with different color borders.

+ +

Try updating the live code below to recreate the finished example:

+ +

{{EmbedGHLiveSample("css-examples/learn/tasks/selectors/attribute-links.html", '100%', 800)}}

+ +
+

For assessment or further work purposes, download the starting point for this task to work in your own editor or in an online editor.

+
+ +

Assessment or further help

+ +

You can practice these examples in the Interactive Editors mentioned above.

+ +

If you would like your work assessed, or are stuck and want to ask for help:

+ +
    +
  1. Put your work into an online shareable editor such as CodePen, jsFiddle, or Glitch. You can write the code yourself, or use the starting point files linked to in the above sections.
  2. +
  3. Write a post asking for assessment and/or help at the MDN Discourse forum Learning category. Your post should include: +
      +
    • A descriptive title such as "Assessment wanted for Selectors skill test 1".
    • +
    • Details of what you have already tried, and what you would like us to do, e.g. if you are stuck and need help, or want an assessment.
    • +
    • A link to the example you want to be assessed or need help with, in an online shareable editor (as mentioned in step 1 above). This is a good practice to get into — it's very hard to help someone with a coding problem if you can't see their code.
    • +
    • A link to the actual task or assessment page, so we can find the question you want help with.
    • +
    +
  4. +
diff --git a/files/ru/learn/css/building_blocks/selectors/type_class_and_id_selectors/index.html b/files/ru/learn/css/building_blocks/selectors/type_class_and_id_selectors/index.html new file mode 100644 index 0000000000..875899ab41 --- /dev/null +++ b/files/ru/learn/css/building_blocks/selectors/type_class_and_id_selectors/index.html @@ -0,0 +1,130 @@ +--- +title: 'Селекторы типа, класса и ID' +slug: Learn/CSS/Building_blocks/Селекторы/Type_Class_and_ID_Selectors +tags: + - CSS + - id + - Класс + - Начинающий + - Обучение + - Селекторы +translation_of: Learn/CSS/Building_blocks/Selectors/Type_Class_and_ID_Selectors +--- +

{{LearnSidebar}}{{PreviousMenuNext("Learn/CSS/Building_blocks/Selectors", "Learn/CSS/Building_blocks/Selectors/Attribute_selectors", "Learn/CSS/Building_blocks")}}

+ +

В этом уроке мы рассмотрим некоторые из базисных селекторов, которые вы, вероятно, будете чаще всего использовать в вашей работе.

+ + + + + + + + + + + + +
Необходимые условия:Базовая компьютерная грамотность, установка базового ПО, базовые знания о работе с файлами, основы HTML (изучите Введение в HTML) и понимание работы CSS (изучите Введение в CSS.)
Задача:Изучить различные селекторы CSS, которые мы можем использовать, чтобы применить CSS к документу.
+ +

Селекторы типа

+ +

Селектор типа иногда называется селектором имени тега или селектором элемента, поскольку он выбирает тег/элемент HTML в вашем документе. В примере ниже мы использовали селекторы span, em и strong.

+ +

Попробуйте добавить CSS-правило, чтобы выбрать элемент <h1> и изменить его цвет на синий.

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/type.html", '100%', 1100)}}

+ +

Универсальный селектор

+ +

Универсальный селектор обозначается звездочкой (*). Он выбирает всё в документе (или внутри родительского элемента, если он сцеплен с другим элементом и с комбинатором потомка). В следующем примере мы используем универсальный селектор, чтобы убрать внешние отступы у всех элементов. Несмотря на стилизацию по умолчанию, добавленную браузером, — она раздвигает заголовки и абзацы с помощью отступов, — всё плотно сжато.

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/universal.html", '100%', 750)}}

+ +

Такого рода поведение иногда можно увидеть в «таблицах сброса стилей», которые вычищают всю стилизацию браузера. Так как универсальный селектор вызывает глобальные изменения, мы используем его в очень специфических ситуациях, таких как та, что описана ниже.

+ +

Использование универсального селектора для облегчения чтения ваших селекторов

+ +

Одно из применений универсального селектора состоит в том, чтобы облегчить чтение селекторов и сделать их более удобопонятными с точки зрения того, что они делают. Например, если мы хотим выбрать элементы-потомки элемента <article>, которые являются первыми дочерними элементами своего родителя, включая дочерние элементы самого <article>, и сделать их шрифт жирным, мы могли бы использовать псевдо-класс {{cssxref(":first-child")}}, который мы будем изучать в уроке о псевдо-классах и псевдо-элементах, как селектор-потомок вместе с селектором элемента <article>

+ +
article :first-child {
+  font-weight: bold;
+}
+ +

Однако этот селектор можно спутать с article:first-child, который выберет любой элемент <article>, являющийся первым дочерним элементом другого элемента .

+ +

Чтобы избежать этой путаницы, мы можем добавить универсальный селектор в псевдо-класс :first-child , чтобы было очевидно, что делает селектор. Он выбирает любой элемент, который является первым дочерним элементом элемента <article> или первым дочерним элементом любого потомка элемента <article>:

+ +
article *:first-child {
+  font-weight: bold;
+} 
+ +

Хотя оба делают одно и то же, удобочитаемость значительно улучшилась.

+ +

Селекторы класса

+ +

Селектор класса начинается с символа точки (.). Он выберет в документе всё, к чему применён этот класс. В живом примере ниже мы создали класс с именем .highlight, и применили его к нескольким местам в документе. Все элементы, к которым применён класс, подсвечиваются.

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/class.html", '100%', 750)}}

+ +

Нацеливание классов на отдельные элементы

+ +

Вы можете создать селектор, нацеленный на конкретные элементы, к которым применён класс. В следующем примере мы подсветим <span> с классом highlight иначе, чем заголовок <h1> с классом highlight. Мы сделаем это, используя селектор типа для элемента, на который нацелены, с классом, добавленным с помощью точки, без пробела между ними.

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/class-type.html", '100%', 750)}}

+ +

Этот подход сужает границы правила. Правило будет применяться только к этой конкретной комбинации элемента и класса. Вам нужно будет добавить другой селектор, если вы решили, что правило должно применяться и к другим элементам.

+ +

Нацеливание на элемент, к которому применено более одного класса

+ +

Вы можете применить несколько классов к элементу и нацелиться на них по отдельности, или выбрать элемент только если присутствуют все классы селектора. Это может быть полезно при создании компонентов, которые могут сочетаться на вашем сайте разными способами.

+ +

В примере ниже у нас есть <div>, содержащий примечание. Серая граница применятеся когда блок имеет класс notebox. Если у блока есть также класс warning или danger, мы меняем {{cssxref("border-color")}}.

+ +

Мы можем указать браузеру, что мы хотим подобрать только такой элемент, к которому применены два класса, сцепив их вместе без пробелов между ними. Вы увидите, что к последнему <div> не применён ни один стиль, так как он имеет только класс danger; ему нужен ещё и класс notebox, чтобы получить какую-нибудь стилизацию.

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/class-many.html", '100%', 900)}}

+ +

Селекторы ID

+ +

Селектор ID начинается с #, а не с точки, но используется так же, как и селектор класса. Однако ID может быть использован единожды на странице, и к элементу может быть применён только один id. Можно выбрать элемент, которому присвоен  id, а также вы можете предварить ID селектором типа для нацеливания на элемент, имеющий соответствующее сочетание элемента и ID. Вы можете увидеть оба варианта использования в следующем примере:

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/id.html", '100%', 750)}}

+ +
+

Предупреждение: Может показаться, что неоднократное использование в документе одного и того же ID выполняет задачи стилизования, но не стоит этого делать. Результатом будет неверный код, который приведёт к многочисленным странностям в поведении.

+
+ +
+

Примечание: Как мы знаем из урока по специфичности, ID имеет высокую специфичность. Он будет брать верх над большинством других селекторов. В большинстве случаев предпочтительнее добавить элементу класс, чем ID. Однако, если использование ID это единственный способ нацелиться на элемент — возможно, потому вы не имеете доступа к разметке и, следовательно, возможности её редактировать — это будет работать.

+
+ +

В следующей статье

+ +

Мы продолжим изучение селекторов и рассмотрим селекторы атрибута.

+ +

{{PreviousMenuNext("Learn/CSS/Building_blocks/Selectors", "Learn/CSS/Building_blocks/Selectors/Attribute_selectors", "Learn/CSS/Building_blocks")}}

+ +

В этом модуле

+ +
    +
  1. Каскад и наследование
  2. +
  3. Селекторы CSS + +
  4. +
  5. Модель коробки (The box model)
  6. +
  7. Фон и границы
  8. +
  9. Обработка разных направлений текста
  10. +
  11. Переполнение содержимого
  12. +
  13. Значения и единицы измерения
  14. +
  15. Изменение размеров в CSS
  16. +
  17. Элементы изображений, форм и медиа-элементы
  18. +
  19. Стилизация таблиц
  20. +
  21. Отладка CSS
  22. +
  23. Организация вашей CSS
  24. +
diff --git "a/files/ru/learn/css/building_blocks/\320\272\320\260\321\201\320\272\320\260\320\264_\320\267\320\260\320\264\320\260\321\207\320\270/index.html" "b/files/ru/learn/css/building_blocks/\320\272\320\260\321\201\320\272\320\260\320\264_\320\267\320\260\320\264\320\260\321\207\320\270/index.html" deleted file mode 100644 index b6524f9ed3..0000000000 --- "a/files/ru/learn/css/building_blocks/\320\272\320\260\321\201\320\272\320\260\320\264_\320\267\320\260\320\264\320\260\321\207\320\270/index.html" +++ /dev/null @@ -1,51 +0,0 @@ ---- -title: 'Проверьте ваши навыки: Каскад' -slug: Learn/CSS/Building_blocks/Каскад_задачи -tags: - - CSS - - Начинающий -translation_of: Learn/CSS/Building_blocks/Cascade_tasks ---- -
{{LearnSidebar}}
- -
- -

Цель этого задания — помочь вам проверить ваше понимание некоторых значений и элементов, которые мы рассмотрели в уроке Каскад и наследование.

- -
-

Примечание: Вы можете проверять решения в интерактивном редакторе, расположенном ниже, но, возможно, вам будут полезны онлайн-инструменты, такие как  CodePen, jsFiddle или Glitch, которые можно использовать для работы над заданием, предварительно загрузив в них код.
-
- Если вы зашли в тупик, обратитесь к нам за помощью — смотрите раздел {{anch("Оценка или дальнейшая помощь")}} внизу этой страницы.

-
- -

Задание 1

- -

В этом задании вам надо использовать одно из специальных значений, рассмотренных нами в разделе Контроль наследования,  чтобы написать в новом правиле объявление, которое восстановит белый цвет фона без использования фактического значения цвета.

- -

Barely visible yellow links on a white background.

- -

Посмотрите, сможете ли вы повторить эту картинку в примере ниже.

- -

{{EmbedGHLiveSample("css-examples/learn/tasks/cascade/cascade.html", '100%', 700)}}

- -
-

Для получения оценки или для дальнейшей работы загрузите исходный код для этого задания в ваш собственный редактор или в онлайн-редактор.

-
- -

Оценка или дальнейшая помощь

- -

Вы можете упражняться на этих примерах в интерактивных редакторах, упомянутых выше.

- -

Если вы хотите, чтобы вашу работу оценили, или вы зашли в тупик и хотите попросить о помощи:

- -
    -
  1. Поместите вашу работу в онлайн-редактор с возможностью совместного редактирования, например, CodePen, jsFiddle или Glitch. Вы можете сами написать код или использвать файлы с исходным кодом, расположенные по ссылке в предыдущем разделе.
  2. -
  3. Напишите сообщение с просьбой оценить и/или помочь на форуме в категории "Обучение": MDN Discourse forum Learning category. Ваше сообщение должно включать: -
      -
    • Описательный заголовок, например, "Необходима оценка для теста 1 Каскад" ("Assessment wanted for Cascade skill test 1").
    • -
    • Подробности того, что вы уже попытались сделать, и чего бы вы хотели от нас, т.е. или вы в тупике и нуждаетесь в помощи, или хотите оценки.
    • -
    • Ссылка на пример, который вы просите оценить или который вызвал затруднения, в онлайн-редакторе с возможностью совместного редактирования (как указано в шаге 1 выше). Это принятая практика погружения в вопрос — очень трудно помочь кому-либо решить проблему кодирования, если вы не видите его код.
    • -
    • Ссылка на страницу с заданием, чтобы мы могли найти вопрос, на который вы затрудняетесь ответить.
    • -
    -
  4. -
diff --git "a/files/ru/learn/css/building_blocks/\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/attribute_selectors/index.html" "b/files/ru/learn/css/building_blocks/\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/attribute_selectors/index.html" deleted file mode 100644 index 9a6a2c4c07..0000000000 --- "a/files/ru/learn/css/building_blocks/\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/attribute_selectors/index.html" +++ /dev/null @@ -1,160 +0,0 @@ ---- -title: Селекторы атрибута -slug: Learn/CSS/Building_blocks/Селекторы/Attribute_selectors -tags: - - CSS - - Атрибут - - Начинающий - - Обучение - - Селекторы -translation_of: Learn/CSS/Building_blocks/Selectors/Attribute_selectors ---- -

{{LearnSidebar}}{{PreviousMenuNext("Learn/CSS/Building_blocks/Selectors/Type_Class_and_ID_Selectors", "Learn/CSS/Building_blocks/Selectors/Pseudo-classes_and_pseudo-elements", "Learn/CSS/Building_blocks")}}

- -

Как вы знаете из курса о HTML, элементы могут иметь атрибуты, которые дают дополнительную информацию о размечаемом элементе. В CSS вы можете использовать селекторы атрибута для стилизации элементов с определенными атрибутами. Этот урок покажет вам, как использовать эти очень полезные селекторы.

- - - - - - - - - - - - -
Необходимые условия:Базовая компьютерная грамотность, установка базового ПО, базовые знания о работе с файлами, основы HTML (изучите Введение в HTML) и понимание работы CSS (изучите Введение в CSS.)
Задача:Узнать, что такое селекторы атрибута и как их использовать.
- -

Селекторы наличия и значения

- -

Эти селекторы делают возможным выбор элемента, основанный только на наличии атрибута (например, href) или на всевозможных разного рода сочетаниях со значением атрибута.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
СелекторПримерОписание
[attr]a[title]Выбирает элементы с атрибутом attr (имя которого это значение в квадратных скобках).
[attr=value]a[href="https://example.com"]Выбирает элементы с атрибутом attr, значение которого в точности равно value строке внутри кавычек.
[attr~=value]p[class~="special"] -

Выбирает элементы с атрибутом attr, значение которого в точности равно value или содержит value в своём (разделённом пробелами) списке значений.

-
[attr|=value]div[lang|="zh"]Выбирает элементы с атрибутом attr, значение которого в точности равно value или начинается с value, за которым сразу следует дефис.
- -

В приведённом ниже примере вы можете увидеть использование этих селекторов.

- - - -

{{EmbedGHLiveSample("css-examples/learn/selectors/attribute.html", '100%', 800)}}

- -

Селекторы вхождения подстроки

- -

Эти селекторы предоставляют более широкие возможности для выявления вхождения подстроки в значение атрибута. Например, если у вас есть классы box-warning и box-error и вы хотите выбрать всё, что начинается со стороки "box-", вы можете использовать [class^="box-"], чтобы выбрать оба класса (или [class|="box"] как описано в предыдущем разделе).

- - - - - - - - - - - - - - - - - - - - - - - - - - -
СелекторПримерОписание
[attr^=value]li[class^="box-"]Выбирает элементы с атрибутом attr (его имя это значение в квадратных скобках), значение которого начинается с value.
[attr$=value]li[class$="-box"]Выбирает элементы с атрибутом attr, значение которого заканчивается на value.
[attr*= ]li[class*="box"]Выбирает элементы с атрибутом attr, значение которого содержит value, независимо от его положения внутри строки.
- -

(Отступление: возможно, будет полезным заметить, что ^ и $ давно используются как якоря в так называемых регулярных выражениях и обозначают начинается с и заканчивается на.)

- -

Следующий пример показывает, как используются эти селекторы:

- - - -

{{EmbedGHLiveSample("css-examples/learn/selectors/attribute-substring.html", '100%', 800)}}

- -

Чувствительность к регистру

- -

Если вы хотите выбрать значения атрибута без учета регистра, вы можете использовать значение i перед закрывающей скобкой. Этот признак говорит браузеру, что символы ASCII должны сопоставляться без учета регистра. Без этого признака значения будут сопоставлены в соответствии с чувствительностью к регистру языка документав случае HTML такая чувствительность присутствует.

- -

В примере ниже первый селектор выберет значение, начинающееся с aэто соответствует только первому элементу списка, потому что два других элемента списка начинаются с заглавной буквы A. Второй селектор использует признак нечувствительности к регистру и поэтому выберет все элементы списка.

- -

{{EmbedGHLiveSample("css-examples/learn/selectors/attribute-case.html", '100%', 800)}}

- -
-

Примечание: Существует также более новое значение s, которое вызывает сопоставление с учетом регистра в контекстах, где сопоставление обычно не учитывает регистр, однако это не так хорошо поддерживается в браузерах и не очень полезно в контексте HTML.

-
- -

Следующие шаги

- -

Итак, мы рассмотрели селекторы атрибута, и вы можете перейти к следующей статье, в которой рассказывается о псевдоклассах и псевдоэлементах.

- -

{{PreviousMenuNext("Learn/CSS/Building_blocks/Selectors/Type_Class_and_ID_Selectors", "Learn/CSS/Building_blocks/Selectors/Pseudo-classes_and_pseudo-elements", "Learn/CSS/Building_blocks")}}

- -

В этом модуле

- -
    -
  1. Каскад и наследование
  2. -
  3. Селекторы CSS - -
  4. -
  5. Модель коробки (The box model)
  6. -
  7. Фон и границы
  8. -
  9. Обработка разных направлений текста
  10. -
  11. Переполнение содержимого
  12. -
  13. Значения и единицы измерения
  14. -
  15. Изменение размеров в CSS
  16. -
  17. Элементы изображений, форм и медиа-элементы
  18. -
  19. Стилизация таблиц
  20. -
  21. Отладка CSS
  22. -
  23. Организация вашей CSS
  24. -
diff --git "a/files/ru/learn/css/building_blocks/\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/combinators/index.html" "b/files/ru/learn/css/building_blocks/\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/combinators/index.html" deleted file mode 100644 index 7a076e05a8..0000000000 --- "a/files/ru/learn/css/building_blocks/\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/combinators/index.html" +++ /dev/null @@ -1,113 +0,0 @@ ---- -title: Комбинаторы -slug: Learn/CSS/Building_blocks/Селекторы/Combinators -tags: - - CSS - - Селекторы - - комбинаторы -translation_of: Learn/CSS/Building_blocks/Selectors/Combinators ---- -

{{LearnSidebar}}{{PreviousMenuNext("Learn/CSS/Building_blocks/Selectors/Pseudo-classes_and_pseudo-elements", "Learn/CSS/Building_blocks/The_box_model", "Learn/CSS/Building_blocks")}}

- -

Наконец мы рассмотрим селекторы, которые называются комбинаторами, поскольку они соединяют другие селекторы, создавая полезную связь селекторов друг с другом и расположением содержимого в документе.

- - - - - - - - - - - - -
Необходимые условия:Базовая компьютерная грамотность, установленное базовое программное обеспечение, базовые знания о работе с файлами, основы HTML (изучите Введение в HTML) и понимание работы CSS (изучите Введение в CSS.)
Цель:Узнать о различных комбинаторных селекторах, которые могут быть использованы в CSS.
- -

Комбинатор потомка

- -

Селектор потомка — обычно представляется символом пробела ( ) — соединяет два селектора так, что элементы, соответствующие второму селектору, выбираются, если они имеют предка (родителя, родителя родителя, родителя родителя родителя и т.д.), соответствующего первому селектору. Селекторы, которые используют комбинатор потомка, называются селекторами потомка.

- -
body article p
- -

В приведенном ниже примере выбирается только тот элемент <p>, который находится внутри элемента с классом.box.

- -

{{EmbedGHLiveSample("css-examples/learn/selectors/descendant.html", '100%', 500)}}

- -

Дочерний комбинатор

- -

Дочерний комбинатор (>) помещается между двумя селекорами CSS. При этом будут выбраны только те элементы, соответствующие второму селектору, которые являются прямыми потомками элементов, соответствующих первому селектору. Все элементы-потомки на более низких уровнях иерархии будут пропущены. Например, чтобы выбрать только те элементы <p>, которые являются дочерними элементами <article>, селетор пишется так:

- -
article > p
- -

Другой пример. Имеется неупорядоченный список, заключающий в себе другой, упорядоченный список. Дочерний комбинатор используется для того, чтобы выбрать только те элементы <li>, которые являются прямыми потомками <ul>, и присвоить им верхнюю границу красного цвета.

- -

Если вы уберёте символ >, указывающий на то, что это селектор с дочерним комбинатором, селетор превратится в селектор всех потомков (комбинатор - пробел) и все элементы <li> получат верхнюю границу красного цвета.

- -

{{EmbedGHLiveSample("css-examples/learn/selectors/child.html", '100%', 600)}}

- -

Соседний родственный комбинатор

- -

Соседний родственный селектор (+) используется для выбора элемента, который непосредственно следует за другим элементом и находится на одном с ним уровне иерархии. Например, чтобы выбрать все элементы <img> , которые идут сразу после элементов <p> :

- -
p + img
- -

Распространенный вариант использования — сделать что-то с абзацем, который следует за заголовком, как в примере ниже. Здесь мы ищем абзац, который непосредственно примыкает к <h1>, и стилизуем его.

- -

Если вы вставите какой-то другой элемент, например <h2> между <h1> и <p>, вы обнаружите, что абзац больше не соответствует селектору и поэтому не получает цвет фона и переднего плана, применяемый, когда элемент является соседним.

- -

{{EmbedGHLiveSample("css-examples/learn/selectors/adjacent.html", '100%', 800)}}

- -

Общий родственный комбинатор

- -

Если вы хотите выбрать родственные элементы, даже если они не являются непосредственными соседями, то вы можете использовать общий родственный комбинатор (~). Чтобы выбрать все элементы <img>, которые находятся в любом месте после элементов <p>, надо указать так:

- -
p ~ img
- -

В приведенном ниже примере мы выбираем все элементы <p>, которые идут после <h1>, и хотя в документе есть также <div>, тем не менее <p>, который идет после него, будет выбран.

- -

{{EmbedGHLiveSample("css-examples/learn/selectors/general.html", '100%', 600)}}

- -

Использование комбинаторов

- -

Вы можете соединять с помощью комбинаторов любые селекторы, которые мы изучали в предыдущих уроках, чтобы выбрать часть вашего документа. Например, если мы хотим выбрать пункты списка с классом "a", которые являются прямыми потомками <ul>, можно использовать следующую комбинацию:

- -
ul > li[class="a"]  {  }
- -

Однако будьте осторожны при создании больших списков селекторов, которые выделяют очень конкретные части вашего документа. Будет трудно повторно использовать правила CSS, так как вы сделали селектор очень специфичным для определения местоположения этого элемента в разметке.

- -

Часто бывает лучше создать простой класс и применить его к рассматриваемому элементу. Тем не менее, ваши знания о комбинаторах будут очень полезны, если вам нужно добраться до чего-то в вашем документе и вы не можете получить доступ к HTML, возможно, из-за того, что он генерируется CMS.

- -

Проверьте ваши навыки!

- -

Мы охватили много тем в этой статье. А вы можете вспомнить наиболее важную информацию? Можете пройти несколько дополнительных тестов для того чтобы убедиться в том, что вы усвоили эту информацию, прежде чем пойдёте дальше — смотрите Проверьте ваши навыки: Селекторы.

- -

Двигаемся дальше

- -

Это последний раздел в наших уроках по селекторам. Далее мы перейдем к другой важной части CSS — CSS модель коробки.

- -

{{PreviousMenuNext("Learn/CSS/Building_blocks/Selectors/Pseudo-classes_and_pseudo-elements", "Learn/CSS/Building_blocks/The_box_model", "Learn/CSS/Building_blocks")}}

- -

В этом модуле

- -
    -
  1. Каскад и наследование
  2. -
  3. Селекторы CSS - -
  4. -
  5. Модель коробки
  6. -
  7. Фон и границы
  8. -
  9. Обработка разных направлений текста
  10. -
  11. Переполнение содержимого
  12. -
  13. Значения и единицы измерения
  14. -
  15. Изменение размеров в CSS
  16. -
  17. Элементы изображений, форм и медиа-элементы
  18. -
  19. Стилизация таблиц
  20. -
  21. Отладка CSS
  22. -
  23. Организация вашей CSS
  24. -
diff --git "a/files/ru/learn/css/building_blocks/\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/index.html" "b/files/ru/learn/css/building_blocks/\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/index.html" deleted file mode 100644 index 3819af4207..0000000000 --- "a/files/ru/learn/css/building_blocks/\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/index.html" +++ /dev/null @@ -1,235 +0,0 @@ ---- -title: Селекторы CSS -slug: Learn/CSS/Building_blocks/Селекторы -tags: - - Attribute - - Beginner - - CSS - - Learn - - Pseudo-class - - Pseudo-element - - id - - Обучение - - Псевдоэлемент - - псевдокласс - - селектор -translation_of: Learn/CSS/Building_blocks/Selectors ---- -
{{LearnSidebar}}{{PreviousMenuNext("Learn/CSS/Building_blocks/Cascade_and_inheritance", "Learn/CSS/Building_blocks/Selectors/Type_Class_and_ID_Selectors", "Learn/CSS/Building_blocks")}}
- -

В {{Glossary("CSS")}}-селекторы используются для стилизации {{glossary("HTML")}} элементов на веб-странице. Существует широкий выбор CSS-селекторов, позволяющий максимально точно отбирать элементы для стилизации. В этой статье и её подстатьях мы в мельчайших подробностях рассмотрим разные их типы и увидим, как они работают.

- - - - - - - - - - - - -
Необходимые знания:Базовая компьютерная грамотность, основное программное обеспечение, понимание работы с файлами, базовые знания HTML (смотрите Введение в HTML), и представление о том, как работает CSS (смотрите Введение в CSS).
Цель:Узнать, как работают CSS-селекторы.
- -

Что такое селекторы?

- -

Вы уже встерчались с селекторами. Это выражения, которые говорят браузеру, к какому элементу HTML нужно применить те или иные свойства CSS, определённые внутри блока объявления стиля.

- -

Some code with the h1 highlighted.

- -

Ранее Вы встречали несколько разных селекторов и узнали, что существуют селекторы, которые по-разному относятся к документу, — например используя элемент h1 или класс .special.

- -

В CSS селекторы определяются в спецификации CSS-селекторов; как и другие части CSS, нужно поддерживать их работу в браузерах. Большинство селекторов, которые Вы встретите, определены в Спецификации селекторов 3 уровня, где Вы сможете найти всю информацию о поддержке селекторов в браузерах.

- -

Несколько селекторов

- -

Несколько селекторов, использующих одни и те же таблицы стилей, можно объединить в лист селекторов: правило будет добавлено к каждому селектору. К примеру, у меня есть одинаковые правила для заголовка h1 и класса .special; я могу написать их так:

- -
h1 {
-  color: blue;
-}
-
-.special {
-  color: blue;
-} 
- -

А могу написать короче — просто отделив селекторы запятыми:

- -
h1, .special {
-  color: blue;
-} 
- -

Пробел можно вставлять до или после запятой. Ещё удобнее писать каждый селектор с новой строки:

- -
h1,
-.special {
-  color: blue;
-} 
- -

В упражнении ниже объедините два селектора в одном правиле. Результат должен остаться таким же.

- -

{{EmbedGHLiveSample("css-examples/learn/selectors/selector-list.html", '100%', 1000)}} 

- -

При объединении селекторов таким образом, при условии если хоть один селектор будет недействительным, всё правило будет пропущено.

- -

В примере ниже правило для селектора класса не будет работать, в то время как h1 будет стилизован.

- -
h1 {
-  color: blue;
-}
-
-..special {
-  color: blue;
-} 
- -

Но если мы объединим селекторы, правило не применится ни к h1, ни к классу: оно считается недействительным.

- -
h1, ..special {
-  color: blue;
-} 
- -

Типы селекторов

- -

Понимание того, какой именно селектор вам нужен, очень помогает подобрать подходящий элемент. Сейчас мы разберём разные виды селекторов.

- -

Селекторы тегов, классов и идентификаторов

- -

К этой группе относятся селекторы HTML-элементов, таких как <h1>.

- -
h1 { }
- -

К группе относятся и селекторы классов:

- -
.box { }
- -

или селекторы идентификаторов (ID):

- -
#unique { }
- -

Селекторы атрибутов

- -

Эта группа селекторов позволяет выбирать селекторы, основываясь на наличии у них конкретного атрибута элемента:

- -
a[title] { }
- -

или основываясь на значении атрибута:

- -
a[href="https://example.com"] { }
- -

Псевдоклассы, псевдоэлементы

- -

К этой группе относятся псевдоклассы, которые стилизуют определённое состояние элемента. Псевдокласс :hover, например, применяет правило, только если на элемент наведён курсор мыши

- -
a:hover { }
- -

К группе ещё относятся псевдоэлементы, которые выбирают определённую часть элемента (вместо целого элемента). Например, ::first-line всегда выбирает первую строку внутри элемента (абзаца <p> в нашем случае), действуя, как если бы тег <span> оборачивал первую строку, а затем был стилизован.

- -
p::first-line { }
- -

Комбинаторы

- -

И последняя группа селекторов: она позволяет объединять селекторы, чтобы было легче находить конкретные элементы внутри документа. В следующем примере мы отыскали дочерний элемент <article> с помощью комбинатора дочерних элементов (>):

- -
article > p { }
- -

Продолжение

- -

Ниже можно просмотреть таблицу различных видов селекторов с соответствующими ссылками, или Вы можете двинуться дальше: нас ждут селекторы тегов, классов и идентификаторов.

- -

{{PreviousMenuNext("Learn/CSS/Building_blocks/Cascade_and_inheritance", "Learn/CSS/Building_blocks/Selectors/Type_Class_and_ID_Selectors", "Learn/CSS/Building_blocks")}}

- -

Справка о селекторах

- -

В таблице ниже — доступные сейчас селекторы, а также ссылки к страницам, где рассказывается, как использовать каждый из них. Я также добавил ссылки на страницы MDN для каждого селектора, чтобы вы могли проверить, поддерживаются ли они браузерами.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
СелекторПримерРуководство
Селектор по типуh1 {  }Селектор по типу
Универсальный селектор* {  }Универсальный селектор
Селектор класса.box {  }Селекторы классов
Селектор ID#unique { }Селекторы по ID
Селектор атрибутов a[title] {  }Селекторы атрибутов
Селектор псевдоклассовp:first-child { }Псевдоклассы
Селектор псевдоэлементовp::first-line { }Псевдоэлементы
Селектор потомковarticle pСелектор потомков
Селектор дочерних элементовarticle > pСелектор дочерних элементов
Смежные селекторыh1 + pСмежные селекторы
Селектор братских элементовh1 ~ pСелектор братских элементов
- -

В этом модуле

- -
    -
  1. Каскад и наследование
  2. -
  3. CSS-селекторы - -
  4. -
  5. Блоки в CSS
  6. -
  7. Фон и границы
  8. -
  9. Изменение направления текста
  10. -
  11. Перекрытие содержимого
  12. -
  13. Значения свойств CSS
  14. -
  15. Изменение размеров в CSS
  16. -
  17. Изображения, формы и прочие медиа-элементы
  18. -
  19. Стилизация таблиц
  20. -
  21. Отладка CSS
  22. -
  23. Организация CSS-кода
  24. -
diff --git "a/files/ru/learn/css/building_blocks/\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/pseudo-classes_and_pseudo-elements/index.html" "b/files/ru/learn/css/building_blocks/\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/pseudo-classes_and_pseudo-elements/index.html" deleted file mode 100644 index 4fe67b8adb..0000000000 --- "a/files/ru/learn/css/building_blocks/\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/pseudo-classes_and_pseudo-elements/index.html" +++ /dev/null @@ -1,415 +0,0 @@ ---- -title: 'Псевдоклассы, псевдоэлементы' -slug: Learn/CSS/Building_blocks/Селекторы/Pseudo-classes_and_pseudo-elements -tags: - - CSS - - Начинающий - - Обучение - - Псевдо - - Псевдоэлемент - - Селекторы - - псевдокласс -translation_of: Learn/CSS/Building_blocks/Selectors/Pseudo-classes_and_pseudo-elements ---- -

{{LearnSidebar}}{{PreviousMenuNext("Learn/CSS/Building_blocks/Selectors/Attribute_selectors", "Learn/CSS/Building_blocks/Selectors/Combinators", "Learn/CSS/Building_blocks")}}

- -

Следующий набор селекторов, который мы рассмотрим, относится к псевдоклассам и псевдоэлементам. Их очень много, и они часто служат довольно специфическим целям. После того как вы узнаете порядок их использования, просмотрите список — не найдётся ли в нём что-либо, что поможет решить стоящую перед вами задачу. Кроме того, будет полезным заглянуть на соответствующую каждому селектору страницу MDN, чтобы прояснить, как его обрабатывает браузер.

- - - - - - - - - - - - -
Необходимые условия:Базовая компьютерная грамотность, установка базового ПО, базовые знания о работе с файлами, основы HTML (изучите Введение в HTML) и понимание работы CSS (изучите Введение в CSS.)
Цель:Узнать о селекторах псевдокласса и псевдоэлемента.
- -

Что такое псевдокласс?

- -

Псевдокласс — это селектор, который выбирает элементы, находящиеся в специфическом состоянии, например, они являются первым элементом своего типа, или на них наведён указатель мыши. Они обычно действуют так, как если бы вы применили класс к какой-то части вашего документа, что часто помогает сократить избыточные классы в разметке и даёт более гибкий, удобный в поддержке код.

- -

Псевдоклассы — это ключевые слова, которые начинаются с двоеточия:

- -
:pseudo-class-name
- -

Простой пример псевдокласса

- -

Давайте рассмотрим простой пример. Если бы мы хотели сделать шрифт первого абзаца статьи более крупным и жирным, мы могли бы добавить класс к этому абзацу, а затем добавить CSS к этому классу, как показано в первом примере ниже:

- -

{{EmbedGHLiveSample("css-examples/learn/selectors/first-child.html", '100%', 800)}}

- -

Однако поддержка может оказаться утомительной — что если новый абзац будет добавлен в верхнюю часть документа? Тогда нам нужно будет передвинуть класс к новому абзацу. Вместо добавления класса мы могли бы использовать селектор псевдокласса {{cssxref(":first-child")}} — он всегда будет нацелен на первый дочерний элемент в статье, и нам больше не нужно будет редактировать HTML (к тому же это не всегда возможно, например, в случае если он генерируется CMS.)

- -

{{EmbedGHLiveSample("css-examples/learn/selectors/first-child2.html", '100%', 700)}}

- -

Все псевдоклассы ведут себя подобным образом. Они нацелены на какой-то фрагмент вашего документа, находящийся в определенном состоянии, и ведут себя так, как если бы вы добавили класс в свой HTML. Рассмотрим некоторые другие примеры в MDN:

- - - -
-

Примечание : Правильно писать псевдоклассы и элементы без какого бы то ни было предшествующего им селектора элемента. В примере выше вы могли бы написать :first-child и правило было бы применено к любому элементу, оказавшемуся первым дочерним для <article>, не только к первому дочернему абзацу — :first-child равнозначно *:first-child. Однако обычно вы хотите большего контроля, поэтому вам нужен более специфичный селектор.

-
- -

Псевдоклассы пользовательского действия

- -

Некоторые псевдоклассы применяются только тогда, когда пользователь некоторым образом взаимодействует с документом. Эти псевдоклассы действий пользователя, иногда называемые динамическими псевдоклассами, действуют так, как если бы класс был добавлен к элементу в момент взаимодействия с ним пользователя. Примеры даны для:

- - - -

{{EmbedGHLiveSample("css-examples/learn/selectors/hover.html", '100%', 500)}}

- -

Что такое псевдоэлемент?

- -

Псевдоэлементы ведут себя сходным образом, однако они действуют так, как если бы вы добавили в разметку целый новый HTML-элемент, а не применили класс к существующим элементам. Псевдоэлементы начинаются с двойного двоеточия ::.

- -
::pseudo-element-name
- -
-

Примечание: Некоторые ранние псевдоэлементы использовали синтаксис одинарного двоеточия, которое вы можете иногда видеть в коде или примерах. Современные браузеры поддерживают ранние псевдоэлементы с одинарным или двойным двоеточием синтаксиса для обратной совместимости.

-
- -

Например, если вы хотите выбрать первую строку абзаца, вы могли бы обернуть ее в <span> и использовать селектор элемента; однако это может не сработать, если количество слов, которые вы обернули, будет больше или меньше ширины родительского элемента. Поскольку мы, как правило, не знаем, сколько слов поместится в строке — т.к. их количество меняется, если меняется ширина экрана или размер шрифта — то надёжного решения при помощи HTML нет.

- -

Селектор псевдоэлемента ::first-line сделает это наверняка — если количество слов увеличивается или уменьшается, он всё равно будет выбирать только первую строку.

- -

{{EmbedGHLiveSample("css-examples/learn/selectors/first-line.html", '100%', 800)}}

- -

Он действует так, как если бы <span> волшебным образом был обёрнут вокруг этой первой отформатированной строки и обновлялся бы каждый раз при изменении длины строки.

- -

Вы можете видеть, что селектор выбирает первую строку обоих абзацев.

- -

Объединение псевдоклассов и псевдоэлементов

- -

Если вы хотите сделать шрифт первой строки первого абзаца жирным, вы можете связать вместе селекторы :first-child и ::first-line. Попробуйте отредактировать предыдущий живой пример, чтобы использовалась следующая CSS. Мы говорим, что хотим выбрать первую строку первого элемента <p>, который находится внутри элемента <article>.

- -
article p:first-child::first-line {
-  font-size: 120%;
-  font-weight: bold;
-}
- -

Генерация контента с помощью ::before и ::after

- -

Существует пара специальных псевдоэлементов, которые используются вместе со свойством content для вставки содержимого в документ с помощью CSS.

- -

Вы можете использовать их для вставки строки текста, как в приведенном ниже живом примере. Попробуйте изменить текстовое значение свойства {{cssxref("content")}} и вы увидите, как изменится результат. Можете также изменить псевдоэлемент ::before на ::after и увидите, что текст вставлен в конце элемента, а не в начале.

- -

{{EmbedGHLiveSample("css-examples/learn/selectors/before.html", '100%', 400)}}

- -

Однако вставка строк текста из CSS в реальности происходит не слишком часто, поскольку этот текст недоступен для некоторых экранных дикторов и его будет трудно найти и отредактировать в будущем.

- -

Более корректным использованием этих псевдоэлементов является вставка значка, например маленькой стрелки, добавленной в приведенном ниже примере, которая является визуальным указателем, не предназначенным для зачитывания с помощью экранного диктора:

- -

{{EmbedGHLiveSample("css-examples/learn/selectors/after-icon.html", '100%', 400)}}

- -

Эти псевдоэлементы также часто используются для вставки пустой строки, которая затем может быть стилизована так же, как и любой элемент на странице.

- -

В следующем примере мы добавили пустую строку, используя псевдоэлемент ::before. Мы установили display: block, чтобы стилизовать его по ширине и высоте. Затем мы используем CSS, чтобы стилизовать его так же, как и любой другой элемент. Вы можете поиграть с CSS и изменить его внешний вид и поведение.

- -

{{EmbedGHLiveSample("css-examples/learn/selectors/before-styled.html", '100%', 500)}}

- -

Использование псевдоэлементов ::before и ::after вместе со свойством content в CSS называется "генерируемым контентом" в CSS, и вы часто будете видеть, как этот метод используется для различных задач. Отличным примером является сайт CSS Arrow Please, который помогает вам генерировать стрелку с помощью CSS. Посмотрите на CSS, когда вы создадите свою стрелку, и вы увидите использование псевдо-элементов {{cssxref("::before")}} и {{cssxref("::after")}}. Всякий раз, когда вы будете видеть эти селекторы, смотрите на свойство {{cssxref("content")}}, чтобы увидеть, что добавляется в документ..

- -

Справочный раздел

- -

Существует большое количество псевдоклассов и псевдоэлементов, и полезно иметь список, к которому можно обращаться. Ниже приведены таблицы, в которых они перечислены, со ссылками на их справочные страницы в MDN. Используйте эти таблицы как справочник, чтобы видеть массив доступных вам средств для нацеливания на элементы.

- -

Псевдоклассы

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
СелекторОписание
{{ Cssxref(":active") }}Подходит, когда пользователь активирует (например, щелкает мышью) элемент.
{{ Cssxref(":any-link") }}Соответствует как состоянию :link, так и состоянию:visited ссылки.
{{ Cssxref(":blank") }}Соответствует элементу <input>, для которого значение ввода является пустым.
{{ Cssxref(":checked") }}Соответствует переключателю или флажку в выбранном состоянии.
{{ Cssxref(":current") }}Соответствует элементу или предку элемента, который в данный момент отображается.
{{ Cssxref(":default") }}Соответствует одному или нескольким элементам пользовательского интерфейса, которые являются элементами по умолчанию (обрабатывают нажатие клавиши enter) в наборе сходных элементов.
{{ Cssxref(":dir") }}Выбирает элемент на основе его направленности (значение атрибута HTML dir или свойства CSS direction ).
{{ Cssxref(":disabled") }}Соответствует элементам пользовательского интерфейса, которые находятся в отключённом состоянии.
{{ Cssxref(":empty") }}Соответствует элементу, у которого нет дочерних элементов, кроме необязательного пробела.
{{ Cssxref(":enabled") }}Соответствует элементам пользовательского интерфейса, которые находятся во включённом состоянии.
{{ Cssxref(":first") }}В постраничном носителе соответствует первой странице.
{{ Cssxref(":first-child") }}Соответствует элементу, который является первым среди других дочерних элементов одного предка.
{{ Cssxref(":first-of-type") }}Соответствует элементу, который является первым определенного типа среди других дочерних элементов одного предка.
{{ Cssxref(":focus") }}Соответствует элементу, имеющему фокус.
{{ Cssxref(":focus-visible")}}Соответствует элементу, имеющему фокус, при этом фокус должен быть виден пользователю.
{{ Cssxref(":focus-within") }}Соответствует элементу с фокусом, а также элементу с потомком, который имеет фокус.
{{ Cssxref(":future") }}Соответствует элементам после текущего элемента.
{{ Cssxref(":hover") }}Соответствует элементу, на который наведён курсор мыши.
{{ Cssxref(":indeterminate") }}Соответствует элементам пользовательского интерфейса, значение которых находится в неопределенном состоянии, обычно checkboxes.
{{ Cssxref(":in-range") }}Соответствует элементу с диапазоном, когда его значение находится в пределах диапазона.
{{ Cssxref(":invalid") }}Соответствует элементу, например <input>, в недопустимом состоянии.
{{ Cssxref(":lang") }}Соответствует элементу, основанному на языке (значение атрибута HTML lang).
{{ Cssxref(":last-child") }}Соответствует элементу, который является последним среди других дочерних элементов одного предка.
{{ Cssxref(":last-of-type") }}Соответствует элементу, который является последним определённого типа среди других дочерних элементов одного предка.
{{ Cssxref(":left") }}В постраничном носителе соответствует левосторонним страницам.
{{ Cssxref(":link")}}Соответствует непосещавшимся ссылкам.
{{ Cssxref(":local-link")}}Соответствует ссылкам, указывающим на страницы, которые расположены на том же сайте, что и текущий документ.
{{ Cssxref(":is", ":is()")}}Соответствует любому селектору из полученного списка селекторов.
{{ Cssxref(":not") }}Соответствует объектам, не входящим в список селекторов, переданный в качестве значения этому селектору.
{{ Cssxref(":nth-child") }}Соответствует элементам из списка дочерних элементов одного предка, которые подобраны по формуле вида an+b (например, 2n + 1 будет соответствовать элементам 1, 3, 5, 7 и т. д. Все нечетные числа.)
{{ Cssxref(":nth-of-type") }}Соответствует элементам из списка дочерних элементов одного предка, имеющим определенный тип (например, элементы <p>) — дочерние элементы подобраны по формуле вида an+b (например, 2n + 1 будет соответствовать элементам 1, 3, 5, 7 и т. д. Все нечетные числа.)
{{ Cssxref(":nth-last-child") }}Соответствует элементам из списка дочерних элементов одного предка, считая в обратном порядке от конца. Дочерние элементы подобраны по формуле вида an+b (например, 2n + 1 будет соответствовать последнему элементу в последовательности, затем на два элемента до него, затем ещё на два элемента назад и т. д. Все нечетные, считая с конца.)
{{ Cssxref(":nth-last-of-type") }}Соответствует элементам из списка дочерних элементов одного предка, имеющим определенный тип (например, элементы <p>), считая в обратном порядке от конца. Дочерние элементы подобраны по формуле вида an+b (например, 2n + 1 будет соответствовать последнему элементу этого типа в последовательности, затем на два элемента до него, затем ещё на два элемента назад и т. д. Все нечетные, считая с конца.)
{{ Cssxref(":only-child") }}Соответствует элементу, являющемуся единственным дочерним для своего предка.
{{ Cssxref(":only-of-type") }}Соответствует элементу, который отличается по типу от всех других дочерних элементов общего предка.
{{ Cssxref(":optional") }}Соответствует необязательным элементам формы.
{{ Cssxref(":out-of-range") }}Соответствует элементу с диапазоном, когда его значение находится вне диапазона.
{{ Cssxref(":past") }}Соответствует элементам перед текущим элементом.
{{ Cssxref(":placeholder-shown") }}Соответствует элементу input, который показывает текст-заполнитель.
{{ Cssxref(":playing") }}Соответствует элементу, представляющему аудио, видео или подобный ресурс с возможными состояниями “воспроизведён” или “приостановлен”, когда этот элемент “воспроизводится”.
{{ Cssxref(":paused") }}Соответствует элементу, представляющему аудио, видео или подобный ресурс с возможными состояниями “воспроизведён” или “приостановлен”, когда этот элемент “приостановлен”.
{{ Cssxref(":read-only") }}Соответствует элементу, который не может быть изменён пользователем.
{{ Cssxref(":read-write") }}Соответствует элементу, который может быть изменён пользователем.
{{ Cssxref(":required") }}Соответствует обязательным элементам формы.
{{ Cssxref(":right") }}В постраничном носителе соответствует правосторонним страницам.
{{ Cssxref(":root") }}Соответствует элементу, который является корнем документа.
{{ Cssxref(":scope") }}Соответствует любому элементу, который является элементом области видимости.
{{ Cssxref(":valid") }}Соответствует элементу, такому как <input>, в допустимом состоянии.
{{ Cssxref(":target") }}Соответствует элементу, если он является целью текущего URL (т. е. если у него есть ID, соответствующий текущему URL fragment).
{{ Cssxref(":visited") }}Соответствует посещённым ссылкам.
- -

Псевдоэлементы

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
СелекторОписание
{{ Cssxref("::after") }}Соответствует элементу, который допускает стилизацию и появляется после текущего содержимого порождающего элемента.
{{ Cssxref("::before") }}Соответствует элементу, который допускает стилизацию и появляется перед текущим содержимым порождающего элемента.
{{ Cssxref("::first-letter") }}Соответствует первой букве элемента.
{{ Cssxref("::first-line") }}Соответствует первой строке содержимого порождающего элемента.
{{ Cssxref("::grammar-error") }} -

Соответствует части документа, содержащей грамматическую ошибку, отмеченную браузером.

-
{{ Cssxref("::marker") }}Соответствует полю маркера пункта списка, которое обычно содержит жирную точку или число.
-

{{ Cssxref("::selection") }}

-
Соответствует части документа, которая была выбрана.
{{ Cssxref("::spelling-error") }} -

Соответствует части документа, содержащей орфографическую ошибку, отмеченную браузером.

-
- -

{{PreviousMenuNext("Learn/CSS/Building_blocks/Selectors/Attribute_selectors", "Learn/CSS/Building_blocks/Selectors/Combinators", "Learn/CSS/Building_blocks")}}

- -

В этом модуле

- -
    -
  1. Каскад и наследование
  2. -
  3. Селекторы CSS - -
  4. -
  5. Модель коробки
  6. -
  7. Фон и границы
  8. -
  9. Обработка разных направлений текста
  10. -
  11. Переполнение содержимого
  12. -
  13. Значения и единицы измерения
  14. -
  15. Изменение размеров в CSS
  16. -
  17. Элементы изображений, форм и медиа-элементы
  18. -
  19. Стилизация таблиц
  20. -
  21. Отладка CSS
  22. -
  23. Организация вашей CSS
  24. -
diff --git "a/files/ru/learn/css/building_blocks/\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/type_class_and_id_selectors/index.html" "b/files/ru/learn/css/building_blocks/\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/type_class_and_id_selectors/index.html" deleted file mode 100644 index 875899ab41..0000000000 --- "a/files/ru/learn/css/building_blocks/\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/type_class_and_id_selectors/index.html" +++ /dev/null @@ -1,130 +0,0 @@ ---- -title: 'Селекторы типа, класса и ID' -slug: Learn/CSS/Building_blocks/Селекторы/Type_Class_and_ID_Selectors -tags: - - CSS - - id - - Класс - - Начинающий - - Обучение - - Селекторы -translation_of: Learn/CSS/Building_blocks/Selectors/Type_Class_and_ID_Selectors ---- -

{{LearnSidebar}}{{PreviousMenuNext("Learn/CSS/Building_blocks/Selectors", "Learn/CSS/Building_blocks/Selectors/Attribute_selectors", "Learn/CSS/Building_blocks")}}

- -

В этом уроке мы рассмотрим некоторые из базисных селекторов, которые вы, вероятно, будете чаще всего использовать в вашей работе.

- - - - - - - - - - - - -
Необходимые условия:Базовая компьютерная грамотность, установка базового ПО, базовые знания о работе с файлами, основы HTML (изучите Введение в HTML) и понимание работы CSS (изучите Введение в CSS.)
Задача:Изучить различные селекторы CSS, которые мы можем использовать, чтобы применить CSS к документу.
- -

Селекторы типа

- -

Селектор типа иногда называется селектором имени тега или селектором элемента, поскольку он выбирает тег/элемент HTML в вашем документе. В примере ниже мы использовали селекторы span, em и strong.

- -

Попробуйте добавить CSS-правило, чтобы выбрать элемент <h1> и изменить его цвет на синий.

- -

{{EmbedGHLiveSample("css-examples/learn/selectors/type.html", '100%', 1100)}}

- -

Универсальный селектор

- -

Универсальный селектор обозначается звездочкой (*). Он выбирает всё в документе (или внутри родительского элемента, если он сцеплен с другим элементом и с комбинатором потомка). В следующем примере мы используем универсальный селектор, чтобы убрать внешние отступы у всех элементов. Несмотря на стилизацию по умолчанию, добавленную браузером, — она раздвигает заголовки и абзацы с помощью отступов, — всё плотно сжато.

- -

{{EmbedGHLiveSample("css-examples/learn/selectors/universal.html", '100%', 750)}}

- -

Такого рода поведение иногда можно увидеть в «таблицах сброса стилей», которые вычищают всю стилизацию браузера. Так как универсальный селектор вызывает глобальные изменения, мы используем его в очень специфических ситуациях, таких как та, что описана ниже.

- -

Использование универсального селектора для облегчения чтения ваших селекторов

- -

Одно из применений универсального селектора состоит в том, чтобы облегчить чтение селекторов и сделать их более удобопонятными с точки зрения того, что они делают. Например, если мы хотим выбрать элементы-потомки элемента <article>, которые являются первыми дочерними элементами своего родителя, включая дочерние элементы самого <article>, и сделать их шрифт жирным, мы могли бы использовать псевдо-класс {{cssxref(":first-child")}}, который мы будем изучать в уроке о псевдо-классах и псевдо-элементах, как селектор-потомок вместе с селектором элемента <article>

- -
article :first-child {
-  font-weight: bold;
-}
- -

Однако этот селектор можно спутать с article:first-child, который выберет любой элемент <article>, являющийся первым дочерним элементом другого элемента .

- -

Чтобы избежать этой путаницы, мы можем добавить универсальный селектор в псевдо-класс :first-child , чтобы было очевидно, что делает селектор. Он выбирает любой элемент, который является первым дочерним элементом элемента <article> или первым дочерним элементом любого потомка элемента <article>:

- -
article *:first-child {
-  font-weight: bold;
-} 
- -

Хотя оба делают одно и то же, удобочитаемость значительно улучшилась.

- -

Селекторы класса

- -

Селектор класса начинается с символа точки (.). Он выберет в документе всё, к чему применён этот класс. В живом примере ниже мы создали класс с именем .highlight, и применили его к нескольким местам в документе. Все элементы, к которым применён класс, подсвечиваются.

- -

{{EmbedGHLiveSample("css-examples/learn/selectors/class.html", '100%', 750)}}

- -

Нацеливание классов на отдельные элементы

- -

Вы можете создать селектор, нацеленный на конкретные элементы, к которым применён класс. В следующем примере мы подсветим <span> с классом highlight иначе, чем заголовок <h1> с классом highlight. Мы сделаем это, используя селектор типа для элемента, на который нацелены, с классом, добавленным с помощью точки, без пробела между ними.

- -

{{EmbedGHLiveSample("css-examples/learn/selectors/class-type.html", '100%', 750)}}

- -

Этот подход сужает границы правила. Правило будет применяться только к этой конкретной комбинации элемента и класса. Вам нужно будет добавить другой селектор, если вы решили, что правило должно применяться и к другим элементам.

- -

Нацеливание на элемент, к которому применено более одного класса

- -

Вы можете применить несколько классов к элементу и нацелиться на них по отдельности, или выбрать элемент только если присутствуют все классы селектора. Это может быть полезно при создании компонентов, которые могут сочетаться на вашем сайте разными способами.

- -

В примере ниже у нас есть <div>, содержащий примечание. Серая граница применятеся когда блок имеет класс notebox. Если у блока есть также класс warning или danger, мы меняем {{cssxref("border-color")}}.

- -

Мы можем указать браузеру, что мы хотим подобрать только такой элемент, к которому применены два класса, сцепив их вместе без пробелов между ними. Вы увидите, что к последнему <div> не применён ни один стиль, так как он имеет только класс danger; ему нужен ещё и класс notebox, чтобы получить какую-нибудь стилизацию.

- -

{{EmbedGHLiveSample("css-examples/learn/selectors/class-many.html", '100%', 900)}}

- -

Селекторы ID

- -

Селектор ID начинается с #, а не с точки, но используется так же, как и селектор класса. Однако ID может быть использован единожды на странице, и к элементу может быть применён только один id. Можно выбрать элемент, которому присвоен  id, а также вы можете предварить ID селектором типа для нацеливания на элемент, имеющий соответствующее сочетание элемента и ID. Вы можете увидеть оба варианта использования в следующем примере:

- -

{{EmbedGHLiveSample("css-examples/learn/selectors/id.html", '100%', 750)}}

- -
-

Предупреждение: Может показаться, что неоднократное использование в документе одного и того же ID выполняет задачи стилизования, но не стоит этого делать. Результатом будет неверный код, который приведёт к многочисленным странностям в поведении.

-
- -
-

Примечание: Как мы знаем из урока по специфичности, ID имеет высокую специфичность. Он будет брать верх над большинством других селекторов. В большинстве случаев предпочтительнее добавить элементу класс, чем ID. Однако, если использование ID это единственный способ нацелиться на элемент — возможно, потому вы не имеете доступа к разметке и, следовательно, возможности её редактировать — это будет работать.

-
- -

В следующей статье

- -

Мы продолжим изучение селекторов и рассмотрим селекторы атрибута.

- -

{{PreviousMenuNext("Learn/CSS/Building_blocks/Selectors", "Learn/CSS/Building_blocks/Selectors/Attribute_selectors", "Learn/CSS/Building_blocks")}}

- -

В этом модуле

- -
    -
  1. Каскад и наследование
  2. -
  3. Селекторы CSS - -
  4. -
  5. Модель коробки (The box model)
  6. -
  7. Фон и границы
  8. -
  9. Обработка разных направлений текста
  10. -
  11. Переполнение содержимого
  12. -
  13. Значения и единицы измерения
  14. -
  15. Изменение размеров в CSS
  16. -
  17. Элементы изображений, форм и медиа-элементы
  18. -
  19. Стилизация таблиц
  20. -
  21. Отладка CSS
  22. -
  23. Организация вашей CSS
  24. -
diff --git "a/files/ru/learn/css/building_blocks/\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213_\320\267\320\260\320\264\320\260\321\207\320\270/index.html" "b/files/ru/learn/css/building_blocks/\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213_\320\267\320\260\320\264\320\260\321\207\320\270/index.html" deleted file mode 100644 index b8f36063c2..0000000000 --- "a/files/ru/learn/css/building_blocks/\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213_\320\267\320\260\320\264\320\260\321\207\320\270/index.html" +++ /dev/null @@ -1,137 +0,0 @@ ---- -title: 'Проверьте ваши навыки: Селекторы' -slug: Learn/CSS/Building_blocks/Селекторы/Селекторы_Задачи -tags: - - CSS - - Начинающий -translation_of: Learn/CSS/Building_blocks/Selectors/Selectors_Tasks ---- -
{{LearnSidebar}}
- -
- -

Цель этой задачи — помочь вам проверить ваше понимание селекторов в CSS.

- -
-

Примечание: Вы можете проверять решения в интерактивном редакторе, расположенном ниже, но, возможно, вам будут полезны онлайн-инструменты, такие как  CodePen, jsFiddle или Glitch, которые можно использовать для работы над заданием, предварительно загрузив в них код.
-
- Если вы зашли в тупик, обратитесь к нам за помощью — смотрите раздел Оценка или дальнейшая помощь внизу этой страницы.

-
- -

Selectors One

- -

Without changing the HTML, use CSS to do the following things:

- - - -

Text with the CSS applied for the solution to task 1.

- -

Try updating the live code below to recreate the finished example:

- -

{{EmbedGHLiveSample("css-examples/learn/tasks/selectors/type.html", '100%', 700)}}

- -
-

For assessment or further work purposes, download the starting point for this task to work in your own editor or in an online editor.

-
- -

Selectors Two

- -

Without changing the HTML, make the following changes to the look of the content in this example:

- - - -

Text with the CSS applied for the solution to task 2.

- -

Try updating the live code below to recreate the finished example:

- -

{{EmbedGHLiveSample("css-examples/learn/tasks/selectors/class-id.html", '100%', 800)}}

- -
-

For assessment or further work purposes, download the starting point for this task to work in your own editor or in an online editor.

-
- -

Selectors Three

- -

In this example, try making the following changes without adding to the HTML.

- - - -

Text with the CSS applied for the solution to task 3.

- -

Try updating the live code below to recreate the finished example:

- -

{{EmbedGHLiveSample("css-examples/learn/tasks/selectors/pseudo.html", '100%', 800)}}

- -
-

For assessment or further work purposes, download the starting point for this task to work in your own editor or in an online editor.

-
- -

Selectors Four

- -

In this task try the following:

- - - -

Text with the CSS applied for the solution to task 4.

- -

Try updating the live code below to recreate the finished example:

- -

{{EmbedGHLiveSample("css-examples/learn/tasks/selectors/combinators.html", '100%', 800)}}

- -
-

For assessment or further work purposes, download the starting point for this task to work in your own editor or in an online editor.

-
- -

Selectors Five

- -

In this final task add CSS using attribute selectors to do the following:

- - - -

Four links with different color borders.

- -

Try updating the live code below to recreate the finished example:

- -

{{EmbedGHLiveSample("css-examples/learn/tasks/selectors/attribute-links.html", '100%', 800)}}

- -
-

For assessment or further work purposes, download the starting point for this task to work in your own editor or in an online editor.

-
- -

Assessment or further help

- -

You can practice these examples in the Interactive Editors mentioned above.

- -

If you would like your work assessed, or are stuck and want to ask for help:

- -
    -
  1. Put your work into an online shareable editor such as CodePen, jsFiddle, or Glitch. You can write the code yourself, or use the starting point files linked to in the above sections.
  2. -
  3. Write a post asking for assessment and/or help at the MDN Discourse forum Learning category. Your post should include: -
      -
    • A descriptive title such as "Assessment wanted for Selectors skill test 1".
    • -
    • Details of what you have already tried, and what you would like us to do, e.g. if you are stuck and need help, or want an assessment.
    • -
    • A link to the example you want to be assessed or need help with, in an online shareable editor (as mentioned in step 1 above). This is a good practice to get into — it's very hard to help someone with a coding problem if you can't see their code.
    • -
    • A link to the actual task or assessment page, so we can find the question you want help with.
    • -
    -
  4. -
diff --git a/files/ru/learn/css/css_layout/multicol_skills/index.html b/files/ru/learn/css/css_layout/multicol_skills/index.html new file mode 100644 index 0000000000..c549f1210b --- /dev/null +++ b/files/ru/learn/css/css_layout/multicol_skills/index.html @@ -0,0 +1,78 @@ +--- +title: 'Проверь свои навыки: Multicol' +slug: Learn/CSS/CSS_layout/Навыки_Multicol +translation_of: Learn/CSS/CSS_layout/Multicol_skills +--- +
{{LearnSidebar}}
+ +
+ +

Цель этого задания — чтобы вы поработали с CSS свойствами {{CSSxRef("column-count")}}, {{CSSxRef("column-width")}}, {{CSSxRef("column-gap")}}, {{CSSxRef("column-span")}} и {{CSSxRef("column-rule")}} и со значениями которые описаны в нашем уроке Макет с несколькими столбцами. Вы будете работать над тремя небольшими задачами, использующими различные элементы из пройденного материала.

+ +
+

Примечание: Вы можете опробовать решения в интерактивных редакторах ниже, однако может быть полезным загрузить код и использовать онлайн инструменты такие как CodePen, jsFiddle, or Glitch чтобы проработать задания.

+ +

Если вы застрянете, попросите нас о помощи — см. раздел {{anch("Оценка и дальнейшая помощь")}} в конце страницы.

+
+ +

Multicol Раз

+ +

В этом задании вам необходимо создать три столбца с отступом 50px между каждый столбцом.

+ +

Three columns of text

+ +

Попробуйте обновить живой пример ниже для воссоздания законченного примера:

+ +

{{EmbedGHLiveSample("css-examples/learn/tasks/multicol/multicol1.html", '100%', 1000)}}

+ +
+

Для оценки или дальнейшей работы, загрузите отправную точку этого задания чтобы работать в вашем собственном или онлайн редакторе.

+
+ +

Multicol Два

+ +

Создайте столбцы с минимальной шириной 200px.

+ +

Затем добавьте серую линейку 5px между каждым столбцом, убедитесь, что между краями линейки и содержимым столбцов есть пространство 10px.

+ +

Three columns of text with a grey rule between them.

+ +

Попробуйте обновить живой код ниже для воссоздания законченного примера:

+ +

{{EmbedGHLiveSample("css-examples/learn/tasks/multicol/multicol2.html", '100%', 1000)}}

+ +
+

Для оценки или дальнейшей работы, загрузите отправную точку этого задания чтобы работать в вашем собственном или онлайн редакторе.

+
+ +

Multicol Три

+ +

Заставьте элемент содержащий заголовок и подзаголовок растянуться через все столбцы так чтоб это выглядело как на картинке

+ +

Three columns of text with a heading and subheading spanning all three in the middle.

+ +

Попробуйте обновить живой код ниже для воссоздания законченного примера:

+ +

{{EmbedGHLiveSample("css-examples/learn/tasks/multicol/multicol3.html", '100%', 1000)}}

+ +
+

Для оценки или дальнейшей работы, загрузите отправную точку этого задания чтобы работать в вашем собственном или онлайн редакторе.

+
+ +

Оценка и дальнейшая помощь

+ +

Вы можете попрактиковаться с этими примерами в интерактивных редакторах упомянутых выше.

+ +

Если вы хотите, чтобы вашу работу оценили, или вы застряли и хотите попросить помощи:

+ +
    +
  1. Разместите свою работу в онлайн редакторе в которым можно поделиться работами в таком как  CodePen, jsFiddle, или Glitch. Вы можете написать код самостоятельно или использовать файлы с отправными точками ссылки на которые имеются в разделах выше.
  2. +
  3. Напишите пост с просьбой оценки и/или помощи на MDN Discourse forum Learning category. Ваш пост должен включать: +
      +
    • Описательный заголовок такой как "Требуется оценка проверки навыков по Multicol задание 1".
    • +
    • Детали о том, что вы уже попытались сделать и что бы вы хотели, чтобы мы сделали, например, если вы застряли и вам нужна помощь, либо вы хотите оценку.
    • +
    • Ссылку на онлайн редактор (как упомянуто выше в пункте 1) с примером, который нуждается в оценке или с которым нужна помощь. Это хорошая практика чтобы вникнуть — очень сложно помочь кому-либо с проблемным кодом если вы не видите их код.
    • +
    • Ссылку на актуальную задачу или страницу оценки, чтобы мы могли найти вопрос, по которому вам нужна помощь.
    • +
    +
  4. +
diff --git a/files/ru/learn/css/css_layout/multiple-column_layout/index.html b/files/ru/learn/css/css_layout/multiple-column_layout/index.html new file mode 100644 index 0000000000..9ba48bbbef --- /dev/null +++ b/files/ru/learn/css/css_layout/multiple-column_layout/index.html @@ -0,0 +1,468 @@ +--- +title: Макет с несколькими столбцами +slug: Learn/CSS/CSS_layout/Макет_с_несколькими_столбцами +translation_of: Learn/CSS/CSS_layout/Multiple-column_Layout +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/CSS/CSS_layout/Positioning", "Learn/CSS/CSS_layout/Responsive_Design", "Learn/CSS/CSS_layout")}}
+ +

Спецификация макет с несколькими столбцами дает вам метод верстки контента по столбцам, точно также как вы можете видеть в газете. Эта статья объясняет, как использовать эту функцию.

+ + + + + + + + + + + + +
Необходимые знания: +

Основы HTML (изучите Введение в HTML), идея о том как работает CSS (изучите Введение в CSS.)

+
Задача: +

Изучить как создавать макет с неколькими столбцами на веб-страницах, такой как вы модете найти в газете.

+
+ +

Базовый пример

+ +

Сейчас мы будем изучать как использовать макет с несколькими столбцами, часто называемый multicol. Вы можете следовать за нами скачав файл отправной точки multicol и добавлять CSS в соответствующие места. В конце раздела вы можете посмотреть живой пример того, как конечный код должен выглядеть.

+ +

Наша отправная точка содержит немного очень простого HTML; обертака с классом container внутри которого имеется заголовок и несколько параграфов.

+ +

{{htmlelement("div")}} с классом контейнер станет нашим multicol контейнером. Мы включаем multicol используя одно из двух свойств {{cssxref("column-count")}} или {{cssxref("column-width")}}. Какое значение вы дадите свойству column-count столько столбцов он и создаст, поэтому если вы добавите следующий CSS в ваши стили и перезагрузите страницу, то получите три столбца:

+ +
.container {
+  column-count: 3;
+}
+
+ +

Колонки, которые вы создаете имеют гибкую ширину — браузер решает какое пространство назначить каждому столбцу.

+ +
+ + +
<div class="container">
+  <h1>Simple multicol example</h1>
+
+  <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat vulputate.
+  Duis felis orci, pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at ultricies tellus laoreet sit amet. Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet orci vel, viverra egestas ligula.
+  Curabitur vehicula tellus neque, ac ornare ex malesuada et. In vitae convallis lacus. Aliquam erat volutpat. Suspendisse
+  ac imperdiet turpis. Aenean finibus sollicitudin eros pharetra congue. Duis ornare egestas augue ut luctus. Proin blandit
+  quam nec lacus varius commodo et a urna. Ut id ornare felis, eget fermentum sapien.</p>
+
+  <p>Nam vulputate diam nec tempor bibendum. Donec luctus augue eget malesuada ultrices. Phasellus turpis est, posuere sit amet dapibus ut, facilisis sed est. Nam id risus quis ante semper consectetur eget aliquam lorem. Vivamus tristique
+  elit dolor, sed pretium metus suscipit vel. Mauris ultricies lectus sed lobortis finibus. Vivamus eu urna eget velit
+  cursus viverra quis vestibulum sem. Aliquam tincidunt eget purus in interdum. Cum sociis natoque penatibus et magnis
+  dis parturient montes, nascetur ridiculus mus.</p>
+</div>
+
+ +
.container {
+  column-count: 3;
+}
+
+
+ +

{{ EmbedLiveSample('Multicol_1', '100%', 400) }}

+ +

Измените ваш CSS чтобы использовать следующий column-width:

+ +
.container {
+  column-width: 200px;
+}
+
+ +

Теперь браузер будет давать столько столбцов размером, который вы определили, сколько он сможет; любое оставшееся пространство далее делится между существующими столбцами. Это значит, что вы не получите точную ширину, которую вы задали, только если ваш контейнер не делится точно на эту ширину.

+ +
+ + +
.container {
+  column-width: 200px;
+}
+
+
+ +

{{ EmbedLiveSample('Multicol_2', '100%', 400) }}

+ +

Стилизация столбцов

+ +

Столбцы, созданные при помощи multicol не могут быть стилизованы по одному. Нет способа сделать один столбец больше, чем другие, или изменить фон или цвет текста одного столбца. У вас есть две возможности изменить способ отображения столбцов:

+ + + +

Используя ваш пример выше, измените размер отступа добавлением свойства column-gap:

+ +
.container {
+  column-width: 200px;
+  column-gap: 20px;
+}
+ +

Вы можете поиграть с разными значениями — свойство принимает любые единицы измерения длины. Теперь добавьте линейку между столбцами при помощи column-rule. Таким же способом как и свойство {{cssxref("border")}} с которым вы сталкивались в предыдущих уроках, column-rule — это короткая запись {{cssxref("column-rule-color")}}, {{cssxref("column-rule-style")}} и {{cssxref("column-rule-width")}} и принимает те же значения что и border.

+ +
.container {
+  column-count: 3;
+  column-gap: 20px;
+  column-rule: 4px dotted rgb(79, 185, 227);
+}
+ +

Попробуйте добавить линейки других стилей и цветов.

+ +
+ +
+ +

{{ EmbedLiveSample('Multicol_3', '100%', 400) }}

+ +

Следует обратить внимание на то, что линейка не занимает никакой ширины. Она располагается в промежутках, которые вы создали при помощи column-gap. Чтобы придать больше пространства по обе стороны от линейки, вам нужно увеличить размер column-gap.

+ +

Свойств column-span

+ +

Вы можете заставить элемент растянуться через все столбцы. В этом случае контент разрывается, когда сталкивается со spanning элементом и продолжается ниже, создавая новый набор блоков столбцов. Чтобы растянуть элемент через все столбцы используйте свойство {{cssxref("column-span")}} установленное на значение all.

+ +
+

Обратите внимание что невозможно растянуть элемент через несколько столбцов. Это свойство может иметь либо значение none (по умолчанию) либо all.

+
+ +
+ +
+ +

{{ EmbedLiveSample('Multicol_Span', '100%', 400) }}

+ +

Столбцы и фрагментация

+ +

Содержимое макета нескольких столбцов является фрагментированным. По сути, он ведет себя так же, как контент в постраничных медиа — так же, как когда вы печатаете веб-страницы. Когда вы переводите ваш контент в multicol контейнер он фрагментируется на столбцы и контент разбивается чтобы позволить этому произойти.

+ +

Порой это разрывание происходит в местах, мешающих чтению. В живом примере ниже, я использовал multicol чтобы разместить несколько блоков, каждый из которых имеет заголовок и немного текста внутри. Заголовок отделяется от текста, если столбцы разделяются между ними.

+ +
+ + +
<div class="container">
+    <div class="card">
+      <h2>I am the heading</h2>
+      <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat
+                vulputate. Duis felis orci, pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at ultricies
+                tellus laoreet sit amet. Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet orci
+                vel, viverra egestas ligula.</p>
+    </div>
+
+    <div class="card">
+      <h2>I am the heading</h2>
+      <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat
+                vulputate. Duis felis orci, pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at ultricies
+                tellus laoreet sit amet. Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet orci
+                vel, viverra egestas ligula.</p>
+    </div>
+
+    <div class="card">
+      <h2>I am the heading</h2>
+      <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat
+                vulputate. Duis felis orci, pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at ultricies
+                tellus laoreet sit amet. Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet orci
+                vel, viverra egestas ligula.</p>
+    </div>
+    <div class="card">
+      <h2>I am the heading</h2>
+      <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat
+                vulputate. Duis felis orci, pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at ultricies
+                tellus laoreet sit amet. Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet orci
+                vel, viverra egestas ligula.</p>
+    </div>
+
+    <div class="card">
+      <h2>I am the heading</h2>
+      <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat
+                vulputate. Duis felis orci, pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at ultricies
+                tellus laoreet sit amet. Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet orci
+                vel, viverra egestas ligula.</p>
+    </div>
+
+    <div class="card">
+      <h2>I am the heading</h2>
+      <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat
+                vulputate. Duis felis orci, pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at ultricies
+                tellus laoreet sit amet. Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet orci
+                vel, viverra egestas ligula.</p>
+    </div>
+
+    <div class="card">
+      <h2>I am the heading</h2>
+      <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat
+                vulputate. Duis felis orci, pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at ultricies
+                tellus laoreet sit amet. Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet orci
+                vel, viverra egestas ligula.</p>
+    </div>
+
+</div>
+
+ +
.container {
+  column-width: 250px;
+  column-gap: 20px;
+}
+
+.card {
+  background-color: rgb(207, 232, 220);
+  border: 2px solid rgb(79, 185, 227);
+  padding: 10px;
+  margin: 0 0 1em 0;
+}
+
+ +

{{ EmbedLiveSample('Multicol_4', '100%', 600) }}

+ +

Для того чтобы управлять этим поведением мы можем использовать свойства из спецификации CSS Фрагментации. Эта спецификация дает нам свойства для управления разрывами контента в multicol и постраничных медиа. Например, добавьте свойство {{cssxref("break-inside")}} со значением avoid к правилам .card. Это контейнер заголовка и текста и поэтому мы не хотим фрагментировать этот блок.

+ +

В настоящее время также стоит добавлять старое свойство page-break-inside: avoid для лучшей поддержки старых браузеров.

+ +
.card {
+  break-inside: avoid;
+  page-break-inside: avoid;
+  background-color: rgb(207,232,220);
+  border: 2px solid rgb(79,185,227);
+  padding: 10px;
+  margin: 0 0 1em 0;
+}
+
+ +

Перезагрузите страницу и ваши блоки должны остаться в целости.

+ +
+ + +
.container {
+  column-width: 250px;
+  column-gap: 20px;
+}
+
+.card {
+  break-inside: avoid;
+  page-break-inside: avoid;
+  background-color: rgb(207, 232, 220);
+  border: 2px solid rgb(79, 185, 227);
+  padding: 10px;
+  margin: 0 0 1em 0;
+}
+
+ +

{{ EmbedLiveSample('Multicol_5', '100%', 600) }}

+ +

Проверь свои навыки!

+ +

Вы достигли конца этой статьи, но помните ли вы самую важную информацию? Вы можете найти дальнейшие тесты для проверки того, что вы усвоили эту информацию прежде чем, отправитесь дальше — см. Поверьте свои навыки: Макет с несколькими столбцами.

+ +

Заключение

+ +

Вы теперь знаете, как использовать базовые функции макета с несколькими столбцами, еще один инструмент в вашем распоряжении при выборе метода макета для дизайна который вы строите.

+ +

См. также

+ + + +

{{PreviousMenuNext("Learn/CSS/CSS_layout/Positioning", "Learn/CSS/CSS_layout/Responsive_Design", "Learn/CSS/CSS_layout")}}

+ +

В этом модуле

+ + diff --git a/files/ru/learn/css/css_layout/normal_flow/index.html b/files/ru/learn/css/css_layout/normal_flow/index.html new file mode 100644 index 0000000000..d936c240c5 --- /dev/null +++ b/files/ru/learn/css/css_layout/normal_flow/index.html @@ -0,0 +1,96 @@ +--- +title: Базовый поток +slug: Learn/CSS/CSS_layout/Нормальный_поток +tags: + - float + - grid +translation_of: Learn/CSS/CSS_layout/Normal_Flow +--- +
{{LearnSidebar}}
+ +

{{PreviousMenuNext("Learn/CSS/CSS_layout/Introduction", "Learn/CSS/CSS_layout/Flexbox", "Learn/CSS/CSS_layout")}}

+ +

Эта статья объясняет нормальный/базовый поток (normal flow) или способ, которым элементы страницы располагаются на веб-странице по умолчанию.

+ + + + + + + + + + + + +
Что нужно знать прежде чем изучать:Основы HTML (изучите Введение в HTML), и понимания как работает CSS (изучите Введение в CSS.)
Цель:Объяснить как браузеры размещают элементы на веб-странице по умолчанию, т.е. прежде, чем мы начнем вносить какие-либо изменения.
+ +

Как говорилось ранее, элементы на веб-странице располагаются в нормальном потоке, если вы не применили к ним ни единого CSS для изменения их поведения. И, как мы уже выяснили, вы можете изменить поведение элементов либо путем изменения их положения в этом нормальном потоке, либо удалением этих элементов из этого потока. Хорошо структурированный документ, читабельный в нормальном потоке является лучшим путём начала любой веб-страницы. Это гарантирует, что ваш контент будет читабельным, даже если пользователи используют очень ограниченный браузер или устройство для чтения, которое считывает содержимое страницы. Кроме того, поскольку нормальный поток предназначен для создания читабельного документа, имейте в виду, что вы не сражаетесь с первоначальным видом документа, а работаете с ним.

+ +

Прежде чем углубиться в разные способы компоновки, стоит пересмотреть некоторые из вещей, которые вы изучили в предыдущих модулях в отношении нормального потока документов. 

+ +

Как элементы располагаются по умолчанию?

+ +

Прежде всего, индивидуальные боксы элементов располагаются в зависимости от содержимого элементов, затем добавляя какой-нибудь padding, border и margin вокруг них - это опять-таки боксовая модель, которую мы рассмотрели ранее.

+ +

По умолчанию содержимое элемента уровня блока составляет 100% от ширины его родительского элемента и столь же высок, как и его содержимое. Встроенные элементы высоки и широки, как их содержимое. Вы не можете установить ширину или высоту на встроенные элементы — они просто находятся внутри содержимого элементов блочного уровня. Если вы хотите контролировать размер встроенного элемента вам нужно настроить его так, чтобы он себя вёл как элемент блочного уровня при помощи display: block; (или даже,  display: inline-block;, который смешивает характеристики обоих.).

+ +

Это объясняет отдельные элементы, но как насчет того, как элементы взаимодействуют друг с другом? Нормальный поток макета (упомянутый в статье введения макета) - это система, посредством которой элементы размещаются внутри окна просмотра браузера. По умолчанию элементы уровня блока выкладываются в направлении, что блокирует отображение в режиме записи документа - каждый из них будет отображаться в новой строке ниже последней строки, и они будут разделены любым полем, установленным на них. Поэтому на английском языке или на любом другом, в котором режим писания горизонтальный, сверху вниз, элементы уровня блока располагаются вертикально.

+ +

Встроенные элементы ведут себя по-другому — они не появляются на новых строках; они распологаются на той же строке, что и другие и любой смежной или завернутый текст располагается на всю ширину внутри элемента уровня родительского блока, до тех пор, пока не закончится пространство. Если пространства нет, тогда текст и/или элементы перейдут на новую строку (не с абзаца).

+ +

Если два смежных элемента имеют заданные для них поля/внешние отступы (margin) и эти поля соприкасаются друг с другом, большее из них остается, а меньшее исчезает — это звётся схлопывание полей (margin collapsing), и мы рассматривали это ранее.

+ +

Давайте посмотрим на пример, который объясняет всё из того, что мы рассмотрели в данной статье:

+ +
+
<h1>Базовый поток документа</h1>
+
+<p>Я базовый элемент уровня блока. Мои соседние блочные элементы находятся на новой строке подо мной.</p>
+
+<p>По умолчанию мы охватываем 100% ширины нашего родительского элемента, и мы так же высоки, как и наш child-контент. Наша общая ширина и высота - это наш контент + внутренний отступ (padding) + ширина / высота границы.</p>
+
+<p>Мы отделены нашими полями. Из-за схлопывания полей мы отделены шириной одного из наших полей, а не обоих</p>
+
+<p>Встроенные элементы <span>такие как этот</span> и <span>этот</span> находятся на одной линии с другими, и смежным текстом, если есть пространство. Встроенные элементы, что не влезают <span>переходять на новую строку если это возможно (как этот текст)</span>если же это невозможно, они переходят на новую строку, как это изображение: <img src="https://mdn.mozillademos.org/files/13360/long.jpg"></p>
+ +
body {
+  width: 500px;
+  margin: 0 auto;
+}
+
+p {
+  background: rgba(255,84,104,0.3);
+  border: 2px solid rgb(255,84,104);
+  padding: 10px;
+  margin: 10px;
+}
+
+span {
+  background: white;
+  border: 1px solid black;
+}
+
+ +

{{ EmbedLiveSample('Normal_Flow', '100%', 500) }}

+ +

Заключение

+ +

Теперь, когда вы поняли нормальный поток и как браузер выкладывает содержимое по умолчанию, двигаемся дальше, чтобы понять как это изменить для создания макета согласно вашему дизайну.

+ +

{{PreviousMenuNext("Learn/CSS/CSS_layout/Introduction", "Learn/CSS/CSS_layout/Flexbox", "Learn/CSS/CSS_layout")}}

+ +

В этом модуле

+ + diff --git a/files/ru/learn/css/css_layout/position_skills/index.html b/files/ru/learn/css/css_layout/position_skills/index.html new file mode 100644 index 0000000000..f63a3a3a94 --- /dev/null +++ b/files/ru/learn/css/css_layout/position_skills/index.html @@ -0,0 +1,64 @@ +--- +title: 'Проверьте свои навыки: позиционирование' +slug: Learn/CSS/CSS_layout/Навыки_позиционирования +translation_of: Learn/CSS/CSS_layout/Position_skills +--- +
{{LearnSidebar}}
+ +
+ +

Цель этого задания - чтобы вы поработали с CSS свойством {{CSSxRef("position")}} и его значениями которые описаны в нашем уроке Позиционирование. Вы будете работать над двумя небольшими задачами, использующими различные элементы из пройденного материала.

+ +
+

Примечание: Вы можете опробовать решения в интерактивных редакторах ниже, однако может быть полезным загрузить код и использовать онлайн инструменты такие как CodePen, jsFiddle, или Glitch чтобы проработать задания.

+ +

Если вы застрянете, попросите нас о помощи — см. раздел {{anch("Оценка и дальнейшая помощь")}} в конце страницы

+
+ +

Позиционирование Раз

+ +

В этом задании вам необходимо расположить элементы с классом target в верхнем правом углу контейнера, который имеет серую границу 5px.

+ +

The green box is at the top right of a container with a grey border.

+ +

Попробуйте обновить живой код ниже для воссоздания законченного примера:

+ +

{{EmbedGHLiveSample("css-examples/learn/tasks/position/position1.html", '100%', 1000)}}

+ +

В качестве дополнительной задачи, сможете ли вы изменить цель так чтоб она отображалась под текстом?

+ +
+

Для оценки или дальнейшей работы, загрузите отправную точку этого задания чтобы работать в вашем собственном или онлайн редакторе

+
+ +

Позиционирование Два

+ +

В примере ниже если вы прокрутите блок боковая панель прокручивается вместе с контентом. Измените его так чтобы боковая панель оставалась на месте и прокручивался только контент.

+ +

The content is scrolled but the sidebar has stayed in place.

+ +

Попробуйте обновить живой код ниже для воссоздания законченного примера:

+ +

{{EmbedGHLiveSample("css-examples/learn/tasks/position/position2.html", '100%', 1000)}}

+ +
+

ля оценки или дальнейшей работы, загрузите отправную точку этого задания чтобы работать в вашем собственном или онлайн редактор

+
+ +

Оценка и дальнейшая помощь

+ +

Вы можете попрактиковаться с этими примерами в интерактивных редакторах упомянутых выше.

+ +

Если вы хотите, чтобы вашу работу оценили, или вы застряли и хотите попросить помощи:

+ +
    +
  1. Разместите свою работу в онлайн редакторе в которым можно поделиться работами в таком как CodePen, jsFiddle, или Glitch. Вы можете написать код самостоятельно или использовать файлы с отправными точками ссылки на которые имеются в разделах выше.
  2. +
  3. Напишите пост с просьбой оценки и/или помощи на MDN Discourse forum Learning category. Ваш пост должен включать: +
      +
    • Описательный заголовок такой как "Требуется оценка проверки навыков по Позиционированияю".
    • +
    • Детали о том, что вы уже попытались сделать и что бы вы хотели, чтобы мы сделали, например, если вы застряли и вам нужна помощь, либо вы хотите оценку.
    • +
    • Ссылку на онлайн редактор (как упомянуто выше в пункте 1) с примером, который нуждается в оценке или с которым нужна помощь. Это хорошая практика чтобы вникнуть — очень сложно помочь кому-либо с проблемным кодом если вы не видите их код.
    • +
    • Ссылку на актуальную задачу или страницу оценки, чтобы мы могли найти вопрос, по которому вам нужна помощь.
    • +
    +
  4. +
diff --git a/files/ru/learn/css/css_layout/responsive_design/index.html b/files/ru/learn/css/css_layout/responsive_design/index.html new file mode 100644 index 0000000000..978b4e43dc --- /dev/null +++ b/files/ru/learn/css/css_layout/responsive_design/index.html @@ -0,0 +1,328 @@ +--- +title: Отзывчивый дизайн +slug: Learn/CSS/CSS_layout/Отзывчивый_дизайн +translation_of: Learn/CSS/CSS_layout/Responsive_Design +--- +
{{learnsidebar}}{{PreviousMenuNext("Learn/CSS/CSS_layout/Multiple-column_Layout", "Learn/CSS/CSS_layout/Media_queries", "Learn/CSS/CSS_layout")}}
+ +

На заре веб-дизайна страницы создавались для экрана определенного размера. Если у пользователя был экран большего или меньшего размера чем ожидал дизайнер, то результат мог быть от нежелательных полос прокрутки, до слишком длинной строки и плохого использования пространства. Поскольку становились доступны много различных размеров экранов, появилась концепция отзывчивого (адаптивого) веб-дизайна (responsive web design (RWD)) — набор методов, которые позволяют веб-страницам менять свой макет и внешний вид в соответствии с разной шириной экрана, разрешением и т.д. Это та самая, идея которая изменила подход к дизайну веба для множества устройств, и в этой статье мы поможем вам понять основные методы, которые вам необходимо знать, чтобы освоить его.

+ + + + + + + + + + + + +
Необходимые знания: +

Основы HTML (изучите Введение в HTML), идея о том как работает CSS (изучите Введение в CSS и Устройство CSS.)

+
Задача: +

Понять базовые концепции и историю отзывчивого дизайна.

+
+ +

Исторические макеты сайтов

+ +

В какой-то момент истории при разработке веб-сайта у вас было два варианта:

+ + + +

Эти два подхода, как правило, приводили к тому, что веб-сайт лучше всего выглядел на экране человека, создавшего сайт! Жидкий сайт приводил к раздавленному дизайну на маленьких экранах (как видно ниже) и не читаемо длинным строкам на больших.

+ +
A layout with two columns squashed into a mobile size viewport. +
+
+ +
+

Примечание: Посмотрите этот простой жидкий макет: пример, исходный код. При просмотре примера, растягивайте и сжимайте окно браузера чтобы увидеть, как это выглядит при разных размерах.

+
+ +

Сайт с фиксированной шириной рисковал иметь горизонтальную полосу прокрутки на экранах меньших чем ширина сайта (как видно ниже) и много белого пространства на краях дизайна на больших экранах.

+ +
A layout with a horizontal scrollbar in a mobile viewport. +
+
+ +
+

Примечание: Посмотрите этот простой макет с фиксированной шириной: пример, исходный код. Снова изучите результат по мере изменения размера окна браузера.

+
+ +
+

Примечание: Скриншоты выше сделаны используя Responsive Design Mode в Firefox DevTools.

+
+ +

Когда мобильный веб стал становиться реальностью с первыми функциональными телефонами, компании желающие охватить мобильники начали создавать в основном специальные мобильные версии своих сайтов, с различными URL (часто что-то наподобие m.example.com или example.mobi). Это означало, что необходимо было разрабатывать и поддерживать в актуальном состоянии две отдельные версии сайта.

+ +

Кроме того, эти мобильные сайты часто предлагали очень урезанный вариант. Поскольку мобильные гаджеты стали мощнее и способными отображать целые веб-сайты, пользователей мобильных устройств раздражало, что они обнаруживали себя запертыми в мобильной версии сайта, неспособные получить доступ к информации, которая, как они знали, есть в полнофункциональной версии сайта.

+ +

Гибкий макет до отзывчивого дизайна

+ +

Было разработано несколько подходов чтобы попытаться разрешить недостатки построения веб-сайтов жидким методом или методом с фиксированной шириной. В 2004 году Камерон Адамс написал пост Resolution dependent layout, описывающий метод создания дизайна который мог бы адаптироваться к разным разрешениям экрана. Этот подход требовал, чтобы JavaScript узнавал разрешение экрана и загружал корректный CSS.

+ +

Зои Миккели Гилленвотер сыграла важную роль в свой работе описав и формализовав различные способы посредствам которых могут быть созданы гибкие сайты, пытаясь найти золотую середину между заполнением экрана или полностью фиксированным размером.

+ +

Отзывчивый дизайн

+ +

Термин адаптивный дизайн был Придуман Итаном Маркоттом в 2010 году и описывал использование трех методов в сочетании.

+ +
    +
  1. Первой была идея жидких сеток, нечто что уже исследовала Гилленвотер, что можно прочитать в статье Маркотта - Fluid Grids (опубликовано в 2009 в A List Apart).
  2. +
  3. Вторым методом была идея жидких изображений. Используя очень простой метод настройки свойства max-width на 100%, изображения будут становиться меньше если содержащий столбец становится уже чем изначальный размер изображения, но никогда не становится больше. Это позволяет изображению уменьшаться чтобы соответствовать столбцу гибких размеров, а не перекрываться с ним, но не расти и становиться пиксельным если столбец становится шире изображения.
  4. +
  5. Третьим ключевым компонентом был media query. Media Query позволяют переключать тип макета применяя только CSS то, что Камерон Адамс исследовал, используя JavaScript. Вместо того чтобы иметь один макет для всех размеров экранов, макет мог изменяться. Боковые панели можно перемещать для маленьких экранов, либо отображать альтернативную навигацию.
  6. +
+ +

Очень важно понять, что адаптивный веб-дизайн это не отдельная технология, это термин используемый, чтобы описать подход к веб-дизайну или набор лучших практик, используемых для создания макета, который может реагировать на используемое устройство для просмотра контента. В первоначальном исследовании Маркотта это означало гибкие сетки (с использованием floats) и media query, однако почти за 10 лет, прошедших с момента написания этой статьи, адаптивная работа стала стандартом по умолчанию. Современные методы макета CSS отзывчивы по своей сути, и у нас есть новые штучки, встроенные в веб-платформу для того, чтобы делать дизайн отзывчивых сайтов проще.

+ +

Остальная часть этой статьи укажет вам на различные функции веб-платформы, которые вы, возможно, захотите использовать при создании адаптивного сайта.

+ +

Media Queries (Медиа-запросы)

+ +

Отзывчивый дизайн был способен появится только благодаря media query. Спецификация Media Queries Level 3 стала Рекомендованным Кандидатом в 2009 году, что означает, что она была признана готовой к реализации в браузерах. Медиа запросы позволяют нам проводить серию тестов (например, является ли экран пользователя больше, чем определенная ширина или разрешение) и выборочно применять CSS к стилю страницы соответственно с нуждами пользователя.

+ +

Например, следующий медиа запрос проверяет отображается ли текущая страница как экранная медиа (а не как печатный документ) и имеет ли область просмотра ширину как минимум 800 px. CSS будет применяться к селектору .container только если эти две вещи истины.

+ +
@media screen and (min-width: 800px) {
+  .container {
+    margin: 1em 2em;
+  }
+} 
+
+ +

Вы можете добавлять несколько медиа запросов в пределах одной таблицы стилей, подстраивая весь ваш макет или его части так чтоб соответствовать наилучшим образом разным размерам экрана. Точки, в которых применяется media query и меняется макет, известны как контрольные точки.

+ +

Общим подходом при использовании Media Queriy является создание простого одно колоночного макета для устройств с узкими экранами (например, мобильные телефоны), затем проверка для бо'льших экранов и применение макета с несколькими столбцам, когда вы знаете, что у вас достаточно ширины экрана чтобы уместить все. Это часто называют дизайном сначала мобильный (mobile first).

+ +

Узнать больше о Media Query можно в документации MDN.

+ +

Гибкие сетки

+ +

Отзывчивые сайты не просто меняют свой макет между контрольными точками, они построены на гибких сетках. Гибкая сетка подразумевает что вам не надо заботиться о каждом возможном существующем размере устройства и строить для них идеальный макет в пикселях. Такой подход был бы невозможен имея широкое множество существующих устройств разных размеров, как и факт того, что даже на ПК люди не всегда используют браузер с развернутым до максимума окном.

+ +

Используя гибкую сетку, вам всего лишь надо добавить контрольную точку и изменить дизайн в точке, когда ваш контент начинает выглядеть плохо. Например, если длина строки становится нечитаемо длинной при увеличении размера экрана, или блок становится сдавленным с двумя словами в каждой строке при сужении экрана.

+ +

В первые дни отзывчивого дизайна, нашим единственным вариантом выполнения было использование floats. Гибкий обтекаемый макет достигался путем присвоения каждому элементу процентной ширины удостоверившись, что итоговые значения в макете не превышают 100%. В своей оригинальной статье о плавучих сетках Маркотт подробно описал формулу для преобразования макета, созданного с использованием пикселей, в проценты.

+ +
target / context = result 
+
+ +

Например, если размер нашего целевого столбца — 60 пикселей, а контекст (или контейнер) в котором он находится — 960 пикселей, то мы делим 60 на 960 чтобы получить значение которое мы можем использовать в нашем CSS, после переноса десятичной точки вправо на 2 цифры.

+ +
.col {
+  width: 6.25%; /* 60 / 960 = 0.0625 */
+} 
+
+ +

Этот подход сегодня можно найти во многих местах в Интернете и он задокументирован здесь в разделе макетов в нашей статье Устаревших методов макетов. В вашей работе вероятно, что вы столкнетесь с веб-сайтами, использующими этот подход, поэтому стоит понимать его, даже если вы не будете строить современные сайты используя гибкие сетки основанные на float.

+ +

Следующий пример демонстрирует простой отзывчивый дизайн используя Media Query и гибкие сетки. На узких экранах макет отображает блоки, сложенные друг на друга:

+ +
A mobile view of the layout with boxes stacked on top of each other vertically. +
+
+ +

На более широких экранах они премещаются в два столбца:

+ +
A desktop view of a layout with two columns. +
+
+ +
+

Примечание: Вы можете найти живой пример и исходный код этого примера на GitHub.

+
+ +

Современные технологии макетов

+ +

Современные методы макетов такие как Макет с несколькими столбцами, Flexbox, и Grid являются отзывчивыми по умолчанию. Они все предполагают, что вы пытаетесь создать гибкую сетку и дают вам более легкий способ сделать так.

+ +

Multicol

+ +

Самый старый из этих методов — это multicol, когда вы задаете column-count, это отражает то на сколько столбцов вы хотите разбить ваш контент. Далее браузер рассчитывает их размер, размер, который изменится согласно размеру экрана.

+ +
.container {
+  column-count: 3;
+} 
+
+ +

Если вместо этого вы зададите column-width, то вы определите минимальную ширину. Браузер создаст столько столбцов той ширины, сколько будет комфортно умещаться в контейнер, а затем поделит оставшееся пространство между всеми столбцами. Поэтому число столбцов будет меняться согласно тому сколько имеется места.

+ +
.container {
+  column-width: 10em;
+} 
+
+ +

Flexbox

+ +

В Flexbox, в качестве исходного поведения, flex элементы будут сжиматься и распределять пространство между элементами в соответствии с пространством в их контейнере. Изменяя значения flex-grow и flex-shrink вы можете указать, как вы хотите, чтобы предметы вели себя когда они сталкиваются с бо'льшим или меньшим пространством вокруг себя.

+ +

В примере ниже каждый flex элемент будет принимать равное количество пространства во flex контейнере используя запись flex: 1 как описано в главе Flexbox: Гибкое изменение размеров flex элементов.

+ +
.container {
+  display: flex;
+}
+
+.item {
+  flex: 1;
+} 
+
+ +
+

Примечание: В качестве примера мы перестроили простой отзывчивый макет выше, в этот раз используя flexbox. Вы видите что нас больше не надо использовать странные процентные значения для подсчета размера столбцов: пример, исходный код.

+
+ +

CSS grid

+ +

В макете CSS Grid единицы измерения fr позволяют распределять доступное пространство между дорожками сетки. Следующий пример создает grid контейнер с тремя дорожками размером 1fr. Это создаст три вертикальные дорожки, каждая занимающая одну часть свободного пространства в контейнере. Вы можете узнать больше об этом подходе к созданию сетки в теме Изучение Макета Grid в разделе Гибкие grids с единицами fr.

+ +
.container {
+  display: grid;
+  grid-template-columns: 1fr 1fr 1fr;
+} 
+
+ +
+

Примечание: версия grid макета еще проще, поскольку мы можем определить столбцы в .wrapper: пример, исходный код.

+
+ +

Отзывчивые изображения

+ +

Самый простой подход к отзывчивым изображениям был описан в ранних статьях Маркотта по отзывчивому дизайну. По сути, вы берете изображение максимального размера, которое могло понадобиться, и уменьшаете его. Этот подход до сих пор используется и в большинстве таблиц стилей вы найдете следующий CSS:

+ +
img {
+  max-width: 100%;
+} 
+
+ +

Существуют очевидные недостатки к этому подходу. Изображение может быть изображено намного меньше своего исходного размера, что является пустой тратой пропускной способности — пользователь мобильных может загружать изображение, в несколько раз превышающее размер того, что он фактически видит в окне браузера. Кроме того, вам может не понадобиться такое же соотношение сторон изображения на мобильном устройстве, как на компьютере. Либо, учитывая меньший размер изображения на мобильном телефоне, вы можете захотеть показать совсем другое изображение, которое легче понять на маленьком экране. Такие вещи можно достичь, просто уменьшая изображение.

+ +

Отзывчивые изображения, используя элемент {{htmlelement("picture")}} и атрибуты srcset и sizes элемента {{htmlelement("img")}} оба решают эти проблемы. Вы можете указать несколько размеров вместе с «подсказками» (метаданные, описывающие размер экрана и разрешение, для которых изображение лучше всего подходит), и браузер выберет наиболее подходящее изображение для каждого устройства, гарантируя, что пользователь загрузит изображение подходящего размера для устройства, которое они используют.

+ +

Вы также можете напрямую использовать изображения разных размеров, обеспечивая разное кадрирование или совершенно другое изображение для разных размеров экрана.

+ +

Вы можете найти подробное руководство по отзывчивым изображениям в разделе ищучения HTML на MDN.

+ +

Отзывчивая типография

+ +

Элементом отзывчивого дизайна, не освещенного ранее в работе, была идея отзывчивой типографии. Главным образом, она описывает изменение размера шрифта в пределах media queries для того, чтобы отображать бо'льшую или меньшую площадь экрана.

+ +

В этом примере, мы хотим задать нашему заголовку первого уровня 4rem, что значит, что он будет в четыре раза больше нашего базового размера шрифта. Это очень большой заголовок! Мы хотим этот гигантский заголовок только на экранах больших размеров, поэтому мы сначала создаем меньший заголовок, а затем используем media queries чтобы переписать его для больших экранов если мы знаем что у пользователя есть экран размером как минимум 1200px.

+ +
html {
+  font-size: 1em;
+}
+
+h1 {
+  font-size: 2rem;
+}
+
+@media (min-width: 1200px) {
+  h1 {
+    font-size: 4rem;
+  }
+} 
+
+ +

Мы отредактировали наш приведенный выше пример отзывчивой сетки grid, чтобы он также включал в себя адаптивный тип, используя описанный метод. Вы можете видеть, как заголовок меняет размеры, когда макет переходит в версию с двумя столбцами.

+ +

В мобильных версиях заголовок меньше:

+ +
A stacked layout with a small heading size. +
+
+ +

На компьютерах, однако, мы видим больший размер заголовка:

+ +
A two column layout with a large heading. +
+
+ +
+

Примечание: смотрите этот пример в действии: пример, исходный код.

+
+ +

Такой подход к типографии показывает, что вам не надо ограничивать media queries только изменением макета страницы. Они могут быть использоваться для настройки любого элемента, чтобы сделать его более удобным или привлекательным при других размерах экрана.

+ +

Using viewport units for responsive typography

+ +

An interesting approach is to use the viewport unit vw to enable responsive typography. 1vw is equal to one percent of the viewport width, meaning that if you set your font size using vw, it will always relate to the size of the viewport.

+ +
h1 {
+  font-size: 6vw;
+}
+ +

The problem with doing the above is that the user loses the ability to zoom any text set using the vw unit, as that text is always related to the size of the viewport. Therefore you should never set text using viewport units alone.

+ +

There is a solution, and it involves using calc(). If you add the vw unit to a value set using a fixed size such as ems or rems then the text will still be zoomable. Essentially, the vw unit adds on top of that zoomed value:

+ +
h1 {
+  font-size: calc(1.5rem + 3vw);
+}
+ +

This means that we only need to specify the font size for the heading once, rather than set it up for mobile and redefine it in the media queries. The font then gradually increases as you increase the size of the viewport.

+ +
+

See an example of this in action: example, source code.

+
+ +

The viewport meta tag

+ +

If you look at the HTML source of a responsive page, you will usually see the following {{htmlelement("meta")}} tag in the <head> of the document.

+ +
<meta name="viewport" content="width=device-width,initial-scale=1">
+
+ +

This meta tag tells mobile browsers that they should set the width of the viewport to the device width, and scale the document to 100% of its intended size, which shows the document at the mobile-optimized size that you intended.

+ +

Why is this needed? Because mobile browsers tend to lie about their viewport width.

+ +

This meta tag exists because when the original iPhone launched and people started to view websites on a small phone screen, most sites were not mobile optimized. The mobile browser would, therefore, set the viewport width to 960 pixels, render the page at that width, and show the result as a zoomed-out version of the desktop layout. Other mobile browsers (e.g. on Google Android) did the same thing. Users could zoom in and pan around the website to view the bits they were interested in, but it looked bad. You will still see this today if you have the misfortune to come across a site that does not have a responsive design.

+ +

The trouble is that your responsive design with breakpoints and media queries won't work as intended on mobile browsers. If you've got a narrow screen layout that kicks in at 480px viewport width or less, and the viewport is set at 960px, you'll never see your narrow screen layout on mobile. By setting width=device-width you are overriding Apple's default width=960px with the actual width of the device, so your media queries will work as intended.

+ +

So you should always include the above line of HTML in the head of your documents.

+ +

There are other settings you can use with the viewport meta tag, however in general the above line is what you will want to use.

+ + + +

You should avoid using minimum-scale, maximum-scale, and in particular setting user-scalable to no. Users should be allowed to zoom as much or as little as they need to; preventing this causes accessibility problems.

+ +
+

Note: There is a CSS @ rule designed to replace the viewport meta tag — @viewport — however, it has poor browser support. When both are used the meta tag overrides @viewport.

+
+ +

Summary

+ +

Responsive design refers to a site or application design that responds to the environment in which it is viewed. It encompasses a number of CSS and HTML features and techniques and is now essentially just how we build websites by default. Consider the sites that you visit on your phone — it is probably fairly unusual to come across a site that is the desktop version scaled down, or where you need to scroll sideways to find things. This is because the web has moved to this approach of designing responsively.

+ +

It has also become much easier to achieve responsive designs with the help of the layout methods you have learned in these lessons. If you are new to web development today you have many more tools at your disposal than in the early days of responsive design. It is therefore worth checking the age of any materials you are referencing. While the historical articles are still useful, modern use of CSS and HTML makes it far easier to create elegant and useful designs, no matter what device your visitor views the site with.

+ +

{{PreviousMenuNext("Learn/CSS/CSS_layout/Multiple-column_Layout", "Learn/CSS/CSS_layout/Media_queries", "Learn/CSS/CSS_layout")}}

+ +

In this module

+ + diff --git "a/files/ru/learn/css/css_layout/\320\274\320\260\320\272\320\265\321\202_\321\201_\320\275\320\265\321\201\320\272\320\276\320\273\321\214\320\272\320\270\320\274\320\270_\321\201\321\202\320\276\320\273\320\261\321\206\320\260\320\274\320\270/index.html" "b/files/ru/learn/css/css_layout/\320\274\320\260\320\272\320\265\321\202_\321\201_\320\275\320\265\321\201\320\272\320\276\320\273\321\214\320\272\320\270\320\274\320\270_\321\201\321\202\320\276\320\273\320\261\321\206\320\260\320\274\320\270/index.html" deleted file mode 100644 index 9ba48bbbef..0000000000 --- "a/files/ru/learn/css/css_layout/\320\274\320\260\320\272\320\265\321\202_\321\201_\320\275\320\265\321\201\320\272\320\276\320\273\321\214\320\272\320\270\320\274\320\270_\321\201\321\202\320\276\320\273\320\261\321\206\320\260\320\274\320\270/index.html" +++ /dev/null @@ -1,468 +0,0 @@ ---- -title: Макет с несколькими столбцами -slug: Learn/CSS/CSS_layout/Макет_с_несколькими_столбцами -translation_of: Learn/CSS/CSS_layout/Multiple-column_Layout ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/CSS/CSS_layout/Positioning", "Learn/CSS/CSS_layout/Responsive_Design", "Learn/CSS/CSS_layout")}}
- -

Спецификация макет с несколькими столбцами дает вам метод верстки контента по столбцам, точно также как вы можете видеть в газете. Эта статья объясняет, как использовать эту функцию.

- - - - - - - - - - - - -
Необходимые знания: -

Основы HTML (изучите Введение в HTML), идея о том как работает CSS (изучите Введение в CSS.)

-
Задача: -

Изучить как создавать макет с неколькими столбцами на веб-страницах, такой как вы модете найти в газете.

-
- -

Базовый пример

- -

Сейчас мы будем изучать как использовать макет с несколькими столбцами, часто называемый multicol. Вы можете следовать за нами скачав файл отправной точки multicol и добавлять CSS в соответствующие места. В конце раздела вы можете посмотреть живой пример того, как конечный код должен выглядеть.

- -

Наша отправная точка содержит немного очень простого HTML; обертака с классом container внутри которого имеется заголовок и несколько параграфов.

- -

{{htmlelement("div")}} с классом контейнер станет нашим multicol контейнером. Мы включаем multicol используя одно из двух свойств {{cssxref("column-count")}} или {{cssxref("column-width")}}. Какое значение вы дадите свойству column-count столько столбцов он и создаст, поэтому если вы добавите следующий CSS в ваши стили и перезагрузите страницу, то получите три столбца:

- -
.container {
-  column-count: 3;
-}
-
- -

Колонки, которые вы создаете имеют гибкую ширину — браузер решает какое пространство назначить каждому столбцу.

- -
- - -
<div class="container">
-  <h1>Simple multicol example</h1>
-
-  <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat vulputate.
-  Duis felis orci, pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at ultricies tellus laoreet sit amet. Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet orci vel, viverra egestas ligula.
-  Curabitur vehicula tellus neque, ac ornare ex malesuada et. In vitae convallis lacus. Aliquam erat volutpat. Suspendisse
-  ac imperdiet turpis. Aenean finibus sollicitudin eros pharetra congue. Duis ornare egestas augue ut luctus. Proin blandit
-  quam nec lacus varius commodo et a urna. Ut id ornare felis, eget fermentum sapien.</p>
-
-  <p>Nam vulputate diam nec tempor bibendum. Donec luctus augue eget malesuada ultrices. Phasellus turpis est, posuere sit amet dapibus ut, facilisis sed est. Nam id risus quis ante semper consectetur eget aliquam lorem. Vivamus tristique
-  elit dolor, sed pretium metus suscipit vel. Mauris ultricies lectus sed lobortis finibus. Vivamus eu urna eget velit
-  cursus viverra quis vestibulum sem. Aliquam tincidunt eget purus in interdum. Cum sociis natoque penatibus et magnis
-  dis parturient montes, nascetur ridiculus mus.</p>
-</div>
-
- -
.container {
-  column-count: 3;
-}
-
-
- -

{{ EmbedLiveSample('Multicol_1', '100%', 400) }}

- -

Измените ваш CSS чтобы использовать следующий column-width:

- -
.container {
-  column-width: 200px;
-}
-
- -

Теперь браузер будет давать столько столбцов размером, который вы определили, сколько он сможет; любое оставшееся пространство далее делится между существующими столбцами. Это значит, что вы не получите точную ширину, которую вы задали, только если ваш контейнер не делится точно на эту ширину.

- -
- - -
.container {
-  column-width: 200px;
-}
-
-
- -

{{ EmbedLiveSample('Multicol_2', '100%', 400) }}

- -

Стилизация столбцов

- -

Столбцы, созданные при помощи multicol не могут быть стилизованы по одному. Нет способа сделать один столбец больше, чем другие, или изменить фон или цвет текста одного столбца. У вас есть две возможности изменить способ отображения столбцов:

- - - -

Используя ваш пример выше, измените размер отступа добавлением свойства column-gap:

- -
.container {
-  column-width: 200px;
-  column-gap: 20px;
-}
- -

Вы можете поиграть с разными значениями — свойство принимает любые единицы измерения длины. Теперь добавьте линейку между столбцами при помощи column-rule. Таким же способом как и свойство {{cssxref("border")}} с которым вы сталкивались в предыдущих уроках, column-rule — это короткая запись {{cssxref("column-rule-color")}}, {{cssxref("column-rule-style")}} и {{cssxref("column-rule-width")}} и принимает те же значения что и border.

- -
.container {
-  column-count: 3;
-  column-gap: 20px;
-  column-rule: 4px dotted rgb(79, 185, 227);
-}
- -

Попробуйте добавить линейки других стилей и цветов.

- -
- -
- -

{{ EmbedLiveSample('Multicol_3', '100%', 400) }}

- -

Следует обратить внимание на то, что линейка не занимает никакой ширины. Она располагается в промежутках, которые вы создали при помощи column-gap. Чтобы придать больше пространства по обе стороны от линейки, вам нужно увеличить размер column-gap.

- -

Свойств column-span

- -

Вы можете заставить элемент растянуться через все столбцы. В этом случае контент разрывается, когда сталкивается со spanning элементом и продолжается ниже, создавая новый набор блоков столбцов. Чтобы растянуть элемент через все столбцы используйте свойство {{cssxref("column-span")}} установленное на значение all.

- -
-

Обратите внимание что невозможно растянуть элемент через несколько столбцов. Это свойство может иметь либо значение none (по умолчанию) либо all.

-
- -
- -
- -

{{ EmbedLiveSample('Multicol_Span', '100%', 400) }}

- -

Столбцы и фрагментация

- -

Содержимое макета нескольких столбцов является фрагментированным. По сути, он ведет себя так же, как контент в постраничных медиа — так же, как когда вы печатаете веб-страницы. Когда вы переводите ваш контент в multicol контейнер он фрагментируется на столбцы и контент разбивается чтобы позволить этому произойти.

- -

Порой это разрывание происходит в местах, мешающих чтению. В живом примере ниже, я использовал multicol чтобы разместить несколько блоков, каждый из которых имеет заголовок и немного текста внутри. Заголовок отделяется от текста, если столбцы разделяются между ними.

- -
- - -
<div class="container">
-    <div class="card">
-      <h2>I am the heading</h2>
-      <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat
-                vulputate. Duis felis orci, pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at ultricies
-                tellus laoreet sit amet. Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet orci
-                vel, viverra egestas ligula.</p>
-    </div>
-
-    <div class="card">
-      <h2>I am the heading</h2>
-      <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat
-                vulputate. Duis felis orci, pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at ultricies
-                tellus laoreet sit amet. Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet orci
-                vel, viverra egestas ligula.</p>
-    </div>
-
-    <div class="card">
-      <h2>I am the heading</h2>
-      <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat
-                vulputate. Duis felis orci, pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at ultricies
-                tellus laoreet sit amet. Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet orci
-                vel, viverra egestas ligula.</p>
-    </div>
-    <div class="card">
-      <h2>I am the heading</h2>
-      <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat
-                vulputate. Duis felis orci, pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at ultricies
-                tellus laoreet sit amet. Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet orci
-                vel, viverra egestas ligula.</p>
-    </div>
-
-    <div class="card">
-      <h2>I am the heading</h2>
-      <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat
-                vulputate. Duis felis orci, pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at ultricies
-                tellus laoreet sit amet. Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet orci
-                vel, viverra egestas ligula.</p>
-    </div>
-
-    <div class="card">
-      <h2>I am the heading</h2>
-      <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat
-                vulputate. Duis felis orci, pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at ultricies
-                tellus laoreet sit amet. Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet orci
-                vel, viverra egestas ligula.</p>
-    </div>
-
-    <div class="card">
-      <h2>I am the heading</h2>
-      <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat
-                vulputate. Duis felis orci, pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at ultricies
-                tellus laoreet sit amet. Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet orci
-                vel, viverra egestas ligula.</p>
-    </div>
-
-</div>
-
- -
.container {
-  column-width: 250px;
-  column-gap: 20px;
-}
-
-.card {
-  background-color: rgb(207, 232, 220);
-  border: 2px solid rgb(79, 185, 227);
-  padding: 10px;
-  margin: 0 0 1em 0;
-}
-
- -

{{ EmbedLiveSample('Multicol_4', '100%', 600) }}

- -

Для того чтобы управлять этим поведением мы можем использовать свойства из спецификации CSS Фрагментации. Эта спецификация дает нам свойства для управления разрывами контента в multicol и постраничных медиа. Например, добавьте свойство {{cssxref("break-inside")}} со значением avoid к правилам .card. Это контейнер заголовка и текста и поэтому мы не хотим фрагментировать этот блок.

- -

В настоящее время также стоит добавлять старое свойство page-break-inside: avoid для лучшей поддержки старых браузеров.

- -
.card {
-  break-inside: avoid;
-  page-break-inside: avoid;
-  background-color: rgb(207,232,220);
-  border: 2px solid rgb(79,185,227);
-  padding: 10px;
-  margin: 0 0 1em 0;
-}
-
- -

Перезагрузите страницу и ваши блоки должны остаться в целости.

- -
- - -
.container {
-  column-width: 250px;
-  column-gap: 20px;
-}
-
-.card {
-  break-inside: avoid;
-  page-break-inside: avoid;
-  background-color: rgb(207, 232, 220);
-  border: 2px solid rgb(79, 185, 227);
-  padding: 10px;
-  margin: 0 0 1em 0;
-}
-
- -

{{ EmbedLiveSample('Multicol_5', '100%', 600) }}

- -

Проверь свои навыки!

- -

Вы достигли конца этой статьи, но помните ли вы самую важную информацию? Вы можете найти дальнейшие тесты для проверки того, что вы усвоили эту информацию прежде чем, отправитесь дальше — см. Поверьте свои навыки: Макет с несколькими столбцами.

- -

Заключение

- -

Вы теперь знаете, как использовать базовые функции макета с несколькими столбцами, еще один инструмент в вашем распоряжении при выборе метода макета для дизайна который вы строите.

- -

См. также

- - - -

{{PreviousMenuNext("Learn/CSS/CSS_layout/Positioning", "Learn/CSS/CSS_layout/Responsive_Design", "Learn/CSS/CSS_layout")}}

- -

В этом модуле

- - diff --git "a/files/ru/learn/css/css_layout/\320\275\320\260\320\262\321\213\320\272\320\270_multicol/index.html" "b/files/ru/learn/css/css_layout/\320\275\320\260\320\262\321\213\320\272\320\270_multicol/index.html" deleted file mode 100644 index c549f1210b..0000000000 --- "a/files/ru/learn/css/css_layout/\320\275\320\260\320\262\321\213\320\272\320\270_multicol/index.html" +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: 'Проверь свои навыки: Multicol' -slug: Learn/CSS/CSS_layout/Навыки_Multicol -translation_of: Learn/CSS/CSS_layout/Multicol_skills ---- -
{{LearnSidebar}}
- -
- -

Цель этого задания — чтобы вы поработали с CSS свойствами {{CSSxRef("column-count")}}, {{CSSxRef("column-width")}}, {{CSSxRef("column-gap")}}, {{CSSxRef("column-span")}} и {{CSSxRef("column-rule")}} и со значениями которые описаны в нашем уроке Макет с несколькими столбцами. Вы будете работать над тремя небольшими задачами, использующими различные элементы из пройденного материала.

- -
-

Примечание: Вы можете опробовать решения в интерактивных редакторах ниже, однако может быть полезным загрузить код и использовать онлайн инструменты такие как CodePen, jsFiddle, or Glitch чтобы проработать задания.

- -

Если вы застрянете, попросите нас о помощи — см. раздел {{anch("Оценка и дальнейшая помощь")}} в конце страницы.

-
- -

Multicol Раз

- -

В этом задании вам необходимо создать три столбца с отступом 50px между каждый столбцом.

- -

Three columns of text

- -

Попробуйте обновить живой пример ниже для воссоздания законченного примера:

- -

{{EmbedGHLiveSample("css-examples/learn/tasks/multicol/multicol1.html", '100%', 1000)}}

- -
-

Для оценки или дальнейшей работы, загрузите отправную точку этого задания чтобы работать в вашем собственном или онлайн редакторе.

-
- -

Multicol Два

- -

Создайте столбцы с минимальной шириной 200px.

- -

Затем добавьте серую линейку 5px между каждым столбцом, убедитесь, что между краями линейки и содержимым столбцов есть пространство 10px.

- -

Three columns of text with a grey rule between them.

- -

Попробуйте обновить живой код ниже для воссоздания законченного примера:

- -

{{EmbedGHLiveSample("css-examples/learn/tasks/multicol/multicol2.html", '100%', 1000)}}

- -
-

Для оценки или дальнейшей работы, загрузите отправную точку этого задания чтобы работать в вашем собственном или онлайн редакторе.

-
- -

Multicol Три

- -

Заставьте элемент содержащий заголовок и подзаголовок растянуться через все столбцы так чтоб это выглядело как на картинке

- -

Three columns of text with a heading and subheading spanning all three in the middle.

- -

Попробуйте обновить живой код ниже для воссоздания законченного примера:

- -

{{EmbedGHLiveSample("css-examples/learn/tasks/multicol/multicol3.html", '100%', 1000)}}

- -
-

Для оценки или дальнейшей работы, загрузите отправную точку этого задания чтобы работать в вашем собственном или онлайн редакторе.

-
- -

Оценка и дальнейшая помощь

- -

Вы можете попрактиковаться с этими примерами в интерактивных редакторах упомянутых выше.

- -

Если вы хотите, чтобы вашу работу оценили, или вы застряли и хотите попросить помощи:

- -
    -
  1. Разместите свою работу в онлайн редакторе в которым можно поделиться работами в таком как  CodePen, jsFiddle, или Glitch. Вы можете написать код самостоятельно или использовать файлы с отправными точками ссылки на которые имеются в разделах выше.
  2. -
  3. Напишите пост с просьбой оценки и/или помощи на MDN Discourse forum Learning category. Ваш пост должен включать: -
      -
    • Описательный заголовок такой как "Требуется оценка проверки навыков по Multicol задание 1".
    • -
    • Детали о том, что вы уже попытались сделать и что бы вы хотели, чтобы мы сделали, например, если вы застряли и вам нужна помощь, либо вы хотите оценку.
    • -
    • Ссылку на онлайн редактор (как упомянуто выше в пункте 1) с примером, который нуждается в оценке или с которым нужна помощь. Это хорошая практика чтобы вникнуть — очень сложно помочь кому-либо с проблемным кодом если вы не видите их код.
    • -
    • Ссылку на актуальную задачу или страницу оценки, чтобы мы могли найти вопрос, по которому вам нужна помощь.
    • -
    -
  4. -
diff --git "a/files/ru/learn/css/css_layout/\320\275\320\260\320\262\321\213\320\272\320\270_\320\277\320\276\320\267\320\270\321\206\320\270\320\276\320\275\320\270\321\200\320\276\320\262\320\260\320\275\320\270\321\217/index.html" "b/files/ru/learn/css/css_layout/\320\275\320\260\320\262\321\213\320\272\320\270_\320\277\320\276\320\267\320\270\321\206\320\270\320\276\320\275\320\270\321\200\320\276\320\262\320\260\320\275\320\270\321\217/index.html" deleted file mode 100644 index f63a3a3a94..0000000000 --- "a/files/ru/learn/css/css_layout/\320\275\320\260\320\262\321\213\320\272\320\270_\320\277\320\276\320\267\320\270\321\206\320\270\320\276\320\275\320\270\321\200\320\276\320\262\320\260\320\275\320\270\321\217/index.html" +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: 'Проверьте свои навыки: позиционирование' -slug: Learn/CSS/CSS_layout/Навыки_позиционирования -translation_of: Learn/CSS/CSS_layout/Position_skills ---- -
{{LearnSidebar}}
- -
- -

Цель этого задания - чтобы вы поработали с CSS свойством {{CSSxRef("position")}} и его значениями которые описаны в нашем уроке Позиционирование. Вы будете работать над двумя небольшими задачами, использующими различные элементы из пройденного материала.

- -
-

Примечание: Вы можете опробовать решения в интерактивных редакторах ниже, однако может быть полезным загрузить код и использовать онлайн инструменты такие как CodePen, jsFiddle, или Glitch чтобы проработать задания.

- -

Если вы застрянете, попросите нас о помощи — см. раздел {{anch("Оценка и дальнейшая помощь")}} в конце страницы

-
- -

Позиционирование Раз

- -

В этом задании вам необходимо расположить элементы с классом target в верхнем правом углу контейнера, который имеет серую границу 5px.

- -

The green box is at the top right of a container with a grey border.

- -

Попробуйте обновить живой код ниже для воссоздания законченного примера:

- -

{{EmbedGHLiveSample("css-examples/learn/tasks/position/position1.html", '100%', 1000)}}

- -

В качестве дополнительной задачи, сможете ли вы изменить цель так чтоб она отображалась под текстом?

- -
-

Для оценки или дальнейшей работы, загрузите отправную точку этого задания чтобы работать в вашем собственном или онлайн редакторе

-
- -

Позиционирование Два

- -

В примере ниже если вы прокрутите блок боковая панель прокручивается вместе с контентом. Измените его так чтобы боковая панель оставалась на месте и прокручивался только контент.

- -

The content is scrolled but the sidebar has stayed in place.

- -

Попробуйте обновить живой код ниже для воссоздания законченного примера:

- -

{{EmbedGHLiveSample("css-examples/learn/tasks/position/position2.html", '100%', 1000)}}

- -
-

ля оценки или дальнейшей работы, загрузите отправную точку этого задания чтобы работать в вашем собственном или онлайн редактор

-
- -

Оценка и дальнейшая помощь

- -

Вы можете попрактиковаться с этими примерами в интерактивных редакторах упомянутых выше.

- -

Если вы хотите, чтобы вашу работу оценили, или вы застряли и хотите попросить помощи:

- -
    -
  1. Разместите свою работу в онлайн редакторе в которым можно поделиться работами в таком как CodePen, jsFiddle, или Glitch. Вы можете написать код самостоятельно или использовать файлы с отправными точками ссылки на которые имеются в разделах выше.
  2. -
  3. Напишите пост с просьбой оценки и/или помощи на MDN Discourse forum Learning category. Ваш пост должен включать: -
      -
    • Описательный заголовок такой как "Требуется оценка проверки навыков по Позиционированияю".
    • -
    • Детали о том, что вы уже попытались сделать и что бы вы хотели, чтобы мы сделали, например, если вы застряли и вам нужна помощь, либо вы хотите оценку.
    • -
    • Ссылку на онлайн редактор (как упомянуто выше в пункте 1) с примером, который нуждается в оценке или с которым нужна помощь. Это хорошая практика чтобы вникнуть — очень сложно помочь кому-либо с проблемным кодом если вы не видите их код.
    • -
    • Ссылку на актуальную задачу или страницу оценки, чтобы мы могли найти вопрос, по которому вам нужна помощь.
    • -
    -
  4. -
diff --git "a/files/ru/learn/css/css_layout/\320\275\320\276\321\200\320\274\320\260\320\273\321\214\320\275\321\213\320\271_\320\277\320\276\321\202\320\276\320\272/index.html" "b/files/ru/learn/css/css_layout/\320\275\320\276\321\200\320\274\320\260\320\273\321\214\320\275\321\213\320\271_\320\277\320\276\321\202\320\276\320\272/index.html" deleted file mode 100644 index d936c240c5..0000000000 --- "a/files/ru/learn/css/css_layout/\320\275\320\276\321\200\320\274\320\260\320\273\321\214\320\275\321\213\320\271_\320\277\320\276\321\202\320\276\320\272/index.html" +++ /dev/null @@ -1,96 +0,0 @@ ---- -title: Базовый поток -slug: Learn/CSS/CSS_layout/Нормальный_поток -tags: - - float - - grid -translation_of: Learn/CSS/CSS_layout/Normal_Flow ---- -
{{LearnSidebar}}
- -

{{PreviousMenuNext("Learn/CSS/CSS_layout/Introduction", "Learn/CSS/CSS_layout/Flexbox", "Learn/CSS/CSS_layout")}}

- -

Эта статья объясняет нормальный/базовый поток (normal flow) или способ, которым элементы страницы располагаются на веб-странице по умолчанию.

- - - - - - - - - - - - -
Что нужно знать прежде чем изучать:Основы HTML (изучите Введение в HTML), и понимания как работает CSS (изучите Введение в CSS.)
Цель:Объяснить как браузеры размещают элементы на веб-странице по умолчанию, т.е. прежде, чем мы начнем вносить какие-либо изменения.
- -

Как говорилось ранее, элементы на веб-странице располагаются в нормальном потоке, если вы не применили к ним ни единого CSS для изменения их поведения. И, как мы уже выяснили, вы можете изменить поведение элементов либо путем изменения их положения в этом нормальном потоке, либо удалением этих элементов из этого потока. Хорошо структурированный документ, читабельный в нормальном потоке является лучшим путём начала любой веб-страницы. Это гарантирует, что ваш контент будет читабельным, даже если пользователи используют очень ограниченный браузер или устройство для чтения, которое считывает содержимое страницы. Кроме того, поскольку нормальный поток предназначен для создания читабельного документа, имейте в виду, что вы не сражаетесь с первоначальным видом документа, а работаете с ним.

- -

Прежде чем углубиться в разные способы компоновки, стоит пересмотреть некоторые из вещей, которые вы изучили в предыдущих модулях в отношении нормального потока документов. 

- -

Как элементы располагаются по умолчанию?

- -

Прежде всего, индивидуальные боксы элементов располагаются в зависимости от содержимого элементов, затем добавляя какой-нибудь padding, border и margin вокруг них - это опять-таки боксовая модель, которую мы рассмотрели ранее.

- -

По умолчанию содержимое элемента уровня блока составляет 100% от ширины его родительского элемента и столь же высок, как и его содержимое. Встроенные элементы высоки и широки, как их содержимое. Вы не можете установить ширину или высоту на встроенные элементы — они просто находятся внутри содержимого элементов блочного уровня. Если вы хотите контролировать размер встроенного элемента вам нужно настроить его так, чтобы он себя вёл как элемент блочного уровня при помощи display: block; (или даже,  display: inline-block;, который смешивает характеристики обоих.).

- -

Это объясняет отдельные элементы, но как насчет того, как элементы взаимодействуют друг с другом? Нормальный поток макета (упомянутый в статье введения макета) - это система, посредством которой элементы размещаются внутри окна просмотра браузера. По умолчанию элементы уровня блока выкладываются в направлении, что блокирует отображение в режиме записи документа - каждый из них будет отображаться в новой строке ниже последней строки, и они будут разделены любым полем, установленным на них. Поэтому на английском языке или на любом другом, в котором режим писания горизонтальный, сверху вниз, элементы уровня блока располагаются вертикально.

- -

Встроенные элементы ведут себя по-другому — они не появляются на новых строках; они распологаются на той же строке, что и другие и любой смежной или завернутый текст располагается на всю ширину внутри элемента уровня родительского блока, до тех пор, пока не закончится пространство. Если пространства нет, тогда текст и/или элементы перейдут на новую строку (не с абзаца).

- -

Если два смежных элемента имеют заданные для них поля/внешние отступы (margin) и эти поля соприкасаются друг с другом, большее из них остается, а меньшее исчезает — это звётся схлопывание полей (margin collapsing), и мы рассматривали это ранее.

- -

Давайте посмотрим на пример, который объясняет всё из того, что мы рассмотрели в данной статье:

- -
-
<h1>Базовый поток документа</h1>
-
-<p>Я базовый элемент уровня блока. Мои соседние блочные элементы находятся на новой строке подо мной.</p>
-
-<p>По умолчанию мы охватываем 100% ширины нашего родительского элемента, и мы так же высоки, как и наш child-контент. Наша общая ширина и высота - это наш контент + внутренний отступ (padding) + ширина / высота границы.</p>
-
-<p>Мы отделены нашими полями. Из-за схлопывания полей мы отделены шириной одного из наших полей, а не обоих</p>
-
-<p>Встроенные элементы <span>такие как этот</span> и <span>этот</span> находятся на одной линии с другими, и смежным текстом, если есть пространство. Встроенные элементы, что не влезают <span>переходять на новую строку если это возможно (как этот текст)</span>если же это невозможно, они переходят на новую строку, как это изображение: <img src="https://mdn.mozillademos.org/files/13360/long.jpg"></p>
- -
body {
-  width: 500px;
-  margin: 0 auto;
-}
-
-p {
-  background: rgba(255,84,104,0.3);
-  border: 2px solid rgb(255,84,104);
-  padding: 10px;
-  margin: 10px;
-}
-
-span {
-  background: white;
-  border: 1px solid black;
-}
-
- -

{{ EmbedLiveSample('Normal_Flow', '100%', 500) }}

- -

Заключение

- -

Теперь, когда вы поняли нормальный поток и как браузер выкладывает содержимое по умолчанию, двигаемся дальше, чтобы понять как это изменить для создания макета согласно вашему дизайну.

- -

{{PreviousMenuNext("Learn/CSS/CSS_layout/Introduction", "Learn/CSS/CSS_layout/Flexbox", "Learn/CSS/CSS_layout")}}

- -

В этом модуле

- - diff --git "a/files/ru/learn/css/css_layout/\320\276\321\202\320\267\321\213\320\262\321\207\320\270\320\262\321\213\320\271_\320\264\320\270\320\267\320\260\320\271\320\275/index.html" "b/files/ru/learn/css/css_layout/\320\276\321\202\320\267\321\213\320\262\321\207\320\270\320\262\321\213\320\271_\320\264\320\270\320\267\320\260\320\271\320\275/index.html" deleted file mode 100644 index 978b4e43dc..0000000000 --- "a/files/ru/learn/css/css_layout/\320\276\321\202\320\267\321\213\320\262\321\207\320\270\320\262\321\213\320\271_\320\264\320\270\320\267\320\260\320\271\320\275/index.html" +++ /dev/null @@ -1,328 +0,0 @@ ---- -title: Отзывчивый дизайн -slug: Learn/CSS/CSS_layout/Отзывчивый_дизайн -translation_of: Learn/CSS/CSS_layout/Responsive_Design ---- -
{{learnsidebar}}{{PreviousMenuNext("Learn/CSS/CSS_layout/Multiple-column_Layout", "Learn/CSS/CSS_layout/Media_queries", "Learn/CSS/CSS_layout")}}
- -

На заре веб-дизайна страницы создавались для экрана определенного размера. Если у пользователя был экран большего или меньшего размера чем ожидал дизайнер, то результат мог быть от нежелательных полос прокрутки, до слишком длинной строки и плохого использования пространства. Поскольку становились доступны много различных размеров экранов, появилась концепция отзывчивого (адаптивого) веб-дизайна (responsive web design (RWD)) — набор методов, которые позволяют веб-страницам менять свой макет и внешний вид в соответствии с разной шириной экрана, разрешением и т.д. Это та самая, идея которая изменила подход к дизайну веба для множества устройств, и в этой статье мы поможем вам понять основные методы, которые вам необходимо знать, чтобы освоить его.

- - - - - - - - - - - - -
Необходимые знания: -

Основы HTML (изучите Введение в HTML), идея о том как работает CSS (изучите Введение в CSS и Устройство CSS.)

-
Задача: -

Понять базовые концепции и историю отзывчивого дизайна.

-
- -

Исторические макеты сайтов

- -

В какой-то момент истории при разработке веб-сайта у вас было два варианта:

- - - -

Эти два подхода, как правило, приводили к тому, что веб-сайт лучше всего выглядел на экране человека, создавшего сайт! Жидкий сайт приводил к раздавленному дизайну на маленьких экранах (как видно ниже) и не читаемо длинным строкам на больших.

- -
A layout with two columns squashed into a mobile size viewport. -
-
- -
-

Примечание: Посмотрите этот простой жидкий макет: пример, исходный код. При просмотре примера, растягивайте и сжимайте окно браузера чтобы увидеть, как это выглядит при разных размерах.

-
- -

Сайт с фиксированной шириной рисковал иметь горизонтальную полосу прокрутки на экранах меньших чем ширина сайта (как видно ниже) и много белого пространства на краях дизайна на больших экранах.

- -
A layout with a horizontal scrollbar in a mobile viewport. -
-
- -
-

Примечание: Посмотрите этот простой макет с фиксированной шириной: пример, исходный код. Снова изучите результат по мере изменения размера окна браузера.

-
- -
-

Примечание: Скриншоты выше сделаны используя Responsive Design Mode в Firefox DevTools.

-
- -

Когда мобильный веб стал становиться реальностью с первыми функциональными телефонами, компании желающие охватить мобильники начали создавать в основном специальные мобильные версии своих сайтов, с различными URL (часто что-то наподобие m.example.com или example.mobi). Это означало, что необходимо было разрабатывать и поддерживать в актуальном состоянии две отдельные версии сайта.

- -

Кроме того, эти мобильные сайты часто предлагали очень урезанный вариант. Поскольку мобильные гаджеты стали мощнее и способными отображать целые веб-сайты, пользователей мобильных устройств раздражало, что они обнаруживали себя запертыми в мобильной версии сайта, неспособные получить доступ к информации, которая, как они знали, есть в полнофункциональной версии сайта.

- -

Гибкий макет до отзывчивого дизайна

- -

Было разработано несколько подходов чтобы попытаться разрешить недостатки построения веб-сайтов жидким методом или методом с фиксированной шириной. В 2004 году Камерон Адамс написал пост Resolution dependent layout, описывающий метод создания дизайна который мог бы адаптироваться к разным разрешениям экрана. Этот подход требовал, чтобы JavaScript узнавал разрешение экрана и загружал корректный CSS.

- -

Зои Миккели Гилленвотер сыграла важную роль в свой работе описав и формализовав различные способы посредствам которых могут быть созданы гибкие сайты, пытаясь найти золотую середину между заполнением экрана или полностью фиксированным размером.

- -

Отзывчивый дизайн

- -

Термин адаптивный дизайн был Придуман Итаном Маркоттом в 2010 году и описывал использование трех методов в сочетании.

- -
    -
  1. Первой была идея жидких сеток, нечто что уже исследовала Гилленвотер, что можно прочитать в статье Маркотта - Fluid Grids (опубликовано в 2009 в A List Apart).
  2. -
  3. Вторым методом была идея жидких изображений. Используя очень простой метод настройки свойства max-width на 100%, изображения будут становиться меньше если содержащий столбец становится уже чем изначальный размер изображения, но никогда не становится больше. Это позволяет изображению уменьшаться чтобы соответствовать столбцу гибких размеров, а не перекрываться с ним, но не расти и становиться пиксельным если столбец становится шире изображения.
  4. -
  5. Третьим ключевым компонентом был media query. Media Query позволяют переключать тип макета применяя только CSS то, что Камерон Адамс исследовал, используя JavaScript. Вместо того чтобы иметь один макет для всех размеров экранов, макет мог изменяться. Боковые панели можно перемещать для маленьких экранов, либо отображать альтернативную навигацию.
  6. -
- -

Очень важно понять, что адаптивный веб-дизайн это не отдельная технология, это термин используемый, чтобы описать подход к веб-дизайну или набор лучших практик, используемых для создания макета, который может реагировать на используемое устройство для просмотра контента. В первоначальном исследовании Маркотта это означало гибкие сетки (с использованием floats) и media query, однако почти за 10 лет, прошедших с момента написания этой статьи, адаптивная работа стала стандартом по умолчанию. Современные методы макета CSS отзывчивы по своей сути, и у нас есть новые штучки, встроенные в веб-платформу для того, чтобы делать дизайн отзывчивых сайтов проще.

- -

Остальная часть этой статьи укажет вам на различные функции веб-платформы, которые вы, возможно, захотите использовать при создании адаптивного сайта.

- -

Media Queries (Медиа-запросы)

- -

Отзывчивый дизайн был способен появится только благодаря media query. Спецификация Media Queries Level 3 стала Рекомендованным Кандидатом в 2009 году, что означает, что она была признана готовой к реализации в браузерах. Медиа запросы позволяют нам проводить серию тестов (например, является ли экран пользователя больше, чем определенная ширина или разрешение) и выборочно применять CSS к стилю страницы соответственно с нуждами пользователя.

- -

Например, следующий медиа запрос проверяет отображается ли текущая страница как экранная медиа (а не как печатный документ) и имеет ли область просмотра ширину как минимум 800 px. CSS будет применяться к селектору .container только если эти две вещи истины.

- -
@media screen and (min-width: 800px) {
-  .container {
-    margin: 1em 2em;
-  }
-} 
-
- -

Вы можете добавлять несколько медиа запросов в пределах одной таблицы стилей, подстраивая весь ваш макет или его части так чтоб соответствовать наилучшим образом разным размерам экрана. Точки, в которых применяется media query и меняется макет, известны как контрольные точки.

- -

Общим подходом при использовании Media Queriy является создание простого одно колоночного макета для устройств с узкими экранами (например, мобильные телефоны), затем проверка для бо'льших экранов и применение макета с несколькими столбцам, когда вы знаете, что у вас достаточно ширины экрана чтобы уместить все. Это часто называют дизайном сначала мобильный (mobile first).

- -

Узнать больше о Media Query можно в документации MDN.

- -

Гибкие сетки

- -

Отзывчивые сайты не просто меняют свой макет между контрольными точками, они построены на гибких сетках. Гибкая сетка подразумевает что вам не надо заботиться о каждом возможном существующем размере устройства и строить для них идеальный макет в пикселях. Такой подход был бы невозможен имея широкое множество существующих устройств разных размеров, как и факт того, что даже на ПК люди не всегда используют браузер с развернутым до максимума окном.

- -

Используя гибкую сетку, вам всего лишь надо добавить контрольную точку и изменить дизайн в точке, когда ваш контент начинает выглядеть плохо. Например, если длина строки становится нечитаемо длинной при увеличении размера экрана, или блок становится сдавленным с двумя словами в каждой строке при сужении экрана.

- -

В первые дни отзывчивого дизайна, нашим единственным вариантом выполнения было использование floats. Гибкий обтекаемый макет достигался путем присвоения каждому элементу процентной ширины удостоверившись, что итоговые значения в макете не превышают 100%. В своей оригинальной статье о плавучих сетках Маркотт подробно описал формулу для преобразования макета, созданного с использованием пикселей, в проценты.

- -
target / context = result 
-
- -

Например, если размер нашего целевого столбца — 60 пикселей, а контекст (или контейнер) в котором он находится — 960 пикселей, то мы делим 60 на 960 чтобы получить значение которое мы можем использовать в нашем CSS, после переноса десятичной точки вправо на 2 цифры.

- -
.col {
-  width: 6.25%; /* 60 / 960 = 0.0625 */
-} 
-
- -

Этот подход сегодня можно найти во многих местах в Интернете и он задокументирован здесь в разделе макетов в нашей статье Устаревших методов макетов. В вашей работе вероятно, что вы столкнетесь с веб-сайтами, использующими этот подход, поэтому стоит понимать его, даже если вы не будете строить современные сайты используя гибкие сетки основанные на float.

- -

Следующий пример демонстрирует простой отзывчивый дизайн используя Media Query и гибкие сетки. На узких экранах макет отображает блоки, сложенные друг на друга:

- -
A mobile view of the layout with boxes stacked on top of each other vertically. -
-
- -

На более широких экранах они премещаются в два столбца:

- -
A desktop view of a layout with two columns. -
-
- -
-

Примечание: Вы можете найти живой пример и исходный код этого примера на GitHub.

-
- -

Современные технологии макетов

- -

Современные методы макетов такие как Макет с несколькими столбцами, Flexbox, и Grid являются отзывчивыми по умолчанию. Они все предполагают, что вы пытаетесь создать гибкую сетку и дают вам более легкий способ сделать так.

- -

Multicol

- -

Самый старый из этих методов — это multicol, когда вы задаете column-count, это отражает то на сколько столбцов вы хотите разбить ваш контент. Далее браузер рассчитывает их размер, размер, который изменится согласно размеру экрана.

- -
.container {
-  column-count: 3;
-} 
-
- -

Если вместо этого вы зададите column-width, то вы определите минимальную ширину. Браузер создаст столько столбцов той ширины, сколько будет комфортно умещаться в контейнер, а затем поделит оставшееся пространство между всеми столбцами. Поэтому число столбцов будет меняться согласно тому сколько имеется места.

- -
.container {
-  column-width: 10em;
-} 
-
- -

Flexbox

- -

В Flexbox, в качестве исходного поведения, flex элементы будут сжиматься и распределять пространство между элементами в соответствии с пространством в их контейнере. Изменяя значения flex-grow и flex-shrink вы можете указать, как вы хотите, чтобы предметы вели себя когда они сталкиваются с бо'льшим или меньшим пространством вокруг себя.

- -

В примере ниже каждый flex элемент будет принимать равное количество пространства во flex контейнере используя запись flex: 1 как описано в главе Flexbox: Гибкое изменение размеров flex элементов.

- -
.container {
-  display: flex;
-}
-
-.item {
-  flex: 1;
-} 
-
- -
-

Примечание: В качестве примера мы перестроили простой отзывчивый макет выше, в этот раз используя flexbox. Вы видите что нас больше не надо использовать странные процентные значения для подсчета размера столбцов: пример, исходный код.

-
- -

CSS grid

- -

В макете CSS Grid единицы измерения fr позволяют распределять доступное пространство между дорожками сетки. Следующий пример создает grid контейнер с тремя дорожками размером 1fr. Это создаст три вертикальные дорожки, каждая занимающая одну часть свободного пространства в контейнере. Вы можете узнать больше об этом подходе к созданию сетки в теме Изучение Макета Grid в разделе Гибкие grids с единицами fr.

- -
.container {
-  display: grid;
-  grid-template-columns: 1fr 1fr 1fr;
-} 
-
- -
-

Примечание: версия grid макета еще проще, поскольку мы можем определить столбцы в .wrapper: пример, исходный код.

-
- -

Отзывчивые изображения

- -

Самый простой подход к отзывчивым изображениям был описан в ранних статьях Маркотта по отзывчивому дизайну. По сути, вы берете изображение максимального размера, которое могло понадобиться, и уменьшаете его. Этот подход до сих пор используется и в большинстве таблиц стилей вы найдете следующий CSS:

- -
img {
-  max-width: 100%;
-} 
-
- -

Существуют очевидные недостатки к этому подходу. Изображение может быть изображено намного меньше своего исходного размера, что является пустой тратой пропускной способности — пользователь мобильных может загружать изображение, в несколько раз превышающее размер того, что он фактически видит в окне браузера. Кроме того, вам может не понадобиться такое же соотношение сторон изображения на мобильном устройстве, как на компьютере. Либо, учитывая меньший размер изображения на мобильном телефоне, вы можете захотеть показать совсем другое изображение, которое легче понять на маленьком экране. Такие вещи можно достичь, просто уменьшая изображение.

- -

Отзывчивые изображения, используя элемент {{htmlelement("picture")}} и атрибуты srcset и sizes элемента {{htmlelement("img")}} оба решают эти проблемы. Вы можете указать несколько размеров вместе с «подсказками» (метаданные, описывающие размер экрана и разрешение, для которых изображение лучше всего подходит), и браузер выберет наиболее подходящее изображение для каждого устройства, гарантируя, что пользователь загрузит изображение подходящего размера для устройства, которое они используют.

- -

Вы также можете напрямую использовать изображения разных размеров, обеспечивая разное кадрирование или совершенно другое изображение для разных размеров экрана.

- -

Вы можете найти подробное руководство по отзывчивым изображениям в разделе ищучения HTML на MDN.

- -

Отзывчивая типография

- -

Элементом отзывчивого дизайна, не освещенного ранее в работе, была идея отзывчивой типографии. Главным образом, она описывает изменение размера шрифта в пределах media queries для того, чтобы отображать бо'льшую или меньшую площадь экрана.

- -

В этом примере, мы хотим задать нашему заголовку первого уровня 4rem, что значит, что он будет в четыре раза больше нашего базового размера шрифта. Это очень большой заголовок! Мы хотим этот гигантский заголовок только на экранах больших размеров, поэтому мы сначала создаем меньший заголовок, а затем используем media queries чтобы переписать его для больших экранов если мы знаем что у пользователя есть экран размером как минимум 1200px.

- -
html {
-  font-size: 1em;
-}
-
-h1 {
-  font-size: 2rem;
-}
-
-@media (min-width: 1200px) {
-  h1 {
-    font-size: 4rem;
-  }
-} 
-
- -

Мы отредактировали наш приведенный выше пример отзывчивой сетки grid, чтобы он также включал в себя адаптивный тип, используя описанный метод. Вы можете видеть, как заголовок меняет размеры, когда макет переходит в версию с двумя столбцами.

- -

В мобильных версиях заголовок меньше:

- -
A stacked layout with a small heading size. -
-
- -

На компьютерах, однако, мы видим больший размер заголовка:

- -
A two column layout with a large heading. -
-
- -
-

Примечание: смотрите этот пример в действии: пример, исходный код.

-
- -

Такой подход к типографии показывает, что вам не надо ограничивать media queries только изменением макета страницы. Они могут быть использоваться для настройки любого элемента, чтобы сделать его более удобным или привлекательным при других размерах экрана.

- -

Using viewport units for responsive typography

- -

An interesting approach is to use the viewport unit vw to enable responsive typography. 1vw is equal to one percent of the viewport width, meaning that if you set your font size using vw, it will always relate to the size of the viewport.

- -
h1 {
-  font-size: 6vw;
-}
- -

The problem with doing the above is that the user loses the ability to zoom any text set using the vw unit, as that text is always related to the size of the viewport. Therefore you should never set text using viewport units alone.

- -

There is a solution, and it involves using calc(). If you add the vw unit to a value set using a fixed size such as ems or rems then the text will still be zoomable. Essentially, the vw unit adds on top of that zoomed value:

- -
h1 {
-  font-size: calc(1.5rem + 3vw);
-}
- -

This means that we only need to specify the font size for the heading once, rather than set it up for mobile and redefine it in the media queries. The font then gradually increases as you increase the size of the viewport.

- -
-

See an example of this in action: example, source code.

-
- -

The viewport meta tag

- -

If you look at the HTML source of a responsive page, you will usually see the following {{htmlelement("meta")}} tag in the <head> of the document.

- -
<meta name="viewport" content="width=device-width,initial-scale=1">
-
- -

This meta tag tells mobile browsers that they should set the width of the viewport to the device width, and scale the document to 100% of its intended size, which shows the document at the mobile-optimized size that you intended.

- -

Why is this needed? Because mobile browsers tend to lie about their viewport width.

- -

This meta tag exists because when the original iPhone launched and people started to view websites on a small phone screen, most sites were not mobile optimized. The mobile browser would, therefore, set the viewport width to 960 pixels, render the page at that width, and show the result as a zoomed-out version of the desktop layout. Other mobile browsers (e.g. on Google Android) did the same thing. Users could zoom in and pan around the website to view the bits they were interested in, but it looked bad. You will still see this today if you have the misfortune to come across a site that does not have a responsive design.

- -

The trouble is that your responsive design with breakpoints and media queries won't work as intended on mobile browsers. If you've got a narrow screen layout that kicks in at 480px viewport width or less, and the viewport is set at 960px, you'll never see your narrow screen layout on mobile. By setting width=device-width you are overriding Apple's default width=960px with the actual width of the device, so your media queries will work as intended.

- -

So you should always include the above line of HTML in the head of your documents.

- -

There are other settings you can use with the viewport meta tag, however in general the above line is what you will want to use.

- - - -

You should avoid using minimum-scale, maximum-scale, and in particular setting user-scalable to no. Users should be allowed to zoom as much or as little as they need to; preventing this causes accessibility problems.

- -
-

Note: There is a CSS @ rule designed to replace the viewport meta tag — @viewport — however, it has poor browser support. When both are used the meta tag overrides @viewport.

-
- -

Summary

- -

Responsive design refers to a site or application design that responds to the environment in which it is viewed. It encompasses a number of CSS and HTML features and techniques and is now essentially just how we build websites by default. Consider the sites that you visit on your phone — it is probably fairly unusual to come across a site that is the desktop version scaled down, or where you need to scroll sideways to find things. This is because the web has moved to this approach of designing responsively.

- -

It has also become much easier to achieve responsive designs with the help of the layout methods you have learned in these lessons. If you are new to web development today you have many more tools at your disposal than in the early days of responsive design. It is therefore worth checking the age of any materials you are referencing. While the historical articles are still useful, modern use of CSS and HTML makes it far easier to create elegant and useful designs, no matter what device your visitor views the site with.

- -

{{PreviousMenuNext("Learn/CSS/CSS_layout/Multiple-column_Layout", "Learn/CSS/CSS_layout/Media_queries", "Learn/CSS/CSS_layout")}}

- -

In this module

- - diff --git a/files/ru/learn/css/css_properties/index.html b/files/ru/learn/css/css_properties/index.html deleted file mode 100644 index a6d9e5d116..0000000000 --- a/files/ru/learn/css/css_properties/index.html +++ /dev/null @@ -1,133 +0,0 @@ ---- -title: 'CSS properties: what they are and how to use them' -slug: Learn/CSS/CSS_properties -translation_of: Learn/CSS/Building_blocks/Selectors -translation_of_original: Learn/CSS/CSS_properties ---- -
-

{{Glossary("CSS")}} определяет как должна выглядеть вебстраница. Он использует предопределенные правила вместе с селекторами и свойствами для применения стилей к элементам HTML или группам элементов.

-
- - - - - - - - - - - - -
Prerequisites:Basics of {{Glossary("HTML")}}, HTML elements, and how to link HTML documents to CSS stylesheets.
Objective:Learn about different CSS selectors and properties enough to style a simple webpage.
- -

Summary

- -

Разделение содержимого и стиля делает Веб разработку намного быстрее и проще. Когда вы определяете только стуктуру документа в вашем HTML файле и храните всю информацию о стиле в отдельном файле (называемом stylesheet), вы можете обновлять стили нескольких документов одновременно (а так же экономить ресурсы компьютера).

- -

CSS syntax consists of easy-to-use, intuitive keywords.

- -
p {
-   font-family: "Times New Roman", georgia, sans-serif;
-   font-size: 24px;
-}
- -

In the example above, p is a selector that applies styles to all the {{HTMLElement("p")}} elements at once. The CSS properties font-family and font-size are enclosed within curly braces and the corresponding values, right after the colon, determine the styles.

- -

There are more than 250 properties you can apply to your document. From text to layout, (almost) anything is possible.

- -

Active Learning

- -

There is no active learning available yet. Please, consider contributing.

- -

Deeper dive

- -

If properties are fairly simple to use, selectors are another story. Okay, they aren't that hard, and mastering them unleashes the full potential of CSS. In the next examples, we will introduce the most common selectors.

- -

A CSS rule consists of selectors associated with properties. Selectors specify which elements will receive the properties laid down in the rule. Multiple rules can apply to the same element; the CSS cascade (which we'll discuss later on) determines which rule ends up taking effect in the case of conflicts. For now, just remember that the rule with the most specific selector overrides the rules with more generic selectors.

- -

The element selector

- -

Element selectors select HTML elements by element names only. Moreover, like all CSS selectors, you can apply a common set of properties to several elements at once.

- -

For our first example, let's assume the following HTML code fragment:

- -
<h1>I'm an example</h1>
-<p>In this example, I'm a paragraph</p>
-<p>And I'm another paragraph</p>
-
- -

In the following CSS rule, the element selector p applies the given styles simultaneously to all the {{HTMLElement("p")}} elements of our HTML document, preventing extensive rewriting. We are using the {{cssxref("font-family")}} property (which defines the font in which text appears) and the {{cssxref("font-size")}} (which defines text size).

- -
p {
-  font-family: "Helvetica", Arial, sans-serif;
-  font-size  : 12px;
-}
- -

The next CSS rule only applies to {{HTMLElement("h1")}} elements. We are using the {{cssxref("font-size")}} property to make our title twice the size of the body text, and the {{cssxref("font-weight")}} property to make the title bold.

- -
h1 {
-  font-size  : 24px;
-  font-weight: bold;
-}
- -

The following CSS rule applies the requisite styles to both {{HTMLElement("h1")}} and {{HTMLElement("p")}} elements, potentially removing even more duplication. (This use is called "group selector" or "chain selector". Notice the comma separating the selectors). Here we are using the {{cssxref("color")}} property to specify the same text color for both headings and paragraphs.

- -
h1, p {
-  color: darkmagenta;
-}
- -

Here is the result of all this code:

- -

{{ EmbedLiveSample('The_element_selector') }}

- -

The id selector

- -

The id attribute of a particular HTML element uniquely identifies that element. Hence, an id selector is used only when a set of style rules applies to a single element.

- -

For our next example, let's assume the following HTML code fragment:

- -
<p id="hello">Hello world!</p> 
- -

The following CSS rule applies only to that unique identified element. To make a selector into an id selector, you must put a hash character (#) in front of the id name. We are using three properties: {{cssxref("text-align")}} to center the text within the paragraph {{cssxref("border")}} to add a thin line around the paragraph, and {{cssxref("padding")}} to add some extra inner-margin between the text and the border.

- -
#hello {
-  text-align: center;
-  border    : 1px solid black;
-  padding   : 8px;
-}
- -

And the result is the following:

- -

{{ EmbedLiveSample('The_id_selector') }}

- -

The class selector

- -

Within HTML, the class attribute lets you apply multiple identifiers to HTML elements. Those identifiers can be used with CSS to match groups of elements regardless of element name.

- -

For our next example, let's assume the following HTML code fragment:

- -
<h1 class="hello">Hey there!</h1>
-<p class="hello bye">Let's hang out together!</p>
-<p class="bye">And walk over the mountain</p>
-
- -

Let's apply a CSS rule for all elements with the class hello. To make the selector into a class selector, put a period/full stop before the class name. We use the {{cssxref("font-style")}} property to italicize the text.

- -
.hello {
-  font-style: italic;
-}
- -

And another one for all elements with the class bye. Here we are using the {{cssxref("text-decoration")}} property to draw a line through the text.

- -
.bye {
-  text-decoration: line-through;
-}
- -

Here's what happened:

- -

{{ EmbedLiveSample('The_class_selector') }}

- -

Next step

- -

So we've gone over the basics to get started with CSS. You can learn more about text styling or start exploring our CSS Tutorials right away.

diff --git a/files/ru/learn/css/first_steps/how_css_is_structured/index.html b/files/ru/learn/css/first_steps/how_css_is_structured/index.html new file mode 100644 index 0000000000..d2c60edcfb --- /dev/null +++ b/files/ru/learn/css/first_steps/how_css_is_structured/index.html @@ -0,0 +1,528 @@ +--- +title: Как структурирован CSS +slug: Learn/CSS/First_steps/Как_структурирован_CSS +tags: + - Beginner + - CSS + - HTML + - Learn + - Комментарии + - Обучение + - Свойство + - Структура + - значения + - отступ + - селектор + - сокращение +translation_of: Learn/CSS/First_steps/How_CSS_is_structured +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/CSS/First_steps/Getting_started", "Learn/CSS/First_steps/How_CSS_works", "Learn/CSS/First_steps")}}
+ +

Теперь, когда у вас есть представление о том, чем является CSS, и о его основах, настало время посмотреть немного глубже в структуру самого языка. Нам уже встречались многие из обсуждаемых здесь концепций; вы можете вернуться к этому, чтобы разобраться, если вы обнаружите какие-либо более поздние концепции запутанными.

+ + + + + + + + + + + + +
Необходимые знания:Базовая компьютерная грамотность, Базовое програмное обеспечение, базовые знания работа с файлами, и базовые знания HTML (статья Введение в HTML), и знание о том Как работает CSS
Задача:Подробно узнать основные синтаксические структуры CSS.
+ +

Применение CSS к вашему HTML

+ +

Первое, что мы рассмотрим, это три метода применения CSS к документу.

+ +

Внешняя таблица стилей

+ +

В статье ​Начало работы с CSS мы связывали внешнюю таблицу стилей с нашей страницей. Это самый распространенный и полезный способ крепления CSS к документу, так вы можете привязать CSS сразу к нескольким страницам, что позволяет стилизовать их всё с той же таблицей стилей. В большинстве случаев различные страницы сайта будут выглядеть почти так же, поэтому вы можете использовать один и тот же набор правил для основного вида.

+ +

Внешняя таблица стилей - это когда у вас есть CSS отдельным файлом с расширением .css, и ссылка на него из HTML-элемента <link>:

+ +
<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Я пробую писать CSS</title>
+    <link rel="stylesheet" href="styles.css">
+  </head>
+  <body>
+    <h1>Привет!</h1>
+    <p>Это мой первый опыт в CSS</p>
+  </body>
+</html>
+ +

Файл CSS может выглядеть следующим образом:

+ +
h1 {
+  color: blue;
+  background-color: yellow;
+  border: 1px solid black;
+}
+
+p {
+  color: red;
+}
+ +

Атрибут href элемента {{htmlelement("link")}} должен ссылаться на файл в файловой системе.

+ +

В приведенном выше примере файл CSS находится в той же папке, что и HTML-документ, но вы можете поместить его куда-нибудь ещё и настроить относительный путь, например:

+ +
<!-- Файл находится внутри под-директории styles, находящейся в текущей директории -->
+<link rel="stylesheet" href="styles/style.css">
+
+<!-- Файл — внутри под-директории styles внутри под-под-директории general и так далее -->
+<link rel="stylesheet" href="styles/general/style.css">
+
+<!-- Вверх на один уровень в директории, затем направиться в под-директорию styles -->
+<link rel="stylesheet" href="../styles/style.css">
+ +

Внутренняя таблица стилей

+ +

Внутренняя таблица стилей, где у вас нет внешнего файла CSS, но вместо этого CSS помещён внутри элемента {{htmlelement("style")}}, содержащейся внутри HTML {{htmlelement("head")}}.

+ +

Таким образом, HTML будет выглядеть вот так:

+ +
<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Я пробую писать CSS</title>
+    <style>
+      h1 {
+        color: blue;
+        background-color: yellow;
+        border: 1px solid black;
+      }
+
+      p {
+        color: red;
+      }
+    </style>
+  </head>
+  <body>
+    <h1>Привет!</h1>
+    <p>Это мой первый опыт в CSS</p>
+  </body>
+</html>
+ +

Это может быть полезно в некоторых обстоятельствах (возможно, вы работаете с системой управления контентом, где вы не можете изменить CSS-файлы непосредственно), но это менее эффективно, чем внешние таблицы стилей: CSS будет необходимо прописывать отдельно для каждой страницы и изменять, если требуются изменения.

+ +

Встроенные стили

+ +

Встроенные стили являются правилами CSS, которые влияют только на один элемент, содержащиеся в атрибуте style:

+ +
<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Я пробую писать CSS</title>
+  </head>
+  <body>
+    <h1 style="color: blue;background-color: yellow;border: 1px solid black;">Привет!</h1>
+    <p style="color:red;">Это мой первый опыт в CSS</p>
+  </body>
+</html>
+ +

Пожалуйста, не делайте этого! Это очень плохо для технического обслуживания (вам, возможно, придётся обновить одну и ту же информацию несколько раз в одном документе), а также смешивает ваши презентационные данные CSS с структурной информацией HTML, что делает код трудным для чтения и понимания. Хранение различных типов кода отделено делает работу гораздо более лёгкой для всех, кто работает над кодом.

+ +

Есть несколько мест, где встроенные стили являются более распространенными или даже желательными. Вам, возможно, придется прибегнуть к использованию их, если ваша рабочая среда сильно ограничена (возможно, ваша CMS позволяет редактировать только HTML-тело). Вы также увидите, как они использовали много в HTML электронной почте, чтобы получить совместимость с таким количеством почтовых клиентов, со скольким это возможно.

+ +

Игра с CSS в этой статье

+ +

Существует много возможностей, чтобы поиграть с CSS в этой статье. Для этого мы рекомендуем создать новый каталог / папку на вашем компьютере и внутри него создать копии следующих двух файлов:

+ +

index.html:

+ +
<!DOCTYPE html>
+<html lang="ru">
+  <head>
+    <meta charset="utf-8">
+    <title>Я пробую писать CSS</title>
+    <link rel="stylesheet" href="styles.css">
+  </head>
+  <body>
+
+    <p>Пишите сюда свой код</p>
+
+  </body>
+</html>
+ +

styles.css:

+ +
/* Пишите сюда свой код */
+
+p {
+  color: red;
+}
+ +

Затем, когда вы столкнетесь с CSS и захотите поэкспериментировать со стилями, измените содержимое <body> HTML-документа и начинайте добавлять CSS-стили внутри вашего файла CSS.

+ +

Если вы не используете систему, в которой вы можете легко создавать файлы, вы можете вместо этого использовать интерактивный редактор ниже чтобы экспериментировать.

+ +

{{EmbedGHLiveSample("css-examples/learn/getting-started/experiment-sandbox.html", '100%', 800)}} 

+ +

Читайте дальше и получайте удовольствие!

+ +

Селекторы

+ +

Говоря о CSS, нельзя не упомянуть о селекторах, о некоторых типах которых мы уже говорили в руководстве Начало работы с CSS. Селектор — это то, как мы обозначаем что-либо в нашем HTML-документе, чтобы стилизовать его. Если стиль не применился, то это, скорее всего, потому, что селектор в таблицах стилей не совпал с тем, что в HTML-документе.

+ +

Каждое CSS-правило начинается с одного или нескольких селекторов, отделяемых друг от друга запятыми, чтобы дать понять браузеру, к чему применять стили. В следующем примере перечислены стандартные селекторы:

+ +
h1  /* это селектор тегов */
+a:link  /* это селектор ссылок */
+.manythings  /* это селектор классов (классы применяются тогда, когда необходимо применить правило к нескольким элементам) */
+#onething  /* это селектор идентификаторов (они применяются, когда правило относится к одному элементу) */
+*  /* уневерсальный селектор */
+.box p  /* селектор потомков */
+.box p:first-child  /* селектор потомков + селектор псевдоклассов */
+h1, h2, .intro  /* пречисление селекторов */
+
+ +
+

Примечание: Вы узнаете больше о селекторах в руководстве CSS-селекторы в следующем модуле.

+
+ +

Спецификация

+ +

Иногда может случаться такое, что два селектора будут относиться к одному и тому же элементу HTML. Смотрите: в примере ниже я задал правило для элемента p — он будет синим; также я задал класс, который сделает элемент красным:

+ +
.special {
+  color: red;
+}
+
+p {
+  color: blue;
+}
+ +

А теперь допустим, что в нашем HTML-коде у нас есть абзац p с классом special. Оба правила могут быть добавлены: так какое же одержит верх? Как вы думаете, какого цвета будет надпись?

+ +
<p class="special">Какого же я цвета?</p>
+ +

В языке CSS есть правила, которые определяют, какое правило "выиграет" в случае подобного столкновения — они называются каскадами, или спецификациями. В примере ниже мы задали два правила для селектора p, но в итоге текст будет синим: объвление, делающее надпись синей, появилось позже того, которое делает её красной. Это каскад в действии.

+ +
p {
+  color: red;
+}
+
+p {
+  color: blue;
+}
+ +

А в примере с селектором класса и селектором тега победит селектор класса — даже если он объявлен раньше.

+ +

Попрактикуйтесь сами — добавьте два правила для параграфа p { ... } в вашу таблицу стилей. Затем добавьте класс к одному элементу p и попробуйте применить к нему какой-нибудь стиль.

+ +

Понимание каскадов, или правил, улучшается с практикой. В статье Каскад и наследование я хорошенько объясню, как определить уровень спецификации. А пока что запомните, что иногда CSS не применяется так, как вы того хотели бы, так как у чего-то в таблице стилей больший уровень спецификации.

+ +

Свойства и значения

+ +

Если говорить в общем, CSS строится на двух его составляющих:

+ +
+
Свойства 
+
Определяют, какую характеристику вы желаете изменить (например, font-size, width, background-color).
+
+ +
+
Значения 
+
Это величина свойства, определяющая, как и/или насколько вы желаете изменить свойство.
+
+ +

На изображении внизу выделены свойство и его значение. Здесь свойство — color, а его значение — blue.

+ +

A declaration highlighted in the CSS

+ +

Свойство вкупе со значением называется CSS-объявлением. CSS-объявления помещаются внутри блока объявлений CSS. Ниже показан наш CSS-код с выделенным блоком объявлений.

+ +

A highlighted declaration block

+ +

Наконец блок объявлений воссоединяется с селекторами, образуя CSS-правила. Наше изображение содержит два правила — одно для селектора h1, другое для селектора p. Правило для h1 выделено.

+ +

The rule for h1 highlighted

+ +

Установление значений для CSS-свойств — вот суть языка CSS. Движок CSS определяет, какие объявления применять к каждому элементу на странице, чтобы соответствующим образом размещать и стилизовать его. Необходимо запомнить, что и свойства, и значения чувствительны к регистру. Пара свойство–значение разделяется двоеточием (:).

+ +

Попробуйте подобрать нужные значения к следующим свойствам, а свойства добавить в ваш код:

+ + + +
+

Важно: Если свойство или значение не определено, то объявление считается недействительным — и будет попросту проигнорировано.

+
+ +
+

Важно: В CSS (и прочих веб-стандартах) американское написание является стандартом. Например, color надо всегда писать color; британский вариант colour не будет работать.

+
+ +

Функции

+ +

Чаще всего значения принимают форму числа или ключевого слова; существуют способы создавать функции для значений. Для примера можно взять функцию calc(). Она позволяет вам совершать лёгкие математические вычисления внутри CSS, например:

+ +
+
<div class="outer"><div class="box">The inner box is 90% - 30px.</div></div>
+ +
.outer {
+  border: 5px solid black;
+}
+
+.box {
+  padding: 10px;
+  width: calc(90% - 30px);
+  background-color: rebeccapurple;
+  color: white;
+}
+
+ +

В результате получим это:

+ +

{{EmbedLiveSample('calc_example', '100%', 200)}}

+ +

Функция состоит из названия и скобок, внутри который помещается выражение с допустимыми для данной функции знаками. В примере выше я задал значение ширины блока равной 90% внешнего блока минус 30px. Не могу же я сказать, чему равны 90% блока?!

+ +

В следующем примере будут различные значения для свойства {{cssxref("<transform>")}} rotate().

+ +
+
<div class="box"></div>
+ +
.box {
+  margin: 30px;
+  width: 100px;
+  height: 100px;
+  background-color: rebeccapurple;
+  transform: rotate(0.8turn)
+}
+
+ +

Результат этого кода будет:

+ +

{{EmbedLiveSample('transform_example', '100%', 200)}}

+ +

Найдите несколько значений для следующих свойств, а свойства добавьте в ваш файл:

+ + + +

@правила

+ +

До сих пор не сталкивались мы с правилами @rules (произносится как эт-рулс, от английского "at-rules"). Это особые правила, дающие CSS инструкции, как вести себя. У некоторых правил @rules простые названия и значения. Чтобы, к примеру, импортировать ещё одну таблицу стилей в основной CSS-файл, нужно использовать @import:

+ +
@import 'styles2.css';
+ +

Чаще других встречается @rules под названием @media: оно позволяет вам использовать медиа-запросы, чтобы применять CSS в определённых случаях, только если выполняются те или иные условия (например, при изменении размеров окна или при просмотре сайта с иного типа устройства).

+ +

Ниже у нас CSS-файл, в котором значение заднего фона элемента <body> равно pink. Однако после мы добавили правило @media, которое делает задний фон элемента синим, при условии если ширина окна не менее 30em.

+ +
body {
+  background-color: pink;
+}
+
+@media (min-width: 30em) {
+  body {
+    background-color: blue;
+  }
+}
+ +

Вы столкнётесь и с другими правилами @rules в продолжение следующих уроков.

+ +

Добавьте правило, которое изменяет стиль элемента, основываясь на ширине окна. Измените ширину окна, чтобы увидеть результат.

+ +

Стенография

+ +

Некоторые свойства вроде {{cssxref("font")}}, {{cssxref("background")}}, {{cssxref("padding")}}, {{cssxref("border")}} и {{cssxref("margin")}} называются стенографическими свойствами, — они позволяют установать несколько значений свойств в одной строке, ускоряя запись и делая её аккуратной.

+ +

К примеру, это строка (комментарий не в счёт):

+ +
/* В четырёхзначных стенографиях наподобие padding и margin значения добавляются
+   в порядке верх–право–низ–лево (по часовой стрелке сверху). В трёхзначных стенограммах
+   значения добавляются в порядке верх(низ)–право–лево.
+   В двузначных стенограммах значения добавляются
+   от верхнего/нижнего края к левому/правому краю */
+padding: 10px 15px 15px 5px;
+ +

делает то же самое, что и эти четыре, вместе взятые:

+ +
padding-top: 10px;
+padding-right: 15px;
+padding-bottom: 15px;
+padding-left: 5px;
+
+ +

или эти:

+ +
padding-block-start: 10px
+padding-inline-end: 15px;
+padding-block-end: 15px;
+padding-inline-start: 5px;
+ +

в то время как строка:

+ +
background: red url(bg-graphic.png) 10px 10px repeat-x fixed;
+ +

делает то же, что и эти строки:

+ +
background-color: red;
+background-image: url(bg-graphic.png);
+background-position: 10px 10px;
+background-repeat: repeat-x;
+background-scroll: fixed;
+ +

Мы не будем проходить это сейчас — вы можете найти эти и многие другие стенографии в Руководстве по CSS.

+ +

Добавьте вышеупоминутые объвления в ваш код. Попробуйте изменить значения и посмотреть на результат.

+ +
+

Осторожно: Стенографии позволяют пропускать некоторые величины, и это может отразиться на результате недолжным образом.

+
+ +

Комментарии

+ +

Как и в HTML, вы можете делать комментарии, чтобы прояснить тот или иной отрывок кода.

+ +

Комментарии в CSS начинаются с /* и окачиваются с */. В примере ниже я отметил комментариями различные разделы кода. Это очень полезно для навигации — комментарии легче искать.

+ +
/* Работаю над основными элементами */
+/* -------------------------------------------------------------------------------------------- */
+body {
+  font: 1em/150% Helvetica, Arial, sans-serif;
+  padding: 1em;
+  margin: 0 auto;
+  max-width: 33em;
+}
+
+@media (min-width: 70em) {
+  /* Позволяет определить размер шрифта. На широких экранах
+     больше размер шрифта для удобства чтения */
+  body {
+    font-size: 130%;
+  }
+}
+
+h1 {font-size: 1.5em;}
+
+/* Работаю над элементами, вложенными в DOM  */
+/* -------------------------------------------------------------------------------------------- */
+div p, #id:first-line {
+  background-color: red;
+  background-style: none
+}
+
+div p{
+  margin: 0;
+  padding: 1em;
+}
+
+div p + p {
+  padding-top: 0;
+}
+ +

Отделяя комментариями участки кода, не нуждающиеся в проверке, вы можете выискивать ошибку (если такая есть). Ниже я отделил правило для селектора .special.

+ +
/*.special {
+  color: red;
+}*/
+
+p {
+  color: blue;
+}
+ +

Добавьте комментарии в ваш CSS-код, чтобы приноровиться к ним.

+ +

Отступы

+ +

Под отступами подразумеваются пробелы, табуляция и перенос на новую строку. Как и в HTML, браузер будет стараться игнорировать большие отступы в CSS-коде; к тому же большие отступы пагубны для читаемости кода.

+ +

В примере ниже каждое объявление (а также начало/окончание правила) находится на своей строке — это, возможно, наилучший вариант написания CSS-кода: он понятен и аккуратен:

+ +
body {
+  font: 1em/150% Helvetica, Arial, sans-serif;
+  padding: 1em;
+  margin: 0 auto;
+  max-width: 33em;
+}
+
+@media (min-width: 70em) {
+  body {
+    font-size: 130%;
+  }
+}
+
+h1 {
+  font-size: 1.5em;
+}
+
+div p,
+#id:first-line {
+  background-color: red;
+  background-style: none
+}
+
+div p {
+  margin: 0;
+  padding: 1em;
+}
+
+div p + p {
+  padding-top: 0;
+}
+
+ +

То же самое вы можете написать, не добавляя большие отступы, — коды идентичны; но я уверен, вы согласитесь, что это очень тяжело прочитать:

+ +
body {font: 1em/150% Helvetica, Arial, sans-serif; padding: 1em; margin: 0 auto; max-width: 33em;}
+@media (min-width: 70em) { body {font-size: 130%;} }
+
+h1 {font-size: 1.5em;}
+
+div p, #id:first-line {background-color: red; background-style: none}
+div p {margin: 0; padding: 1em;}
+div p + p {padding-top: 0;}
+
+ +

Как вы будете оформлять код — решать вам; хотя, работая в команде, вы обнаружите, что она придерживается тех правил форматирования, которые в ней утверждены.

+ +

Внимательно делайте отступы в свойствах и значениях. К примеру, такие объявления будут работать:

+ +
margin: 0 auto;
+padding-left: 10px;
+ +

А такие объявления не действительны:

+ +
margin: 0auto;
+padding- left: 10px;
+ +

Всегда отделяйте друг от друга значения, а свойства пишите без пробелов через дефис.

+ +

Добавьте отступы в ваш код и посмотрите, что повлияет на код, а что нет.

+ +

Что дальше?

+ +

Полезно знать, как браузер делает из HTML и CSS готовую страницу, поэтом следующая ваша статья — Как работает CSS — мы рассмотрим этот процесс.

+ +

{{PreviousMenuNext("Learn/CSS/First_steps/Getting_started", "Learn/CSS/First_steps/How_CSS_works", "Learn/CSS/First_steps")}}

+ +

В этом модуле

+ +
    +
  1. Что такое CSS?
  2. +
  3. Начало работы с CSS
  4. +
  5. Как структурирован CSS
  6. +
  7. Как работает CSS
  8. +
  9. Использование ваших новых знаний
  10. +
diff --git a/files/ru/learn/css/first_steps/what_is_css/index.html b/files/ru/learn/css/first_steps/what_is_css/index.html new file mode 100644 index 0000000000..6b5bdf8924 --- /dev/null +++ b/files/ru/learn/css/first_steps/what_is_css/index.html @@ -0,0 +1,130 @@ +--- +title: Что такое CSS? +slug: Learn/CSS/First_steps/Что_такое_CSS +tags: + - Beginner + - CSS + - Learn + - Введение в CSS + - Начинающий + - Обучение + - Синтаксис + - Спецификации +translation_of: Learn/CSS/First_steps/What_is_CSS +--- +
{{LearnSidebar}}
+ +
{{NextMenu("Learn/CSS/First_steps/Getting_started", "Learn/CSS/First steps")}}
+ +

{{Glossary("CSS")}} (Каскадные таблицы стилей) позволяет создавать великолепно выглядящие веб-страницы, но как же это работает? Эта статья объясняет, что такое CSS, с помощью простого примера синтаксиса, а также охватывает некоторые ключевые термины о языке.

+ + + + + + + + + + + + +
Требуемые знания:Базовые компьютерные знания, установка базового програмного обеспечения, базовые знания работа с файлами и базовые знания HTML  (Введение в HTML).
Задача:Узнать, что такое CSS.
+ +

В модуле Основы HTML мы рассмотрели, что такое HTML и как он используется для разметки документов. Эти документы будут доступны для чтения в веб-браузере. Заголовки будут выглядеть больше, чем обычный текст, абзацы разбиваются на новую строку и будут иметь пространство между друг другом. Ссылки выделены цветом и подчеркнуты, чтобы отличить их от остального текста. То, что Вы видите, — это стили браузера по умолчанию — самые основные стили, которые браузер применяет к HTML, чтобы гарантировать, что он будет в основном читабельным, даже если автор страницы не указал явный стиль.

+ +

+ +

Тем не менее, интернет был бы скучным, если бы все сайты выглядели так. Используя CSS, Вы можете до мелочей контролировать, как элементы HTML выглядят в браузере, представляя вашу разметку, используя любой понравившийся Вам дизайн.

+ +

Для чего нужен CSS?

+ +

Как мы уже упоминали ранее, CSS — это язык для определения того, как документы представляются пользователям — как они оформляются, размещаются и т. д.

+ +

Документ обычно представляет собой текстовый файл, структурированный с использованием языка разметки: {{Glossary("HTML")}} — самый распространенный язык разметки, но Вы также можете встретить другие языки разметки, такие как {{Glossary("SVG")}} или {{Glossary("XML")}}.

+ +

Представление документа пользователю означает преобразование его в форму, используемую Вашей аудиторией. {{Glossary("browser","Browsers")}}, такие как {{Glossary("Mozilla Firefox","Firefox")}}, {{Glossary("Google Chrome","Chrome")}} или {{Glossary("Microsoft Edge","Edge")}} , предназначены для визуального представления документов, например, на экране компьютера, проектора или принтера.

+ +
+

Примечание: Браузер иногда называют {{Glossary("User agent","user agent")}}, что в основном означает компьютерную программу, которая представляет человека внутри компьютерной системы. Браузеры — это основной тип пользовательского агента, о котором мы думаем, когда говорим о CSS, но он не единственный. Доступны и другие пользовательские агенты, например, те, которые преобразуют документы HTML и CSS в файлы PDF для печати.

+
+ +

CSS может использоваться для очень простой стилизации текста документа, например, изменение цвета и размера заголовков и ссылок. Он может быть использован для создания макета, например, превращение одного столбца текста в макет с основной областью контента и боковой панелью для соответствующей информации. Это может даже использоваться для эффектов, таких как анимация. Посмотрите на ссылки в этом параграфе для конкретных примеров.

+ +

Синтаксис CSS

+ +

CSS — это язык на основе правил: Вы задаёте правила, определяющие группы стилей, которые должны применяться к определённым элементам или группам элементов на Вашей веб-странице. Например:

+ +

«Я хочу, чтобы основной заголовок на моей странице отображался крупным красным текстом».

+ +

В следующем коде показано очень простое правило CSS, которое будет соответствовать стилю, описанному выше:

+ +
h1 {
+    color: red;
+    font-size: 5em;
+}
+ +

Правило открывается с помощью {{Glossary("CSS Selector", "селектора")}} . Этот селектор выбирает HTML-элемент, который мы собираемся стилизовать. В этом случае мы используем заголовки первого уровня — ({{htmlelement("h1")}}).

+ +

Затем у нас есть набор фигурных скобок { }. Внутри них будет один или несколько объявлений, которые принимают форму пары свойства и его значения. Каждая пара указывает свойство элемента(-ов), который(-е) мы выбираем, а затем значение, которое мы хотели бы присвоить свойству.

+ +

Перед двоеточием у нас есть свойство, а после двоеточия — значение. CSS-{{Glossary("property/CSS","свойства")}} имеют разные допустимые значения в зависимости от того, какое свойство указывается. В нашем примере мы имеем свойство color, которое может принимать различные цветовые значения. У нас также есть свойство font-size. Это свойство может принимать различные значения размера, как и свойства.

+ +

Таблица стилей CSS будет содержать много таких правил, написанных одно за другим.

+ +
h1 {
+    color: red;
+    font-size: 5em;
+}
+
+p {
+    color: black;
+}
+ +

Вы обнаружите, что Вы быстро изучаете некоторые значения, тогда как другие Вам нужно искать. Страницы отдельных свойств в MDN дают Вам быстрый способ поиска свойств и их значений, когда Вы забыли или хотите узнать, что ещё Вы можете использовать в качестве значения.

+ +
+

Примечание: Вы можете найти ссылки на все страницы свойств CSS (вместе с другими функциями CSS), перечисленные в MDN Руководстве по CSS. Кроме того, Вы должны привыкнуть к поиску "MDN css-feature-name" в Вашем бразере, когда Вам нужно узнать больше информации о функции CSS. Например, попробуйте поискать «mdn color» и «mdn font-size»!

+
+ +

CSS-модули

+ +

Поскольку существует множество вещей, которые можно стилизовать с помощью CSS, язык разбит на модули. По мере изучения MDN Вы увидите ссылки на эти модули, а многие страницы документации организованы вокруг определенного модуля. Например, вы можете взглянуть на ссылку MDN в модуле Свойства фона и границ, чтобы узнать, какова его цель и какие различные свойства и другие функции он содержит. Вы также найдёте ссылки на спецификацию CSS, которая определяет технологию (см. ниже).

+ +

На этом этапе вам не нужно слишком беспокоиться о том, как структурирован CSS, однако это может упростить поиск информации, если, например, вы знаете, что определённое свойство может быть найдено среди других похожих вещей, и поэтому, вероятно, в той же спецификации.

+ +

Для конкретного примера давайте вернемся к модулю Свойства фона и границ — Вы можете подумать, что это логично для свойств background-color и border-color, которые будут определены в этом модуле. И Вы правы.

+ +

Технические характеристики CSS

+ +

Все технологии веб-стандартов (HTML, CSS, JavaScript и т. д.) определены в гигантских документах, называемых спецификациями, которые публикуются организациями по стандартизации (такие как {{glossary("W3C")}}, {{glossary("WHATWG")}}, {{glossary("ECMA")}} или {{glossary("Khronos")}}) и определяют, как эти технологии должны вести себя.

+ +

CSS ничем не отличается — он разработан группой в W3C, которая называется CSS Working Group. Эта группа состоит из представителей производителей браузеров и других компаний, которые заинтересованы в CSS. Есть также другие люди, известные как приглашенные эксперты, которые выступают как независимые голоса; они не связаны с членами организации.

+ +

Новые функции CSS разрабатываются или определяются рабочей группой CSS. Иногда потому, что конкретный браузер заинтересован в том, чтобы иметь какие-то возможности, иногда потому, что веб-дизайнеры и разработчики запрашивают функцию, а иногда потому, что сама рабочая группа определила требование. CSS постоянно развивается, появляются новые функции. Тем не менее, ключевым моментом в CSS является то, что все работают очень усердно, чтобы никогда не менять вещи таким образом, чтобы это сломало старые сайты. Веб-сайт, созданный в 2000 году, с использованием ограниченного CSS, доступного в то время, должен всё ещё использоваться в браузере сегодня!

+ +

Как новичок в CSS, вполне вероятно, что Вы найдете CSS-спецификации ошеломляющими — они предназначены для инженеров, чтобы использовать их для реализации поддержки функций в пользовательских агентах, а не для веб-разработчиков, чтобы читать, чтобы понимать CSS. Многие опытные разработчики предпочитают обращаться к документации MDN или другим учебникам. Однако стоит знать, что они существуют, понимать взаимосвязь между используемым CSS, поддержкой браузера (см. ниже) и спецификациями.

+ +

Поддержка браузера

+ +

После того как CSS был указан, он будет полезен для разработки веб-страниц, только если один или несколько браузеров его реализовали. Это означает, что код был написан для превращения инструкции в нашем CSS-файле во что-то, что может быть выведено на экран. Мы рассмотрим этот процесс подробнее на уроке Как работает CSS. Это необычно для всех браузеров, чтобы реализовать функцию одновременно, и поэтому обычно есть пробел, где вы можете использовать некоторую часть CSS в одних браузерах, а не в других. По этой причине полезно проверять состояние реализации. На каждой странице свойств в MDN Вы можете видеть статус интересующего Вас свойства, чтобы Вы могли определить, сможете ли Вы использовать её на веб-сайте.

+ +

Ниже приведена диаграмма данных для CSS свойства font-family:

+ +

{{Compat("css.properties.font-family")}}

+ +

Что дальше?

+ +

Теперь, когда у вас есть некоторое представление о том, что такое CSS, давайте перейдем к Началу работы с CSS, где Вы можете начать писать CSS самостоятельно.

+ +

{{NextMenu("Learn/CSS/First_steps/Getting_started", "Learn/CSS/First_steps")}}

+ +

В этом модуле

+ +
    +
  1. Что такое CSS?
  2. +
  3. Начало работы с CSS
  4. +
  5. Как структурирован CSS
  6. +
  7. Как работает CSS
  8. +
  9. Использование ваших новых знаний
  10. +
diff --git "a/files/ru/learn/css/first_steps/\320\272\320\260\320\272_\321\201\321\202\321\200\321\203\320\272\321\202\321\203\321\200\320\270\321\200\320\276\320\262\320\260\320\275_css/index.html" "b/files/ru/learn/css/first_steps/\320\272\320\260\320\272_\321\201\321\202\321\200\321\203\320\272\321\202\321\203\321\200\320\270\321\200\320\276\320\262\320\260\320\275_css/index.html" deleted file mode 100644 index d2c60edcfb..0000000000 --- "a/files/ru/learn/css/first_steps/\320\272\320\260\320\272_\321\201\321\202\321\200\321\203\320\272\321\202\321\203\321\200\320\270\321\200\320\276\320\262\320\260\320\275_css/index.html" +++ /dev/null @@ -1,528 +0,0 @@ ---- -title: Как структурирован CSS -slug: Learn/CSS/First_steps/Как_структурирован_CSS -tags: - - Beginner - - CSS - - HTML - - Learn - - Комментарии - - Обучение - - Свойство - - Структура - - значения - - отступ - - селектор - - сокращение -translation_of: Learn/CSS/First_steps/How_CSS_is_structured ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/CSS/First_steps/Getting_started", "Learn/CSS/First_steps/How_CSS_works", "Learn/CSS/First_steps")}}
- -

Теперь, когда у вас есть представление о том, чем является CSS, и о его основах, настало время посмотреть немного глубже в структуру самого языка. Нам уже встречались многие из обсуждаемых здесь концепций; вы можете вернуться к этому, чтобы разобраться, если вы обнаружите какие-либо более поздние концепции запутанными.

- - - - - - - - - - - - -
Необходимые знания:Базовая компьютерная грамотность, Базовое програмное обеспечение, базовые знания работа с файлами, и базовые знания HTML (статья Введение в HTML), и знание о том Как работает CSS
Задача:Подробно узнать основные синтаксические структуры CSS.
- -

Применение CSS к вашему HTML

- -

Первое, что мы рассмотрим, это три метода применения CSS к документу.

- -

Внешняя таблица стилей

- -

В статье ​Начало работы с CSS мы связывали внешнюю таблицу стилей с нашей страницей. Это самый распространенный и полезный способ крепления CSS к документу, так вы можете привязать CSS сразу к нескольким страницам, что позволяет стилизовать их всё с той же таблицей стилей. В большинстве случаев различные страницы сайта будут выглядеть почти так же, поэтому вы можете использовать один и тот же набор правил для основного вида.

- -

Внешняя таблица стилей - это когда у вас есть CSS отдельным файлом с расширением .css, и ссылка на него из HTML-элемента <link>:

- -
<!DOCTYPE html>
-<html>
-  <head>
-    <meta charset="utf-8">
-    <title>Я пробую писать CSS</title>
-    <link rel="stylesheet" href="styles.css">
-  </head>
-  <body>
-    <h1>Привет!</h1>
-    <p>Это мой первый опыт в CSS</p>
-  </body>
-</html>
- -

Файл CSS может выглядеть следующим образом:

- -
h1 {
-  color: blue;
-  background-color: yellow;
-  border: 1px solid black;
-}
-
-p {
-  color: red;
-}
- -

Атрибут href элемента {{htmlelement("link")}} должен ссылаться на файл в файловой системе.

- -

В приведенном выше примере файл CSS находится в той же папке, что и HTML-документ, но вы можете поместить его куда-нибудь ещё и настроить относительный путь, например:

- -
<!-- Файл находится внутри под-директории styles, находящейся в текущей директории -->
-<link rel="stylesheet" href="styles/style.css">
-
-<!-- Файл — внутри под-директории styles внутри под-под-директории general и так далее -->
-<link rel="stylesheet" href="styles/general/style.css">
-
-<!-- Вверх на один уровень в директории, затем направиться в под-директорию styles -->
-<link rel="stylesheet" href="../styles/style.css">
- -

Внутренняя таблица стилей

- -

Внутренняя таблица стилей, где у вас нет внешнего файла CSS, но вместо этого CSS помещён внутри элемента {{htmlelement("style")}}, содержащейся внутри HTML {{htmlelement("head")}}.

- -

Таким образом, HTML будет выглядеть вот так:

- -
<!DOCTYPE html>
-<html>
-  <head>
-    <meta charset="utf-8">
-    <title>Я пробую писать CSS</title>
-    <style>
-      h1 {
-        color: blue;
-        background-color: yellow;
-        border: 1px solid black;
-      }
-
-      p {
-        color: red;
-      }
-    </style>
-  </head>
-  <body>
-    <h1>Привет!</h1>
-    <p>Это мой первый опыт в CSS</p>
-  </body>
-</html>
- -

Это может быть полезно в некоторых обстоятельствах (возможно, вы работаете с системой управления контентом, где вы не можете изменить CSS-файлы непосредственно), но это менее эффективно, чем внешние таблицы стилей: CSS будет необходимо прописывать отдельно для каждой страницы и изменять, если требуются изменения.

- -

Встроенные стили

- -

Встроенные стили являются правилами CSS, которые влияют только на один элемент, содержащиеся в атрибуте style:

- -
<!DOCTYPE html>
-<html>
-  <head>
-    <meta charset="utf-8">
-    <title>Я пробую писать CSS</title>
-  </head>
-  <body>
-    <h1 style="color: blue;background-color: yellow;border: 1px solid black;">Привет!</h1>
-    <p style="color:red;">Это мой первый опыт в CSS</p>
-  </body>
-</html>
- -

Пожалуйста, не делайте этого! Это очень плохо для технического обслуживания (вам, возможно, придётся обновить одну и ту же информацию несколько раз в одном документе), а также смешивает ваши презентационные данные CSS с структурной информацией HTML, что делает код трудным для чтения и понимания. Хранение различных типов кода отделено делает работу гораздо более лёгкой для всех, кто работает над кодом.

- -

Есть несколько мест, где встроенные стили являются более распространенными или даже желательными. Вам, возможно, придется прибегнуть к использованию их, если ваша рабочая среда сильно ограничена (возможно, ваша CMS позволяет редактировать только HTML-тело). Вы также увидите, как они использовали много в HTML электронной почте, чтобы получить совместимость с таким количеством почтовых клиентов, со скольким это возможно.

- -

Игра с CSS в этой статье

- -

Существует много возможностей, чтобы поиграть с CSS в этой статье. Для этого мы рекомендуем создать новый каталог / папку на вашем компьютере и внутри него создать копии следующих двух файлов:

- -

index.html:

- -
<!DOCTYPE html>
-<html lang="ru">
-  <head>
-    <meta charset="utf-8">
-    <title>Я пробую писать CSS</title>
-    <link rel="stylesheet" href="styles.css">
-  </head>
-  <body>
-
-    <p>Пишите сюда свой код</p>
-
-  </body>
-</html>
- -

styles.css:

- -
/* Пишите сюда свой код */
-
-p {
-  color: red;
-}
- -

Затем, когда вы столкнетесь с CSS и захотите поэкспериментировать со стилями, измените содержимое <body> HTML-документа и начинайте добавлять CSS-стили внутри вашего файла CSS.

- -

Если вы не используете систему, в которой вы можете легко создавать файлы, вы можете вместо этого использовать интерактивный редактор ниже чтобы экспериментировать.

- -

{{EmbedGHLiveSample("css-examples/learn/getting-started/experiment-sandbox.html", '100%', 800)}} 

- -

Читайте дальше и получайте удовольствие!

- -

Селекторы

- -

Говоря о CSS, нельзя не упомянуть о селекторах, о некоторых типах которых мы уже говорили в руководстве Начало работы с CSS. Селектор — это то, как мы обозначаем что-либо в нашем HTML-документе, чтобы стилизовать его. Если стиль не применился, то это, скорее всего, потому, что селектор в таблицах стилей не совпал с тем, что в HTML-документе.

- -

Каждое CSS-правило начинается с одного или нескольких селекторов, отделяемых друг от друга запятыми, чтобы дать понять браузеру, к чему применять стили. В следующем примере перечислены стандартные селекторы:

- -
h1  /* это селектор тегов */
-a:link  /* это селектор ссылок */
-.manythings  /* это селектор классов (классы применяются тогда, когда необходимо применить правило к нескольким элементам) */
-#onething  /* это селектор идентификаторов (они применяются, когда правило относится к одному элементу) */
-*  /* уневерсальный селектор */
-.box p  /* селектор потомков */
-.box p:first-child  /* селектор потомков + селектор псевдоклассов */
-h1, h2, .intro  /* пречисление селекторов */
-
- -
-

Примечание: Вы узнаете больше о селекторах в руководстве CSS-селекторы в следующем модуле.

-
- -

Спецификация

- -

Иногда может случаться такое, что два селектора будут относиться к одному и тому же элементу HTML. Смотрите: в примере ниже я задал правило для элемента p — он будет синим; также я задал класс, который сделает элемент красным:

- -
.special {
-  color: red;
-}
-
-p {
-  color: blue;
-}
- -

А теперь допустим, что в нашем HTML-коде у нас есть абзац p с классом special. Оба правила могут быть добавлены: так какое же одержит верх? Как вы думаете, какого цвета будет надпись?

- -
<p class="special">Какого же я цвета?</p>
- -

В языке CSS есть правила, которые определяют, какое правило "выиграет" в случае подобного столкновения — они называются каскадами, или спецификациями. В примере ниже мы задали два правила для селектора p, но в итоге текст будет синим: объвление, делающее надпись синей, появилось позже того, которое делает её красной. Это каскад в действии.

- -
p {
-  color: red;
-}
-
-p {
-  color: blue;
-}
- -

А в примере с селектором класса и селектором тега победит селектор класса — даже если он объявлен раньше.

- -

Попрактикуйтесь сами — добавьте два правила для параграфа p { ... } в вашу таблицу стилей. Затем добавьте класс к одному элементу p и попробуйте применить к нему какой-нибудь стиль.

- -

Понимание каскадов, или правил, улучшается с практикой. В статье Каскад и наследование я хорошенько объясню, как определить уровень спецификации. А пока что запомните, что иногда CSS не применяется так, как вы того хотели бы, так как у чего-то в таблице стилей больший уровень спецификации.

- -

Свойства и значения

- -

Если говорить в общем, CSS строится на двух его составляющих:

- -
-
Свойства 
-
Определяют, какую характеристику вы желаете изменить (например, font-size, width, background-color).
-
- -
-
Значения 
-
Это величина свойства, определяющая, как и/или насколько вы желаете изменить свойство.
-
- -

На изображении внизу выделены свойство и его значение. Здесь свойство — color, а его значение — blue.

- -

A declaration highlighted in the CSS

- -

Свойство вкупе со значением называется CSS-объявлением. CSS-объявления помещаются внутри блока объявлений CSS. Ниже показан наш CSS-код с выделенным блоком объявлений.

- -

A highlighted declaration block

- -

Наконец блок объявлений воссоединяется с селекторами, образуя CSS-правила. Наше изображение содержит два правила — одно для селектора h1, другое для селектора p. Правило для h1 выделено.

- -

The rule for h1 highlighted

- -

Установление значений для CSS-свойств — вот суть языка CSS. Движок CSS определяет, какие объявления применять к каждому элементу на странице, чтобы соответствующим образом размещать и стилизовать его. Необходимо запомнить, что и свойства, и значения чувствительны к регистру. Пара свойство–значение разделяется двоеточием (:).

- -

Попробуйте подобрать нужные значения к следующим свойствам, а свойства добавить в ваш код:

- - - -
-

Важно: Если свойство или значение не определено, то объявление считается недействительным — и будет попросту проигнорировано.

-
- -
-

Важно: В CSS (и прочих веб-стандартах) американское написание является стандартом. Например, color надо всегда писать color; британский вариант colour не будет работать.

-
- -

Функции

- -

Чаще всего значения принимают форму числа или ключевого слова; существуют способы создавать функции для значений. Для примера можно взять функцию calc(). Она позволяет вам совершать лёгкие математические вычисления внутри CSS, например:

- -
-
<div class="outer"><div class="box">The inner box is 90% - 30px.</div></div>
- -
.outer {
-  border: 5px solid black;
-}
-
-.box {
-  padding: 10px;
-  width: calc(90% - 30px);
-  background-color: rebeccapurple;
-  color: white;
-}
-
- -

В результате получим это:

- -

{{EmbedLiveSample('calc_example', '100%', 200)}}

- -

Функция состоит из названия и скобок, внутри который помещается выражение с допустимыми для данной функции знаками. В примере выше я задал значение ширины блока равной 90% внешнего блока минус 30px. Не могу же я сказать, чему равны 90% блока?!

- -

В следующем примере будут различные значения для свойства {{cssxref("<transform>")}} rotate().

- -
-
<div class="box"></div>
- -
.box {
-  margin: 30px;
-  width: 100px;
-  height: 100px;
-  background-color: rebeccapurple;
-  transform: rotate(0.8turn)
-}
-
- -

Результат этого кода будет:

- -

{{EmbedLiveSample('transform_example', '100%', 200)}}

- -

Найдите несколько значений для следующих свойств, а свойства добавьте в ваш файл:

- - - -

@правила

- -

До сих пор не сталкивались мы с правилами @rules (произносится как эт-рулс, от английского "at-rules"). Это особые правила, дающие CSS инструкции, как вести себя. У некоторых правил @rules простые названия и значения. Чтобы, к примеру, импортировать ещё одну таблицу стилей в основной CSS-файл, нужно использовать @import:

- -
@import 'styles2.css';
- -

Чаще других встречается @rules под названием @media: оно позволяет вам использовать медиа-запросы, чтобы применять CSS в определённых случаях, только если выполняются те или иные условия (например, при изменении размеров окна или при просмотре сайта с иного типа устройства).

- -

Ниже у нас CSS-файл, в котором значение заднего фона элемента <body> равно pink. Однако после мы добавили правило @media, которое делает задний фон элемента синим, при условии если ширина окна не менее 30em.

- -
body {
-  background-color: pink;
-}
-
-@media (min-width: 30em) {
-  body {
-    background-color: blue;
-  }
-}
- -

Вы столкнётесь и с другими правилами @rules в продолжение следующих уроков.

- -

Добавьте правило, которое изменяет стиль элемента, основываясь на ширине окна. Измените ширину окна, чтобы увидеть результат.

- -

Стенография

- -

Некоторые свойства вроде {{cssxref("font")}}, {{cssxref("background")}}, {{cssxref("padding")}}, {{cssxref("border")}} и {{cssxref("margin")}} называются стенографическими свойствами, — они позволяют установать несколько значений свойств в одной строке, ускоряя запись и делая её аккуратной.

- -

К примеру, это строка (комментарий не в счёт):

- -
/* В четырёхзначных стенографиях наподобие padding и margin значения добавляются
-   в порядке верх–право–низ–лево (по часовой стрелке сверху). В трёхзначных стенограммах
-   значения добавляются в порядке верх(низ)–право–лево.
-   В двузначных стенограммах значения добавляются
-   от верхнего/нижнего края к левому/правому краю */
-padding: 10px 15px 15px 5px;
- -

делает то же самое, что и эти четыре, вместе взятые:

- -
padding-top: 10px;
-padding-right: 15px;
-padding-bottom: 15px;
-padding-left: 5px;
-
- -

или эти:

- -
padding-block-start: 10px
-padding-inline-end: 15px;
-padding-block-end: 15px;
-padding-inline-start: 5px;
- -

в то время как строка:

- -
background: red url(bg-graphic.png) 10px 10px repeat-x fixed;
- -

делает то же, что и эти строки:

- -
background-color: red;
-background-image: url(bg-graphic.png);
-background-position: 10px 10px;
-background-repeat: repeat-x;
-background-scroll: fixed;
- -

Мы не будем проходить это сейчас — вы можете найти эти и многие другие стенографии в Руководстве по CSS.

- -

Добавьте вышеупоминутые объвления в ваш код. Попробуйте изменить значения и посмотреть на результат.

- -
-

Осторожно: Стенографии позволяют пропускать некоторые величины, и это может отразиться на результате недолжным образом.

-
- -

Комментарии

- -

Как и в HTML, вы можете делать комментарии, чтобы прояснить тот или иной отрывок кода.

- -

Комментарии в CSS начинаются с /* и окачиваются с */. В примере ниже я отметил комментариями различные разделы кода. Это очень полезно для навигации — комментарии легче искать.

- -
/* Работаю над основными элементами */
-/* -------------------------------------------------------------------------------------------- */
-body {
-  font: 1em/150% Helvetica, Arial, sans-serif;
-  padding: 1em;
-  margin: 0 auto;
-  max-width: 33em;
-}
-
-@media (min-width: 70em) {
-  /* Позволяет определить размер шрифта. На широких экранах
-     больше размер шрифта для удобства чтения */
-  body {
-    font-size: 130%;
-  }
-}
-
-h1 {font-size: 1.5em;}
-
-/* Работаю над элементами, вложенными в DOM  */
-/* -------------------------------------------------------------------------------------------- */
-div p, #id:first-line {
-  background-color: red;
-  background-style: none
-}
-
-div p{
-  margin: 0;
-  padding: 1em;
-}
-
-div p + p {
-  padding-top: 0;
-}
- -

Отделяя комментариями участки кода, не нуждающиеся в проверке, вы можете выискивать ошибку (если такая есть). Ниже я отделил правило для селектора .special.

- -
/*.special {
-  color: red;
-}*/
-
-p {
-  color: blue;
-}
- -

Добавьте комментарии в ваш CSS-код, чтобы приноровиться к ним.

- -

Отступы

- -

Под отступами подразумеваются пробелы, табуляция и перенос на новую строку. Как и в HTML, браузер будет стараться игнорировать большие отступы в CSS-коде; к тому же большие отступы пагубны для читаемости кода.

- -

В примере ниже каждое объявление (а также начало/окончание правила) находится на своей строке — это, возможно, наилучший вариант написания CSS-кода: он понятен и аккуратен:

- -
body {
-  font: 1em/150% Helvetica, Arial, sans-serif;
-  padding: 1em;
-  margin: 0 auto;
-  max-width: 33em;
-}
-
-@media (min-width: 70em) {
-  body {
-    font-size: 130%;
-  }
-}
-
-h1 {
-  font-size: 1.5em;
-}
-
-div p,
-#id:first-line {
-  background-color: red;
-  background-style: none
-}
-
-div p {
-  margin: 0;
-  padding: 1em;
-}
-
-div p + p {
-  padding-top: 0;
-}
-
- -

То же самое вы можете написать, не добавляя большие отступы, — коды идентичны; но я уверен, вы согласитесь, что это очень тяжело прочитать:

- -
body {font: 1em/150% Helvetica, Arial, sans-serif; padding: 1em; margin: 0 auto; max-width: 33em;}
-@media (min-width: 70em) { body {font-size: 130%;} }
-
-h1 {font-size: 1.5em;}
-
-div p, #id:first-line {background-color: red; background-style: none}
-div p {margin: 0; padding: 1em;}
-div p + p {padding-top: 0;}
-
- -

Как вы будете оформлять код — решать вам; хотя, работая в команде, вы обнаружите, что она придерживается тех правил форматирования, которые в ней утверждены.

- -

Внимательно делайте отступы в свойствах и значениях. К примеру, такие объявления будут работать:

- -
margin: 0 auto;
-padding-left: 10px;
- -

А такие объявления не действительны:

- -
margin: 0auto;
-padding- left: 10px;
- -

Всегда отделяйте друг от друга значения, а свойства пишите без пробелов через дефис.

- -

Добавьте отступы в ваш код и посмотрите, что повлияет на код, а что нет.

- -

Что дальше?

- -

Полезно знать, как браузер делает из HTML и CSS готовую страницу, поэтом следующая ваша статья — Как работает CSS — мы рассмотрим этот процесс.

- -

{{PreviousMenuNext("Learn/CSS/First_steps/Getting_started", "Learn/CSS/First_steps/How_CSS_works", "Learn/CSS/First_steps")}}

- -

В этом модуле

- -
    -
  1. Что такое CSS?
  2. -
  3. Начало работы с CSS
  4. -
  5. Как структурирован CSS
  6. -
  7. Как работает CSS
  8. -
  9. Использование ваших новых знаний
  10. -
diff --git "a/files/ru/learn/css/first_steps/\321\207\321\202\320\276_\321\202\320\260\320\272\320\276\320\265_css/index.html" "b/files/ru/learn/css/first_steps/\321\207\321\202\320\276_\321\202\320\260\320\272\320\276\320\265_css/index.html" deleted file mode 100644 index 6b5bdf8924..0000000000 --- "a/files/ru/learn/css/first_steps/\321\207\321\202\320\276_\321\202\320\260\320\272\320\276\320\265_css/index.html" +++ /dev/null @@ -1,130 +0,0 @@ ---- -title: Что такое CSS? -slug: Learn/CSS/First_steps/Что_такое_CSS -tags: - - Beginner - - CSS - - Learn - - Введение в CSS - - Начинающий - - Обучение - - Синтаксис - - Спецификации -translation_of: Learn/CSS/First_steps/What_is_CSS ---- -
{{LearnSidebar}}
- -
{{NextMenu("Learn/CSS/First_steps/Getting_started", "Learn/CSS/First steps")}}
- -

{{Glossary("CSS")}} (Каскадные таблицы стилей) позволяет создавать великолепно выглядящие веб-страницы, но как же это работает? Эта статья объясняет, что такое CSS, с помощью простого примера синтаксиса, а также охватывает некоторые ключевые термины о языке.

- - - - - - - - - - - - -
Требуемые знания:Базовые компьютерные знания, установка базового програмного обеспечения, базовые знания работа с файлами и базовые знания HTML  (Введение в HTML).
Задача:Узнать, что такое CSS.
- -

В модуле Основы HTML мы рассмотрели, что такое HTML и как он используется для разметки документов. Эти документы будут доступны для чтения в веб-браузере. Заголовки будут выглядеть больше, чем обычный текст, абзацы разбиваются на новую строку и будут иметь пространство между друг другом. Ссылки выделены цветом и подчеркнуты, чтобы отличить их от остального текста. То, что Вы видите, — это стили браузера по умолчанию — самые основные стили, которые браузер применяет к HTML, чтобы гарантировать, что он будет в основном читабельным, даже если автор страницы не указал явный стиль.

- -

- -

Тем не менее, интернет был бы скучным, если бы все сайты выглядели так. Используя CSS, Вы можете до мелочей контролировать, как элементы HTML выглядят в браузере, представляя вашу разметку, используя любой понравившийся Вам дизайн.

- -

Для чего нужен CSS?

- -

Как мы уже упоминали ранее, CSS — это язык для определения того, как документы представляются пользователям — как они оформляются, размещаются и т. д.

- -

Документ обычно представляет собой текстовый файл, структурированный с использованием языка разметки: {{Glossary("HTML")}} — самый распространенный язык разметки, но Вы также можете встретить другие языки разметки, такие как {{Glossary("SVG")}} или {{Glossary("XML")}}.

- -

Представление документа пользователю означает преобразование его в форму, используемую Вашей аудиторией. {{Glossary("browser","Browsers")}}, такие как {{Glossary("Mozilla Firefox","Firefox")}}, {{Glossary("Google Chrome","Chrome")}} или {{Glossary("Microsoft Edge","Edge")}} , предназначены для визуального представления документов, например, на экране компьютера, проектора или принтера.

- -
-

Примечание: Браузер иногда называют {{Glossary("User agent","user agent")}}, что в основном означает компьютерную программу, которая представляет человека внутри компьютерной системы. Браузеры — это основной тип пользовательского агента, о котором мы думаем, когда говорим о CSS, но он не единственный. Доступны и другие пользовательские агенты, например, те, которые преобразуют документы HTML и CSS в файлы PDF для печати.

-
- -

CSS может использоваться для очень простой стилизации текста документа, например, изменение цвета и размера заголовков и ссылок. Он может быть использован для создания макета, например, превращение одного столбца текста в макет с основной областью контента и боковой панелью для соответствующей информации. Это может даже использоваться для эффектов, таких как анимация. Посмотрите на ссылки в этом параграфе для конкретных примеров.

- -

Синтаксис CSS

- -

CSS — это язык на основе правил: Вы задаёте правила, определяющие группы стилей, которые должны применяться к определённым элементам или группам элементов на Вашей веб-странице. Например:

- -

«Я хочу, чтобы основной заголовок на моей странице отображался крупным красным текстом».

- -

В следующем коде показано очень простое правило CSS, которое будет соответствовать стилю, описанному выше:

- -
h1 {
-    color: red;
-    font-size: 5em;
-}
- -

Правило открывается с помощью {{Glossary("CSS Selector", "селектора")}} . Этот селектор выбирает HTML-элемент, который мы собираемся стилизовать. В этом случае мы используем заголовки первого уровня — ({{htmlelement("h1")}}).

- -

Затем у нас есть набор фигурных скобок { }. Внутри них будет один или несколько объявлений, которые принимают форму пары свойства и его значения. Каждая пара указывает свойство элемента(-ов), который(-е) мы выбираем, а затем значение, которое мы хотели бы присвоить свойству.

- -

Перед двоеточием у нас есть свойство, а после двоеточия — значение. CSS-{{Glossary("property/CSS","свойства")}} имеют разные допустимые значения в зависимости от того, какое свойство указывается. В нашем примере мы имеем свойство color, которое может принимать различные цветовые значения. У нас также есть свойство font-size. Это свойство может принимать различные значения размера, как и свойства.

- -

Таблица стилей CSS будет содержать много таких правил, написанных одно за другим.

- -
h1 {
-    color: red;
-    font-size: 5em;
-}
-
-p {
-    color: black;
-}
- -

Вы обнаружите, что Вы быстро изучаете некоторые значения, тогда как другие Вам нужно искать. Страницы отдельных свойств в MDN дают Вам быстрый способ поиска свойств и их значений, когда Вы забыли или хотите узнать, что ещё Вы можете использовать в качестве значения.

- -
-

Примечание: Вы можете найти ссылки на все страницы свойств CSS (вместе с другими функциями CSS), перечисленные в MDN Руководстве по CSS. Кроме того, Вы должны привыкнуть к поиску "MDN css-feature-name" в Вашем бразере, когда Вам нужно узнать больше информации о функции CSS. Например, попробуйте поискать «mdn color» и «mdn font-size»!

-
- -

CSS-модули

- -

Поскольку существует множество вещей, которые можно стилизовать с помощью CSS, язык разбит на модули. По мере изучения MDN Вы увидите ссылки на эти модули, а многие страницы документации организованы вокруг определенного модуля. Например, вы можете взглянуть на ссылку MDN в модуле Свойства фона и границ, чтобы узнать, какова его цель и какие различные свойства и другие функции он содержит. Вы также найдёте ссылки на спецификацию CSS, которая определяет технологию (см. ниже).

- -

На этом этапе вам не нужно слишком беспокоиться о том, как структурирован CSS, однако это может упростить поиск информации, если, например, вы знаете, что определённое свойство может быть найдено среди других похожих вещей, и поэтому, вероятно, в той же спецификации.

- -

Для конкретного примера давайте вернемся к модулю Свойства фона и границ — Вы можете подумать, что это логично для свойств background-color и border-color, которые будут определены в этом модуле. И Вы правы.

- -

Технические характеристики CSS

- -

Все технологии веб-стандартов (HTML, CSS, JavaScript и т. д.) определены в гигантских документах, называемых спецификациями, которые публикуются организациями по стандартизации (такие как {{glossary("W3C")}}, {{glossary("WHATWG")}}, {{glossary("ECMA")}} или {{glossary("Khronos")}}) и определяют, как эти технологии должны вести себя.

- -

CSS ничем не отличается — он разработан группой в W3C, которая называется CSS Working Group. Эта группа состоит из представителей производителей браузеров и других компаний, которые заинтересованы в CSS. Есть также другие люди, известные как приглашенные эксперты, которые выступают как независимые голоса; они не связаны с членами организации.

- -

Новые функции CSS разрабатываются или определяются рабочей группой CSS. Иногда потому, что конкретный браузер заинтересован в том, чтобы иметь какие-то возможности, иногда потому, что веб-дизайнеры и разработчики запрашивают функцию, а иногда потому, что сама рабочая группа определила требование. CSS постоянно развивается, появляются новые функции. Тем не менее, ключевым моментом в CSS является то, что все работают очень усердно, чтобы никогда не менять вещи таким образом, чтобы это сломало старые сайты. Веб-сайт, созданный в 2000 году, с использованием ограниченного CSS, доступного в то время, должен всё ещё использоваться в браузере сегодня!

- -

Как новичок в CSS, вполне вероятно, что Вы найдете CSS-спецификации ошеломляющими — они предназначены для инженеров, чтобы использовать их для реализации поддержки функций в пользовательских агентах, а не для веб-разработчиков, чтобы читать, чтобы понимать CSS. Многие опытные разработчики предпочитают обращаться к документации MDN или другим учебникам. Однако стоит знать, что они существуют, понимать взаимосвязь между используемым CSS, поддержкой браузера (см. ниже) и спецификациями.

- -

Поддержка браузера

- -

После того как CSS был указан, он будет полезен для разработки веб-страниц, только если один или несколько браузеров его реализовали. Это означает, что код был написан для превращения инструкции в нашем CSS-файле во что-то, что может быть выведено на экран. Мы рассмотрим этот процесс подробнее на уроке Как работает CSS. Это необычно для всех браузеров, чтобы реализовать функцию одновременно, и поэтому обычно есть пробел, где вы можете использовать некоторую часть CSS в одних браузерах, а не в других. По этой причине полезно проверять состояние реализации. На каждой странице свойств в MDN Вы можете видеть статус интересующего Вас свойства, чтобы Вы могли определить, сможете ли Вы использовать её на веб-сайте.

- -

Ниже приведена диаграмма данных для CSS свойства font-family:

- -

{{Compat("css.properties.font-family")}}

- -

Что дальше?

- -

Теперь, когда у вас есть некоторое представление о том, что такое CSS, давайте перейдем к Началу работы с CSS, где Вы можете начать писать CSS самостоятельно.

- -

{{NextMenu("Learn/CSS/First_steps/Getting_started", "Learn/CSS/First_steps")}}

- -

В этом модуле

- -
    -
  1. Что такое CSS?
  2. -
  3. Начало работы с CSS
  4. -
  5. Как структурирован CSS
  6. -
  7. Как работает CSS
  8. -
  9. Использование ваших новых знаний
  10. -
diff --git a/files/ru/learn/css/howto/css_faq/index.html b/files/ru/learn/css/howto/css_faq/index.html new file mode 100644 index 0000000000..cecfb92b82 --- /dev/null +++ b/files/ru/learn/css/howto/css_faq/index.html @@ -0,0 +1,182 @@ +--- +title: Common CSS questions +slug: Web/CSS/Common_CSS_Questions +translation_of: Learn/CSS/Howto/CSS_FAQ +--- +

Why doesn't my CSS, which is valid, render correctly?

+ +

Браузер использует декларацию DOCTYPE чтобы выбрать, как именно отображать документ - в форме, более совместимой с современными стандартами или в форме,  которую будут поддерживать старые браузеры. Правильное использование декларациии DOCTYPE в начале вашего HTML кода повлияет на совместимость с современными стандартами веб браузеров.

+ +

У современных браузеров есть два режима отображения веб-страниц:

+ + + +

Gecko-based browsers, have a third Almost Standards Mode that has only a few minor quirks.

+ +

This is a list of the most commonly used DOCTYPE declarations that will trigger Standards or Almost Standards mode:

+ +
<!DOCTYPE html> /* This is the HTML5 doctype. Given that each modern browser uses an HTML5
+                   parser, this is the recommended doctype */
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
+"http://www.w3.org/TR/html4/loose.dtd">
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+ +

Why doesn't my CSS, which is valid, render at all?

+ +

To be applied, a CSS stylesheet must be served with a text/css MIME type. If the Web server doesn't serve it with this type, it won't be applied.

+ +

What is the difference between id and class?

+ +

HTML elements can have an id and/or class attribute. The id attribute assigns a name to the element it is applied to, and for valid markup, there can be only one element with that name. The class attribute assigns a class name to the element, and that name can be used on many elements within the page. CSS allows you to apply styles to particular id and/or class names.
+
+ Use an id-specific style when you want to restrict the applied styling rules to one specific block or element. This style will only be used by the element with that particular id.
+
+ Use a class-specific style when you want to apply the styling rules to many blocks and elements within the page.

+ +

Stylesheets with fewer rules are usually more performant. It is therefore recommended to use classes as much as possible, and to reserve the use of id for specific uses (like to connect label and form elements or for styling elements that must be semantically unique).

+ +

See CSS selectors

+ +

How do I restore the default value of a property?

+ +

Initially CSS didn't provide a "default" keyword and the only way to restore the default value of a property is to explicitly re-declare that property.

+ +

This has changed with CSS 2; the keyword initial is now a valid value for a CSS property. It resets it to its default value, which is defined in the CSS specification of the given property.

+ +

How do I derive one style from another?

+ +

CSS does not allow one style to be defined in terms of another. (See Eric Meyer's note about the Working Group's stance). However, assigning multiple classes to a single element can provide the same effect.

+ +

How do I assign multiple classes to an element?

+ +

HTML elements can be assigned multiple classes by listing the classes in the class attribute, with a blank space to separate them.

+ +
<style type="text/css">
+.news { background: black; color: white; }
+.today { font-weight: bold; }
+</style>
+
+<div class="news today">
+... content of today's news ...
+</div>
+
+ +

If the same property is declared in both rules, the conflict is resolved first through specificity, then according to the order of the CSS declarations. The order of classes in the class attribute is not relevant.

+ +

Why don't my style rules work properly?

+ +

Style rules that are syntactically correct may not apply in certain situations. You can use DOM Inspector's CSS Style Rules view to debug problems of this kind, but the most frequent instances of ignored style rules are listed below.

+ +

HTML elements hierarchy

+ +

The way CSS styles are applied to HTML elements depends also on the elements hierarchy. It is important to remember that a rule applied to a descendent overrides the style of the parent, in spite of any specificity or priority of CSS rules.

+ +
.news { color: black; }
+.corpName { font-weight: bold; color: red; }
+
+<!-- news item text is black, but corporate name is red and in bold -->
+<div class="news">
+   (Reuters) <span class="corpName">General Electric</span> (GE.NYS) announced on Thursday...
+</div>
+
+ +

In case of complex HTML hierarchies, if a rule seems to be ignored, check if the element is inside another element with a different style.

+ +

Explicitly re-defined style rule

+ +

In CSS stylesheets, order is important. If you define a rule and then you re-define the same rule, the last definition is used.

+ +
#stockTicker { font-weight: bold; }
+.stockSymbol { color: red; }
+/*  other rules             */
+/*  other rules             */
+/*  other rules             */
+.stockSymbol { font-weight: normal; }
+
+<!-- most text is in bold, except "GE", which is red and not bold -->
+<div id="stockTicker">
+   NYS: <span class="stockSymbol">GE</span> +1.0 ...
+</div>
+
+ +

To avoid this kind of error, try to define rules only once for a certain selector, and group all rules belonging to that selector.

+ +

Use of a shorthand property

+ +

Using shorthand properties for defining style rules is good because it uses a very compact syntax. Using shorthand with only some attributes is possible and correct, but it must be remembered that undeclared attributes are automatically reset to default. This means that a previous rule for a single attribute could be implicitly overridden.

+ +
#stockTicker { font-size: 12px; font-family: Verdana; font-weight: bold; }
+.stockSymbol { font: 14px Arial; color: red; }
+
+<div id="stockTicker">
+   NYS: <span class="stockSymbol">GE</span> +1.0 ...
+</div>
+
+ +

In the previous example the problem occurred on rules belonging to different elements, but it could happen also for the same element, because rule order is important.

+ +
#stockTicker {
+   font-weight: bold;
+   font: 12px Verdana;  /* font-weight is now normal */
+}
+
+ +

Use of the * selector

+ +

The * wildcard selector refers to any element, and it has to be used with particular care.

+ +
body * { font-weight: normal; }
+#stockTicker { font: 12px Verdana; }
+.corpName { font-weight: bold; }
+.stockUp { color: red; }
+
+<div id="section">
+   NYS: <span class="corpName"><span class="stockUp">GE</span></span> +1.0 ...
+</div>
+
+ +

In this example the body * selector applies the rule to all elements inside body, at any hierarchy level, including the .stockUp class. So font-weight: bold; applied to the .corpName class is overridden by font-weight: normal; applied to all elements in the body.

+ +

The use of the * selector should be minimized as it is a slow selector, especially when not used as the first element of a selector. Its use should be avoided as much as possible.

+ +

Specificity in CSS

+ +

When multiples rules apply to a certain element, the rule chosen depends on its style specificity. Inline style (in HTML style attributes) comes first, followed by ID selectors, then class selectors and eventually element-name selectors.

+ +
div { color: black; }
+#orange { color: orange; }
+.green { color: green; }
+
+<div id="orange" class="green" style="color: red;">This is red</div>
+
+ +

The rules are more complicated when the selector has multiple parts. More detailed information about how selector specificity is calculated can be found in the CSS 2.1 Specification chapter 6.4.3.

+ +

What do the -moz-*, -ms-*, -webkit-*, -o-* and -khtml-* properties do?

+ +

These properties, called prefixed properties, are extensions to the CSS standard. They are used to use experimental and non-standard features without polluting the regular namespace, preventing future incompatibilities to arise when the standard is extended.

+ +

The use of such properties on production websites is not recommended. If nevertheless needed, you are hinted to make a plan for the website evolution: these prefixed properties can be modified or even suppressed when the standard evolves.

+ +

Please see the Mozilla CSS Extensions page for more information on the Mozilla-prefixed CSS properties.

+ +

How does z-index relate to positioning?

+ +

The z-index property specifies the stack order of elements.

+ +

An element with a higher z-index/stack order is always in front of an element with a lower z-index/stack order.

+ +

Z-index will only work on elements that have a specified position (position:absolute, position:relative, or position:fixed).

diff --git a/files/ru/learn/css/howto/index.html b/files/ru/learn/css/howto/index.html new file mode 100644 index 0000000000..105c7f0a97 --- /dev/null +++ b/files/ru/learn/css/howto/index.html @@ -0,0 +1,86 @@ +--- +title: Использование CSS для решения общих проблем +slug: Learn/CSS/Как +translation_of: Learn/CSS/Howto +--- +

Следующие ссылки указывают на решения общих повседневных проблем, вам придется решать их с помощью CSS.

+ +

Примеры и использование

+ + + +

Необычное или передовые технологии

+ +

Beyond the basics, CSS is allows very advanced design techniques. These articles help you tackle the hardest use cases you may face.

+ +

Общие

+ + + +

Дополнительные эффекты

+ + + +

Разметка

+ + + +

Смотрите также

+ +

CSS FAQ — A collection of smaller bits of information, covering a variety of topics from debugging to selector usage.

diff --git a/files/ru/learn/css/introduction_to_css/ponimanie_osnov_css/index.html b/files/ru/learn/css/introduction_to_css/ponimanie_osnov_css/index.html deleted file mode 100644 index 9009c684d8..0000000000 --- a/files/ru/learn/css/introduction_to_css/ponimanie_osnov_css/index.html +++ /dev/null @@ -1,123 +0,0 @@ ---- -title: Понимание основ CSS -slug: Learn/CSS/Introduction_to_CSS/Ponimanie_osnov_CSS -translation_of: Learn/CSS/Building_blocks/Fundamental_CSS_comprehension ---- -
{{LearnSidebar}}
- -
{{PreviousMenu("Learn/CSS/Introduction_to_CSS/Debugging_CSS", "Learn/CSS/Introduction_to_CSS")}}
- -

Вы многое прошли в этом модуле, и должно быть вас посетило это прекрасное чувство, что дошли до конца! Последний шаг перед тем, как двигаться дальше, это попытка пройти проверку по материалам модуля — это включает в себя ряд соответствующих упражнений, которые должны быть выполнены для того, чтобы создать заключительный проект — визитка, карточка игрока, профиль в социльной сети.

- - - - - - - - - - - - -
Предварительно:Перед попыткой пройти проверку вы должны проработать все статьи в этом модуля.
Цель:Проверка понимания основной теории, синтаксиса и техник CSS.
- -

Отправной пункт

- -

Чтобы начать проверку, вы должны:

- - - -
-

Примечание: Вместо этого вы можете использовать для проверки такие сайты как  JSBin или Thimble. Вы можете скопировать HTML и заполнить CSS в одном из этих онлайн редакторов и использовать этот URL чтобы указать элементу <img> файл изображения. Если используемый онлайн-редактор не имеет отдельной панели для CSS, вы можете поместить его в элемент <style> в заголовке документа.

-
- -

Краткое описание проекта

- -

Вам предоставили некоторый исходный HTML и изображение, и нужно написать необходимые CSS-правила, чтобы стилизовать это в маленькую онлайн-визитку, которая может, возможно, стать картой игрока или профилем в социальных сетях. Следующие разделы описывают, что вам нужно сделать.

- -

Первоначальные настройки:

- - - -

Позаботимся о селекторах и наборах правил, предоставленных в файле CSS:

- - - -

Какие новые наборы правил надо написать:

- - - -
-

Примечание: Имейте в виду, что второй набор правил устанавливает font-size: 10px; для элемента<html> — это означает, что для любых потомков <html> em будет равен 10px, а не 16px, как это задано по умолчанию. (Это, конечно, при условии, что у потомков, о которых идет речь, нет предков, находящихся в иерархии между ними и <html>, на которых установлен другой размер шрифта. Это может повлиять на необходимые значения, хотя в этом простом примере это не проблема).

-
- -

Другие вещи для размышления:

- - - -

Советы и подсказки

- - - -

Образец

- -

На следующем снимке экрана показан образец того, как должен выглядеть готовый дизайн:

- -

A view of the finished business card, show a reader header and footer, and a darker center panel containing the main details and image.

- -

Проверка

- -

Если вы проходите эту проверку в рамках организованного курса, у вас должна быть возможность отдать свою работу своему учителю/наставнику для оценки. Если вы самообучаетесь, то вы можете получить руководство по оценке достаточно простым путем: спросив в теме обсуждения об этом упражнении, или в канале #mdn IRC на Mozilla IRC. Но сначала попробуйте выполнить упражнение — вы ничего не выиграете путем обмана!

- -

{{PreviousMenu("Learn/CSS/Introduction_to_CSS/Debugging_CSS", "Learn/CSS/Introduction_to_CSS")}}

- -

В этом модуле

- - diff --git a/files/ru/learn/css/styling_text/styling_lists/index.html b/files/ru/learn/css/styling_text/styling_lists/index.html new file mode 100644 index 0000000000..b749acb5cc --- /dev/null +++ b/files/ru/learn/css/styling_text/styling_lists/index.html @@ -0,0 +1,389 @@ +--- +title: Стилизация списков +slug: Learn/CSS/Styling_text/Стилизация_списков +translation_of: Learn/CSS/Styling_text/Styling_lists +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/CSS/Styling_text/Fundamentals", "Learn/CSS/Styling_text/Styling_links", "Learn/CSS/Styling_text")}}
+ +

Списки, по-большому счету, ведут себя также как любой другой текст, но существуют некоторые специфичные натройки CSS, о которых вы должны знать. В этой статье они все описываются.

+ + + + + + + + + + + + +
Требования: +

Базовая компьютерная грамотность, основы HTML (изучите Введение в HTML), основы CSS (изучите Введение в CSS), CSS основы по тексту и шрифтам.

+
Цель:Познакомиться с лучшими практиками и свойствами по стилизации списков.
+ +

Пример простого списка

+ +

Для начала, давайте взглянем на пример простого списка. В данной статье мы рассмотрим ненумерованный, нумерованный и описательный списки  — все они имеют аналогичные свойства стилизации, но некоторые имеют свои специальные свойства. Не стилизованный пример доступен на Github (проверьте также источник кода.)

+ +

HTML для нашего примера списка представлен ниже:

+ +
<h2>Shopping (unordered) list</h2>
+
+<p>Paragraph for reference, paragraph for reference, paragraph for reference,
+paragraph for reference, paragraph for reference, paragraph for reference.</p>
+
+<ul>
+  <li>Hummus</li>
+  <li>Pita</li>
+  <li>Green salad</li>
+  <li>Halloumi</li>
+</ul>
+
+<h2>Recipe (ordered) list</h2>
+
+<p>Paragraph for reference, paragraph for reference, paragraph for reference,
+paragraph for reference, paragraph for reference, paragraph for reference.</p>
+
+<ol>
+  <li>Toast pita, leave to cool, then slice down the edge.</li>
+  <li>Fry the halloumi in a shallow, non-stick pan, until browned on both sides.</li>
+  <li>Wash and chop the salad.</li>
+  <li>Fill pita with salad, hummus, and fried halloumi.</li>
+</ol>
+
+<h2>Ingredient description list</h2>
+
+<p>Paragraph for reference, paragraph for reference, paragraph for reference,
+paragraph for reference, paragraph for reference, paragraph for reference.</p>
+
+<dl>
+  <dt>Hummus</dt>
+  <dd>A thick dip/sauce generally made from chick peas blended with tahini, lemon juice, salt, garlic, and other ingredients.</dd>
+  <dt>Pita</dt>
+  <dd>A soft, slightly leavened flatbread.</dd>
+  <dt>Halloumi</dt>
+  <dd>A semi-hard, unripened, brined cheese with a higher-than-usual melting point, usually made from goat/sheep milk.</dd>
+  <dt>Green salad</dt>
+  <dd>That green healthy stuff that many of us just use to garnish kebabs.</dd>
+</dl>
+ +

Если вы перейдете к живому примеру прямо сейчас и изучите элемент списка используя инструменты разработчика браузера, то вы заметите несколько стилей установленных по умолчанию:

+ + + +

Управление интервалами списков

+ +

При оформлении списков, вам необходимо настроить их стили так, чтоб они сохраняли то же вертикальное расстояние, что и окружающие их элементы (такие как параграфы и изображения; иногда называемые вертикальным ритмом) и то же расстояние по горизонтали как и между собой (посмотреть законченный стилизированный пример на Github, а также найти исходный код.)

+ +

CSS, используемый для оформления текста и интервалов, выглядит следующим образом:

+ +
/* General styles */
+
+html {
+  font-family: Helvetica, Arial, sans-serif;
+  font-size: 10px;
+}
+
+h2 {
+  font-size: 2rem;
+}
+
+ul,ol,dl,p {
+  font-size: 1.5rem;
+}
+
+li, p {
+  line-height: 1.5;
+}
+
+/* Description list styles */
+
+
+dd, dt {
+  line-height: 1.5;
+}
+
+dt {
+  font-weight: bold;
+}
+
+dd {
+  margin-bottom: 1.5rem;
+}
+ + + +

Стили специфичные для списков

+ +

Теперь, рассмотрев общие методы интервалов для списков, давайте изучим некоторые специфичные спискам свойства. Существует три свойства, с которых вам надо начать знакомство, которые могут быть установлены для элементов {{htmlelement("ul")}} или {{htmlelement("ol")}}:

+ + + +

Стили маркеров

+ +

Как указано выше, свойство {{cssxref("list-style-type")}} позволяет вам устанавливать какой тип маркера использовать в качестве точек маркера. В нашем примере мы установили использование заглавных римских цифр в упорядоченном списке:

+ +
ol {
+  list-style-type: upper-roman;
+}
+ +

Это дает нам следующий вид:

+ +

an ordered list with the bullet points set to appear outside the list item text.

+ +

Вы можете найти гораздо больше опций, заглянув на справочную страницу {{cssxref ("list-style-type")}}.

+ +

Позиция маркера

+ +

Свойство {{cssxref("list-style-position")}} устанавливает будет ли появляться маркер внутри пунктов списка или снаружи перед началом каждого пункта. Значение по умолчанию — outside, которое заставляет маркеры находится снаружи пунктов списка, как видно выше.

+ +

Если вы установите значение на inside, то маркеры будут находиться внутри строк:

+ +
ol {
+  list-style-type: upper-roman;
+  list-style-position: inside;
+}
+ +

an ordered list with the bullet points set to appear inside the list item text.

+ +

Использование пользовательского изображения как маркер

+ +

Свойство {{cssxref("list-style-image")}} позволяет вам использовать пользовательское изображение в качестве вашего маркера. Синтаксис довольно прост:

+ +
ul {
+  list-style-image: url(star.svg);
+}
+ +

Однако это свойство немного ограничено с точки зрения управления позициями, размерами (и т.д.) маркеров. Вам лучше использовать семейство свойств {{cssxref ("background")}}, о которых вы узнаете намного больше в модуле Styling boxes. А пока вот вам образец для дегустации!

+ +

В нашем законченном примере мы оформили неупорядоченный список следующим образом (поверх того, что вы уже видели выше):

+ +
ul {
+  padding-left: 2rem;
+  list-style-type: none;
+}
+
+ul li {
+  padding-left: 2rem;
+  background-image: url(star.svg);
+  background-position: 0 0;
+  background-size: 1.6rem 1.6rem;
+  background-repeat: no-repeat;
+}
+ +

Мы сделали следующее:

+ + + +

Это дает нам следующий результат:

+ +

an unordered list with the bullet points set as little star images

+ +

короткая запись list-style

+ +

Эти три свойства упомянутые выше могут все быть заданы, используя лишь одну короткую запись свойства, {{cssxref("list-style")}}. Например, следующий CSS:

+ +
ul {
+  list-style-type: square;
+  list-style-image: url(example.png);
+  list-style-position: inside;
+}
+ +

Может быть заменен этим:

+ +
ul {
+  list-style: square url(example.png) inside;
+}
+ +

Значения могут быть перечислены в любом порядке, и вы можете использовать одно, два и все три (значения по умолчанию, использованные для свойств, которые не включены — disc, none, и outside). Если указаны и type и image, тип используется в качестве запасного варианта, если изображение по какой-либо причине не может быть загружено.

+ +

Контроль счета списка

+ +

Иногда вам может понадобиться вести счет в упорядоченном списке по-другому — например начинать с цифры отличной от 1, или считать в обратном порядке, или вести счет с шагом больше 1. HTML и CSS имеют несколько инструментов которые помогут с этим.

+ +

start

+ +

Атрибут {{htmlattrxref("start","ol")}} позволит вам начать счет списка с цифры отличной от 1. Например:

+ +
<ol start="4">
+  <li>Toast pita, leave to cool, then slice down the edge.</li>
+  <li>Fry the halloumi in a shallow, non-stick pan, until browned on both sides.</li>
+  <li>Wash and chop the salad.</li>
+  <li>Fill pita with salad, hummus, and fried halloumi.</li>
+</ol>
+ +

что даст вам такой результат:

+ +

{{ EmbedLiveSample('start', '100%', 150) }}

+ +

reversed

+ +

Атрибут {{htmlattrxref("reversed","ol")}} начнет отсчет по убыванию вместо возрастания. Например:

+ +
<ol start="4" reversed>
+  <li>Toast pita, leave to cool, then slice down the edge.</li>
+  <li>Fry the halloumi in a shallow, non-stick pan, until browned on both sides.</li>
+  <li>Wash and chop the salad.</li>
+  <li>Fill pita with salad, hummus, and fried halloumi.</li>
+</ol>
+ +

что даст вам такой результат:

+ +

{{ EmbedLiveSample('reversed', '100%', 150) }}

+ +
+

Обратите внимание: Если пунктов в списке в обратном списке больше, чем значение атрибута start, счет продолжится до нуля и далее отрицательные значения.

+
+ +

value

+ +

Атрибут {{htmlattrxref("value","ol")}} позволит вам установить специфичные цифровые значения к пунктам списка. Например:

+ +
<ol>
+  <li value="2">Toast pita, leave to cool, then slice down the edge.</li>
+  <li value="4">Fry the halloumi in a shallow, non-stick pan, until browned on both sides.</li>
+  <li value="6">Wash and chop the salad.</li>
+  <li value="8">Fill pita with salad, hummus, and fried halloumi.</li>
+</ol>
+ +

что даст вам такой результат:

+ +

{{ EmbedLiveSample('value', '100%', 150) }}

+ +
+

Обратите внимание: Даже если вы используете нечисловой {{cssxref("list-style-type")}}, вам все равно надо использовать эквивалентное цифровое значение в атрибуте value.

+
+ +

Активное изучение: Стилизация вложенного списка

+ +

В этой сессии активного изучения, мы хотим, чтобы вы взяли все что вы выучили выше и попробовали стилизовать вложенный список. Мы предоставили вам HTML и хотим, чтобы вы:

+ +
    +
  1. Задали неупорядоченному списку квадратные маркеры.
  2. +
  3. Задали пунктам неупорядоченного и упорядоченного списка 1,5 межстрочный интервал их размера шрифта.
  4. +
  5. Задали упорядоченному списку маркеры в виде строчных букв.
  6. +
  7. Не стесняйтесь играться с примерами списков столько сколько вам нравится, экспериментируя с типами маркеров, интервалами или со всем что вы найдете.
  8. +
+ +

Если вы допустите ошибку, вы всегда можете сделать сброс используя кнопку Reset. Если вы застрянете, нажмите кнопку Show solution чтобы посмотреть возможный ответ.

+ + + +

{{ EmbedLiveSample('Playable_code', 700, 800) }}

+ +

Смотрите также

+ +

Счетчики CSS предоставляют расширенные инструменты для настройки счета и оформления списков, но они довольно сложные. Мы рекомендуем изучить это, если вы захотите размяться. Смотрите:

+ + + +

Заключение

+ +

В плане стилизации списки сравнительно легко освоить, как только вы освоите несколько связанных базовых принципов и специфичные свойства. В следующей статье мы перейдем к методам стилизации ссылок.

+ +

{{PreviousMenuNext("Learn/CSS/Styling_text/Fundamentals", "Learn/CSS/Styling_text/Styling_links", "Learn/CSS/Styling_text")}}

+ +

В этом модуле

+ + diff --git a/files/ru/learn/css/styling_text/typesetting_a_homepage/index.html b/files/ru/learn/css/styling_text/typesetting_a_homepage/index.html new file mode 100644 index 0000000000..4f77ee31bc --- /dev/null +++ b/files/ru/learn/css/styling_text/typesetting_a_homepage/index.html @@ -0,0 +1,126 @@ +--- +title: 'Задание: Стилизирование школьного сайта' +slug: 'Learn/CSS/Styling_text/Задание:_Стилизирование_школьного_сайта' +translation_of: Learn/CSS/Styling_text/Typesetting_a_homepage +--- +
{{LearnSidebar}}
+ +
{{PreviousMenu("Learn/CSS/Styling_text/Web_fonts", "Learn/CSS/Styling_text")}}
+ +

В этой оценке мы проверим ваше понимание всех методов стилизации текста, которые мы рассмотрели в этом модуле дав вам задание стилизовать текст домашней страницы общественной школы. Вы можете просто развлечься, выполняя задание.

+ + + + + + + + + + + + +
Предварительные требования:Вы должны были изучить все статьи в этом модуле, прежде чем приступать к оценке.
Задача:Проверить понимание методов CSS по стилизации текста.
+ +

Отправная точка

+ +

Чтобы начать эту оценку, вам необходимо:

+ + + +

В качестве альтернативы, вы можете пользоваться сайтами как  JSBin или Glitch чтобы выполнить оценку. Вы можете вставить HTML и заполнить CSS в одном из этих онлайн-редакторов и использовать этот URL чтобы указать фоновое изображение. Если же онлайн-редактор, которым вы пользуетесь, не имеет отдельной CSS панели, тогда вводите его в элемент <style> в head документа.

+ +
+

Обратите внимание: Если вы застрянете, то попросите помощи — см. секцию {{anch("Оценка или дальнейшая помощь")}} в конце этой страницы.

+
+ +

Краткое описание проекта

+ +

Вам предоставлен некоторый "сырой" HTML для домашней страницы воображаемого общественного колледжа, плюс немного CSS который стилизует страницу в макет с тремя колонками и обеспечивает еще каким-то другим элементарным стилем. Вы должны писать ваш дополнительный CSS после комментария в низу CSS файла, чтобы убедиться, что вы с легкостью заметите части проделанные вами. Не переживайте если некоторые селекторы повторяются; мы отпустим вас с этим случаем.

+ +

Шрифты:

+ + + +

Общая стилизация текста:

+ + + +

Ссылки:

+ + + +

Списки:

+ + + +

Меню навигации:

+ + + +

Советы и подсказки

+ + + +

Пример

+ +

Следующий скриншот показывает пример того, как может выглядеть законченный дизайн.

+ +

+ +

Оценка или дальнейшая помощь

+ +

Если вы хотите, чтобы вашу работу оценили, или вы застряли и хотите попросить помощи:

+ +
    +
  1. Разместите свою работу в онлайн редакторе в которым можно поделиться работами в таком как CodePen, jsFiddle, или Glitch.
  2. +
  3. Напишите пост с просьбой оценки и/или помощи на MDN Discourse forum Learning category. Ваш пост должен включать: +
      +
    • Описательный заголовок такой как "Требуется оценка верстки домашней страницы общественный школы".
    • +
    • Детали о том, что вы уже попытались сделать и что бы вы хотели, чтобы мы сделали, например, если вы застряли и вам нужна помощь, либо вы хотите оценку.
    • +
    • Ссылку на онлайн редактор (как упомянуто выше в пункте 1) с примером, который нуждается в оценке или с которым нужна помощь. Это хорошая практика чтобы вникнуть — очень сложно помочь кому-либо с проблемным кодом если вы не видите их код.
    • +
    • Ссылку на актуальную задачу или страницу оценки, чтобы мы могли найти вопрос, по которому вам нужна помощь.
    • +
    +
  4. +
+ +

{{PreviousMenu("Learn/CSS/Styling_text/Web_fonts", "Learn/CSS/Styling_text")}}

+ +

В этом модуле

+ + diff --git a/files/ru/learn/css/styling_text/web_fonts/index.html b/files/ru/learn/css/styling_text/web_fonts/index.html new file mode 100644 index 0000000000..f6ca27747f --- /dev/null +++ b/files/ru/learn/css/styling_text/web_fonts/index.html @@ -0,0 +1,203 @@ +--- +title: Веб-шрифты +slug: Learn/CSS/Styling_text/Веб_шрифты +translation_of: Learn/CSS/Styling_text/Web_fonts +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/CSS/Styling_text/Styling_links", "Learn/CSS/Styling_text/Typesetting_a_homepage", "Learn/CSS/Styling_text")}}
+ +

В первой статье модуля, мы изучали основные функции CSS доступные для стилизации шрифтов и текста. В этой статье мы продвинемся дальше изучая веб-шрифты в деталях — они позволяют вам загружать пользовательские шрифты вместе с вашей веб-страницей, чтобы обеспечить более разнообразный, индивидуальный стиль текста.

+ + + + + + + + + + + + +
Предварительные требования:Основная компьютерная грамотность, основы HTML (изучите Введение в HTML), основы CSS (изучите Введение в CSS), Основы CSS текста и шрифта.
Задача: +

Изучить как применять веб-шрифты к веб-странице, использовать сторонний сервис или писать код самостоятельно.

+
+ +

Краткое повторение семейств шрифтов

+ +

Как мы рассматривали в Фундаментальной стилизации текста и шрифта, шрифты примененные к вашему HTML могут контролироваться при помощи свойства {{cssxref("font-family")}}. Оно принимает одно и более имен семейств шрифтов и браузер следует по списку пока не найдет тот шрифт, который является доступным в системе, под управлением которой он работает:

+ +
p {
+  font-family: Helvetica, "Trebuchet MS", Verdana, sans-serif;
+}
+ +

Эта система работает хорошо, но традиционно выбор шрифтов веб-разработчиков была ограниченной. Существует только горсть шрифтов которые вы можете гарантировать, что они являются доступными во всех распространенных системах — так называемые Безопасные веб-шрифты. Вы можете использовать стек шрифта для указания предпочтительных шрифтов, за которыми следует веб-безопасные альтернативы, за которыми следует системный шрифт по умолчанию, но это добавляет дополнительной работы с точки зрения тестирования, чтобы убедиться, что ваш дизайн выглядит хорошо с каждым из шрифтов и т. д.

+ +

Веб-шрифты

+ +

Но есть альтернатива, которая работает очень хорошо начиная с 6-ой версии IE. Веб-шрифты — это функция CSS позволяющая вам указывать файлы шрифтов, загружаемые вместе с вашим веб-сайтом по мере доступа к нему, это означает, что любой браузер, поддерживающий веб-шрифты, может иметь в своем распоряжении именно те шрифты, которые вы укажете. Замечательно! Требуемый синтаксис выглядит примерно так:

+ +

Во-первых, у вас есть блок {{cssxref("@font-face")}} в начале CSS, который указывает файл(-ы) шрифтов для загрузки:

+ +
@font-face {
+  font-family: "myFont";
+  src: url("myFont.woff");
+}
+ +

Ниже вы можете использовать имя семейства шрифтов, указанное внутри @font-face, чтобы применить свой собственный шрифт ко всему, что вам нравится, как обычно:

+ +
html {
+  font-family: "myFont", "Bitstream Vera Serif", serif;
+}
+ +

Синтаксис становится немного сложнее, чем этот; мы вдадимся в подробности ниже.

+ +

Есть две важные вещи, которые нужно иметь в виду о веб-шрифтах:

+ +
    +
  1. Браузеры поддерживают разные форматы шрифтов, поэтому вам будут нужны несколько форматов шрифтов для приличной кросс-браузерной поддержки. Например, большинство современных браузеров поддерживают WOFF/WOFF2 (Web Open Font Format versions 1 and 2), наиболее эффективный формат, но старые версии IE поддерживают только шрифты EOT (Embedded Open Type) и вам возможно понадобиться включать версию SVG шрифта для поддержки старых версий браузеров iPhone и Android. Ниже мы покажем вам как генерировать требуемый код.
  2. +
  3. В основном шрифты не бесплатны для использования. Вы должны платить за них и/или соблюдать другие условия лицензии такие как указание создателя шрифта в коде (или на вашем сайте). Вы не должны красть шрифты и использовать их без должного указания авторства.
  4. +
+ +
+

Обратите внимание: Веб-шрифты как технология поддерживается в Internet Explorer начиная с 4 версии!

+
+ +

Активное изучение: пример веб-шрифта

+ +

Имея это в виду, давайте создадим базовый пример веб-шрифта из первых принципов. Сложно продемонстрировать это на встроенном живом примере, поэтому вместо, мы бы хотели, чтобы следовали детальным шагам в секциях ниже, чтобы понять идею процесса

+ +

Вы должны использовать файлы web-font-start.html и web-font-start.css как отправную точку добавляя в них ваш код (см. живой пример). Сейчас сделайте копию этих файлов в новой директории на вашем компьютере. В файле web-font-start.css вы найдете некоторый минимальный CSS для работы с базовым макетом и версткой примера.

+ +

Поиск шрифтов

+ +

В этом примере мы будем использовать два веб-шрифта, один для заголовков, и другой для основного текста. Для того чтобы начать нам необходимо найти файлы шрифтов, которые содержат эти шрифты. Шрифты созданы шрифтовыми "цехами" и хранятся в разных форматах фалов. Как правило существует три типа сайтов, где вы можете получить шрифты:

+ + + +

Давайте найдем какие-нибудь шрифты! Отправляйтесь на Font Squirrel и выберите два шрифта — симпатичный интересный шрифт для заголовков (может быть симпатично выглядящий или шрифт с засечками) и немного менее кричащий и более читабельный шрифт для параграфов. Когда вы найдете каждый шрифт, нажмите на кнопку загрузки и сохраните файлы в той же директории, где ранее вы сохранили файлы HTML и CSS. Не имеет значения являются ли они TTF (True Type Fonts) или OTF (Open Type Fonts).

+ +

В любом случае распакуйте архив со шрифтом (веб-шрифты обычно распространяются в ZIP файлах, содержащих файл(-ы) шрифта и лицензионную информацию). Вы можете обнаружить несколько файлов шрифтов в упаковке (архиве) — некоторые шрифты распространяются как семейство с различными доступными вариантами, например тонкий, средний, жирный, курсив, тонкий курсив и т.д. В этом примере мы просто хотим, чтобы вы позаботились о едином файле шрифта для каждого варианта.

+ +
+

Обратите внимание: В разделе "Find fonts" в колонке справа, вы можете кликать по различным тегам и классификациям чтобы отфильтровать отображаемые варианты для выбора.

+
+ +

Генерация требуемого кода

+ +

Теперь вам надо будет сгенерировать требуемый код (и форматы шрифтов). Для каждого шрифта проделайте следующие шаги.

+ +
    +
  1. Убедитесь, что вы выполнили все лицензионные требования если вы собираетесь использовать это в коммерческих и/или веб проектах.
  2. +
  3. Перейдите на Fontsquirrel Webfont Generator.
  4. +
  5. Выгрузите два ваших файла шрифтов используя кнопку Upload Fonts.
  6. +
  7. Поставьте галочку отмеченную "Yes, the fonts I'm uploading are legally eligible for web embedding".
  8. +
  9. Кликните по Download your kit.
  10. +
+ +

После того как генератор закончит обработку, вы должны получить ZIP файл к загрузке — сохраните его в той же директории что и ваши HTML и CSS.

+ +

Реализация кода в вашем демо

+ +

Теперь распакуйте набор веб-шрифта, который вы только что сгенерировали. Внутри распакованной папки вы увидите три полезных элемента:

+ + + +

Для внедрения их в ваше демо следуйте следующим шагам:

+ +
    +
  1. Переименуйте распакованную папку на что-нибудь легкое и простое, например fonts.
  2. +
  3. Откройте файл stylesheet.css и скопируйте содержимое обоих @font-face блоков в ваш файл web-font-start.css — вам надо вставить их в самый верх, до любого вашего CSS, так как шрифты должны быть импортированы до того, как вы сможете использовать их на вашем сайте.
  4. +
  5. Каждый из функций url() указывает на файл шрифта который мы хотим импортировать в наш CSS — мы должны убедиться в том, что пути к файлам верные, поэтому добавьте fonts/ в начало каждого пути (настройте так как необходимо).
  6. +
  7. Теперь вы можете использовать эти шрифты в ваших стеках шрифтов, как и любой веб-безопасный или по умолчанию системный шрифт. Например:
  8. +
+ +
font-family: 'zantrokeregular', serif;
+ +

Вы должны получить демо-страницу с какими-то реализованными симпатичными шрифтами. Поскольку различные шрифты создаются в разных размерах, вам может понадобиться настроить размер, интервалы и т.д., чтобы отладить внешний вид.

+ +

+ +
+

Обратите внимание: Если у вас возникли какие-либо проблемы с тем что что-то не работает, смело сравнивайте файлы вашей версии с нашей законченной — см. web-font-finished.html и web-font-finished.css (run the finished example live).

+
+ +

Использование онлайн-сервиса шрифтов

+ +

Онлайн-сервисы шрифтов обычно хранят и обслуживают шрифты для вас, поэтому вам не надо переживать о написании @font-face кода и обычно необходимо просто вставить строчку или две простого кода в ваш сайт для того чтобы все работало. Примеры включают Adobe Fonts и Cloud.typography. Большинство из этих услуг на основе подписки, за исключением Google Fonts, полезный бесплатный сервис, особенно для быстрого тестирования работы и написания демо.

+ +

Большинство из этих сервисов легки в использовании, поэтому мы не будем освещать их в деталях. Давайте кратко рассмотрим Google fonts, чтобы вы понимали идею. И снова, используйте копии web-font-start.html и web-font-start.css в качестве отправной точки.

+ +
    +
  1. Отправляйтесь на Google Fonts.
  2. +
  3. Используйте фильтры с правой стороны чтобы отобразить типы шрифтов, которые вы хотите выбрать и выберите пару шрифтов, которые вам понравятся.
  4. +
  5. Для выбора семейства шрифтов нажмите на кнопку ⊕ рядом с ним.
  6. +
  7. Когда вы выбрали семейства шрифтов, нажмите на панель [Number] Families Selected в низу страницы.
  8. +
  9. На полученном экране, сначала вам надо скопировать строку показанного HTML кода и вставить ее в head вашего HTML файла. Вставьте его выше существующего {{htmlelement("link")}} элемента для того, чтоб шрифт импортировался до того, как вы начнете пользоваться им в вашем CSS.
  10. +
  11. Далее вам надо скопировать CSS-объявления, перечисленные в вашем CSS, чтобы применить пользовательские шрифты к вашему HTML.
  12. +
+ +
+

Обратите внимание: Вы можете найти законченные версии google-font.html и google-font.css, если вам необходимо сверить вашу работу с нашей (см. live).

+
+ +

@font-face более детально

+ +

Давайте исследуем тот @font-face синтаксис, который fontsquirrel сгенерировал для вас. Это то, как выглядит один из этих блоков:

+ +
@font-face {
+  font-family: 'ciclefina';
+  src: url('fonts/cicle_fina-webfont.eot');
+  src: url('fonts/cicle_fina-webfont.eot?#iefix') format('embedded-opentype'),
+         url('fonts/cicle_fina-webfont.woff2') format('woff2'),
+         url('fonts/cicle_fina-webfont.woff') format('woff'),
+         url('fonts/cicle_fina-webfont.ttf') format('truetype'),
+         url('fonts/cicle_fina-webfont.svg#ciclefina') format('svg');
+  font-weight: normal;
+  font-style: normal;
+}
+ +

Это называется "пуленепробиваемым @font-face синтаксисом", после публикации Пола Айриша (Paul Irish), с самого начала, когда @font-face начал получать популярность (Bulletproof @font-face Syntax). Давайте пройдемся по нему, чтобы посмотреть, что он делает:

+ + + +
+

Обратите внимание: Вы также можете указать определенные значения {{cssxref("font-variant")}} и {{cssxref("font-stretch")}} для ваших веб-шрифтов. В новых браузерах вы также можете указать значение {{cssxref("unicode-range")}}, который является конкретным диапазоном символов, которые вы хотите использовать из веб-шрифта — в поддерживающих браузерах, будут загружены только указанные символы, сохраняя от ненужной загрузки. Creating Custom Font Stacks with Unicode-Range от Drew McLellan предоставляет некоторые полезные идеи того как это использовать

+
+ +

Переменные шрифты

+ +

В браузерах доступна новая технология, называемая переменными шрифтами — это шрифты, которые позволяют включить в единственный файл много разных вариантов дизайнов шрифтов, вместо того чтобы иметь отдельные файлы шрифтов для каждой ширины, толщины или стиля. Они несколько продвинуты для нашего курса для начинающих, но если вы хотите расширить свои знания и посмотреть на них, прочитайте наше Руководство по переменным шрифтам.

+ +

Испытайте свои навыки!

+ +

Вы достигли конца этой статьи и уже испытали некоторые навыки в наших разделах активного изучения, но сможете ли вы вспомнить самую важную информацию продвигаясь дальше? Вы можете найти задание для проверки того что вы усвоили информацию к конце модуля — см. Задание: стилизация школьного сайта.

+ +

Заключение

+ +

Теперь, когда вы ознакомились с нашими статьями об основах стилизации текста, пришло время проверить ваше понимание нашей оценкой модуля «Задание: стилизация школьного сайта».

+ +

{{PreviousMenuNext("Learn/CSS/Styling_text/Styling_links", "Learn/CSS/Styling_text/Typesetting_a_homepage", "Learn/CSS/Styling_text")}}

+ +

В этом модуле

+ + diff --git "a/files/ru/learn/css/styling_text/\320\262\320\265\320\261_\321\210\321\200\320\270\321\204\321\202\321\213/index.html" "b/files/ru/learn/css/styling_text/\320\262\320\265\320\261_\321\210\321\200\320\270\321\204\321\202\321\213/index.html" deleted file mode 100644 index f6ca27747f..0000000000 --- "a/files/ru/learn/css/styling_text/\320\262\320\265\320\261_\321\210\321\200\320\270\321\204\321\202\321\213/index.html" +++ /dev/null @@ -1,203 +0,0 @@ ---- -title: Веб-шрифты -slug: Learn/CSS/Styling_text/Веб_шрифты -translation_of: Learn/CSS/Styling_text/Web_fonts ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/CSS/Styling_text/Styling_links", "Learn/CSS/Styling_text/Typesetting_a_homepage", "Learn/CSS/Styling_text")}}
- -

В первой статье модуля, мы изучали основные функции CSS доступные для стилизации шрифтов и текста. В этой статье мы продвинемся дальше изучая веб-шрифты в деталях — они позволяют вам загружать пользовательские шрифты вместе с вашей веб-страницей, чтобы обеспечить более разнообразный, индивидуальный стиль текста.

- - - - - - - - - - - - -
Предварительные требования:Основная компьютерная грамотность, основы HTML (изучите Введение в HTML), основы CSS (изучите Введение в CSS), Основы CSS текста и шрифта.
Задача: -

Изучить как применять веб-шрифты к веб-странице, использовать сторонний сервис или писать код самостоятельно.

-
- -

Краткое повторение семейств шрифтов

- -

Как мы рассматривали в Фундаментальной стилизации текста и шрифта, шрифты примененные к вашему HTML могут контролироваться при помощи свойства {{cssxref("font-family")}}. Оно принимает одно и более имен семейств шрифтов и браузер следует по списку пока не найдет тот шрифт, который является доступным в системе, под управлением которой он работает:

- -
p {
-  font-family: Helvetica, "Trebuchet MS", Verdana, sans-serif;
-}
- -

Эта система работает хорошо, но традиционно выбор шрифтов веб-разработчиков была ограниченной. Существует только горсть шрифтов которые вы можете гарантировать, что они являются доступными во всех распространенных системах — так называемые Безопасные веб-шрифты. Вы можете использовать стек шрифта для указания предпочтительных шрифтов, за которыми следует веб-безопасные альтернативы, за которыми следует системный шрифт по умолчанию, но это добавляет дополнительной работы с точки зрения тестирования, чтобы убедиться, что ваш дизайн выглядит хорошо с каждым из шрифтов и т. д.

- -

Веб-шрифты

- -

Но есть альтернатива, которая работает очень хорошо начиная с 6-ой версии IE. Веб-шрифты — это функция CSS позволяющая вам указывать файлы шрифтов, загружаемые вместе с вашим веб-сайтом по мере доступа к нему, это означает, что любой браузер, поддерживающий веб-шрифты, может иметь в своем распоряжении именно те шрифты, которые вы укажете. Замечательно! Требуемый синтаксис выглядит примерно так:

- -

Во-первых, у вас есть блок {{cssxref("@font-face")}} в начале CSS, который указывает файл(-ы) шрифтов для загрузки:

- -
@font-face {
-  font-family: "myFont";
-  src: url("myFont.woff");
-}
- -

Ниже вы можете использовать имя семейства шрифтов, указанное внутри @font-face, чтобы применить свой собственный шрифт ко всему, что вам нравится, как обычно:

- -
html {
-  font-family: "myFont", "Bitstream Vera Serif", serif;
-}
- -

Синтаксис становится немного сложнее, чем этот; мы вдадимся в подробности ниже.

- -

Есть две важные вещи, которые нужно иметь в виду о веб-шрифтах:

- -
    -
  1. Браузеры поддерживают разные форматы шрифтов, поэтому вам будут нужны несколько форматов шрифтов для приличной кросс-браузерной поддержки. Например, большинство современных браузеров поддерживают WOFF/WOFF2 (Web Open Font Format versions 1 and 2), наиболее эффективный формат, но старые версии IE поддерживают только шрифты EOT (Embedded Open Type) и вам возможно понадобиться включать версию SVG шрифта для поддержки старых версий браузеров iPhone и Android. Ниже мы покажем вам как генерировать требуемый код.
  2. -
  3. В основном шрифты не бесплатны для использования. Вы должны платить за них и/или соблюдать другие условия лицензии такие как указание создателя шрифта в коде (или на вашем сайте). Вы не должны красть шрифты и использовать их без должного указания авторства.
  4. -
- -
-

Обратите внимание: Веб-шрифты как технология поддерживается в Internet Explorer начиная с 4 версии!

-
- -

Активное изучение: пример веб-шрифта

- -

Имея это в виду, давайте создадим базовый пример веб-шрифта из первых принципов. Сложно продемонстрировать это на встроенном живом примере, поэтому вместо, мы бы хотели, чтобы следовали детальным шагам в секциях ниже, чтобы понять идею процесса

- -

Вы должны использовать файлы web-font-start.html и web-font-start.css как отправную точку добавляя в них ваш код (см. живой пример). Сейчас сделайте копию этих файлов в новой директории на вашем компьютере. В файле web-font-start.css вы найдете некоторый минимальный CSS для работы с базовым макетом и версткой примера.

- -

Поиск шрифтов

- -

В этом примере мы будем использовать два веб-шрифта, один для заголовков, и другой для основного текста. Для того чтобы начать нам необходимо найти файлы шрифтов, которые содержат эти шрифты. Шрифты созданы шрифтовыми "цехами" и хранятся в разных форматах фалов. Как правило существует три типа сайтов, где вы можете получить шрифты:

- - - -

Давайте найдем какие-нибудь шрифты! Отправляйтесь на Font Squirrel и выберите два шрифта — симпатичный интересный шрифт для заголовков (может быть симпатично выглядящий или шрифт с засечками) и немного менее кричащий и более читабельный шрифт для параграфов. Когда вы найдете каждый шрифт, нажмите на кнопку загрузки и сохраните файлы в той же директории, где ранее вы сохранили файлы HTML и CSS. Не имеет значения являются ли они TTF (True Type Fonts) или OTF (Open Type Fonts).

- -

В любом случае распакуйте архив со шрифтом (веб-шрифты обычно распространяются в ZIP файлах, содержащих файл(-ы) шрифта и лицензионную информацию). Вы можете обнаружить несколько файлов шрифтов в упаковке (архиве) — некоторые шрифты распространяются как семейство с различными доступными вариантами, например тонкий, средний, жирный, курсив, тонкий курсив и т.д. В этом примере мы просто хотим, чтобы вы позаботились о едином файле шрифта для каждого варианта.

- -
-

Обратите внимание: В разделе "Find fonts" в колонке справа, вы можете кликать по различным тегам и классификациям чтобы отфильтровать отображаемые варианты для выбора.

-
- -

Генерация требуемого кода

- -

Теперь вам надо будет сгенерировать требуемый код (и форматы шрифтов). Для каждого шрифта проделайте следующие шаги.

- -
    -
  1. Убедитесь, что вы выполнили все лицензионные требования если вы собираетесь использовать это в коммерческих и/или веб проектах.
  2. -
  3. Перейдите на Fontsquirrel Webfont Generator.
  4. -
  5. Выгрузите два ваших файла шрифтов используя кнопку Upload Fonts.
  6. -
  7. Поставьте галочку отмеченную "Yes, the fonts I'm uploading are legally eligible for web embedding".
  8. -
  9. Кликните по Download your kit.
  10. -
- -

После того как генератор закончит обработку, вы должны получить ZIP файл к загрузке — сохраните его в той же директории что и ваши HTML и CSS.

- -

Реализация кода в вашем демо

- -

Теперь распакуйте набор веб-шрифта, который вы только что сгенерировали. Внутри распакованной папки вы увидите три полезных элемента:

- - - -

Для внедрения их в ваше демо следуйте следующим шагам:

- -
    -
  1. Переименуйте распакованную папку на что-нибудь легкое и простое, например fonts.
  2. -
  3. Откройте файл stylesheet.css и скопируйте содержимое обоих @font-face блоков в ваш файл web-font-start.css — вам надо вставить их в самый верх, до любого вашего CSS, так как шрифты должны быть импортированы до того, как вы сможете использовать их на вашем сайте.
  4. -
  5. Каждый из функций url() указывает на файл шрифта который мы хотим импортировать в наш CSS — мы должны убедиться в том, что пути к файлам верные, поэтому добавьте fonts/ в начало каждого пути (настройте так как необходимо).
  6. -
  7. Теперь вы можете использовать эти шрифты в ваших стеках шрифтов, как и любой веб-безопасный или по умолчанию системный шрифт. Например:
  8. -
- -
font-family: 'zantrokeregular', serif;
- -

Вы должны получить демо-страницу с какими-то реализованными симпатичными шрифтами. Поскольку различные шрифты создаются в разных размерах, вам может понадобиться настроить размер, интервалы и т.д., чтобы отладить внешний вид.

- -

- -
-

Обратите внимание: Если у вас возникли какие-либо проблемы с тем что что-то не работает, смело сравнивайте файлы вашей версии с нашей законченной — см. web-font-finished.html и web-font-finished.css (run the finished example live).

-
- -

Использование онлайн-сервиса шрифтов

- -

Онлайн-сервисы шрифтов обычно хранят и обслуживают шрифты для вас, поэтому вам не надо переживать о написании @font-face кода и обычно необходимо просто вставить строчку или две простого кода в ваш сайт для того чтобы все работало. Примеры включают Adobe Fonts и Cloud.typography. Большинство из этих услуг на основе подписки, за исключением Google Fonts, полезный бесплатный сервис, особенно для быстрого тестирования работы и написания демо.

- -

Большинство из этих сервисов легки в использовании, поэтому мы не будем освещать их в деталях. Давайте кратко рассмотрим Google fonts, чтобы вы понимали идею. И снова, используйте копии web-font-start.html и web-font-start.css в качестве отправной точки.

- -
    -
  1. Отправляйтесь на Google Fonts.
  2. -
  3. Используйте фильтры с правой стороны чтобы отобразить типы шрифтов, которые вы хотите выбрать и выберите пару шрифтов, которые вам понравятся.
  4. -
  5. Для выбора семейства шрифтов нажмите на кнопку ⊕ рядом с ним.
  6. -
  7. Когда вы выбрали семейства шрифтов, нажмите на панель [Number] Families Selected в низу страницы.
  8. -
  9. На полученном экране, сначала вам надо скопировать строку показанного HTML кода и вставить ее в head вашего HTML файла. Вставьте его выше существующего {{htmlelement("link")}} элемента для того, чтоб шрифт импортировался до того, как вы начнете пользоваться им в вашем CSS.
  10. -
  11. Далее вам надо скопировать CSS-объявления, перечисленные в вашем CSS, чтобы применить пользовательские шрифты к вашему HTML.
  12. -
- -
-

Обратите внимание: Вы можете найти законченные версии google-font.html и google-font.css, если вам необходимо сверить вашу работу с нашей (см. live).

-
- -

@font-face более детально

- -

Давайте исследуем тот @font-face синтаксис, который fontsquirrel сгенерировал для вас. Это то, как выглядит один из этих блоков:

- -
@font-face {
-  font-family: 'ciclefina';
-  src: url('fonts/cicle_fina-webfont.eot');
-  src: url('fonts/cicle_fina-webfont.eot?#iefix') format('embedded-opentype'),
-         url('fonts/cicle_fina-webfont.woff2') format('woff2'),
-         url('fonts/cicle_fina-webfont.woff') format('woff'),
-         url('fonts/cicle_fina-webfont.ttf') format('truetype'),
-         url('fonts/cicle_fina-webfont.svg#ciclefina') format('svg');
-  font-weight: normal;
-  font-style: normal;
-}
- -

Это называется "пуленепробиваемым @font-face синтаксисом", после публикации Пола Айриша (Paul Irish), с самого начала, когда @font-face начал получать популярность (Bulletproof @font-face Syntax). Давайте пройдемся по нему, чтобы посмотреть, что он делает:

- - - -
-

Обратите внимание: Вы также можете указать определенные значения {{cssxref("font-variant")}} и {{cssxref("font-stretch")}} для ваших веб-шрифтов. В новых браузерах вы также можете указать значение {{cssxref("unicode-range")}}, который является конкретным диапазоном символов, которые вы хотите использовать из веб-шрифта — в поддерживающих браузерах, будут загружены только указанные символы, сохраняя от ненужной загрузки. Creating Custom Font Stacks with Unicode-Range от Drew McLellan предоставляет некоторые полезные идеи того как это использовать

-
- -

Переменные шрифты

- -

В браузерах доступна новая технология, называемая переменными шрифтами — это шрифты, которые позволяют включить в единственный файл много разных вариантов дизайнов шрифтов, вместо того чтобы иметь отдельные файлы шрифтов для каждой ширины, толщины или стиля. Они несколько продвинуты для нашего курса для начинающих, но если вы хотите расширить свои знания и посмотреть на них, прочитайте наше Руководство по переменным шрифтам.

- -

Испытайте свои навыки!

- -

Вы достигли конца этой статьи и уже испытали некоторые навыки в наших разделах активного изучения, но сможете ли вы вспомнить самую важную информацию продвигаясь дальше? Вы можете найти задание для проверки того что вы усвоили информацию к конце модуля — см. Задание: стилизация школьного сайта.

- -

Заключение

- -

Теперь, когда вы ознакомились с нашими статьями об основах стилизации текста, пришло время проверить ваше понимание нашей оценкой модуля «Задание: стилизация школьного сайта».

- -

{{PreviousMenuNext("Learn/CSS/Styling_text/Styling_links", "Learn/CSS/Styling_text/Typesetting_a_homepage", "Learn/CSS/Styling_text")}}

- -

В этом модуле

- - diff --git "a/files/ru/learn/css/styling_text/\320\267\320\260\320\264\320\260\320\275\320\270\320\265_colon__\321\201\321\202\320\270\320\273\320\270\320\267\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265_\321\210\320\272\320\276\320\273\321\214\320\275\320\276\320\263\320\276_\321\201\320\260\320\271\321\202\320\260/index.html" "b/files/ru/learn/css/styling_text/\320\267\320\260\320\264\320\260\320\275\320\270\320\265_colon__\321\201\321\202\320\270\320\273\320\270\320\267\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265_\321\210\320\272\320\276\320\273\321\214\320\275\320\276\320\263\320\276_\321\201\320\260\320\271\321\202\320\260/index.html" deleted file mode 100644 index 4f77ee31bc..0000000000 --- "a/files/ru/learn/css/styling_text/\320\267\320\260\320\264\320\260\320\275\320\270\320\265_colon__\321\201\321\202\320\270\320\273\320\270\320\267\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265_\321\210\320\272\320\276\320\273\321\214\320\275\320\276\320\263\320\276_\321\201\320\260\320\271\321\202\320\260/index.html" +++ /dev/null @@ -1,126 +0,0 @@ ---- -title: 'Задание: Стилизирование школьного сайта' -slug: 'Learn/CSS/Styling_text/Задание:_Стилизирование_школьного_сайта' -translation_of: Learn/CSS/Styling_text/Typesetting_a_homepage ---- -
{{LearnSidebar}}
- -
{{PreviousMenu("Learn/CSS/Styling_text/Web_fonts", "Learn/CSS/Styling_text")}}
- -

В этой оценке мы проверим ваше понимание всех методов стилизации текста, которые мы рассмотрели в этом модуле дав вам задание стилизовать текст домашней страницы общественной школы. Вы можете просто развлечься, выполняя задание.

- - - - - - - - - - - - -
Предварительные требования:Вы должны были изучить все статьи в этом модуле, прежде чем приступать к оценке.
Задача:Проверить понимание методов CSS по стилизации текста.
- -

Отправная точка

- -

Чтобы начать эту оценку, вам необходимо:

- - - -

В качестве альтернативы, вы можете пользоваться сайтами как  JSBin или Glitch чтобы выполнить оценку. Вы можете вставить HTML и заполнить CSS в одном из этих онлайн-редакторов и использовать этот URL чтобы указать фоновое изображение. Если же онлайн-редактор, которым вы пользуетесь, не имеет отдельной CSS панели, тогда вводите его в элемент <style> в head документа.

- -
-

Обратите внимание: Если вы застрянете, то попросите помощи — см. секцию {{anch("Оценка или дальнейшая помощь")}} в конце этой страницы.

-
- -

Краткое описание проекта

- -

Вам предоставлен некоторый "сырой" HTML для домашней страницы воображаемого общественного колледжа, плюс немного CSS который стилизует страницу в макет с тремя колонками и обеспечивает еще каким-то другим элементарным стилем. Вы должны писать ваш дополнительный CSS после комментария в низу CSS файла, чтобы убедиться, что вы с легкостью заметите части проделанные вами. Не переживайте если некоторые селекторы повторяются; мы отпустим вас с этим случаем.

- -

Шрифты:

- - - -

Общая стилизация текста:

- - - -

Ссылки:

- - - -

Списки:

- - - -

Меню навигации:

- - - -

Советы и подсказки

- - - -

Пример

- -

Следующий скриншот показывает пример того, как может выглядеть законченный дизайн.

- -

- -

Оценка или дальнейшая помощь

- -

Если вы хотите, чтобы вашу работу оценили, или вы застряли и хотите попросить помощи:

- -
    -
  1. Разместите свою работу в онлайн редакторе в которым можно поделиться работами в таком как CodePen, jsFiddle, или Glitch.
  2. -
  3. Напишите пост с просьбой оценки и/или помощи на MDN Discourse forum Learning category. Ваш пост должен включать: -
      -
    • Описательный заголовок такой как "Требуется оценка верстки домашней страницы общественный школы".
    • -
    • Детали о том, что вы уже попытались сделать и что бы вы хотели, чтобы мы сделали, например, если вы застряли и вам нужна помощь, либо вы хотите оценку.
    • -
    • Ссылку на онлайн редактор (как упомянуто выше в пункте 1) с примером, который нуждается в оценке или с которым нужна помощь. Это хорошая практика чтобы вникнуть — очень сложно помочь кому-либо с проблемным кодом если вы не видите их код.
    • -
    • Ссылку на актуальную задачу или страницу оценки, чтобы мы могли найти вопрос, по которому вам нужна помощь.
    • -
    -
  4. -
- -

{{PreviousMenu("Learn/CSS/Styling_text/Web_fonts", "Learn/CSS/Styling_text")}}

- -

В этом модуле

- - diff --git "a/files/ru/learn/css/styling_text/\321\201\321\202\320\270\320\273\320\270\320\267\320\260\321\206\320\270\321\217_\321\201\320\277\320\270\321\201\320\272\320\276\320\262/index.html" "b/files/ru/learn/css/styling_text/\321\201\321\202\320\270\320\273\320\270\320\267\320\260\321\206\320\270\321\217_\321\201\320\277\320\270\321\201\320\272\320\276\320\262/index.html" deleted file mode 100644 index b749acb5cc..0000000000 --- "a/files/ru/learn/css/styling_text/\321\201\321\202\320\270\320\273\320\270\320\267\320\260\321\206\320\270\321\217_\321\201\320\277\320\270\321\201\320\272\320\276\320\262/index.html" +++ /dev/null @@ -1,389 +0,0 @@ ---- -title: Стилизация списков -slug: Learn/CSS/Styling_text/Стилизация_списков -translation_of: Learn/CSS/Styling_text/Styling_lists ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/CSS/Styling_text/Fundamentals", "Learn/CSS/Styling_text/Styling_links", "Learn/CSS/Styling_text")}}
- -

Списки, по-большому счету, ведут себя также как любой другой текст, но существуют некоторые специфичные натройки CSS, о которых вы должны знать. В этой статье они все описываются.

- - - - - - - - - - - - -
Требования: -

Базовая компьютерная грамотность, основы HTML (изучите Введение в HTML), основы CSS (изучите Введение в CSS), CSS основы по тексту и шрифтам.

-
Цель:Познакомиться с лучшими практиками и свойствами по стилизации списков.
- -

Пример простого списка

- -

Для начала, давайте взглянем на пример простого списка. В данной статье мы рассмотрим ненумерованный, нумерованный и описательный списки  — все они имеют аналогичные свойства стилизации, но некоторые имеют свои специальные свойства. Не стилизованный пример доступен на Github (проверьте также источник кода.)

- -

HTML для нашего примера списка представлен ниже:

- -
<h2>Shopping (unordered) list</h2>
-
-<p>Paragraph for reference, paragraph for reference, paragraph for reference,
-paragraph for reference, paragraph for reference, paragraph for reference.</p>
-
-<ul>
-  <li>Hummus</li>
-  <li>Pita</li>
-  <li>Green salad</li>
-  <li>Halloumi</li>
-</ul>
-
-<h2>Recipe (ordered) list</h2>
-
-<p>Paragraph for reference, paragraph for reference, paragraph for reference,
-paragraph for reference, paragraph for reference, paragraph for reference.</p>
-
-<ol>
-  <li>Toast pita, leave to cool, then slice down the edge.</li>
-  <li>Fry the halloumi in a shallow, non-stick pan, until browned on both sides.</li>
-  <li>Wash and chop the salad.</li>
-  <li>Fill pita with salad, hummus, and fried halloumi.</li>
-</ol>
-
-<h2>Ingredient description list</h2>
-
-<p>Paragraph for reference, paragraph for reference, paragraph for reference,
-paragraph for reference, paragraph for reference, paragraph for reference.</p>
-
-<dl>
-  <dt>Hummus</dt>
-  <dd>A thick dip/sauce generally made from chick peas blended with tahini, lemon juice, salt, garlic, and other ingredients.</dd>
-  <dt>Pita</dt>
-  <dd>A soft, slightly leavened flatbread.</dd>
-  <dt>Halloumi</dt>
-  <dd>A semi-hard, unripened, brined cheese with a higher-than-usual melting point, usually made from goat/sheep milk.</dd>
-  <dt>Green salad</dt>
-  <dd>That green healthy stuff that many of us just use to garnish kebabs.</dd>
-</dl>
- -

Если вы перейдете к живому примеру прямо сейчас и изучите элемент списка используя инструменты разработчика браузера, то вы заметите несколько стилей установленных по умолчанию:

- - - -

Управление интервалами списков

- -

При оформлении списков, вам необходимо настроить их стили так, чтоб они сохраняли то же вертикальное расстояние, что и окружающие их элементы (такие как параграфы и изображения; иногда называемые вертикальным ритмом) и то же расстояние по горизонтали как и между собой (посмотреть законченный стилизированный пример на Github, а также найти исходный код.)

- -

CSS, используемый для оформления текста и интервалов, выглядит следующим образом:

- -
/* General styles */
-
-html {
-  font-family: Helvetica, Arial, sans-serif;
-  font-size: 10px;
-}
-
-h2 {
-  font-size: 2rem;
-}
-
-ul,ol,dl,p {
-  font-size: 1.5rem;
-}
-
-li, p {
-  line-height: 1.5;
-}
-
-/* Description list styles */
-
-
-dd, dt {
-  line-height: 1.5;
-}
-
-dt {
-  font-weight: bold;
-}
-
-dd {
-  margin-bottom: 1.5rem;
-}
- - - -

Стили специфичные для списков

- -

Теперь, рассмотрев общие методы интервалов для списков, давайте изучим некоторые специфичные спискам свойства. Существует три свойства, с которых вам надо начать знакомство, которые могут быть установлены для элементов {{htmlelement("ul")}} или {{htmlelement("ol")}}:

- - - -

Стили маркеров

- -

Как указано выше, свойство {{cssxref("list-style-type")}} позволяет вам устанавливать какой тип маркера использовать в качестве точек маркера. В нашем примере мы установили использование заглавных римских цифр в упорядоченном списке:

- -
ol {
-  list-style-type: upper-roman;
-}
- -

Это дает нам следующий вид:

- -

an ordered list with the bullet points set to appear outside the list item text.

- -

Вы можете найти гораздо больше опций, заглянув на справочную страницу {{cssxref ("list-style-type")}}.

- -

Позиция маркера

- -

Свойство {{cssxref("list-style-position")}} устанавливает будет ли появляться маркер внутри пунктов списка или снаружи перед началом каждого пункта. Значение по умолчанию — outside, которое заставляет маркеры находится снаружи пунктов списка, как видно выше.

- -

Если вы установите значение на inside, то маркеры будут находиться внутри строк:

- -
ol {
-  list-style-type: upper-roman;
-  list-style-position: inside;
-}
- -

an ordered list with the bullet points set to appear inside the list item text.

- -

Использование пользовательского изображения как маркер

- -

Свойство {{cssxref("list-style-image")}} позволяет вам использовать пользовательское изображение в качестве вашего маркера. Синтаксис довольно прост:

- -
ul {
-  list-style-image: url(star.svg);
-}
- -

Однако это свойство немного ограничено с точки зрения управления позициями, размерами (и т.д.) маркеров. Вам лучше использовать семейство свойств {{cssxref ("background")}}, о которых вы узнаете намного больше в модуле Styling boxes. А пока вот вам образец для дегустации!

- -

В нашем законченном примере мы оформили неупорядоченный список следующим образом (поверх того, что вы уже видели выше):

- -
ul {
-  padding-left: 2rem;
-  list-style-type: none;
-}
-
-ul li {
-  padding-left: 2rem;
-  background-image: url(star.svg);
-  background-position: 0 0;
-  background-size: 1.6rem 1.6rem;
-  background-repeat: no-repeat;
-}
- -

Мы сделали следующее:

- - - -

Это дает нам следующий результат:

- -

an unordered list with the bullet points set as little star images

- -

короткая запись list-style

- -

Эти три свойства упомянутые выше могут все быть заданы, используя лишь одну короткую запись свойства, {{cssxref("list-style")}}. Например, следующий CSS:

- -
ul {
-  list-style-type: square;
-  list-style-image: url(example.png);
-  list-style-position: inside;
-}
- -

Может быть заменен этим:

- -
ul {
-  list-style: square url(example.png) inside;
-}
- -

Значения могут быть перечислены в любом порядке, и вы можете использовать одно, два и все три (значения по умолчанию, использованные для свойств, которые не включены — disc, none, и outside). Если указаны и type и image, тип используется в качестве запасного варианта, если изображение по какой-либо причине не может быть загружено.

- -

Контроль счета списка

- -

Иногда вам может понадобиться вести счет в упорядоченном списке по-другому — например начинать с цифры отличной от 1, или считать в обратном порядке, или вести счет с шагом больше 1. HTML и CSS имеют несколько инструментов которые помогут с этим.

- -

start

- -

Атрибут {{htmlattrxref("start","ol")}} позволит вам начать счет списка с цифры отличной от 1. Например:

- -
<ol start="4">
-  <li>Toast pita, leave to cool, then slice down the edge.</li>
-  <li>Fry the halloumi in a shallow, non-stick pan, until browned on both sides.</li>
-  <li>Wash and chop the salad.</li>
-  <li>Fill pita with salad, hummus, and fried halloumi.</li>
-</ol>
- -

что даст вам такой результат:

- -

{{ EmbedLiveSample('start', '100%', 150) }}

- -

reversed

- -

Атрибут {{htmlattrxref("reversed","ol")}} начнет отсчет по убыванию вместо возрастания. Например:

- -
<ol start="4" reversed>
-  <li>Toast pita, leave to cool, then slice down the edge.</li>
-  <li>Fry the halloumi in a shallow, non-stick pan, until browned on both sides.</li>
-  <li>Wash and chop the salad.</li>
-  <li>Fill pita with salad, hummus, and fried halloumi.</li>
-</ol>
- -

что даст вам такой результат:

- -

{{ EmbedLiveSample('reversed', '100%', 150) }}

- -
-

Обратите внимание: Если пунктов в списке в обратном списке больше, чем значение атрибута start, счет продолжится до нуля и далее отрицательные значения.

-
- -

value

- -

Атрибут {{htmlattrxref("value","ol")}} позволит вам установить специфичные цифровые значения к пунктам списка. Например:

- -
<ol>
-  <li value="2">Toast pita, leave to cool, then slice down the edge.</li>
-  <li value="4">Fry the halloumi in a shallow, non-stick pan, until browned on both sides.</li>
-  <li value="6">Wash and chop the salad.</li>
-  <li value="8">Fill pita with salad, hummus, and fried halloumi.</li>
-</ol>
- -

что даст вам такой результат:

- -

{{ EmbedLiveSample('value', '100%', 150) }}

- -
-

Обратите внимание: Даже если вы используете нечисловой {{cssxref("list-style-type")}}, вам все равно надо использовать эквивалентное цифровое значение в атрибуте value.

-
- -

Активное изучение: Стилизация вложенного списка

- -

В этой сессии активного изучения, мы хотим, чтобы вы взяли все что вы выучили выше и попробовали стилизовать вложенный список. Мы предоставили вам HTML и хотим, чтобы вы:

- -
    -
  1. Задали неупорядоченному списку квадратные маркеры.
  2. -
  3. Задали пунктам неупорядоченного и упорядоченного списка 1,5 межстрочный интервал их размера шрифта.
  4. -
  5. Задали упорядоченному списку маркеры в виде строчных букв.
  6. -
  7. Не стесняйтесь играться с примерами списков столько сколько вам нравится, экспериментируя с типами маркеров, интервалами или со всем что вы найдете.
  8. -
- -

Если вы допустите ошибку, вы всегда можете сделать сброс используя кнопку Reset. Если вы застрянете, нажмите кнопку Show solution чтобы посмотреть возможный ответ.

- - - -

{{ EmbedLiveSample('Playable_code', 700, 800) }}

- -

Смотрите также

- -

Счетчики CSS предоставляют расширенные инструменты для настройки счета и оформления списков, но они довольно сложные. Мы рекомендуем изучить это, если вы захотите размяться. Смотрите:

- - - -

Заключение

- -

В плане стилизации списки сравнительно легко освоить, как только вы освоите несколько связанных базовых принципов и специфичные свойства. В следующей статье мы перейдем к методам стилизации ссылок.

- -

{{PreviousMenuNext("Learn/CSS/Styling_text/Fundamentals", "Learn/CSS/Styling_text/Styling_links", "Learn/CSS/Styling_text")}}

- -

В этом модуле

- - diff --git "a/files/ru/learn/css/\320\272\320\260\320\272/index.html" "b/files/ru/learn/css/\320\272\320\260\320\272/index.html" deleted file mode 100644 index 105c7f0a97..0000000000 --- "a/files/ru/learn/css/\320\272\320\260\320\272/index.html" +++ /dev/null @@ -1,86 +0,0 @@ ---- -title: Использование CSS для решения общих проблем -slug: Learn/CSS/Как -translation_of: Learn/CSS/Howto ---- -

Следующие ссылки указывают на решения общих повседневных проблем, вам придется решать их с помощью CSS.

- -

Примеры и использование

- - - -

Необычное или передовые технологии

- -

Beyond the basics, CSS is allows very advanced design techniques. These articles help you tackle the hardest use cases you may face.

- -

Общие

- - - -

Дополнительные эффекты

- - - -

Разметка

- - - -

Смотрите также

- -

CSS FAQ — A collection of smaller bits of information, covering a variety of topics from debugging to selector usage.

diff --git a/files/ru/learn/discover_browser_developer_tools/index.html b/files/ru/learn/discover_browser_developer_tools/index.html deleted file mode 100644 index 8cd514efcd..0000000000 --- a/files/ru/learn/discover_browser_developer_tools/index.html +++ /dev/null @@ -1,172 +0,0 @@ ---- -title: Обзор инструментов разработки в браузерах -slug: Learn/Discover_browser_developer_tools -tags: - - Beginner - - Browser - - CSS - - CodingScripting - - Dev Tools - - HTML - - JavaScript - - Браузер - - Новичку - - Обучение -translation_of: Learn/Common_questions/What_are_browser_developer_tools ---- -
{{IncludeSubnav("/ru-RU/Learn")}}
- -

{{Previous("Learn/Getting_started_with_the_web")}}

- -
-

Каждый современный интернет-браузер оснащён мощными инструментами для веб-разработчика. Эти инструменты позволяют делать различные вещи, от изучения загруженных в настоящий момент HTML, CSS и JavaScript до отображения в каких ресурсах нуждается страница и как долго она будет загружаться. Эта статья научит Вас использовать базовые функции инструментов разработчика в Вашем браузере.

-
- -
-

Заметка: Прежде чем начать заниматься с примерами, откройте пример сайта для начинающих, с которым мы работали на предыдущих занятиях. Вам следует держать его открытым, чтобы выполнить описанные ниже действия.

-
- -

Как открыть инструменты веб-разработчика в Вашем браузере?

- -

Панель разработчика находится в нижней части Вашего браузера :

- -

- -

Как её отобразить? Есть три варианта:

- - - -

- -

Inspector: DOM обозреватель и CSS редактор

- -

По-умолчанию, в панели открывается вкладка Inspector, Вы можете увидеть это на скриншоте снизу. Этот инструмент позволяет Вам видеть, как HTML-код выглядит на странице в настоящем времени, также как CSS, который применён к каждому элементу на странице. Это также позволяет Вам в реальном времени редактировать как HTML, так и CSS. Внесённые изменения можно увидеть непосредственно в окне браузера.

- -

- -

Если Вы не видите Inspector,

- - - -

Обзор DOM inspector

- -

Для начала, попробуйте нажать правой кнопкой мыши (Ctrl+клик) по элементу HTML в DOM inspector и посмотрите на контекстное меню. Пункты меню могут различаться в разных браузерах, но важными из них являются одни и те же:

- -

- - - -

Попробуйте изменить что-нибудь через окно Inspector на Вашей странице прямо сейчас. Дважды кликните по элементу, или нажмите правой кнопкой мыши и выберите Править как HTML из контекстного меню. Вы можете сделать любые изменения, какие захотите, но Вы не сможете их сохранить.

- -

Обзор CSS редактора

- -

По-умолчанию, CSS редактор отображает CSS свойства применённые к текущему выбранному элементу:

- -

- -

Эти функции особенно удобны:

- - - -

Вы должно быть уже заметили другие вкладки в  CSS редакторе:

- - - -

Узнать больше

- -

Узнать больше об Inspector в различных браузерах:

- - - -

Консоль JavaScript 

- -

Консоль JavaScript невероятно полезный инструмент для отладки JavaScript, если он не работает, как ожидалось. Она позволяет Вам загружать JavaScript вопреки порядку загрузки скрипта в браузере, и докладывает об ошибках как только браузер пытается выполнить Ваш код. Для доступа к консоли из любого браузера просто нажмите на кнопку Console. (В Internet Explorer, нажмите Ctrl + 2.) Откроется окно, как показано ниже:

- -

- -

Чтобы понять, что происходит, попробуйте ввести фрагменты кода в консоль один за другим (и затем нажмите Enter):

- -
    -
  1. -
    alert('hello!');
    -
  2. -
  3. -
    document.querySelector('html').style.backgroundColor = 'purple';
    -
  4. -
  5. -
    var myImage = document.createElement('img');
    -myImage.setAttribute('src','https://farm4.staticflickr.com/3455/3372925208_e1f2aae4e3_b.jpg');
    -document.querySelector('h1').appendChild(myImage);
    -
  6. -
- -

Теперь попробуйте ввести следующую, неправильную версию кода и посмотрите, что из этого получится.

- -
    -
  1. -
    alert('hello!);
    -
  2. -
  3. -
    document.cheeseSelector('html').style.backgroundColor = 'purple';
    -
  4. -
  5. -
    var myImage = document.createElement('img');
    -myBanana.setAttribute('src','https://farm4.staticflickr.com/3455/3372925208_e1f2aae4e3_b.jpg');
    -document.querySelector('h1').appendChild(myImage);
    -
  6. -
- -

Вы увидите некоторые ошибки, которые сообщит Вам браузер. Зачастую эти ошибки выглядят довольно загадочно, но они должны быть довольно простыми, чтобы можно было выяснить проблему!

- -

Узнать больше

- -

Узнать больше о JavaScript консоли в различных браузерах:

- - diff --git a/files/ru/learn/forms/basic_native_form_controls/index.html b/files/ru/learn/forms/basic_native_form_controls/index.html new file mode 100644 index 0000000000..eae3fbb32d --- /dev/null +++ b/files/ru/learn/forms/basic_native_form_controls/index.html @@ -0,0 +1,690 @@ +--- +title: Стандартные виджеты форм +slug: Learn/HTML/Forms/Стандартные_виджеты_форм +translation_of: Learn/Forms/Basic_native_form_controls +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/HTML/Forms/How_to_structure_an_HTML_form", "Learn/HTML/Forms/Sending_and_retrieving_form_data", "Learn/HTML/Forms")}}
+ +

Сейчас мы детально изучим возможности различных виджетов форм, посмотрим, какие функции доступны для получения информации в различных представлениях. Это исчерпывающая статья, описывающая все доступные стандартные виджеты форм.

+ + + + + + + + + + + + +
Требования:Базовая компьютерная грамотность, базовое понимание HTML.
Цель:Понять, какие типы стандартных виджетов форм доступны в браузерах для сбора информации, как внедрять их, используя HTML.
+ +

Сейчас мы сосредоточимся на виджетах форм, встроенных в браузеры, но поскольку формы HTML остаюстся несколько ограниченными и особенности их реализации различаются для разных браузеров, веб-разработчики иногда создают собственные виджеты форм - прочтите статью Как создать собственную форму позже в данном модуле для более подробного изучения.

+ +
+

Note: Большая часть признаков обсуждаемых в этой статье имеют широкую поддержку в браузерах; мы отметим исключения из этого правила. Если вы хотите больше точных сведений, вам следует обратиться к HTML forms element reference, и в частости к нашей обширной ссылке <input> types.

+
+ +

Стандартные атрибуты

+ +

Многие элементы, используемые для определения виджетов форм, имеют собственные атрибуты. Однако, существует набор атрибутов, общих для всех элементов формы, которые предоставляют вам контроль над их виджетами. Вот список этих общих атрибутов:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Attribute nameDefault valueDescription
autofocus(false)Этот атрибут логического типа позволяет вам определить, должен ли элемент автоматически попадать в фокус при загрузке страницы, пока пользователь не изменит это, например, печатая в другом виджете. Этот атрибут может явно определяться только для одного элемента в документе, ассоциированного с формой.
disabled(false)Этот атрибут логического типа определяет, может ли пользователь взаимодействовать с элементом. Если этот атрибут не определён, то элемент наследует его значение от элемента-родителя. Если атрибут не определён, то по умолчанию пользователь может взаимодействовать с элементом.
formЭлемент формы, с которым ассоциирован виджет. Значением данного атрибута должен быть атрибут id элемента {{HTMLElement("form")}}  в том же документе. Теоретически, это позволяет вам помещать определение виджета за рамками элемента {{HTMLElement("form")}}. На практике, однако, не существует браузеров, поддерживающих данную функцию.
nameНазвание элемента; передаётся вместе с данными формы.
valueНачальное значение элемента.
+ +

Поля ввода текста

+ +

Текстовые поля {{htmlelement("input")}}  являются самыми базовыми виджетами форм. Эти поля наиболее удобны для пользовательского ввода различной информации. Однако, некоторые текстовые поля отличаются от данного и используются для специфических нужд. Мы уже видели нескольк простых примеров.

+ +
+

Note: HTML form text fields are simple plain text input controls. This means that you cannot use them to perform rich editing (bold, italic, etc.). All rich text editors you'll encounter out there are custom widgets created with HTML, CSS, and JavaScript.

+
+ +

Все текстовые поля имеют общие атрибуты:

+ + + +
+

Note: The {{htmlelement("input")}} element is special because it can be almost anything. By simply setting its type attribute, it can change radically, and it is used for creating most types of form widget including single line text fields, controls without text input, time and date controls, and buttons. However, there are some exceptions, like {{htmlelement("textarea")}} for multi-line inputs. Take careful note of these as you read the article.

+
+ +

Однострочные текстовые поля

+ +

Однострочные текстовые поля создаются с использованием элемента {{HTMLElement("input")}}  чей атрибут {{htmlattrxref("type","input")}} имеет значение text (если вы не поставите другое значение атрибута {{htmlattrxref("type","input")}}, text является значением по умолчанию). Значение text для этого атрибута является возвратным, если значение которое вы определили для {{htmlattrxref("type","input")}} неизвестно браузеру (например, если вы определили type="date" а браузер не поддерживает выбор даты).

+ +
+

Note: Вы можете найти примеры всех типов однострочных текстовых полей на GitHub at single-line-text-fields.html (see it live also).

+
+ +

Пример базового одностраничного текстового поля:

+ +
<input type="text" id="comment" name="comment" value="I'm a text field">
+ +

Однострочное текстовое поле имеет только одно настоящее ограничение: если вы вводите текст с разрывами строки, браузер удаляет эти разрывы строк перед отправкой данных.

+ +

Screenshots of single line text fields on several platforms.

+ +

HTML5 enhances the basic single line text field by adding special values for the {{htmlattrxref("type","input")}} attribute. Those values still turn an {{HTMLElement("input")}} element into a single line text field but they add a few extra constraints and features to the field.

+ +

E-mail address field

+ +

Этот тип поля устонавливается со значеним email для атрибута {{htmlattrxref("type","input")}}:

+ +
<input type="email" id="email" name="email" multiple>
+ +

Когда используется этот type, пользователь должен ввести в поле валидный адрес электронной почты; любое другое содержание будет отображено браузером при отправке формы как ошибка. Заметьте, что это проверка ошибок на стороне клиента, выполняемая браузером:

+ +

An invalid email input showing the message Please enter an email address.

+ +

It's also possible to let the user type several e-mail addresses into the same input (separated by commas) by including the {{htmlattrxref("multiple","input")}} attribute.

+ +

On some devices (especially on mobile), a different virtual keypad might be presented that is more suitable for entering email addresses.

+ +
+

Note: You can find out more about form validation in the article Form data validation.

+
+ +

Password field

+ +

This type of field is set using the value password for the {{htmlattrxref("type","input")}} attribute:

+ +
<input type="password" id="pwd" name="pwd">
+ +

It doesn't add any special constraints to the entered text, but it does obscure the value entered into the field (e.g. with dots or asterisks) so it can't be read by others.

+ +

Keep in mind this is just a user interface feature; unless you submit your form securely, it will get sent in plain text, which is bad for security — a malicious party could intercept your data and steal passwords, credit card details, or whatever else you've submitted. The best way to protect users from this is to host any pages involving forms over a secure connection (i.e. at an https:// ... address), so the data is encrypted before it is sent.

+ +

Modern browsers recognize the security implications of sending form data over an insecure connection, and have implemented warnings to deter users from using insecure forms. For more information on what Firefox implements, see Insecure passwords.

+ +

Search field

+ +

This type of field is set by using the value search for the {{htmlattrxref("type","input")}} attribute:

+ +
<input type="search" id="search" name="search">
+ +

The main difference between a text field and a search field is how the browser styles it — often, search fields are rendered with rounded corners, and/or given an "x" to press to clear the entered value. However, there is another added feature worth noting: their values can be automatically saved to be auto completed across multiple pages on the same site.

+ +

Screenshots of search fields on several platforms.

+ +

Phone number field

+ +

This type of field is set using tel as the value of the {{htmlattrxref("type","input")}} attribute:

+ +
<input type="tel" id="tel" name="tel">
+ +

Due to the wide variety of phone number formats around the world, this type of field does not enforce any constraints on the value entered by a user (this can include letters, etc.). This is primarily a semantic difference, although on some devices (especially on mobile), a different virtual keypad might be presented that is more suitable for entering phone numbers.

+ +

URL field

+ +

This type of field is set using the value url for the {{htmlattrxref("type","input")}} attribute:

+ +
<input type="url" id="url" name="url">
+ +

It adds special validation constraints to the field, with the browser reporting an error if invalid URLs are entered.

+ +
Note: Just because the URL is well-formed doesn't necessarily mean that it refers to a location that actually exists.
+ +
+

Note: Fields that have special constraints and are in error prevent the form from being sent; in addition, they can be styled so as to make the error clear. We will discuss this in detail in the article: Data form validation.

+
+ +

Multi-line text fields

+ +

A multi-line text field is specified using a {{HTMLElement("textarea")}} element, rather than using the {{HTMLElement("input")}} element.

+ +
<textarea cols="30" rows="10"></textarea>
+ +

The main difference between a textarea and a regular single line text field is that users are allowed to type text that includes hard line breaks (i.e. pressing return).

+ +

Screenshots of multi-lines text fields on several platforms.

+ +
+

Note: You can find an example of a multi-line text field on GitHub at multi-line-text-field.html (see it live also). Have a look at it, and notice how in most browsers, the text area is given a drag handle on the bottom right to allow the user to resize it. This resizing ability can be turned off by setting the text area's {{cssxref("resize")}} property to none using CSS.

+
+ +

{{htmlelement("textarea")}} also accepts a few extra attributes to control its rendering across several lines (in addition to several others):

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
Attributes for the {{HTMLElement("textarea")}} element
Attribute nameDefault valueDescription
{{htmlattrxref("cols","textarea")}}20The visible width of the text control, in average character widths.
{{htmlattrxref("rows","textarea")}}The number of visible text lines for the control.
{{htmlattrxref("wrap","textarea")}}softIndicates how the control wraps text. Possible values are: hard or soft
+ +

Note that the {{HTMLElement("textarea")}} element is written a bit differently from the {{HTMLElement("input")}} element. The {{HTMLElement("input")}} element is an empty element, which means that it cannot contain any child elements. On the other hand, the {{HTMLElement("textarea")}} element is a regular element that can contain text content children.

+ +

There are two key related points to note here:

+ + + + + +

Drop-down widgets are a simple way to let users select one of many options without taking up much space in the user interface. HTML has two forms of drop down content: the select box, and autocomplete box. In both cases the interaction is the same — once the control is activated, the browser displays a list of values the user can select between.

+ +
+

Note: You can find examples of all the drop-down box types on GitHub at drop-down-content.html (see it live also).

+
+ +

Select box

+ +

A select box is created with a {{HTMLElement("select")}} element with one or more {{HTMLElement("option")}} elements as its children, each of which specifies one of its possible values.

+ +
<select id="simple" name="simple">
+  <option>Banana</option>
+  <option>Cherry</option>
+  <option>Lemon</option>
+</select>
+ +

If required, the default value for the select box can be set using the {{htmlattrxref("selected","option")}} attribute on the desired {{HTMLElement("option")}} element — this option is then preselected when the page loads. The {{HTMLElement("option")}} elements can also be nested inside {{HTMLElement("optgroup")}} elements to create visually associated groups of values:

+ +
<select id="groups" name="groups">
+  <optgroup label="fruits">
+    <option>Banana</option>
+    <option selected>Cherry</option>
+    <option>Lemon</option>
+  </optgroup>
+  <optgroup label="vegetables">
+    <option>Carrot</option>
+    <option>Eggplant</option>
+    <option>Potato</option>
+  </optgroup>
+</select>
+ +

Screenshots of single line select box on several platforms.

+ +

If an {{HTMLElement("option")}} element is set with a value attribute, that attribute's value is sent when the form is submitted. If the value attribute is omitted, the content of the {{HTMLElement("option")}} element is used as the select box's value.

+ +

On the {{HTMLElement("optgroup")}} element, the label attribute is displayed before the values, but even if it looks somewhat like an option, it is not selectable.

+ +

Multiple choice select box

+ +

By default, a select box only lets the user select a single value. By adding the {{htmlattrxref("multiple","select")}} attribute to the {{HTMLElement("select")}} element, you can allow users to select several values, by using the default mechanism provided by the operating system (e.g. holding down Cmd/Ctrl and clicking multiple values).

+ +

Note: In the case of multiple choice select boxes, the select box no longer displays the values as drop-down content — instead, they are all displayed at once in a list.

+ +
<select multiple id="multi" name="multi">
+  <option>Banana</option>
+  <option>Cherry</option>
+  <option>Lemon</option>
+</select>
+ +

Screenshots of multi-lines select box on several platforms.

+ +
Note: All browsers that support the {{HTMLElement("select")}} element also support the {{htmlattrxref("multiple","select")}} attribute on it.
+ +

Autocomplete box

+ +

You can provide suggested, automatically-completed values for form widgets using the {{HTMLElement("datalist")}} element with some child {{HTMLElement("option")}} elements to specify the values to display.

+ +

The data list is then bound to a text field (usually an <input> element) using the {{htmlattrxref("list","input")}} attribute.

+ +

Once a data list is affiliated with a form widget, its options are used to auto-complete text entered by the user; typically, this is presented to the user as a drop-down box listing possible matches for what they've typed into the input.

+ +
<label for="myFruit">What's your favorite fruit?</label>
+<input type="text" name="myFruit" id="myFruit" list="mySuggestion">
+<datalist id="mySuggestion">
+  <option>Apple</option>
+  <option>Banana</option>
+  <option>Blackberry</option>
+  <option>Blueberry</option>
+  <option>Lemon</option>
+  <option>Lychee</option>
+  <option>Peach</option>
+  <option>Pear</option>
+</datalist>
+ +
Note: According to the HTML specification, the {{htmlattrxref("list","input")}} attribute and the {{HTMLElement("datalist")}} element can be used with any kind of widget requiring a user input. However, it is unclear how it should work with controls other than text (color or date for example), and different browsers behave differently from case to case. Because of that, be cautious using this feature with anything but text fields.
+ +
Screenshots of datalist on several platforms.
+ +
+ +

Datalist support and fallbacks

+ +

The  {{HTMLElement("datalist")}} element is a very recent addition to HTML forms, so browser support is a bit more limited than what we saw earlier. Most notably, it isn't supported in IE versions below 10, and Safari still doesn't support it at the time of writing.

+ +

To handle this, here is a little trick to provide a nice fallback for those browsers:

+ +
<label for="myFruit">What is your favorite fruit? (With fallback)</label>
+<input type="text" id="myFruit" name="fruit" list="fruitList">
+
+<datalist id="fruitList">
+  <label for="suggestion">or pick a fruit</label>
+  <select id="suggestion" name="altFruit">
+    <option>Apple</option>
+    <option>Banana</option>
+    <option>Blackberry</option>
+    <option>Blueberry</option>
+    <option>Lemon</option>
+    <option>Lychee</option>
+    <option>Peach</option>
+    <option>Pear</option>
+  </select>
+</datalist>
+
+ +

Browsers that support the {{HTMLElement("datalist")}} element will ignore all the elements that are not {{HTMLElement("option")}} elements and will work as expected. On the other hand, browsers that do not support the {{HTMLElement("datalist")}} element will display the label and the select box. Of course, there are other ways to handle the lack of support for the {{HTMLElement("datalist")}} element, but this is the simplest (others tend to require JavaScript).

+ + + + + + + + + + + + +
Safari 6Screenshot of the datalist element fallback with Safari on Mac OS
Firefox 18Screenshot of the datalist element with Firefox on Mac OS
+ +

Checkable items

+ +

Checkable items are widgets whose state you can change by clicking on them. There are two kinds of checkable item: the check box and the radio button. Both use the {{htmlattrxref("checked","input")}} attribute to indicate whether the widget is checked by default or not.

+ +

It's worth noting that these widgets do not behave exactly like other form widgets. For most form widgets, once the form is submitted all widgets that have a {{htmlattrxref("name","input")}} attribute are sent, even if no value has been filled out. In the case of checkable items, their values are sent only if they are checked. If they are not checked, nothing is sent, not even their name.

+ +
+

Note: You can find the examples from this section on GitHub as checkable-items.html (see it live also).

+
+ +

For maximum usability/accessibility, you are advised to surround each list of related items in a {{htmlelement("fieldset")}}, with a {{htmlelement("legend")}} providing an overall description of the list.  Each individual pair of {{htmlelement("label")}}/{{htmlelement("input")}} elements should be contained in its own list item (or similar). This is shown in the examples. 

+ +

You also need to provide values for these kinds of inputs inside the value attribute if you want them to be meaningful — if no value is provided, check boxes and radio buttons are given a value of on.

+ +

Check box

+ +

A check box is created using the {{HTMLElement("input")}} element with its {{htmlattrxref("type","input")}} attribute set to the value checkbox.

+ +
<input type="checkbox" checked id="carrots" name="carrots" value="carrots">
+
+ +

Including the checked attribute makes the checkbox checked automatically when the page loads.

+ +

Screenshots of check boxes on several platforms.

+ +

Radio button

+ +

A radio button is created using the {{HTMLElement("input")}} element with its {{htmlattrxref("type","input")}} attribute set to the value radio.

+ +
<input type="radio" checked id="soup" name="meal">
+ +

Several radio buttons can be tied together. If they share the same value for their {{htmlattrxref("name","input")}} attribute, they will be considered to be in the same group of buttons. Only one button in a given group may be checked at the same time; this means that when one of them is checked all the others automatically get unchecked. When the form is sent, only the value of the checked radio button is sent. If none of them are checked, the whole pool of radio buttons is considered to be in an unknown state and no value is sent with the form.

+ +
<fieldset>
+  <legend>What is your favorite meal?</legend>
+  <ul>
+    <li>
+      <label for="soup">Soup</label>
+      <input type="radio" checked id="soup" name="meal" value="soup">
+    </li>
+    <li>
+      <label for="curry">Curry</label>
+      <input type="radio" id="curry" name="meal" value="curry">
+    </li>
+    <li>
+      <label for="pizza">Pizza</label>
+      <input type="radio" id="pizza" name="meal" value="pizza">
+    </li>
+  </ul>
+</fieldset>
+ +

Screenshots of radio buttons on several platforms.

+ +

Buttons

+ +

Within HTML forms, there are three kinds of button:

+ +
+
Submit
+
Sends the form data to the server.
+
Reset
+
Resets all form widgets to their default values.
+
Anonymous
+
Buttons that have no automatic effect but can be customized using JavaScript code. If you omit the type attribute, this is the default value.
+
+ +
+

Note: You can find the examples from this section on GitHub as button-examples.html (see it live also).

+
+ +

A button is created using a {{HTMLElement("button")}} element or an {{HTMLElement("input")}} element. It's the value of the {{htmlattrxref("type","input")}} attribute that specifies what kind of button is displayed:

+ +

submit

+ +
<button type="submit">
+    This a <br><strong>submit button</strong>
+</button>
+
+<input type="submit" value="This is a submit button">
+ +

reset

+ +
<button type="reset">
+    This a <br><strong>reset button</strong>
+</button>
+
+<input type="reset" value="This is a reset button">
+ +

anonymous

+ +
<button type="button">
+    This an <br><strong>anonymous button</strong>
+</button>
+
+<input type="button" value="This is an anonymous button">
+ +

Buttons always behave the same whether you use a {{HTMLElement("button")}} element or an {{HTMLElement("input")}} element. There are, however, some notable differences:

+ + + +

Screenshots of buttons on several platforms.

+ +

Technically speaking, there is almost no difference between a button defined with the {{HTMLElement("button")}} element or the {{HTMLElement("input")}} element. The only noticeable difference is the label of the button itself. Within an {{HTMLElement("input")}} element, the label can only be character data, whereas in a {{HTMLElement("button")}} element, the label can be HTML, so it can be styled accordingly.

+ +

Advanced form widgets

+ +

In this section we cover those widgets that let users input complex or unusual data. This includes exact or approximate numbers, dates and times, or colors.

+ +
+

Note: You can find the examples from this section on GitHub as advanced-examples.html (see it live also).

+
+ +

Numbers

+ +

Widgets for numbers are created with the {{HTMLElement("input")}} element, with its {{htmlattrxref("type","input")}} attribute set to the value number. This control looks like a text field but allows only floating-point numbers, and usually provides some buttons to increase or decrease the value of the widget.

+ +

It's also possible to:

+ + + +

Example

+ +
<input type="number" name="age" id="age" min="1" max="10" step="2">
+ +

This creates a number widget whose value is restricted to any value between 1 and 10, and whose increase and decrease buttons change its value by 2.

+ +

number inputs are not supported in versions of Internet Explorer below 10.

+ +

Sliders

+ +

Another way to pick a number is to use a slider. Visually speaking, sliders are less accurate than text fields, therefore they are used to pick a number whose exact value is not necessarily important.

+ +

A slider is created by using the {{HTMLElement("input")}} with its {{htmlattrxref("type","input")}} attribute set to the value range. It's important to properly configure your slider; to that end, it's highly recommended that you set the {{htmlattrxref("min","input")}}, {{htmlattrxref("max","input")}}, and {{htmlattrxref("step","input")}} attributes.

+ +

Example

+ +
<input type="range" name="beans" id="beans" min="0" max="500" step="10">
+ +

This example creates a slider whose value may range between 0 and 500, and whose increment/decrement buttons change the value by +10 and -10.

+ +

One problem with sliders is that they don't offer any kind of visual feedback as to what the current value is. You need to add this yourself with JavaScript, but this is relatively easy to do. In this example we add an empty {{htmlelement("span")}} element, in which we will write the current value of the slider, updating it as it is changed.

+ +
<label for="beans">How many beans can you eat?</label>
+<input type="range" name="beans" id="beans" min="0" max="500" step="10">
+<span class="beancount"></span>
+ +

This can be implemented using some simple JavaScript:

+ +
var beans = document.querySelector('#beans');
+var count = document.querySelector('.beancount');
+
+count.textContent = beans.value;
+
+beans.oninput = function() {
+  count.textContent = beans.value;
+}
+ +

Here we store references to the range input and the span in two variables, then we immediately set the span's textContent to the current value of the input. Finally, we set up an oninput event handler so that every time the range slider is moved, the span textContent is updated to the new input value.

+ +

range inputs are not supported in versions of Internet Explorer below 10.

+ +

Date and time picker

+ +

Gathering date and time values has traditionally been a nightmare for web developers. HTML5 brings some enhancements here by providing a special control to handle this specific kind of data.

+ +

A date and time control is created using the {{HTMLElement("input")}} element and an appropriate value for the {{htmlattrxref("type","input")}} attribute, depending on whether you wish to collect dates, times, or both.

+ +

datetime-local

+ +

This creates a widget to display and pick a date with time, but without any specific time zone information.

+ +
<input type="datetime-local" name="datetime" id="datetime">
+ +

month

+ +

This creates a widget to display and pick a month with a year.

+ +
<input type="month" name="month" id="month">
+ +

time

+ +

This creates a widget to display and pick a time value.

+ +
<input type="time" name="time" id="time">
+ +

week

+ +

This creates a widget to display and pick a week number and its year.

+ +
<input type="week" name="week" id="week">
+ +

All date and time control can be constrained using the {{htmlattrxref("min","input")}} and {{htmlattrxref("max","input")}} attributes.

+ +
<label for="myDate">When are you available this summer?</label>
+<input type="date" name="myDate" min="2013-06-01" max="2013-08-31" id="myDate">
+ +

Warning — The date and time widgets don't have the deepest support. At the moment, Chrome, Edge, Firefox, and Opera support them well, but there is no support in Internet Explorer and Safari has patchy support.

+ +

Color picker

+ +

Colors are always a bit difficult to handle. There are many ways to express them: RGB values (decimal or hexadecimal), HSL values, keywords, etc. The color widget lets users pick a color in both textual and visual ways.

+ +

A color widget is created using the {{HTMLElement("input")}} element with its {{htmlattrxref("type","input")}} attribute set to the value color.

+ +
<input type="color" name="color" id="color">
+ +

Warning — Color widget support it currently not very good. There is no support in Internet Explorer, and Safari currently doesn't support it either. The other major browsers do support it.

+ +

Other widgets

+ +

There are a few other widgets that cannot be easily classified due to their very specific behaviors, but which are still very useful.

+ +
+

Note: You can find the examples from this section on GitHub as other-examples.html (see it live also).

+
+ +

File picker

+ +

HTML forms are able to send files to a server; this specific action is detailed in the article Sending and retrieving form data. The file picker widget is how the user can choose one or more files to send.

+ +

To create a file picker widget, you use the {{HTMLElement("input")}} element with its {{htmlattrxref("type","input")}} attribute set to file. The types of files that are accepted can be constrained using the {{htmlattrxref("accept","input")}} attribute. In addition, if you want to let the user pick more than one file, you can do so by adding the {{htmlattrxref("multiple","input")}} attribute.

+ +

Example

+ +

In this example, a file picker is created that requests graphic image files. The user is allowed to select multiple files in this case.

+ +
<input type="file" name="file" id="file" accept="image/*" multiple>
+ +

Hidden content

+ +

It's sometimes convenient for technical reasons to have pieces of data that are sent with a form but not displayed to the user. To do this, you can add an invisible element in your form. Use an {{HTMLElement("input")}} with its {{htmlattrxref("type","input")}} attribute set to the value hidden.

+ +

If you create such an element, it's required to set its name and value attributes:

+ +
<input type="hidden" id="timestamp" name="timestamp" value="1286705410">
+ +

Image button

+ +

The image button control is one which is displayed exactly like an {{HTMLElement("img")}} element, except that when the user clicks on it, it behaves like a submit button (see above).

+ +

An image button is created using an {{HTMLElement("input")}} element with its {{htmlattrxref("type","input")}} attribute set to the value image. This element supports exactly the same set of attributes as the {{HTMLElement("img")}} element, plus all the attributes supported by other form buttons.

+ +
<input type="image" alt="Click me!" src="my-img.png" width="80" height="30" />
+ +

If the image button is used to submit the form, this widget doesn't submit its value; instead the X and Y coordinates of the click on the image are submitted (the coordinates are relative to the image, meaning that the upper-left corner of the image represents the coordinate 0, 0). The coordinates are sent as two key/value pairs:

+ + + +

So for example when you click on the image of this widget, you are sent to a URL like the following:

+ +
http://foo.com?pos.x=123&pos.y=456
+ +

This is a very convenient way to build a "hot map". How these values are sent and retrieved is detailed in the Sending and retrieving form data article.

+ +

Meters and progress bars

+ +

Meters and progress bars are visual representations of numeric values.

+ +

Progress

+ +

A progress bar represents a value that changes over time up to a maximum value specified by the {{htmlattrxref("max","progress")}} attribute. Such a bar is created using a {{ HTMLElement("progress")}} element.

+ +
<progress max="100" value="75">75/100</progress>
+ +

This is for implementing anything requiring progress reporting, such as the percentage of total files downloaded, or the number of questions filled in on a questionnaire.

+ +

The content inside the {{HTMLElement("progress")}} element is a fallback for browsers that don't support the element and for assistive technologies to vocalize it.

+ +

Meter

+ +

A meter bar represents a fixed value in a range delimited by a {{htmlattrxref("min","meter")}} and a {{htmlattrxref("max","meter")}} value. This value is visualy rendered as a bar, and to know how this bar looks, we compare the value to some other set values:

+ + + +

All browsers that implement the {{HTMLElement("meter")}} element use those values to change the color of the meter bar:

+ + + +

Such a bar is created using a {{HTMLElement("meter")}} element. This is for implementing any kind of meter, for example a bar showing total space used on a disk, which turns red when it starts to get full.

+ +
<meter min="0" max="100" value="75" low="33" high="66" optimum="50">75</meter>
+ +

The content inside the {{HTMLElement("meter")}} element is a fallback for browsers that don't support the element and for assistive technologies to vocalize it.

+ +

Support for progress and meter is fairly good — there is no support in Internet Explorer, but other browsers support it well.

+ +

Conclusion

+ +

As you'll have seen above, there are a lot of different types of available form elements — you don't need to remember all of these details at once, and can return to this article as often as you like to check up on details.

+ +

See also

+ +

To dig into the different form widgets, there are some useful external resources you should check out:

+ + + +

{{PreviousMenuNext("Learn/HTML/Forms/How_to_structure_an_HTML_form", "Learn/HTML/Forms/Sending_and_retrieving_form_data", "Learn/HTML/Forms")}}

+ +

In this module

+ + diff --git a/files/ru/learn/forms/form_validation/index.html b/files/ru/learn/forms/form_validation/index.html new file mode 100644 index 0000000000..f2c5f362ac --- /dev/null +++ b/files/ru/learn/forms/form_validation/index.html @@ -0,0 +1,906 @@ +--- +title: Проверка данных формы (проверка валидности формы на стороне клиента) +slug: Learn/HTML/Forms/Валидация_формы +translation_of: Learn/Forms/Form_validation +--- +

+ +

+ +
+
+
+ +
+
+ +
+
+ +
+
+
<
+ +
+
+ +
<
+
+
+
+ +
{{LearnSidebar}}{{PreviousMenuNext("Learn/HTML/Forms/Sending_and_retrieving_form_data", "Learn/HTML/Forms/How_to_build_custom_form_widgets", "Learn/HTML/Forms")}}
+ +

Проверка данных формы позволяет нам удостовериться в том, что пользователи заполняют форму в  правильном формате, убедиться, что отправленные данные будут успешно работать с нашими приложениями. Эта статья расскажет, что вам нужно знать о проверке формы.

+ + + + + + + + + + + + +
Предпосылки:Компьютерная грамотность, разумное понимание HTML, CSS, и JavaScript.
Задача:Понимать что такое проверка формы (валидация) формы, почему это важно и как это реализовать.
+ +

Что такое валидация формы?

+ +

Откройте любой популярный сайт с формой регистрации и вы заметите, что они дают вам обратную связь, когда вы вводите ваши данные не в том формате, который они ожидают от вас. Вы получите подобные сообщения:

+ + + +

Это называется валидация формы — когда вы вводите данные,  веб-прилолжение проверяет, что данные корректны. Если данные верны, приложение позволяет данным быть отправленными на сервер и (как правило) быть сохраненными в базе данных; если нет -  оно выдает вам сообщение об ошибке, обьясняющее какие исправления необходимо внести. Проверка формы может быть реализована несколькими различными способами.

+ +

Мы хотим сделать заполнение веб-форм максимально простым. Итак, почему мы настаиваем на подтверждении наших форм? Существуют три основные причины:

+ + + +

Различные типы валидации формы

+ +

Существует два разных типа проверки формы, с которыми вы столкнетесь в Интернете:

+ + + +

В реальном мире разработчики склонны использовать комбинацию проверки на стороне клиента и сервера.

+ +

Использование встроенной проверки формы

+ +

Одной из особенностей HTML5 является возможность проверки большинства пользовательских данных без использования скриптов. Это делается с помощью атрибутов проверки элементов формы, которые позволяют вам указывать правила ввода формы, например, нужно ли заполнять значение, минимальная и максимальная длина данных, должно ли это быть число, адрес электронной почты, адрес или что-то еще, и шаблон, которому это должно соответствовать. Если введенные данные соответствуют всем этим правилам, данные считаются валидными; если нет -  невалидными.

+ +

Когда элемент валидный, следующие утверждения верны:

+ + + +

Когда элемент невалидный, следующие утверждения верны:

+ + + +
+

Note: Вот несколько ошибок, которые не позволяют форме быть подтверждённой: {{domxref('validityState.badInput', 'badInput')}}, {{domxref('validityState.patternMismatch','patternMismatch')}}, {{domxref('validityState.rangeOverflow','rangeOverflow')}} or {{domxref('validityState.rangeUnderflow','rangeUnderflow')}}, {{domxref('validityState.stepMismatch','stepMismatch')}}, {{domxref('validityState.tooLong','tooLong')}} or {{domxref('validityState.tooShort','tooShort')}}, {{domxref('validityState.typeMismatch','typeMismatch')}}, {{domxref('validityState.valueMissing','valueMissing')}}, or a {{domxref('validityState.customError','customError')}}.

+
+ +

Примеры встроенных форм валидации

+ +

Ограничения проверки элементов input - простое начало

+ +

В этом разделе мы рассмотрим некоторые функции HTML5, которые можно использовать для проверки {{HTMLElement("input")}} элементов.

+ +

Начнем с простого примера - input, который позволяет вам выбирать ваш любимый плод между бананом и вишней. Он включает простой текст {{HTMLElement("input")}} соответствующий ярлык (label) и отправку (submit) {{htmlelement("button")}}. Вы можете найти исходный код на GitHub fruit-start.html,и живой пример ниже:

+ +
<form>
+  <label for="choose">Would you prefer a banana or cherry?</label>
+  <input id="choose" name="i_like">
+  <button>Submit</button>
+</form>
+ +
input:invalid {
+  border: 2px dashed red;
+}
+
+input:valid {
+  border: 2px solid black;
+}
+
+ +

{{EmbedLiveSample("Simple_start_file", "100%", 80)}}

+ +

Для начала сделаем копию fruit-start.htmlв новом каталоге на жестком диске.

+ +

Требуемый атрибут (required)

+ +

Простейшей функцией проверки HTML5 для использования является  {{htmlattrxref("required", "input")}} атрибут. Если вы хотите сделать ввод обязательным, вы можете пометить элемент, используя этот атрибут. Если этот атрибут установлен, форма не будет отправляться (и будет отображаться сообщение об ошибке), когда поле пустое (поле input также будет считаться невалидным).

+ +

Добавьте атрибут required в ваш input, как показано ниже:

+ +
<form>
+  <label for="choose">Would you prefer a banana or cherry?</label>
+  <input id="choose" name="i_like" required>
+  <button>Submit</button>
+</form>
+ +

Также обратите внимание на CSS, включенный в файл примера:

+ +
input:invalid {
+  border: 2px dashed red;
+}
+
+input:invalid:required {
+  background-image: linear-gradient(to right, pink, lightgreen);
+}
+
+input:valid {
+  border: 2px solid black;
+}
+ +

В этом случае к input будет применяться ярко-красный пунктирный border, когда он невалидный, и более тонкая черная граница, когда он валидный. Попробуйте новое поведение в приведенном ниже примере:

+ +

{{EmbedLiveSample("The_required_attribute", "100%", 80)}}

+ +
+

Note: Вы можете найти этот пример на GitHub как fruit-validation.html (также смотрите source code.)

+
+ +

Попробуйте эту форму без значения. Обратите внимание как невалидный ввод получает фокус, сообщение об ошибке ("Пожалуйста заполните поле") появляется, и форма не отправляется.

+ +

Проверка с регулярными выражениями

+ +

Другая полезная функция проверки - это pattern атрибут , который ожидает Regular Expression в качестве значения. Регулярное выражение (regex) - это шаблон который используется для проверки соответствия символов в текстовых строках, поэтому он идеально подходит для проверки формы, а также для многих других целей в JavaScript.

+ +

Регулярные выражения довольно сложны, и мы не будем подробно разбирать их в этой статье. Ниже приведены некоторые примеры, чтобы вы представляли себе, как они работают:

+ + + +

Вы также можете использовать числа и другие символы в этих выражениях, например:

+ + + +

Вы можете комбинировать их практически, как хотите, указывая разные части, одну за другой:

+ + + +

В любом случае, давайте реализуем пример - обновим ваш HTML, чтобы добавить атрибут шаблона, например:

+ +
<form>
+  <label for="choose">Would you prefer a banana or a cherry?</label>
+  <input id="choose" name="i_like" required pattern="banana|cherry">
+  <button>Submit</button>
+</form>
+ + + +

{{EmbedLiveSample("Validating_against_a_regular_expression", "100%", 50)}}

+ +

В этом примере {{HTMLElement("input")}} элемент принимает одно из двух возможных значений: строку "banana" или строку "cherry".

+ +

На этом этапе попробуйте изменить значение внутри атрибута pattern чтобы сопоставить некоторые из примеров, которые вы видели ранее, и посмотрите, как это влияет на значения, которые вы можете ввести, чтобы сделать входное значение валидным. Попробуйте написать свои собственные, и посмотрите, как это работает! Попробуйте сделать их связанными с фруктами, где это возможно, поэтому ваши примеры имеют смысл!

+ +
+

Примечание: Некоторые {{HTMLElement("input")}} типы элементов не нуждаются в атрибуте {{htmlattrxref("pattern","input")}} чтобы быть валидными. Указание типа email например, проверяет введенное значение через регулярное выражение, соответствующее хорошо сформированному адресу электронной почты (или списку email адресов, разделенных запятыми, если в нем присутствует атрибут {{htmlattrxref("multiple","input")}} attribute). В качестве еще одного примера, поле с типом url автоматически требует правильно сформированного URL.

+
+ +
+

Примечание: Элемент {{HTMLElement("textarea")}} не поддерживает атрибут {{htmlattrxref("pattern","input")}}.

+
+ +

Ограничение длины ваших записей

+ +

Все текстовые поля, созданные с помощью элементов ({{HTMLElement("input")}} или  {{HTMLElement("textarea")}}) могут быть ограничены по размеру, используя атрибуты {{htmlattrxref("minlength","input")}} и{{htmlattrxref("maxlength","input")}}. Поле невалидно если его значение короче чем {{htmlattrxref("minlength","input")}} или значение длиннее значения {{htmlattrxref("maxlength","input")}}. Браузеры часто не позволяют пользователю вводить более длинное значение, чем ожидалось, в текстовые поля в любом случае, но полезно иметь этот мелкозернистый элемент управления.

+ +

Для числовых полей (например <input type="number">), атрибуты {{htmlattrxref("min","input")}} и {{htmlattrxref("max","input")}} также обеспечивают ограничение валидации. Если значение поля меньше атрибута {{htmlattrxref("min","input")}} или больше атрибута {{htmlattrxref("max","input")}}, поле будет невалидным.

+ +

Давайте посмотрим на другой пример. Создайте новую копию файла fruit-start.html.

+ +

Теперь удалите содержимое элемента <body>, и замените его следующим:

+ +
<form>
+  <div>
+    <label for="choose">Would you prefer a banana or a cherry?</label>
+    <input id="choose" name="i_like" required minlength="6" maxlength="6">
+  </div>
+  <div>
+    <label for="number">How many would you like?</label>
+    <input type="number" id="number" name="amount" value="1" min="1" max="10">
+  </div>
+  <div>
+    <button>Submit</button>
+  </div>
+</form>
+ + + + + +

Вот живой пример:

+ +

{{EmbedLiveSample("Constraining_the_length_of_your_entries", "100%", 70)}}

+ +
+

Примечание: <input type="number"> (и другие типы, например range) могут также содержать атрибут {{htmlattrxref("step", "input")}} который указывает, какой инкремент будет увеличиваться или уменьшаться, когда используются элементы управления входом (например, номерные кнопки вверх и вниз)

+
+ +

Полный пример

+ +

Вот полный пример, чтобы показать использование встроенных функций проверки HTML:

+ +
<form>
+  <p>
+    <fieldset>
+      <legend>Title<abbr title="This field is mandatory">*</abbr></legend>
+      <input type="radio" required name="title" id="r1" value="Mr"><label for="r1">Mr.</label>
+      <input type="radio" required name="title" id="r2" value="Ms"><label for="r2">Ms.</label>
+    </fieldset>
+  </p>
+  <p>
+    <label for="n1">How old are you?</label>
+    <!-- The pattern attribute can act as a fallback for browsers which
+         don't implement the number input type but support the pattern attribute.
+         Please note that browsers that support the pattern attribute will make it
+         fail silently when used with a number field.
+         Its usage here acts only as a fallback -->
+    <input type="number" min="12" max="120" step="1" id="n1" name="age"
+           pattern="\d+">
+  </p>
+  <p>
+    <label for="t1">What's your favorite fruit?<abbr title="This field is mandatory">*</abbr></label>
+    <input type="text" id="t1" name="fruit" list="l1" required
+           pattern="[Bb]anana|[Cc]herry|[Aa]pple|[Ss]trawberry|[Ll]emon|[Oo]range">
+    <datalist id="l1">
+      <option>Banana</option>
+      <option>Cherry</option>
+      <option>Apple</option>
+      <option>Strawberry</option>
+      <option>Lemon</option>
+      <option>Orange</option>
+    </datalist>
+  </p>
+  <p>
+    <label for="t2">What's your e-mail?</label>
+    <input type="email" id="t2" name="email">
+  </p>
+  <p>
+    <label for="t3">Leave a short message</label>
+    <textarea id="t3" name="msg" maxlength="140" rows="5"></textarea>
+  </p>
+  <p>
+    <button>Submit</button>
+  </p>
+</form>
+ +
body {
+  font: 1em sans-serif;
+  padding: 0;
+  margin : 0;
+}
+
+form {
+  max-width: 200px;
+  margin: 0;
+  padding: 0 5px;
+}
+
+p > label {
+  display: block;
+}
+
+input[type=text],
+input[type=email],
+input[type=number],
+textarea,
+fieldset {
+/* требуется для правильной формы формы
+    элементов в браузерах на основе WebKit*/
+  -webkit-appearance: none;
+
+  width : 100%;
+  border: 1px solid #333;
+  margin: 0;
+
+  font-family: inherit;
+  font-size: 90%;
+
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+
+input:invalid {
+  box-shadow: 0 0 5px 1px red;
+}
+
+input:focus:invalid {
+  outline: none;
+}
+ +

{{EmbedLiveSample("Full_example", "100%", 420)}}

+ +

Индивидуальные сообщения об ошибках

+ +

Как видно из приведенных выше примеров, каждый раз, когда пользователь пытается отправить невалидную форму, браузер отображает сообщение об ошибке. Способ отображения этого сообщения зависит от браузера.

+ +

Эти автоматизированные сообщения имеют два недостатка:

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Французская версия сообщений обратной связи на странице на английском языке
БраузерОтображение
Firefox 17 (Windows 7)Example of an error message with Firefox in French on an English page
Chrome 22 (Windows 7)Example of an error message with Chrome in French on an English page
Opera 12.10 (Mac OSX)Example of an error message with Opera in French on an English page
+ +

Чтобы настроить внешний вид и текст этих сообщений, вы должны использовать JavaScript; нет способа сделать это, используя только HTML и CSS.

+ +

HTML5 предоставляет API проверки ограничений (API - Application Programing interface, программный интерфейс приложения, англ.) для проверки и настройки состояния элемента формы. Помимо прочего, можно заменить текст сообщения об ошибке. Давайте посмотрим на небольшой пример:

+ +
<form>
+  <label for="mail">I would like you to provide me an e-mail</label>
+  <input type="email" id="mail" name="mail">
+  <button>Submit</button>
+</form>
+ +

В JavaScript вы вызываете метод setCustomValidity():

+ +
var email = document.getElementById("mail");
+
+email.addEventListener("input", function (event) {
+  if (email.validity.typeMismatch) {
+    email.setCustomValidity("I expect an e-mail, darling!");
+  } else {
+    email.setCustomValidity("");
+  }
+});
+ +

{{EmbedLiveSample("Customized_error_messages", "100%", 50)}}

+ +

Проверка форм с использованием JavaScript

+ +

Если вы хотите контролировать внешний вид собственных сообщений об ошибках или работать с браузерами, которые не поддерживают встроенную проверку формы HTML, вы должны использовать JavaScript.

+ +

API проверки валидности HTML5

+ +

Все больше браузеров теперь поддерживают API проверки ограничений, и он становится надежным. Этот API состоит из набора методов и свойств, доступных для каждого элемента формы.

+ +

Свойства API проверки валидности

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
СвойствоОписание
validationMessageЛокализованное сообщение, описывающее ограничения валидности, которым элемент управления не соответствует (если есть), или пустая строка, если элемент управления не является кандидатом для проверки ограничений (willValidate is false), или значение элемента удовлетворяет его ограничениям.
validityобъект {{domxref("ValidityState")}} , описывающий состояние действительности элемента.
validity.customErrorВозвращает true если элемент содержит пользовательскую ошибку; false в противном случае.
validity.patternMismatchВозвращает true если значение элемента не соответствует предоставленному шаблону; false в противном случае.
+
+ если возвращает true, элемент будет соответствовать CSS псевдо-классу {{cssxref(":invalid")}}.
validity.rangeOverflowВозвращает true если значение элемента выше заданного максимума; false в противном случае.
+
+ Если возвращает true, элемент будет соответствовать {{cssxref(":invalid")}} и CSS псевдо-классу. {{cssxref(":out-of-range")}}.
validity.rangeUnderflowВозвращаетtrue если значение элемента меньше заданного минимума; false в противном случае.
+
+ Если возвращает true, элемент будет соответствовать {{cssxref(":invalid")}} и CSS псевдо-классу {{cssxref(":out-of-range")}}.
validity.stepMismatchВозвращаетtrue, если значение элемента не соответствует правилам, предоставляемым атрибутом step; в противном случае false .
+
+ Если возвращает true, элемент будет соответствовать {{cssxref(":invalid")}} и CSS псевдоклассу {{cssxref(":out-of-range")}}.
validity.tooLongВозвращает true если значение элемента больше заданной максимальной длины; иначе будет false
+
+ Если возвращает true, элемент будет соответствовать {{cssxref(":invalid")}} и CSS псевдоклассу {{cssxref(":out-of-range")}}.
validity.typeMismatchВозвращает true если значение элемента не соответствует правильному синтаксису; в противном случае - false.
+ Если возвращает true, элемент будет соответствовать CSS псевдоклассу {{cssxref(":invalid")}}.
validity.validВозвращае true если значение элемента не имеет проблем с валидностью; в противном случае false.
+
+ Если возвращает true, элемент будет соответствовать CSS псевдоклассу {{cssxref(":valid")}} ; CSS псевдоклассу {{cssxref(":invalid")}} в противном случае.
validity.valueMissingВозвращает true если элемент не имеет значения, но является обязательным полем; в противном случае false.
+
+ Если возвращает true, элемент будет соответствовать CSS псевдоклассу {{cssxref(":invalid")}}.
willValidateВозвращает true если элемент будет проверен при отправке формы; в противном случае false.
+ +

Методы API проверки ограничений

+ + + + + + + + + + + + + + + + + + +
МетодОписание
checkValidity()Возвращает true если значение элемента не имеет проблем с валидностью; иначе false. Если элемент невалидный, этот метод также вызывает событие {{event("invalid")}} в элементе .
setCustomValidity(message)Добавляет настраиваемое сообщение об ошибке в элемент; если вы установили собственное сообщение об ошибке, элемент считается невалидным, и отображается указанная ошибка. Это позволяет использовать код JavaScript для установления ошибки валидации, отличного от тех, которые предлагаются стандартным API ограничений валидности. Сообщение показывается пользователю при возникновении проблемы.
+
+ Если аргументом является пустая строка, пользовательская ошибка очищается.
+ +

Для устаревших браузеров можно использовать полифилл как Hyperform чтобы компенсировать отсутствие поддержки API ограничений валидности. Поскольку вы уже используете JavaScript, использование полифилла не является дополнительным бременем для вашего веб-сайта или дизайна или реализации веб-приложения.

+ +

Пример использования API проверки ограничений

+ +

Давайте посмотрим, как использовать этот API для создания настраиваемых сообщений об ошибках. Сначала HTML:

+ +
<form novalidate>
+  <p>
+    <label for="mail">
+      <span>Please enter an email address:</span>
+      <input type="email" id="mail" name="mail">
+      <span class="error" aria-live="polite"></span>
+    </label>
+  </p>
+  <button>Submit</button>
+</form>
+ +

Эта простая форма использует атрибут {{htmlattrxref("novalidate","form")}} для отключения автоматической валидации браузера, что позволяет нашему скрипту контролировать валидацию. Однако это не отключает поддержку API ограничений валидации или применения псевдоклассов CSS {{cssxref(":valid")}}, {{cssxref(":invalid")}}, {{cssxref(":in-range")}} и {{cssxref(":out-of-range")}}. Это означает, что, хотя браузер не проверяет правильность формы перед отправкой своих данных, вы все равно можете сделать это самостоятельно и соответствующим образом сформировать форму.

+ +

Атрибут aria-live гарантирует, что наше индивидуальное сообщение об ошибке будет доступно всем, включая тех, кто использует вспомогательные технологии, такие как скрин-ридеры.

+ +
CSS
+ +

Этот CSS задает стили нашей форме и выводу ошибки, чтобы сделать их визуально более привлекательными.

+ +
/* Это просто, чтобы сделать пример более приятным */
+body {
+  font: 1em sans-serif;
+  padding: 0;
+  margin : 0;
+}
+
+form {
+  max-width: 200px;
+}
+
+p * {
+  display: block;
+}
+
+input[type=email]{
+  -webkit-appearance: none;
+
+  width: 100%;
+  border: 1px solid #333;
+  margin: 0;
+
+  font-family: inherit;
+  font-size: 90%;
+
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+
+/* Наш стиль для невалидных полей */
+input:invalid{
+  border-color: #900;
+  background-color: #FDD;
+}
+
+input:focus:invalid {
+  outline: none;
+}
+
+/* Это стиль для сообщений об ошибке */
+.error {
+  width  : 100%;
+  padding: 0;
+
+  font-size: 80%;
+  color: white;
+  background-color: #900;
+  border-radius: 0 0 5px 5px;
+
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+
+.error.active {
+  padding: 0.3em;
+}
+ +
JavaScript
+ +

Следующий код JavaScript обрабатывает выборочную проверку ошибок.

+ +
//Существует много способов выбрать DOM узел; здесь мы получаем форму и электронную почту
+//поле ввода, а также элемент span, в который мы поместим сообщение об ошибке.
+var form  = document.getElementsByTagName('form')[0];
+var email = document.getElementById('mail');
+var error = document.querySelector('.error');
+
+email.addEventListener("input", function (event) {
+ // Каждый раз, когда пользователь вводит что-либо, мы проверяем,
+  // является ли корректным поле электронной почты.
+  if (email.validity.valid) {
+    // В случае появления сообщения об ошибке, если поле
+    // является корректным, мы удаляем сообщение об ошибке.
+    error.innerHTML = ""; // Сбросить содержимое сообщения
+    error.className = "error"; // Сбросить визуальное состояние сообщения
+  }
+}, false);
+form.addEventListener("submit", function (event) {
+  // Каждый раз, когда пользователь пытается отправить данные, мы проверяем
+   // валидность поля электронной почты.
+  if (!email.validity.valid) {
+
+    // Если поле невалидно, отображается пользовательское
+    // сообщение об ошибке.
+    error.innerHTML = "I expect an e-mail, darling!";
+    error.className = "error active";
+    // И мы предотвращаем отправку формы путем отмены события
+    event.preventDefault();
+  }
+}, false);
+ +

Вот живой результат:

+ +

{{EmbedLiveSample("Example_using_the_constraint_validation_API", "100%", 130)}}

+ +

API ограничений валидации дает вам мощный инструмент для проверки формы, позволяя вам получить контроль над пользовательским интерфейсом больше и лучше того, что вы можете делать только при помощи HTML и CSS.

+ +

Проверка форм без встроенного API

+ +

Иногда, например, с устаревшими браузерами или пользовательскими виджетами, вы не сможете (или не захотите) использовать API проверки ограничений. В этом случае вы все еще можете использовать JavaScript для проверки вашей формы. Проверка формы - это скорее вопрос пользовательского интерфейса, чем проверка валидности данных.

+ +

Чтобы проверить форму, вы должны задать себе несколько вопросов:

+ +
+
Какую проверку я должен выполнить?
+
Вам нужно определить, как проверить ваши данные: операции со строками, преобразование типов, регулярные выражения и т. д. Это зависит от вас. Просто помните, что данные формы всегда являются текстовыми и всегда предоставляются вашему скрипту как строки.
+
Что делать, если форма не проверяется?
+
Это явно вопрос интерфейса. Вы должны решить, как будет выглядеть форма: формально ли отправляет данные? Должны ли вы выделять поля, которые содержат ошибки? Должны отображаться сообщения об ошибках?
+
Как я могу помочь пользователю исправить невалидные данные?
+
Чтобы уменьшить разочарование пользователя, очень важно предоставить как можно больше полезной информации, чтобы помочь им в исправлении их исходных данных. Вы должны предлагать предварительные предложения, чтобы они знали, что ожидается, а также ясные сообщения об ошибках. Если вы хотите вникнуть в требования к пользовательскому интерфейсу проверки формы, есть некоторые полезные статьи, которые вы должны прочитать: + +
+
+ +

Пример, который не использует API валидации ограничений

+ +

Чтобы проиллюстрировать это, давайте перестроим предыдущий пример, чтобы он работал с устаревшими браузерами:

+ +
<form>
+  <p>
+    <label for="mail">
+        <span>Please enter an email address:</span>
+        <input type="text" class="mail" id="mail" name="mail">
+        <span class="error" aria-live="polite"></span>
+    </label>
+  <p>
+  <!-- Some legacy browsers need to have the `type` attribute
+       explicitly set to `submit` on the `button`element -->
+  <button type="submit">Submit</button>
+</form>
+ +

Как вы можете видеть, HTML почти такой же; мы просто удалили функции проверки HTML. Обратите внимание, что ARIA является независимой спецификацией, которая специально не связана с HTML5.

+ +
CSS
+ +

Аналогично, CSS не нужно сильно менять; мы просто переводим CSS-псевдокласс {{cssxref(":invalid")}} в настоящий класс и избегаем использования селектора атрибутов, который не работает в Internet Explorer 6.

+ +
/* This is just to make the example nicer */
+body {
+  font: 1em sans-serif;
+  padding: 0;
+  margin : 0;
+}
+
+form {
+  max-width: 200px;
+}
+
+p * {
+  display: block;
+}
+
+input.mail {
+  -webkit-appearance: none;
+
+  width: 100%;
+  border: 1px solid #333;
+  margin: 0;
+
+  font-family: inherit;
+  font-size: 90%;
+
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+
+/* This is our style for the invalid fields */
+input.invalid{
+  border-color: #900;
+  background-color: #FDD;
+}
+
+input:focus.invalid {
+  outline: none;
+}
+
+/* This is the style of our error messages */
+.error {
+  width  : 100%;
+  padding: 0;
+
+  font-size: 80%;
+  color: white;
+  background-color: #900;
+  border-radius: 0 0 5px 5px;
+
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+
+.error.active {
+  padding: 0.3em;
+}
+ +
JavaScript
+ +

Большие изменения в коде JavaScript, которые должны сделать намного больше тяжелой работы.

+ +
// Существует меньше способов выбрать узел DOM с устаревшими браузерами
+var form  = document.getElementsByTagName('form')[0];
+var email = document.getElementById('mail');
+
+// Ниже приведен трюк для достижения следующего узла Element Element в DOM
+// Это опасно, потому что вы можете легко построить бесконечный цикл.
+// В современных браузерах вам следует использовать элемент element.nextElementSibling
+var error = email;
+while ((error = error.nextSibling).nodeType != 1);
+
+// As per the HTML5 Specification
+var emailRegExp = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
+
+// Многие устаревшие браузеры не поддерживают метод addEventListener.
+// Вот простой способ справиться с этим; это далеко не единственный.
+function addEvent(element, event, callback) {
+  var previousEventCallBack = element["on"+event];
+  element["on"+event] = function (e) {
+    var output = callback(e);
+
+    // Обратный вызов, который возвращает `false`, останавливает цепочку обратного вызова
+     // и прерывает выполнение обратного вызова события.
+    if (output === false) return false;
+
+    if (typeof previousEventCallBack === 'function') {
+      output = previousEventCallBack(e);
+      if(output === false) return false;
+    }
+  }
+};
+
+// Теперь мы можем перестроить наше ограничение валидации
+// Поскольку мы не полагаемся на псевдо-класс CSS, мы должны
+// явно установить допустимый / недопустимый класс в поле электронной почты
+addEvent(window, "load", function () {
+// Здесь мы проверяем, пусто ли поле (помните, что поле не требуется)
+   // Если это не так, мы проверяем, является ли его контент корректным адресом электронной почты.
+  var test = email.value.length === 0 || emailRegExp.test(email.value);
+
+  email.className = test ? "valid" : "invalid";
+});
+
+// Это определяет, что происходит, когда пользователь вводит в поле
+addEvent(email, "input", function () {
+  var test = email.value.length === 0 || emailRegExp.test(email.value);
+  if (test) {
+    email.className = "valid";
+    error.innerHTML = "";
+    error.className = "error";
+  } else {
+    email.className = "invalid";
+  }
+});
+
+// Это определяет, что происходит, когда пользователь пытается отправить данные
+addEvent(form, "submit", function () {
+  var test = email.value.length === 0 || emailRegExp.test(email.value);
+
+  if (!test) {
+    email.className = "invalid";
+    error.innerHTML = "I expect an e-mail, darling!";
+    error.className = "error active";
+
+    // Некоторые устаревшие браузеры не поддерживают метод event.preventDefault ()
+    return false;
+  } else {
+    email.className = "valid";
+    error.innerHTML = "";
+    error.className = "error";
+  }
+});
+ +

Результат выглядит следующим образом:

+ +

{{EmbedLiveSample("Example_that_doesn't_use_the_constraint_validation_API", "100%", 130)}}

+ +

Как вы можете видеть, создать собственную систему проверки не сложно. Трудная часть состоит в том, чтобы сделать его достаточно общим, чтобы использовать его как в кросс-платформенной, так и в любой форме, которую вы могли бы создать. Существует множество библиотек для проверки формы; вы не должны колебаться, чтобы использовать их. Вот несколько примеров:

+ + + +

Удаленная проверка

+ +

В некоторых случаях может быть полезно выполнить некоторую удаленную проверку. Такая проверка необходима, когда данные, введенные пользователем, привязаны к дополнительным данным, хранящимся на стороне сервера вашего приложения. Одним из вариантов использования является регистрационные формы, в которых вы запрашиваете имя пользователя. Чтобы избежать дублирования, разумнее выполнить AJAX запрос для проверки доступности имени пользователя, а не попросить пользователя отправить данные, а затем отправить форму с ошибкой.

+ +

Выполнение такой проверки требует принятия нескольких мер предосторожности:

+ + + +

Заключение

+ +

Проверка формы не требует сложного JavaScript, но она требует тщательного изучения пользователя. Всегда помните, чтобы помочь вашему пользователю исправить данные, которые они предоставляют. Для этого обязательно выполните следующие действия:

+ + + +

{{PreviousMenuNext("Learn/HTML/Forms/Sending_and_retrieving_form_data", "Learn/HTML/Forms/How_to_build_custom_form_widgets", "Learn/HTML/Forms")}}

+ +

В этом модуле

+ + diff --git a/files/ru/learn/forms/how_to_build_custom_form_controls/index.html b/files/ru/learn/forms/how_to_build_custom_form_controls/index.html new file mode 100644 index 0000000000..8a4ca2d6b8 --- /dev/null +++ b/files/ru/learn/forms/how_to_build_custom_form_controls/index.html @@ -0,0 +1,792 @@ +--- +title: Как создавать пользовательские виджеты форм +slug: Learn/HTML/Forms/How_to_build_custom_form_widgets +tags: + - HTML + - Web + - Пример + - Продвинутый + - Руководство + - Формы +translation_of: Learn/Forms/How_to_build_custom_form_controls +--- +
{{LearnSidebar}}{{PreviousMenuNext("Learn/HTML/Forms/Form_validation", "Learn/HTML/Forms/Sending_forms_through_JavaScript", "Learn/HTML/Forms")}}
+ +

Существует много случаев, когда возможностей стандартных виджетов HTML форм недостаточно. Если вы хотите придать лучший вид каким-либо виджетам как, например, {{HTMLElement("select")}}, или вы хотите создать особое поведение виджета, то у вас нет другого выбора, кроме как создать собственные виджеты.

+ +

В этой статье мы рассмотрим как создать такой виджет. Для этого мы возьмем пример: переделка элемента {{HTMLElement("select")}} .

+ +
+

Замечание: Мы сфокусируемся на создании виджетов, а не на том чтобы сделать код  универсальным и многоразовым; поэтому будут использоваться некоторый нетривиальный JavaScript код и манипуляции DOM в неизвестном контексте, что выходит за рамки этой статьи.

+
+ +

Дизайн, структура и семантика

+ +

В начале создания пользовательского виджета необходимо обрисовать что именно вы хотите. Это сэкономит драгоценное время. Особенно важно четко определить все состояния вашего виджета. Чтобы это сделать, лучше начать с существущего виджета, состояния и реакции которго хорошо известны, так что вы сможете просто подражать им насколько это возможно.

+ +

В нашем примере мы будем переделывать элемент {{HTMLElement("select")}}. Вот такой результат мы хотим достичь:

+ +

The three states of a select box

+ +

Этот скриншот показывает три основных состояния нашего виджета: нормальное состояние (слева); активное состояние (посередине) и развернутое состояние (справа).

+ +

С точки зрения реакций нужно чтобы наш виджет взаимодействовал как с мышью, так и с клавиатурой, так же как и стандартный виджет. Давайте сначала определим, как виджет приходит в каждое состояние:

+ +
+
Виджет в нормальном состоянии когда:
+
+
    +
  • страница загружается
  • +
  • виджет был активным и пользователь кликает где-то вне виджета
  • +
  • виджет был активным и пользователь перемещает фокус на другой виджет при помощи клавиатуры
  • +
+ +
+

Замечание: Перемещение фокуса по странице обычно осуществялется клавишей "tab", но не везде. Например в Safari циклический переход между ссылками на странице осуществляется по усмолчанию комбинацией Option+Tab.

+
+
+
Виджет в активном состоянии когда:
+
+
    +
  • пользователь кликает на него
  • +
  • пользователь нажимает клавишу Tab, и он получает фокус
  • +
  • виджет был в развернутом состоянии и позователь кликает на виджет.
  • +
+
+
Виджет в развернутом состоянии:
+
+
    +
  • виджет в любом другом состоянии и пользователь кликает на него
  • +
+
+
+ +

Теперь, когда мы знаем, как изменяются состояния, важно определить, как изменить значение виджета:

+ +
+
Значение изменяется когда:
+
+
    +
  • пользователь кликает на один-из-вариантов когда виджет в развернутом состоянии
  • +
  • пользователь нажимает клавиши стрелка вверх или вниз когда виджет в активном состоянии
  • +
+
+
+ +

Наконец, давайте определим, как будут вести себя варианты виджета:

+ + + +

Для нашего примера остановимся на этом; но, если вы внимательный читатель, вы заметите, что некоторые реакции отсутствуют. Например, как вы думаете, что произойдет если пользователь нажмет клавишу "tab" когда виджет в развернутом состоянии? Ответом будет... ничего. OK, правильная реакция кажется очевидной, но поскольку она не определена в наших спецификациях, то очень легко пропустить реализацию этой реакции. Это особенно верно для командной работы, когда те, кто опеределяет какими должны быть реакции виджета сами не реализуют их.

+ +

Другой забавный пример: что произойдет, если пользователь нажмет клавишу вверх или вниз когда виджет находитися в развернутом состоянии? Это немного сложнее. Если вы предположите, что активное и развернутое состояние полностью различны, то ответом снова будет "ничего не произойдет" , потому что мы не определили никаких взаимодействий с клавиатурой в открытом состоянии. С другой стороны, если вы предположите, что активное и развернутое состояние немного похожи, значение может изменится, но выбранный вариант точно не будет соответственно подсвечен, опять же потому, что мы не определили никаких действий с клавиатуры над вариантами когда виджет находится в развернутом состоянии (мы определили только то, что произойдет, когда виджет развернется, но ничего более).

+ +

В нашем примере пропущенные спецификации очевидны, так что мы с ними справимся, но это может стать реальной проблемой для новых экзотических виджетов, когда никто не имеет ни малейшего представления о том как они должны реагировать. Всегда лучше потратить время на этом этапе дизайна, потому что если вы плохо определите, или забудете определить реакцию виджета, то будет очень сложно изменять ее, когда пользователи уже привыкнут. Если у вас есть сомнения - спросите мнения у окружающих, и, если позволяет бюджет,  не стесняйтесь выполнять пользовательские тесты. Этот процесс называется UX Design (Дизайн взаимодействия с пользователем). Если вы хотите узнать больше об этой теме, вам следует посетить следующие полезные ресурсы:

+ + + +
+

Замечание:  Также, в большинстве систем, есть способ развернуть элемент {{HTMLElement("select")}} чтобы посмотреть все доступные варианты (это то-же что кликнуть мышью элемент {{HTMLElement("select")}} ).  Это возможно комбинацией Alt+Стрелка вниз для Windows и не реализовано в нашем примере —но это будет просто сделать, так как механизм уже реализован дл события click.

+
+ +

Определение структуры и семантики HTML

+ +

Теперь, когда основной функционал виджета определен, пора начать создание виджета. Первым делом определим его HTML структуру и придадим основную семантику. Вот все что нам нужно чтобы переделать элемент {{HTMLElement("select")}}:

+ +
<!-- Это основной контейнер для нашего виджета.
+     Аттрибут tabindex позволяет пользователю переместить фокус на виджет.
+     Позже мы увидим, что лучше его установить через JavaScript. -->
+<div class="select" tabindex="0">
+
+  <!-- Этот контейнер послужит для отображения текущего значения виджета -->
+  <span class="value">Cherry</span>
+
+  <!-- Этот контейнер содержит все варинты. доступные для нашего виджета.
+       Так как это список, то есть смысл использовать элемент ul. -->
+  <ul class="optList">
+    <!-- Каждый вариант содержит то значение, которое будет отображено, позже мы увидим
+         как получить то значение, которое будет отппралено вместе с данными формы -->
+    <li class="option">Cherry</li>
+    <li class="option">Lemon</li>
+    <li class="option">Banana</li>
+    <li class="option">Strawberry</li>
+    <li class="option">Apple</li>
+  </ul>
+
+</div>
+ +

Обратите внимание на использование имен классов: они описывают каждый соответствующий элемет независимо от фактически используемых базовых элементов HTML. Важно быть уверенными что нам не придется жестко привязывать наши CSS и JavaScript к HTML структуре,тогда мы сможем позже вносить изменения не нарушая код виджета. Например, если вы захотите создать эквивалент элемента {{HTMLElement("optgroup")}}.

+ +

Создание внешнего вида с помощью CSS

+ +

Теперь у нас есть структура и мы можем заняться дизайном нашего виджета. Весь смысл создания нашего собственного виджета в том, чтобы мы могли придать ему такой внешний вид, как мы захотим. Поэтому мы разделим нашу работу с CSS на две части: в первой части будут правила CSS абсолютно необходимые чтобы реакции нашего виджета были как у элемента {{HTMLElement("select")}} , а вторая чать будет состоять из красивеньких рюшечек, чтобы виджет выглядел так, как нам нравится.

+ +

Обязательные стили

+ +

Обязательные стили - это те, которые необходимы для обработки трех состояний нашего виджета..

+ +
.select {
+  /* Это создаст контекст позиционирования для списка вариантов */
+  position: relative;
+
+  /* Это сделает наш виджет частью текстового потока и одновременно сделает его
+     изменяемого размера */
+  display : inline-block;
+}
+ +

Еще нам нужен дополнительный класс active, чтобы определить, как будет выглядеть наш виджет в активном состоянии. Так как наш виджет может находится в фокусе, то мы укажем этот стиль еще и для псевдокласса {{cssxref(":focus")}} чтобы быть уверенными, что виджет будет вести себя одинаково.

+ +
.select .active,
+.select:focus {
+  outline: none;
+
+  /* Это свойство - box-shadow - необязательно, однако нам важно видеть активное состояние
+    т.к. мы используем его по умолчанию. Можете спокойно его переопределить. */
+  box-shadow: 0 0 3px 1px #227755;
+}
+ +

Теперь давайте стилизуем список опций:

+ +
/* Селектор .select здесь применен для удобства (синтаксический сахар), чтобы быть уверенными,
+   что определяемые классы находятся в нашем виджете. */
+.select .optList {
+/* Это позволит нам быть уверенными, что список вариантов будет показан ниже значения
+   и вне HTML потока */
+  position : absolute;
+  top      : 100%;
+  left     : 0;
+}
+ +

Еще нам нужен дополнительный класс, для обращения к списку вариантов, когда он скрыт. Это необходимо чтобы справиться с различиями активного и развернутого состояния, т.к. они не совсем совпадают.

+ +
.select .optList.hidden {
+  /* Это самый простой из доступных способов путь скрыть список,
+     а о доступности мы еще поговрим в конце */
+  max-height: 0;
+  visibility: hidden;
+}
+ +

Украшательства

+ +

Теперь, когда основная функциональность на месте, можем начинать развлекаться. То, что мы сделаем дальше, является всего лишь примером того, что возможно, и будет соответствовать скриншоту в начале этой статьи. Но вы можете свободно эксперементировать и посмотреть на что вы способны.

+ +
.select {
+  /* Все размеры будут выражены в em по соображениям удобства
+     (чтобы быть уверенными, что виджет будет изменять размер если пользователь будет
+     использовать увеличение в текстовом режиме браузера). Вычисления сделаны из расчета что
+     1em == 16px что является умолчанием для большинства браузеров.
+     Если вы затрудняетесь с преобразованием px в em, попробуйте http://riddle.pl/emcalc/ */
+  font-size   : 0.625em; /* это (10px) новый размер шрифта для нашего контекста для значения
+                            em в исходном контексте */
+  font-family : Verdana, Arial, sans-serif;
+
+  -moz-box-sizing : border-box;
+  box-sizing : border-box;
+
+  /* Нам нужно добавить дополнительное пространство для стрелки вниз */
+  padding : .1em 2.5em .2em .5em; /* 1px 25px 2px 5px */
+  width   : 10em; /* 100px */
+
+  border        : .2em solid #000; /* 2px */
+  border-radius : .4em; /* 4px */
+  box-shadow    : 0 .1em .2em rgba(0,0,0,.45); /* 0 1px 2px */
+
+  /* Первое объявление - для бразуеров не поддерживающих линейный градиент.
+     Второе объявление - потому что основанные на WebKit браузеры еще не избавились от префикса в нем.
+     Если вам нужна поддержка устаревших браузеров, попробуйте http://www.colorzilla.com/gradient-editor/ */
+  background : #F0F0F0;
+  background : -webkit-linear-gradient(90deg, #E3E3E3, #fcfcfc 50%, #f0f0f0);
+  background : linear-gradient(0deg, #E3E3E3, #fcfcfc 50%, #f0f0f0);
+}
+
+.select .value {
+  /* Так как значение может быть шире, чем наш виджет, нужно быть уверенными, что оно не изменит
+     ширину виджета */
+  display  : inline-block;
+  width    : 100%;
+  overflow : hidden;
+
+  vertical-align: top;
+
+  /* И, если содержимое слишком длинное, лучше иметь красивенькие точечки. */
+  white-space  : nowrap;
+  text-overflow: ellipsis;
+}
+ +

Нам не нужен дополнительный элемент, чтобы создать стрелку вниз; вместо этого мы используем псевдоэлемент {{cssxref(":after")}}. Также её можно создать при помощи простого фонового изображения в классе select.

+ +
.select:after {
+  content : "▼"; /* Мы используем Unicode символ U+25BC; смотрите http://www.utf8-chartable.de */
+  position: absolute;
+  z-index : 1; /* Важно чтобы стрелка не перекрывала элементы списка */
+  top     : 0;
+  right   : 0;
+
+  -moz-box-sizing : border-box;
+  box-sizing : border-box;
+
+  height  : 100%;
+  width   : 2em;  /* 20px */
+  padding-top : .1em; /* 1px */
+
+  border-left  : .2em solid #000; /* 2px */
+  border-radius: 0 .1em .1em 0;  /* 0 1px 1px 0 */
+
+  background-color : #000;
+  color : #FFF;
+  text-align : center;
+}
+ +

Далее стилизуем список вариантов:

+ +
.select .optList {
+  z-index : 2; /* Мы явно сказали, что список вариантов всегда будет перекрывать стрелку вниз */
+
+  /* это сбросит значения стиля по умолчанию для элемента ul */
+  list-style: none;
+  margin : 0;
+  padding: 0;
+
+  -moz-box-sizing : border-box;
+  box-sizing : border-box;
+
+  /* Это для того, чтобы убедиться что если значения будут короче виджета
+     то список вариантов останется таким же по размеру как и сам виджет */
+  min-width : 100%;
+
+  /* В случае, если список слишком длинный, его содержимое не будет помещаться по вертикали
+     (что автоматически добавит полосу прокрутки), но этого никогда не произойдет по горизонтали
+     (потому что мы не установили ширину и содержимое списка будет регулировать ее
+     автоматически. Если это будет невозможно - содержимое будет обрезано.) */
+  max-height: 10em; /* 100px */
+  overflow-y: auto;
+  overflow-x: hidden;
+
+  border: .2em solid #000; /* 2px */
+  border-top-width : .1em; /* 1px */
+  border-radius: 0 0 .4em .4em; /* 0 0 4px 4px */
+
+  box-shadow: 0 .2em .4em rgba(0,0,0,.4); /* 0 2px 4px */
+  background: #f0f0f0;
+}
+ +

Для вариантов нам нужно добавить класс highlight чтобы сделать возможным индентифицировать значение которе пользователь выберет (или выбрал).

+ +
.select .option {
+  padding: .2em .3em; /* 2px 3px */
+}
+
+.select .highlight {
+  background: #000;
+  color: #FFFFFF;
+}
+ +

Итак, вот результат с нашими тремя состояниями:

+ + + + + + + + + + + + + + + + + + + +
Основное состояниеАктивное состояниеРазвернутое состояние
{{EmbedLiveSample("Basic_state",120,130, "", "HTML/Forms/How_to_build_custom_form_widgets/Example_1")}}{{EmbedLiveSample("Active_state",120,130, "", "HTML/Forms/How_to_build_custom_form_widgets/Example_1")}}{{EmbedLiveSample("Open_state",120,130, "", "HTML/Forms/How_to_build_custom_form_widgets/Example_1")}}
Посмотреть исходный код
+ +

Оживи свой виджет с JavaScript

+ +

Теперь, когда наш дизайн и структура готовы, мы можем написать код на JavaScript чтобы виджет действительно заработал.

+ +
+

Предупреждение: Следующий код представлен в образовательных целях и не может быть использован как-есть. Помимо прочего, как мы убедимся, он не пригоден для дальнейшего развития и не будет работать в устаревших браузерах. В нем также есть избыточность которую необходимо оптимизировать использования в рабочем режиме.

+
+ +
+

Замечание: Создание многократно используемых виджетов может быть немного сложнее. W3C Web Component draft является одним из ответов на этот конкретный вопрос. The X-Tag project попытка реализовать эту спецификацию; пожалуйста, посмотрите этот проект.

+
+ +

Почему он не работает?

+ +

Прежде чем мы начнем, запомните одну важную вещь о JavaScript: в браузере это ненадежная технология. Когда вы создаете пользовательские виджеты, вы будете полагаться на JavaScript потому что это необходимое звено для связки. Однако во многих случаях  JavaScript невозможно запустить в браузере:

+ + + +

Из-за этого очень важно серьезно подумать о том, что произойдет, если JavaScript не сработает. Детальное рассмотрение этой проблемы выходит за рамки данной статьи, поскольку эта проблема тесно связана с тем, насколько универсальным и многократно используемым вы хотите сделать свой сценарий, но мы рассмотрим основы этого в нашем примере.

+ +

В нашем примере, если наш JavaScript код не работает, мы используем стандартный элемент {{HTMLElement("select")}}. Для этого, нам нужны две вещи.

+ +

Во-первых нам нужно добавить стандартный элемент {{HTMLElement("select")}} перед каждым использованием нашего пользовательского виджета. Это также необходимо, чтобы отправить данные из нашего пользовательского виджета вместе с остальными данными формы; подробнее рассмотрим это позже.

+ +
<body class="no-widget">
+  <form>
+    <select name="myFruit">
+      <option>Cherry</option>
+      <option>Lemon</option>
+      <option>Banana</option>
+      <option>Strawberry</option>
+      <option>Apple</option>
+    </select>
+
+    <div class="select">
+      <span class="value">Cherry</span>
+      <ul class="optList hidden">
+        <li class="option">Cherry</li>
+        <li class="option">Lemon</li>
+        <li class="option">Banana</li>
+        <li class="option">Strawberry</li>
+        <li class="option">Apple</li>
+      </ul>
+    </div>
+  </form>
+
+</body>
+ +

Во-вторых нам нужно два новых класса, чтобы скрыть ненужные элементы (то есть  "настоящие" элементы {{HTMLElement("select")}}, если скрипт запустился, или наш пользовательский виджет, если скрипт не запустился). По умолчанию наш HTML код скрывает наш пользовательский виджет.

+ +
.widget select,
+.no-widget .select {
+  /* Этот CSS селектор значит:
+     - или мы присваиваем классу body значение "widget" и таким образом мы скрываем элемент {{HTMLElement("select")}}
+     - или мы не меняем класс body, тогда класс body остается в значении "no-widget",
+       и элементы, чей класс "select" будут скрыты */
+  position : absolute;
+  left     : -5000em;
+  height   : 0;
+  overflow : hidden;
+}
+ +

Теперь нам нужен модуль JavaScript, чтобы определить, запущен скрипт или нет. Этот модуль очень простой: если наш скрипт запустится во время загрузки страницы, то он удалит класс класс no-widget и добавит класс widget, чем поменяет видимость элемента  {{HTMLElement("select")}} и нашего пользовательского виджета.

+ +
window.addEventListener("load", function () {
+  document.body.classList.remove("no-widget");
+  document.body.classList.add("widget");
+});
+ + + + + + + + + + + + + + + + + +
Без JSС JS
{{EmbedLiveSample("No_JS",120,130, "", "HTML/Forms/How_to_build_custom_form_widgets/Example_2")}}{{EmbedLiveSample("JS",120,130, "", "HTML/Forms/How_to_build_custom_form_widgets/Example_2")}}
Посмотреть исходный код
+ +
+

Замечание: Если вы действительно хотите сделать свой код универсальным и многоразовым, то вместо переключения классов гораздо лучше просто добавить класс элементам {{HTMLElement("select")}} чтобы их скрыть, и динамически добавлять дерево DOM представляющее пользовательский виджет после каждого элемента {{HTMLElement("select")}} на странице.

+
+ +

Облегчение работы

+ +

В коде который мы собираемся написать, для выполнения всех необходимых действий мы будем использовать стандартный DOM API. Однако, хотя поддержка DOM API в браузерах стала гораздо лучше, все еще есть нюансы с устраевшеними браузерами  (особенно со старым добрым Internet Explorer).

+ +

Чтобы избежать неприятностей с устаревшими браузерами есть два способа: использовать отдельный фреймворк такой как jQuery, $dom, prototype, Dojo, YUI, и т.п., или самостоятельно реализовать недостающие функции которые вам нужны (что можно легко сделать через условную загрузку, например используя библиотеку yepnope).

+ +

Мы планируем использовать следующие функции (от самых рискованных до самых безопасных):

+ +
    +
  1. {{domxref("element.classList","classList")}}
  2. +
  3. {{domxref("EventTarget.addEventListener","addEventListener")}}
  4. +
  5. forEach (This is not DOM but modern JavaScript)
  6. +
  7. {{domxref("element.querySelector","querySelector")}} and {{domxref("element.querySelectorAll","querySelectorAll")}}
  8. +
+ +

Помимо доступности этих специфических функций, остается еще одна проблема чтобы начать. Объект возвращаемый функцией {{domxref("element.querySelectorAll","querySelectorAll()")}} имеет тип {{domxref("NodeList")}} что отличается от Array. Это важно потому, что объекты  Array поддерживают функцию forEach, а {{domxref("NodeList")}} не поддерживает. Так как  {{domxref("NodeList")}} очень похож на Array и нам очень удобно использовать forEach, мы можем просто добавить forEach к объекту {{domxref("NodeList")}} чтобы облегчить нам жизнь, например так:

+ +
NodeList.prototype.forEach = function (callback) {
+  Array.prototype.forEach.call(this, callback);
+}
+ +

Мы не шутили, когда сказали, что это легко сделать.

+ +

Создание процедур обработки событий

+ +

Итак, начало положено, и мы можем приступить к функциям, которые будут использоваться для взаимодействия с пользователем.

+ +
// Эта функция будет вызываться каждый раз, когда наш виджет будет деактивирован
+// Ей передается один параметр
+// select : DOM нода класса `select` который должен быть деактивирован
+function deactivateSelect(select) {
+
+  // Если виджет не активен, то и делать-то нечего
+  if (!select.classList.contains('active')) return;
+
+  // Получаем список опций для нашего виджета
+  var optList = select.querySelector('.optList');
+
+  // Закрываем список опций
+  optList.classList.add('hidden');
+
+  // и деактивируем сам виджет
+  select.classList.remove('active');
+}
+
+// Эта функция бедт вызываться какждый раз, когда пользователь захочет (де)активровать наш виджет
+// Ей передаются два параметра:
+// select : DOM нода класса `select` для активации
+// selectList : список всех DOM нод с классом `select`
+function activeSelect(select, selectList) {
+
+  // Если виджет активен, то и делать-то нечего
+  if (select.classList.contains('active')) return;
+
+  // Нам нужно отключить активное состояние всех наших виджетов
+  // Так как функция deactivateSelect соответствует всем требованиям
+  // функции forEach мы вызываем ее без использования промежуточной анонимной функции
+  selectList.forEach(deactivateSelect);
+
+  // А теперь мы возвращаем активное состояние нужного виджета
+  select.classList.add('active');
+}
+
+// Эта функция будет вызываться каждый раз, когда пользователь будет открывать/закрывать список вариантов
+// Ей передается один параметр:
+// select : DOM нода со списком для переключения состояния
+function toggleOptList(select) {
+
+  // Список хранится в виджете
+  var optList = select.querySelector('.optList');
+
+  // Мы меняем класс виджета чтобы показать/скрыть его
+  optList.classList.toggle('hidden');
+}
+
+// Эта функция будет вызываться каждый раз, когда нам нужно подсветить вариант
+// Ей передаются два параметра:
+// select : DOM нода класса `select` содержащая вариант для подсветки
+// option : DOM нода класса `option` для подсветки
+function highlightOption(select, option) {
+
+  // Мы получаем список всех вариантов доступных в нашем элементе
+  var optionList = select.querySelectorAll('.option');
+
+  // Мы удаляем подсветку всех вариантов
+  optionList.forEach(function (other) {
+    other.classList.remove('highlight');
+  });
+
+  // Подсвечиваем нужный вариант
+  option.classList.add('highlight');
+};
+ +

Это все, что вам нужно для обработки различных состояний пользовательского виджета.

+ +

Далее мы связываем эти функции с соответствующими событиями:

+ +
// Мы обрабатываем событие при загрузке документа.
+window.addEventListener('load', function () {
+  var selectList = document.querySelectorAll('.select');
+
+  // Каждый наш собственный виджет должен быть проинициализирован
+  selectList.forEach(function (select) {
+
+    // также как и его элементы `option`
+    var optionList = select.querySelectorAll('.option');
+
+    // Когда пользователь проводит мышью над элементом `option`, мы подсвечиваем этот вариант
+    optionList.forEach(function (option) {
+      option.addEventListener('mouseover', function () {
+        // Замечание: использование переменных `select` и `option`
+        // ограничено рамками нашей функции.
+        highlightOption(select, option);
+      });
+    });
+
+    // Когда позоватль кликает на наш виджет
+    select.addEventListener('click', function (event) {
+       // Замечание: использование переменной `select`
+       // ограничено рамками нашей функции.
+
+       // Мы переключаем видимость списка вариантов
+      toggleOptList(select);
+    });
+
+    // Когда виджет получает фокус
+    // Виджет получает фокус когда пользователь кликает на него
+    // или переходит на него клавишей табуляции
+    select.addEventListener('focus', function (event) {
+      // Замечание: использование переменных `select` и `selectList`
+      // ограничено рамками нашей функции.
+
+      // Мы активируем наш виджет
+      activeSelect(select, selectList);
+    });
+
+    // Когда виджет теряет фокус
+    select.addEventListener('blur', function (event) {
+      // Замечание: использование переменной `select`
+      // ограничено рамками нашей функции.
+
+      // Мы деактивируем виджет
+      deactivateSelect(select);
+    });
+  });
+});
+ +

В этот момент наш виджет будет изменятт состояние в соответствии с нашим дизайном, но не будет обновлять его значение. С этим мы разберемся дальше.

+ + + + + + + + + + + + + + + +
Пример
{{EmbedLiveSample("Change_states",120,130, "", "HTML/Forms/How_to_build_custom_form_widgets/Example_3")}}
Посмотреть исходный код
+ +

Обработка значения виджета

+ +

Теперь, когда наш виджет работает, мы должны добавить код, чтобы обновить его значение в соответствии с выбором пользователя и сделать возможным отправку этого значения вместе с данными формы.

+ +

Самый простой способ сделать это - использовать встроенный виджет который также есть в нашей форме. Такой виджет будет отслеживать значение со всеми встроенными элементами управления, предоставленными браузером, и значение будет отправлено, как обычно, при отправке формы. Нет смысла заново изобретать велосипед, когда все это уже сделано за нас.

+ +

Как было показано ранее, у нас есть стандартный виджет {{HTMLElement("select")}} в качестве запасного варианта для повышения доступности; поэтому мы просто синхронизируем его значение с нашим собственнным виджетом:

+ +
// Эта функция обновляет отображенное значение и синхронизирует его со стандартным виджетом
+// Ей передается два параметра:
+// select : DOM нода класса `select` содержащая значение которое будет обновлено
+// index  : индекс выбранного значения
+function updateValue(select, index) {
+  // Нам нужно получить стандартный виджет для данного пользовательского
+  // В нашем примере стандартный виджет является братом (sibling) пользовательского виджета
+  var nativeWidget = select.previousElementSibling;
+
+  // Нам также нужно получить значение заполнителя нашего пользовательского виджета
+  var value = select.querySelector('.value');
+
+  // И нам нужен весь список вариантов
+  var optionList = select.querySelectorAll('.option');
+
+  // Установим значение текущего номера выбранного элемента равным index
+  nativeWidget.selectedIndex = index;
+
+  // Соответственно установим значение заполнителя
+  value.innerHTML = optionList[index].innerHTML;
+
+  // И мы подсвечиваем соответствующий вариант нашего пользовательского виджета
+  highlightOption(select, optionList[index]);
+};
+
+// Эта функция возвращает текущий номер выбранного элемента в стандартном виджете
+// Ей передается один параметр:
+// select : DOM нода класса `select` соответствующая стандарному виджету
+function getIndex(select) {
+  // Нам нужно получить доступ к стандартному виджету соответствующему данному
+  // пользовательскому виджету
+  // В нашем примере стандартный виджет - брат (sibling) пользовательского виджета
+  var nativeWidget = select.previousElementSibling;
+
+  return nativeWidget.selectedIndex;
+};
+ +

Исползуя эти две функции мы можем связать стандартный виджет с пользовательским:

+ +
// Мы обрабатываем привязку события при загрузке документа.
+window.addEventListener('load', function () {
+  var selectList = document.querySelectorAll('.select');
+
+  // Каждый пользовательский виджет необходимсо инциализировать:
+  selectList.forEach(function (select) {
+    var optionList = select.querySelectorAll('.option'),
+        selectedIndex = getIndex(select);
+
+    // Мы делаем наш пользовательский виджет фокусируемым
+    select.tabIndex = 0;
+
+    // Мы делаем стандартный виджет более не фокусируемым
+    select.previousElementSibling.tabIndex = -1;
+
+    // Убеждаемся, что выбранное по умолчанию значение корректно отображено
+    updateValue(select, selectedIndex);
+
+    // Кажды раз когда пользователь кликает на вариант, мы соответсвенно обновляем значение
+    optionList.forEach(function (option, index) {
+      option.addEventListener('click', function (event) {
+        updateValue(select, index);
+      });
+    });
+
+    // Когда виджет находится в фокусе, с каждым нажатием на клаиатуре, мы соответственно
+    // обновляем  значение
+    select.addEventListener('keyup', function (event) {
+      var length = optionList.length,
+          index  = getIndex(select);
+
+      // Когда пользователь нажимает стрелку вниз, мы переходим на следующий вариант
+      if (event.keyCode === 40 && index < length - 1) { index++; }
+
+      // Когда пользователь нажимает стрелку вверх, мы переходим на предыдущий вариант
+      if (event.keyCode === 38 && index > 0) { index--; }
+
+      updateValue(select, index);
+    });
+  });
+});
+ +

В приведенном выше коде стоить отметить совйство tabIndex. Использование этого свойства необходимо чтобы стандартный виджет никогда не получил фокус, и чтобы убедиться, что наш пользовательский виджет получает фокус когда пользователь использует клавиатуру или мышь.

+ +

С этим мы закончили! Вот результат:

+ + + + + + + + + + + + + + + +
Пример
{{EmbedLiveSample("Change_states",120,130, "", "HTML/Forms/How_to_build_custom_form_widgets/Example_4")}}
Посмотреть исходный код
+ +

Но секундочку, мы точно закончили?

+ +

Делаем доступным

+ +

Мы создали нечто работающее, и, хотя это далеко от полнофункционального селектбокса, работает это хорошо. Однако то, что мы сделали, это не более, чем возня с DOM. У него нет настоящей семантики, и хотя оно выглыдит как селектбокс, с точки зрения браузера - это не так, поэтому вспомогательные технологии не смогут понять что это селектбокс. Короче говоря, этот хорошенький селектбокс не является доступным для людей с ограниченными возможностями!

+ +

К счастью существует решение, и оно называется ARIA. ARIA - аббревиатура для "Accessible Rich Internet Application" (Доступное всем интернет приложение), и представляет собой W3C спецификацию специально разработанную для того, что мы здесь делаем: делаем веб приложения и пользовательские виджеты ассистивными (доступными для людей с ограниченными возможностями). В основном, это набор атрибутов, которые расширяют HTML, чтобы мы смогли лучше описать роли, состояния и свойства, так что только что изобретенный элемент выглядит как будто он был тем стандартным, за которого он себя выдает. Использовать эти атрибуты очень просто, поэтому давайте сделаем это.

+ +

Аттрибут role

+ +

Ключевой аттрибут используемый в ARIA - это role. Аттрибут role принимает значение, определяющее для чего используется элемент. Каждая роль определяет свои собственные требования и поведение. В нашем примере мы используем роль listbox. Это "составная роль" ("composite role"), т.е. элементы такой роли имеют потомков, у каждого из которых есть отдельная роль (в данном случае, как минимум один дочерний элемент с ролью option).

+ +

Стоит также отметить что ARIA определяет роли, которые по умолчанию применяются к стандартной разметке HTML. Например, элемент {{HTMLElement("table")}} соответствует роли grid, а элемент {{HTMLElement("ul")}} соответствует роли list. Так как мы используем элемент {{HTMLElement("ul")}}, то нам необходимо убедиться что роль listbox нашего виджета заменит роль list элемента {{HTMLElement("ul")}}. С этой целью, мы будем использовать роль presentation. Эта роль разработана чтобы можно было отметить, что элемент не имеет особого значения, а используется исключительно чтобы представить информацию. Мы применим его к нашему элемету {{HTMLElement("ul")}}.

+ +

Чтобы ввести роль listbox нам нужно просто внести следующие изменения в HTML:

+ +
<!-- Мы добавили аттрибут role="listbox" в наш элемент верхнего уровня -->
+<div class="select" role="listbox">
+  <span class="value">Cherry</span>
+  <!-- Также мы добавили аттрибут role="presentation" в элемент ul -->
+  <ul class="optList" role="presentation">
+    <!-- И мы добавили аттрибут role="option" во все элементы li -->
+    <li role="option" class="option">Cherry</li>
+    <li role="option" class="option">Lemon</li>
+    <li role="option" class="option">Banana</li>
+    <li role="option" class="option">Strawberry</li>
+    <li role="option" class="option">Apple</li>
+  </ul>
+</div>
+ +
+

Замечание: Включение как атрибута role так и атрибута class необходимо только если вы хотите обеспечить поддержку устаревших браузеров, которые не поддерживают  селекторы атрибутов CSS.

+
+ +

Атрибут aria-selected 

+ +

Использовать только аттрибут role недостаточно. ARIA также предоставляет множество атрибутов состояний и свойств. Чем больше и уместнее вы их используете, тем ваш виджет будет более понятен для вспомогательных технологий. В нашем случае мы ограничимся использованием одного аттрибута: aria-selected.

+ +

Атрибут aria-selected используется для отметки текущего выбранного варианта; это позволяет ассистивным технологиям информировать пользователя о текущем выборе. Мы будем используя JavaScript динамически отмечать выбранный вариант каждый раз, когда пользователь его выбирает. С этой целью нам нужно пересмотреть нашу функцию updateValue():

+ +
function updateValue(select, index) {
+  var nativeWidget = select.previousElementSibling;
+  var value = select.querySelector('.value');
+  var optionList = select.querySelectorAll('.option');
+
+  // Мы уверены что все варианты не выбраны
+  optionList.forEach(function (other) {
+    other.setAttribute('aria-selected', 'false');
+  });
+
+  // Мы уверены что выбранный вариант отмечен
+  optionList[index].setAttribute('aria-selected', 'true');
+
+  nativeWidget.selectedIndex = index;
+  value.innerHTML = optionList[index].innerHTML;
+  highlightOption(select, optionList[index]);
+};
+ +

Вот окончательный результат всех этих изменений (вы сможете это лучше прочувствовать если испробуете это со вспомогательными технологиями, такими как NVDA или VoiceOver):

+ + + + + + + + + + + + + + + +
Пример
{{EmbedLiveSample("Change_states",120,130, "", "HTML/Forms/How_to_build_custom_form_widgets/Example_5")}}
Посмотреть исходный код
+ +

Заключение

+ +

Мы рассмотрели все основы создания пользовательского виджета формы, и это, как вы видите, нетривиальная задача, и часто проще и лучше положиться на сторонние библиотеки, чем писать их самому с нуля (если, конечно, ваша цель - не создать такую библиотеку).

+ +

Вот несколько библиотек, которые вам стоит рассмотреть перед тем как создавать собственную:

+ + + +

Если вы хотите двигаться далее, то код в этом примере нуждается в некоторм улучшении прежде чем станет универсальным и многоразовым. Это упражнение, которое вы можете попробовать выполнить. Две подсказки, которые помогут вам в этом: первый аргумент всех наших функций одинаков, это значит что эти функции должны быть в одном контексте. Было бы разумным создать объект для совместного использования этого контекста. Также вам нужно сделать его функциональным; это значит, что ему необходимо одинаково хорошо работать с различными браузерами, чья соместимость с  Web стандартами  очень отличается. Повеселись!

+ +

{{PreviousMenuNext("Learn/HTML/Forms/Form_validation", "Learn/HTML/Forms/Sending_forms_through_JavaScript", "Learn/HTML/Forms")}}

+ +

В этом модуле

+ + diff --git a/files/ru/learn/forms/how_to_structure_a_web_form/index.html b/files/ru/learn/forms/how_to_structure_a_web_form/index.html new file mode 100644 index 0000000000..741d773dba --- /dev/null +++ b/files/ru/learn/forms/how_to_structure_a_web_form/index.html @@ -0,0 +1,320 @@ +--- +title: Как структурировать HTML-формы +slug: Learn/HTML/Forms/How_to_structure_an_HTML_form +tags: + - HTML-форма + - Веб-форма + - Изучение + - Новичок + - Структурирование + - Форма +translation_of: Learn/Forms/How_to_structure_a_web_form +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/HTML/Forms/Ваша_первая_HTML_форма", "Learn/HTML/Forms/Стандартные_виджеты_форм", "Learn/HTML/Forms")}}
+ +

Получив базовые знания, теперь мы более подробно рассмотрим элементы, используемые для придания структуры и значения различным частям форм.

+ + + + + + + + + + + + +
Уровень подготовки:Основы компьютерной грамотности, и базовые знания HTML.
Цель:Разобраться как структурировать HTML формы и задавать им семантику для того, чтобы они были удобны и доступны в использовании.
+ +

Гибкость HTML форм делает их одной из самых сложных структур в HTML; вы можете создать любую форму, используя элементы и атрибуты форм. Использование правильной структуры, при создании HTML форм, поможет гарантировать их удобство и доступность.

+ +

Элемент <form>

+ +

Элемент {{HTMLElement("form")}} формально определяет форму и атрибуты, которые определяют поведение этой формы. Каждый раз, когда вы хотите создать HTML-форму, вам нужно начать с создания элемента {{HTMLElement("form")}}, поместив внутрь него всё содержимое. Многие вспомогательные технологии или браузерные плагины могут обнаруживать элементы {{HTMLElement("form")}} и реализовывать специальные хуки, чтобы их было проще использовать.

+ +

Мы уже встречались с этим в предыдущей статье.

+ +
+

Внимание: Строго запрещается размещать форму внутри другой формы. Такое размещение может привести к непредсказуемому поведению форм, в зависимости от браузера. 

+
+ +

Стоит учесть, что всегда можно использовать элементы формы вне {{HTMLElement("form")}}. Тогда по умолчанию этот элемент формы не имеет ничего общего со всеми формами. Вы можете связать его с формой с помощью аттрибута form. В HTML5 был представлен аттрибут form для элементов HTML форм, который позволяет  явно связать элемент с формой, даже если он не заключён внутри {{ HTMLElement("form") }}.

+ +

Элементы <fieldset> и <legend>

+ +

Элемент {{HTMLElement("fieldset")}} - это удобный способ стилистической и семантической группировки элементов формы. Вы можете установить заголовок {{HTMLElement("fieldset")}}, добавив элемент {{HTMLElement("legend")}} сразу после открывающего тега {{HTMLElement("fieldset")}}. Текст элемента {{HTMLElement("legend")}} формально описывает назначение содержимого {{HTMLElement("fieldset")}}.

+ +

Различные вспомогательные технологии будут использовать {{HTMLElement("legend")}} как часть метки label всех элементов внутри {{HTMLElement("fieldset")}}. Например, такие экранные дикторы как Jaws или NVDA произносят заголовок формы {{HTMLElement("legend")}} перед произношением названия меток элементов.

+ +

Небольшой пример:

+ +
<form>
+  <fieldset>
+    <legend>Fruit juice size</legend>
+    <p>
+      <input type="radio" name="size" id="size_1" value="small">
+      <label for="size_1">Small</label>
+    </p>
+    <p>
+      <input type="radio" name="size" id="size_2" value="medium">
+      <label for="size_2">Medium</label>
+    </p>
+    <p>
+      <input type="radio" name="size" id="size_3" value="large">
+      <label for="size_3">Large</label>
+    </p>
+  </fieldset>
+</form>
+ +
+

Примечание: Вы можете найти этот пример в fieldset-legend.html (также посмотрите на результат).

+
+ +

Читая эту форму, экранный диктор произнесёт "Fruit juice size small" для первого элемента, "Fruit juice size medium" - для второго, "Fruit juice size large" - для третьего.

+ +

Вариант использования в этом примере является одним из наиболее важных. Каждый раз, когда у вас есть набор переключателей, вам нужно поместить их внутри {{HTMLElement("fieldset")}}. Также {{HTMLElement("fieldset")}} можно использовать для разделения формы. В идеале, длинную форму разделяют на несколько страниц, однако, если она должна находиться на одной странице, распределение связанных элементов в разные {{HTMLElement("fieldset")}} может повысить удобство использования.

+ +

Из-за своего влияния на вспомогательные технологии элемент {{HTMLElement("fieldset")}} является одним из ключевых элементов для построения доступных форм; однако вы не должны им злоупотреблять. Если возможно, старайтесь проверять, как экранный диктор интерпретирует вашу форму. 

+ +

Элемент <label>

+ +

В предыдущей статье мы увидели, что элемент {{HTMLElement("label")}} принято использовать для указания текстов-подсказок (лейблов) в HTML-формах. Это самый важный элемент для построения доступных форм — при правильной реализации скринридеры будут озвучивать текст-подсказку вместе со связанными элементами. Посмотрите на этот пример из предущей статьи:

+ +
<label for="name">Name:</label> <input type="text" id="name" name="user_name">
+ +

При правильно связанном элементе <label> с элементом <input> через атрибуты for и id соответственно (атрибут for ссылается на атрибут id соответствующего виджета формы), скринридер прочтет вслух что-то наподобие "Name, edit text".

+ +

Если <label> не правильно установлен, скринридер прочитает это как "Edit text blank", что не несет в себе никакой уточняющей информации, позволяющей понять предназначение данного текстового поля.

+ +

Обратите внимание на то, что виджет формы может быть вложен в элемент {{HTMLElement("label")}}, как на примере:

+ +
<label for="name">
+  Name: <input type="text" id="name" name="user_name">
+</label>
+ +

Однако даже в таких случаях лучшей всё равно указывать атрибут for, так как некоторые вспомогательные технологии не распознают неявную связь между текстами-подсказками и виджетами.

+ +

Лейблы тоже кликабельны!

+ +

Ещё одно преимущество при правильно установленных текстах-подсказках заключается в том, что по ним можно кликнуть для активации связанных с ними виджетов. Это поддерживается во всех браузерах. Это удобно как для текстовых полей ввода, в которых устанавливается фокус при клике на текст-посказку, так и для радио-кнопок и чекбоксов — область попадания такого элемента управления может быть очень маленькой, поэтому полезно сделать ее как можно больше.

+ +

Например:

+ +
<form>
+  <p>
+    <label for="taste_1">I like cherry</label>
+    <input type="checkbox" id="taste_1" name="taste_cherry" value="1">
+  </p>
+  <p>
+    <label for="taste_2">I like banana</label>
+    <input type="checkbox" id="taste_2" name="taste_banana" value="2">
+  </p>
+</form>
+ +
+

Примечание: Вы можете посмотреть этот пример тут checkbox-label.html (также можно посмотреть код вживую).

+
+ +

Несколько лейблов

+ +

На самом деле вы можете добавить несколько текстов-подсказок на один виджет формы, но это не очень хорошая идея, так как у некоторых вспомогательных технологий могут возникнуть проблемы с обработкой такой структуры. Вместо использования нескольких лейблов, лучше вложить виджет формы внутрь одного элемента {{htmlelement("label")}}. 

+ +

Рассмотрим этот пример:

+ +
<p>Required fields are followed by <abbr title="required">*</abbr>.</p>
+
+<!-- Тогда это: -->
+<div>
+  <label for="username">Name:</label>
+  <input type="text" name="username">
+  <label for="username"><abbr title="required">*</abbr></label>
+</div>
+
+<!-- лучше сделать таким образом: -->
+<div>
+  <label for="username">
+    <span>Name:</span>
+    <input id="username" type="text" name="username">
+    <abbr title="required">*</abbr>
+  </label>
+</div>
+
+<!-- Но этот вариант лучше всего: -->
+<div>
+  <label for="username">Name: <abbr title="required">*</abbr></label>
+  <input id="username" type="text" name="username">
+</div>
+ +

{{EmbedLiveSample("Multiple_labels", 120, 120)}}

+ +

Параграф на первой строке примера описывает правило для обязательных элементов. Вначале необходимо убедиться, что вспомогательные технологии, такие как программы чтения с экрана, отображают или озвучивают их пользователю, прежде чем он найдет требуемый элемент. Таким образом они будут знать, что означает звёздочка. Программа чтения с экрана будет произносить звёздочку как «звёздочку» или «обязательно», в зависимости от настроек программы чтения с экрана — в любом случае, первый абзац даёт понимание того, что будет означать звёздочка далее в форме.

+ + + +
+

Примечение: В зависимости от программы для чтения с экрана результаты могут немного отличаться. В данной статье для тестирования использовался VoiceOver (NVDA ведет себя аналогично). Также мы были бы рады, если бы вы поделились своим опытом.

+
+ +
+

Примечание: Вы можете найти этот пример на GitHub required-labels.html (также можно посмотреть вживую). Запускайте пример, закомментировав остальные, иначе скриридеры не смогут правильно распознать контент, если у вас будет несколько лейблов и несколько текстовых полей с одинаковым ID!

+
+ +

Частоиспользуемые с формами HTML-структуры

+ +

Помимо структур, характерных только для HTML-форм, хорошо помнить, что формы — это просто HTML. Это означает, что вы можете использовать всю мощь HTML для структурирования HTML-формы.

+ +

Как вы можете заметить в примерах, оборачивать лейбл и виджет формы в элемент {{HTMLElement("div")}} — это общепринятая практика. Элемент {{HTMLElement("p")}} также часто используется, как и HTML-списки (последние часто используются для структурирования множественных чекбоксом или радио-кнопок).

+ +

В добавок к элементу {{HTMLElement("fieldset")}} часто используют HTML-заголовки (например, {{HTMLElement("h1")}}, {{HTMLElement("h2")}}) и секционирование (например, {{HTMLElement("section")}}) для стуктурирования сложных форм.

+ +

Прежде всего, вам нужно найти стиль, который будет удобен именно вам для программирования и который также позволит создавать доступные и удобные формы.

+ +

Каждый отдельный раздел функциональности содержится в элементах {{HTMLElement ("section")}} и {{HTMLElement ("fieldset")}}, содержащий переключатели. Каждый отдельный раздел функциональности должен находиться в отдельном элементе {{HTMLElement ("section")}} с элементами {{HTMLElement ("fieldset")}}, содержащими переключатели.

+ +

Активное обучение: построение структуры формы

+ +

Давайте применим эти идеи на практике и построим более сложноструктурируемую форму — формы оплаты. Форма будет содержать некоторые типы виджетов формы, которые вы можете пока не понять — не переживайте об этом, вы найдёте информацию в следующей статье (Основные нативные элементы управления формами). А пока внимательно прочитайте описание, следуя приведенным ниже инструкциям, и начинайте формировать представление о том, какие элементы обёртки мы используем для структурирования формы и почему.

+ +
    +
  1. Для начала сделайте локальную копию пустого шаблона и CSS для нашей платёжной формы в новой директории на вашем компьютере.
  2. +
  3. Сначала подключите CSS к HTML, добавив следующую строку кода внутрь HTML-елемента {{htmlelement("head")}}: +
    <link href="payment-form.css" rel="stylesheet">
    +
  4. +
  5. Далее начните создавать свою форму с добавления внешнего элемента {{htmlelement("form")}}: +
    <form>
    +
    +</form>
    +
  6. +
  7. Внутри тега <form>, добавьте заголовок и параграф, информирующий пользователей о том, как помечены поля, обязательные для заполнения: +
    <h1>Payment form</h1>
    +<p>Required fields are followed by <strong><abbr title="required">*</abbr></strong>.</p>
    +
  8. +
  9. Далее нам надо добавить более крупный кусок кода под нашей предыдущей записью. Здесь вы можете увидеть, что мы оборачиваем поля с контактной информацией в отдельный элемент {{htmlelement("section")}}. Более того, у нас есть набор из двух радио-кнопок, каждую из которых мы помещаем в отдельный элемент списка ({{htmlelement("li")}}). Наконец, у нас есть два текстовых поля {{htmlelement("input")}} и связанные с ними элементы {{htmlelement("label")}}, которые находятся внутри элементов {{htmlelement("p")}}, а также поле для ввода пароля. Добавьте этот код в вашу форму: +
    <section>
    +    <h2>Contact information</h2>
    +    <fieldset>
    +      <legend>Title</legend>
    +      <ul>
    +          <li>
    +            <label for="title_1">
    +              <input type="radio" id="title_1" name="title" value="M." >
    +              Mister
    +            </label>
    +          </li>
    +          <li>
    +            <label for="title_2">
    +              <input type="radio" id="title_2" name="title" value="Ms.">
    +              Miss
    +            </label>
    +          </li>
    +      </ul>
    +    </fieldset>
    +    <p>
    +      <label for="name">
    +        <span>Name: </span>
    +        <strong><abbr title="required">*</abbr></strong>
    +      </label>
    +      <input type="text" id="name" name="username">
    +    </p>
    +    <p>
    +      <label for="mail">
    +        <span>E-mail: </span>
    +        <strong><abbr title="required">*</abbr></strong>
    +      </label>
    +      <input type="email" id="mail" name="usermail">
    +    </p>
    +    <p>
    +      <label for="pwd">
    +        <span>Password: </span>
    +        <strong><abbr title="required">*</abbr></strong>
    +      </label>
    +      <input type="password" id="pwd" name="password">
    +    </p>
    +</section>
    +
  10. +
  11. Сейчас мы перейдём к второму разделу <section> нашей формы — платёжной информации. В этом разделе у нас есть три отдельных виджета формы со связанными с ними лейблами, находящимися внутри тега <p>. Первый — это выпадающее меню ({{htmlelement("select")}}) для выбора типа кредитной карты. Второй — это элемент <input> с типом number для ввода номера карты. Последний виджет — это элемент <input> с типом date для указания даты окончания действия карты (должен будет появиться виджет с выбором даты или обычное текстовое поле в браузерах, не поддерживающих данные тип). Более новые типы полей описаны в статье The HTML5 input types.
    +
    + Вставьте следующий код под предыдущим разделом: +
    <section>
    +    <h2>Payment information</h2>
    +    <p>
    +      <label for="card">
    +        <span>Card type:</span>
    +      </label>
    +      <select id="card" name="usercard">
    +        <option value="visa">Visa</option>
    +        <option value="mc">Mastercard</option>
    +        <option value="amex">American Express</option>
    +      </select>
    +    </p>
    +    <p>
    +      <label for="number">
    +        <span>Card number:</span>
    +        <strong><abbr title="required">*</abbr></strong>
    +      </label>
    +      <input type="number" id="number" name="cardnumber">
    +    </p>
    +    <p>
    +      <label for="date">
    +        <span>Expiration date:</span>
    +        <strong><abbr title="required">*</abbr></strong>
    +        <em>formatted as mm/yy</em>
    +      </label>
    +      <input type="date" id="date" name="expiration">
    +    </p>
    +</section>
    +
  12. +
  13. Последняя секция, которую мы добавим выглядит намного проще и содержит в себе только элемент {{htmlelement("button")}} с типом submit, для отправки данных. Добавьте этот код в конец вашей формы: +
    <p> <button type="submit">Validate the payment</button> </p>
    +
  14. +
+ +

Вы можете увидеть законченную форму в действии ниже (также её можно найти на GitHub — посмотрите payment-form.html и живой пример):

+ +

{{EmbedLiveSample("A_payment_form","100%",620, "", "Learn/HTML/Forms/How_to_structure_an_HTML_form/Example")}}

+ +

Протестируйте себя!

+ +

Вы дошли до конца статьи, но можете ли вспомнить самую важную информацию? Далее вы можете найти тест, который поможет убедиться, что вы усвоили знания прежде чем двигаться дальше — посмотрите Test your skills: Form structure.

+ +

Заключение

+ +

Теперь у вас есть все необходимые знания для того, чтобы правильно структурировать вашу HTML-форму. Мы подробнее раскроем затронутые здесь темы в нескольких последующих статьях. В следующей же статье мы изучим все возможные типы виджетов форм, которые могут понадобиться для сбора информации от ваших пользователей.

+ +

Смотрите также

+ + + +

{{PreviousMenuNext("Learn/HTML/Forms/Ваша_первая_HTML_форма", "Learn/HTML/Forms/Стандартные_виджеты_форм", "Learn/HTML/Forms")}}

+ +

В этом разделе

+ + + +

Дополнительные темы

+ + diff --git a/files/ru/learn/forms/index.html b/files/ru/learn/forms/index.html new file mode 100644 index 0000000000..02e36df560 --- /dev/null +++ b/files/ru/learn/forms/index.html @@ -0,0 +1,78 @@ +--- +title: Руководство по HTML-формам +slug: Learn/HTML/Forms +tags: + - HTML + - Web + - Начинающие + - Руководство + - Формы +translation_of: Learn/Forms +--- +

{{LearnSidebar}}

+ +

Данное руководство представляет собой серию статей, которые помогут Вам освоить HTML-формы. HTML формы являются очень мощным инструментом для взаимодействия с пользователями; однако, в силу исторических и технических причин, не всегда очевидно, как использовать их в полной мере. В этом руководстве мы рассмотрим все аспекты HTML-форм, от структуры к стилизации, от обработки данных до пользовательских виджетов. Вы научитесь пользоваться Великой силой, которую они предлагают!

+ +

Необходимые условия

+ +

Перед началом этого модуля вам следует изучить хотя бы Введение в HTML. На данный момент у вас не должно возникнуть сложностей с пониманием Основных руководств и использованием нашего руководства по Стандартным виджетам форм.

+ +

Остальные части модуля немного сложнее — легко поместить виджет формы на страницу, но вы не сможете много сделать без использования продвинутых особенностей форм, CSS и JavaScript. Поэтому, перед тем как вы перейдёте к другим частям модуля, мы рекомендуем изучить немного CSS и JavaScript.

+ +
+

Примечание:Если компьютер/планшет/другое устройство, на котором вы работаете, не позволяет вам самостоятельно создавать файлы, то приводимые здесь примеры кода можно посмотреть в онлайновых программах для кодирования, например JSBin или Thimble.

+
+ +

 Основные руководства

+ +
+
Ваша первая HTML-форма
+
Первая статья в серии дает вам начальный опыт в создании HTML-форм, включая разработку простой формы, её реализация при помощи элементов HTML, стилизация при помощи CSS и то, как данные отправляются на сервер.
+
Как структурировать HTML-форму
+
Изучив основы, рассмотрим более подробно элементы, используемые для структурирования и придания смысла различным частям HTML-форм.
+
+ +

Какие виджеты форм доступны?

+ +
+
Стандартные виджеты форм
+
Рассмотрим подробнее функционал различных виджетов форм; какие варианты доступны для сбора различных типов данных.
+
+ +

Валидация и подтверждение данных форм

+ +
+
Отправка данных форм 
+
Данная статья рассматривает что происходит, когда пользователь подтверждает форму — куда отправляются данные и как мы их там обрабатываем. Мы также рассмотрим некоторые проблемы безопасности, связанные с отправкой данных формы.
+
Валидация данных форм
+
Одной отправки данных не достаточно — нам нужно убедиться что данные, введенные пользователем в формы, в правильном формате и не испортят наши приложения. Мы также хотим помочь пользователям правильно заполнить формы и не разочароваться при использовании наших приложений. Валидация форм поможет нам в достижении этих целей — эта статья расскажет вам всё, что нужно знать.
+
+ +

 Продвинутые руководства

+ +
+
Как создавать собственные виджеты форм
+
В некоторых случая стандартные виджеты форм не предоставляют того, что вам нужно, например из-за стиля или функционала. В таких случаях вам придётся создать собственный виджет формы из чистого HTML. В этой статье(с практическим примером) объясняется, как вы это сделаете, а также особенности, на которые необходимо обратить внимание.
+
Отправка форм при помощи JavaScript
+
В этой статье рассматриваются способы использования формы для сборки HTTP-запроса и отправки его через пользовательский JavaScript вместо стандартного представления формы. А также почему вы захотите это сделать и способы реализации (см. использование объектов FormData).
+
HTML-формы в старых браузерах
+
Статья раскрывает особенности обнаружения и т.д. (см. Кросс-браузерное тестирование для более глубокого понимания)
+
+ +

Руководства по стилизации форм

+ +
+
Стилизация HTML-форм
+
Вступительная статья по стилизации форм с помощью CSS, включая все необходимые основы.
+
Продвинутая стилизация HTML-форм
+
В этой статье мы рассмотрим продвинутые техники стилизации форм, которые необходимо использовать при работе с некоторыми более сложными для стилизации элементами.
+
Таблица совместимости свойств для виджетов форм
+
Последняя статья содержит удобный справочник, позволяющий узнать, с какими элементами формы совместимы свойства CSS.
+
+ +

Смотри также

+ + diff --git a/files/ru/learn/forms/sending_and_retrieving_form_data/index.html b/files/ru/learn/forms/sending_and_retrieving_form_data/index.html new file mode 100644 index 0000000000..9e7900f783 --- /dev/null +++ b/files/ru/learn/forms/sending_and_retrieving_form_data/index.html @@ -0,0 +1,352 @@ +--- +title: Отправка данных формы +slug: Learn/HTML/Forms/Отправка_и_Получение_данных_формы +translation_of: Learn/Forms/Sending_and_retrieving_form_data +--- +
{{LearnSidebar}}{{PreviousMenuNext("Learn/HTML/Forms/The_native_form_widgets", "Learn/HTML/Forms/Form_validation", "Learn/HTML/Forms")}}
+ +

В этой статье рассматривается, что происходит, когда пользователь отправляет форму - куда передаются данные и как мы их обрабатываем, когда они туда попадают? Мы также рассмотрим некоторые проблемы безопасности, связанные с отправкой данных формы.

+ + + + + + + + + + + + +
Предварительные знания:Базовая компьютерная грамотность, понимание HTML и базовые знания по HTTP и программированию на стороне сервера.
Задача:Понять, что происходит при отправке данных формы, в том числе получить представление о том, как данные обрабатываются на стороне сервера.
+ +

Куда отправляются данные?

+ +

Здесь мы обсудим, что происходит с данными при отправке формы.

+ +

О клиенсткой/серверной архитектуре

+ +

WEB основан на очень простой клиент-серверной архитектуре, которую можно обобщить следующим образом: клиент (обычно веб-браузер) отправляет запрос на сервер (в основном веб-сервер, такой как Apache, Nginx, IIS, Tomcat, и т. д.), используя протокол HTTP. Сервер отвечает на запрос, используя тот же протокол.A basic schema of the Web client/server architecture

+ +

На стороне клиента HTML-форма - это не более чем удобный способ настройки HTTP-запроса для отправки данных на сервер. Это позволяет пользователю предоставлять информацию для доставки в HTTP-запросе .

+ +
+

Заметка: Для получения более полного представления о том, как работают клиент-серверные архитектуры, ознакомьтесь с модулем «Первые шаги в программировании на стороне сервера».

+
+ +

На стороне клиента: определение способа отправки данных

+ +

Элемент {{HTMLElement("form")}} определяет способ отправки данных. Все его атрибуты предназначены для того, чтобы вы могли настроить запрос на отправку, когда пользователь нажимает кнопку отправки. Двумя наиболее важными атрибутами являются  {{htmlattrxref("action","form")}}  и {{htmlattrxref("method","form")}}.

+ +

Атрибут {{htmlattrxref("action","form")}}

+ +

Этот атрибут определяет, куда отправляются данные. Его значение должно быть действительным URL. Если этот атрибут не указан, данные будут отправлены на URL-адрес страницы, содержащей форму.

+ +

В этом примере данные отправляются на абсолютный URL — http://foo.com:

+ +
<form action="http://foo.com">
+ +

Здесь мы используем относительный URL - данные отправляются на другой URL на сервере:

+ +
<form action="/somewhere_else">
+ +

Если атрибуты не указаны, как показано ниже, данные из формы  {{HTMLElement("form")}} отправляются на ту же страницу, на которой размещается данная форма:

+ +
<form>
+ +

Многие старые страницы используют следующий синтаксис, чтобы указать, что данные должны быть отправлены на ту же страницу, которая содержит форму; это было необходимо, потому что до появления HTML5 атрибут {{htmlattrxref("action", "form")}} был обязательным. Это больше не нужно.

+ +
<form action="#">
+ +
+

Заметка: Можно указать URL, который использует протокол HTTPS (безопасный HTTP). Когда вы делаете это, данные шифруются вместе с остальной частью запроса, даже если сама форма размещается на небезопасной странице, доступ к которой осуществляется через HTTP. С другой стороны, если форма размещается на защищенной странице, но вы указываете небезопасный URL-адрес HTTP с атрибутом {{htmlattrxref("action","form")}}, все браузеры выдают пользователю предупреждение о безопасности при каждой попытке отправки данных, поскольку данные не шифруются.

+
+ +

Атрибут {{htmlattrxref("method","form")}}

+ +

Этот атрибут определяет способ отправки данных. Протокол HTTP предоставляет несколько способов выполнить запрос;  Данные HTML-формы могут передаваться несколькими различными способами, наиболее распространенными из которых являются метод GET и метод POST.

+ +

Чтобы понять разницу между этими двумя методами, давайте вернёмся назад и рассмотрим, как работает HTTP. Каждый раз, когда вы хотите получить доступ к ресурсу в Интернете, браузер отправляет запрос на URL-адрес. HTTP-запрос состоит из двух частей: заголовка, который содержит набор глобальных метаданных о возможностях браузера, и тела, которое может содержать информацию, необходимую серверу для обработки конкретного запроса.

+ +

Метод GET

+ +

Метод GET - это метод, используемый браузером, который говорит серверу, что нужно отправить назад данный ресурс: «Эй, сервер, я хочу получить этот ресурс». В этом случае браузер отправляет пустое тело. Поскольку тело пустое, если форма отправляется с использованием данного метода, данные, отправляемые на сервер, добавляются к URL-адресу.

+ +

Рассмотрим следующую форму:

+ +
<form action="http://foo.com" method="get">
+  <div>
+    <label for="say">What greeting do you want to say?</label>
+    <input name="say" id="say" value="Hi">
+  </div>
+  <div>
+    <label for="to">Who do you want to say it to?</label>
+    <input name="to" id="to" value="Mom">
+  </div>
+  <div>
+    <button>Send my greetings</button>
+  </div>
+</form>
+ +

Поскольку используется метод GET, вы увидите URL www.foo.com/?say=Hi&to=Mom, который появится в адресной строке браузера при отправке формы.

+ +

Данные добавляются в URL как последовательность пар имя / значение. После того, как URL веб-адрес закончился, мы добавляем знак вопроса (?), за которым следуют пары имя / значение, каждая из которых разделена амперсандом (&). В этом случае мы передаем две части данных на сервер:

+ + + +

HTTP-запрос имеет следующий вид:

+ +
GET /?say=Hi&to=Mom HTTP/2.0
+Host: foo.com
+ +
+

Заметка: Вы можете найти этот пример на GitHub — смотрите get-method.html (see it live also).

+
+ +

Метод POST

+ +

Метод POST немного отличается. Браузер использует этот метод для связи с сервером при запросе ответа с учётом данных, представленные в теле HTTP-запроса: «Эй, сервер, взгляни на эти данные и отправь мне соответствующий результат». Если форма отправляется с использованием этого метода, данные добавляются в тело HTTP-запроса.

+ +

Давайте рассмотрим пример — это та же самая форма, которую мы рассматривали в разделе GET выше, но с атрибутом {{htmlattrxref("method","form")}}, установленным в post.

+ +
<form action="http://foo.com" method="post">
+  <div>
+    <label for="say">What greeting do you want to say?</label>
+    <input name="say" id="say" value="Hi">
+  </div>
+  <div>
+    <label for="to">Who do you want to say it to?</label>
+    <input name="to" id="to" value="Mom">
+  </div>
+  <div>
+    <button>Send my greetings</button>
+  </div>
+</form>
+ +

Когда форма отправляется с использованием метода POST, данные добавляются не к URL-адресу, а включаются в тело запроса. HTTP-запрос имеет следующий вид:

+ +
POST / HTTP/2.0
+Host: foo.com
+Content-Type: application/x-www-form-urlencoded
+Content-Length: 13
+
+say=Hi&to=Mom
+ +

Заголовок Content-Length указывает размер тела, а заголовок Content-Type указывает тип данных, отправляемых на сервер. Мы обсудим эти заголовки позже.

+ +
+

Заметка: Вы можете найти этот пример на GitHub — смотрите post-method.html (see it live also).

+
+ +

Просмотр HTTP-запросов

+ +

HTTP-запросы никогда не отображаются пользователю (если вы хотите их видеть, Вам нужно использовать такие инструменты, как Firefox Network Monitor или Chrome Developer Tools). Например, данные формы можно увидеть на вкладке Сеть (Network) в Chrome следующим образом (после отправки формы):

+ +
    +
  1. Нажмите F12
  2. +
  3. Выберите Network
  4. +
  5. Выберите "All"
  6. +
  7. Выберите "foo.com" во вкладке "Name"
  8. +
  9. Выберите "Headers"
  10. +
+ +

Затем вы можете получить данные формы, как показано на рисунке ниже.

+ +

+ +

Единственное, что отображается пользователю — вызываемый URL. Как упоминалось раннее, запрос с методом GET позволит пользователю увидеть информацию из запроса в URL, а запрос с методом POST не позволит. Две причины, почему это может быть важно:

+ +
    +
  1. Если необходимо отправить пароль (или любую другую важную информацию), никогда не используйте метод GET, иначе рискуете отобразить эту информацию в URL-строке, что небезопасно.
  2. +
  3. Если необходимо отправить большой объем информации, POST-метод является предпочтительным, так как некоторые браузеры ограничивают длину URL. К тому же, многие сервера так же ограничивают длину обрабатываемых URL.
  4. +
+ +

На стороне сервера: получение данных

+ +

Какой бы HTTP вы не выбрали, сервер возвращает строку, которая будет последовательно проанализирована для получения данных в формате листа с парами ключ/значение. Способ получения доступа к этому листу зависит от платформы разработки или особенностей фреймворка, который вы можете использовать. Технологии, которые вы используете, определяют, как обрабатываются скопированные ключи. Часто, приоритетным является последнее полученное значение для данного ключа.

+ +

Пример: Чистый PHP

+ +

PHP предлагает несколько глобальных объектов для доступа к данным. Например, вы используете POST-метод, в приведенном ниже примере данные просто получаются и показываются пользователю. Разумеется, как использовать данные — решать только вам. Вы можете отобразить эти данные, поместить в базу данных, отправить по почте или передать эти данные куда-либо еще.

+ +
<?php
+  // The global $_POST variable allows you to access the data sent with the POST method by name
+  // To access the data sent with the GET method, you can use $_GET
+  $say = htmlspecialchars($_POST['say']);
+  $to  = htmlspecialchars($_POST['to']);
+
+  echo  $say, ' ', $to;
+?>
+ +

Пример показывает страницу с данными, которые мы отправили. Вы можете посмотреть это в действии в нашем файле с примером: php-example.html — который содержит те же данные, которые вы видели раньше:  method : post и action из php-example.php. Когда данные переданы на отправку (submit), они переданы в форму php-example.php, которая содержит PHP код из примера выше. Когда код будет выполнен, браузер выведет (output) обработанное сообщение: Hi Mom.

+ +

+ +
+

Примечание: Этот пример не будет работать, когда вы загружаете его в браузер локально — браузер не может интерпретировать PHP код, после отправки данных из формы, браузер просто предложит загрузить PHP файл. Чтобы пример заработал, необходимо отправить его на PHP сервер. Для тестирования PHP на локальных серверах можете пробовать MAMP (Mac and Windows) и/или AMPPS (Mac, Windows, Linux).

+
+ +

Пример: Python

+ +

Этот пример показывает, как вы можете использовать Python для решения той же задачи — отобразить отправленные данные на странице. В этом примере используется Flask framework для визуализации шаблонов, поддерживающих форму отправки данных (смотри python-example.py).

+ +
from flask import Flask, render_template, request
+
+app = Flask(__name__)
+
+@app.route('/', methods=['GET', 'POST'])
+def form():
+    return render_template('form.html')
+
+@app.route('/hello', methods=['GET', 'POST'])
+def hello():
+    return render_template('greeting.html', say=request.form['say'], to=request.form['to'])
+
+if __name__ == "__main__":
+    app.run()
+ +

Два шаблона из коде выше взаимодействуют так:

+ + + +
+

Примечание: Опять же, этот код не будет работать, если вы просто попробуете загрузить его прямо в браузер. Python работает немного иначе, чем PHP — чтобы запустить этот код, нужно установить Python/PIP, потом установить Flask используя команду: pip3 install flask. После этого, вы сможете запустить файл из примера, используя команду: python3 python-example.py, потом открыть localhost:5000 в своем браузере.

+
+ +

Другие языки и фреймворки

+ +

Существует множество других серверных технологий, которые вы можете использовать для работы с формами, включая языки Perl, Java, .Net, Ruby, и прочее. Выбирайте тот, который нравится больше. К тому же, использовать вышеупомянутые технологии непосредственно, без использования фреймворков, может быть сложно. Лучше использовать один из множества высококачественных фреймворков, таких как:

+ + + +

Стоит отметить, что использование фреймворков и работа с формами - это не всегда легко. Но это намного легче, чем пытаться написать аналогичный функционал с нуля, и это определенно сэкономит время. 

+ +
+

Примечание: Обучению фреймворкам и работе с серверами не входит в рамки этой статьи.  Если хотите узнать больше, ссылки ниже помогут в этом. 

+
+ +

Особый случай: отправка файлов

+ +

Отправка файлов с помощью форм HTML —  это особый случай. Файлы — это бинарные данные или рассматриваются как таковые, в то время как все остальные — это текстовые данные. Поскольку HTTP — это текстовый протокол, есть особые требования для работы с бинарными данными.

+ +

Атрибут {{htmlattrxref("enctype","form")}} 

+ +

Этот атрибут позволяет конкретизировать значение в Content-Type HTTP заголовок, включенный в запрос, при генерировании отпавки формы. Этот заголовок очень важен, потому что указывает серверу, какой тип данных отправляется. По умолчанию это: application/x-www-form-urlencoded. На человеческом это значит: "Это форма с данными, которые были закодированы в URL параметры."

+ +

Если хотите отправить файл, нужно сделать следующие три шага:

+ + + +

Пример:

+ +
<form method="post" enctype="multipart/form-data">
+  <div>
+    <label for="file">Choose a file</label>
+    <input type="file" id="file" name="myFile">
+  </div>
+  <div>
+    <button>Send the file</button>
+  </div>
+</form>
+ +
+

Примечание: Некоторые браузеры поддерживают {{htmlattrxref("multiple","input")}} атрибут элемента {{HTMLElement("input")}} , который позволяет выбрать больше одного файла для загрузки, при использовании одного элемента <input> . То, как сервер работает с этими файлами, напрямую зависит от технологий, используемых на сервере. Как упоминалось ранее, использование фреймворков сделает вашу жизнь намного легче. 

+
+ +
+

Предупреждение: Многие сервера имеют заданные ограничения на размер загружаемых файлов и запросы от пользователей, чтобы защититься от возможных злоупотреблений. Важно проверять эти ограничения у администратора сервера, прежде чем загружать файлы.

+
+ +

Проблемы безопасности

+ +

Каждый раз, когда вы отправляете данные на сервер, вы должны учитывать безопасность. HTML-формы являются наиболее распространенными векторами атак на серверы(места, где могут происходить атаки). Проблемы вытекают не из самих форм HTML, а из-за того, как сервер обрабатывает данные из этих форм.

+ +

В зависимости от того, что вы делаете, вы можете столкнуться с некоторыми очень известными проблемами безопасности:

+ +

XSS "Межсайтовый скриптинг" и CSRF "Подделка межсайтовых запросов"

+ +

Межсайтовый скриптинг (XSS "Сross Site Request Forgery") и подделка межсайтовых запросов (CSRF "Cross-Site Scripting") - это распространенные типы атак, которые происходят при отображении данных после ответа сервера или другого пользователя.

+ +

Межсайтовый скриптинг (XSS "Сross Site Request Forgery") позволяет злоумышленникам внедрить клиентский скрипт в веб-страницы, просматриваемые другими пользователями. Подделка межсайтовых запросов (CSRF "Cross-Site Scripting") может использоваться злоумышленниками для обхода средств контроля доступа, таких как одна и та же политика происхождения. Последствие от этих атак может варьироваться от мелких неудобств до значительного риска безопасности.

+ +

CSRF-атаки аналогичны XSS-атакам в том, что они начинаются одинаково - с внедрения клиентского скрипта в веб-страницы - но их конечные цели разные. Злоумышленники CSRF пытаются назначить права пользователям с более высоким уровнем прав доступа(например, администратору сайта), чтобы выполнить действие, которое они не должны выполнять (например, отправка данных ненадежному пользователю). Атаки XSS используют доверие пользователя к веб-сайту, в то время как атаки CSRF используют доверие веб-сайта к пользователю.

+ +

Чтобы предотвратить эти атаки, вы всегда должны проверять данные, которые пользователь отправляет на ваш сервер, и (если вам нужно отобразить их) стараться не отображать HTML-контент, предоставленный пользователем. Вместо этого вы должны обработать предоставленные пользователем данные, чтобы не отображать их слово в слово. Сегодня почти все платформы на рынке реализуют минимальный "фильтр", который удаляет элементы HTML {{HTMLElement ("script")}}, {{HTMLElement ("iframe")}} и {{HTMLElement ("object")}} полученных от любого пользователя. Это помогает снизить риск, но не исключает его полностью.

+ +

SQL - вброс

+ +

SQL -вброс представляет собой тип атак, при которых осуществляется попытка выполнения действия с базой данных, используемой целевым веб-сайтом. В этих случаях обычно осуществляется отправка SQL-запроса в надежде, что сервер выполнит этот запрос (обычно при попытке сервера приложения сохранить данные, отправляемые пользователем). Данный вид атак является одним из самых направленных атак на веб-сайты.

+ +

Последствия могут быть ужасающими, начиная от потери данных и заканчивая утратой контроля над всей инфраструктурой веб-сайта за счет повышения привилегий. Это очень серьезная угроза, поэтому никогда не сохраняйте данные, отправляемые пользователем, без выполнения санитизации данных (например, с помощью mysqli_real_escape_string().

+ +

Вброс HTTP-заголовка и email

+ +

Эти виды атак могут проявляться, когда ваше приложение создает заголовки HTTP или электронные почтовые адреса на основании данных, введенных пользователем в форму. Такие атаки напрямую не повреждают сервер или пользовалей, однако создают уязвимость для таких угроз, как перехват сессии, или для фишинговых атак.

+ +

Такие атаки являются самыми незаметными, но при этом могут превратить ваш сервер в зомби.

+ +

Будьте параноиком: никогда не доверяйте вашим пользователям

+ +

Как вы боретесь с такими угрозами? Этот вопрос выходит далеко за рамки данной статьи, но есть несколько общих правил, которые следует всегда соблюдать. Самое важное из них - никогда не доверяйте вашим пользователям, в том числе себе; даже проверенный пользователь может быть атакован.

+ +

Все данные, поступающие на ваш сервер, необходимо проверять и санитизировать. Все и всегда. Без исключений.

+ + + +

Соблюдая эти три правила, вы сможете избежать многих/большинства проблем. При этом следует помнить, что периодически необходимо проводить анализ защищенности, желательно квалифицированной сторонней организацией. Не считайте, что вы уже сталкивались со всеми возможными угрозами.

+ +
+

Примечание: В статье Безопасность веб-сайта нашего раздела серверного обучения приведено подробное обсуждение упомянутых угроз и возможных способов их устранения.

+
+ +

Заключение

+ +

Как мы увидели, отправлять формы просто, однако защитить приложение может быть довольно трудно. Просто помните, что фронтенд разработчики не должны задавать модель безопасности для приложения. Да, как мы увидим далее, мы можем проверить данные на стороне клиента, однако сервер не может доверять этой проверке, потому что он никогда не может по-настоящему узнать что происходит на стороне клиента.

+ +

См. также

+ +

Если вы хотите узнать больше об обеспечении безопасности веб-приложений, вы можете использовать следущие источники информации:

+ + + +

{{PreviousMenuNext("Learn/HTML/Forms/The_native_form_widgets", "Learn/HTML/Forms/Form_validation", "Learn/HTML/Forms")}}

+ +

В этом модуле

+ + diff --git a/files/ru/learn/forms/sending_forms_through_javascript/index.html b/files/ru/learn/forms/sending_forms_through_javascript/index.html new file mode 100644 index 0000000000..d98ccea1ac --- /dev/null +++ b/files/ru/learn/forms/sending_forms_through_javascript/index.html @@ -0,0 +1,391 @@ +--- +title: Отправка форм при помощи JavaScript +slug: Learn/HTML/Forms/Sending_forms_through_JavaScript +translation_of: Learn/Forms/Sending_forms_through_JavaScript +--- +
{{LearnSidebar}}
+ +

HTML формы могут декларативно отправлять HTTP-запросы. Но формы также могут подготовить HTTP-запросы для отправки с помощью JavaScript, например при помощи XMLHttpRequest. В этой статье исследуются подобные подходы.

+ +

Формы не всегда формы

+ +

В современных веб-приложениях, одностраничных приложениях и приложениях на основе фреймворков, обычно HTML-формы используются для отправки данных без загрузки нового документа при получении данных ответа. В начале поговорим о том почему это требует другого подхода.

+ +

Получение контроля над глобальным интерфейсом

+ +

Отправка стандартной HTML формы, как описывалось в предыдущей статье, загружает URL-адрес, по которому были отправлены данные, это означает, что окно браузера перемещается с полной загрузкой страницы. Если избегать полную перезагрузку страницы, можно обеспечить более плавную работу, за счет предотвращения задержек в сети и возможных визуальных проблем (например, мерцания).

+ +

Многие современные пользовательские интерфейсы используют HTML формы только для сбора пользовательского ввода, а не для для отправки данных. Когда пользователь пытатся отправить свои данные, приложение берет контроль и асинхронно передает данные в фоновом режиме, обновляя только ту часть всего интерфейса пользователя, которой требуется обновление.

+ +

Асинхронная отправка произвольных данных обычно называется AJAX, что означает "Asynchronous JavaScript And XML" (Асинхронный JavaScript и XML).

+ +

Чем он отличается?

+ +

Объект {{domxref("XMLHttpRequest")}} (XHR) DOM может создавать HTTP-запросы, отправлять их, и получать их результат. Исторически, {{domxref("XMLHttpRequest")}} был разработан для получения и отправки XML в качестве формата обмена, который со временем был заменен на JSON. Но ни XML, ни JSON не вписываются в кодировку запроса данных формы. Данные формы (application/x-www-form-urlencoded) состоят из списка пар ключ/значение в кодировке URL. Для передачи бинарных данных, HTTP-запрос преобразуется в multipart/form-data.

+ +
+

Замечание: Сейчас Fetch API часто используется вместо XHR — это современная, обновленная версия XHR, которая работает в похожем стиле, но имеет несколько преимуществ. Большая часть XHR-кода, которую вы увидете в этой статье можно заменить на Fetch.

+
+ +

Если вы управляете фронтендом (кодом, который выполняется в браузере) и бкендом (кодом, который выполняется на стороне сервера), вы можете отправлять JSON/XML и обрабатывать их как хотите.

+ +

Но если вы хотите использовать сторонний сервис, то вам необходимо отправлять данные в формате, который требуется сервису.

+ +

Так как нам следует отправлять подобные данные? Ниже обписаны различные необходимые вам техники.

+ +

Отправка данных формы

+ +

Есть три способа отправки данных формы:

+ + + +

Давайте рассмотрим их подробнее:

+ +

Создание  XMLHttpRequest вручную

+ +

{{domxref("XMLHttpRequest")}} это самый безопасный и надежный способ создавать HTTPзапросы. Для отправки данных формы с помощью {{domxref("XMLHttpRequest")}}, подготовьте данные с помощью URL-кодирования, и соблюдайте специфику запросов данных формы.

+ +

Посмотрите на пример:

+ +
<button>Click Me!</button>
+ +

И на JavaScript:

+ +
const btn = document.querySelector('button');
+
+function sendData( data ) {
+  console.log( 'Sending data' );
+
+  const XHR = new XMLHttpRequest();
+
+  let urlEncodedData = "",
+      urlEncodedDataPairs = [],
+      name;
+
+  // Turn the data object into an array of URL-encoded key/value pairs.
+  for( name in data ) {
+    urlEncodedDataPairs.push( encodeURIComponent( name ) + '=' + encodeURIComponent( data[name] ) );
+  }
+
+  // Combine the pairs into a single string and replace all %-encoded spaces to
+  // the '+' character; matches the behaviour of browser form submissions.
+  urlEncodedData = urlEncodedDataPairs.join( '&' ).replace( /%20/g, '+' );
+
+  // Define what happens on successful data submission
+  XHR.addEventListener( 'load', function(event) {
+    alert( 'Yeah! Data sent and response loaded.' );
+  } );
+
+  // Define what happens in case of error
+  XHR.addEventListener( 'error', function(event) {
+    alert( 'Oops! Something went wrong.' );
+  } );
+
+  // Set up our request
+  XHR.open( 'POST', 'https://example.com/cors.php' );
+
+  // Add the required HTTP header for form data POST requests
+  XHR.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' );
+
+  // Finally, send our data.
+  XHR.send( urlEncodedData );
+}
+
+btn.addEventListener( 'click', function() {
+  sendData( {test:'ok'} );
+} )
+
+ +

Это результат:

+ +

{{EmbedLiveSample("Building_an_XMLHttpRequest_manually", "100%", 50)}}

+ +
+

Note: This use of {{domxref("XMLHttpRequest")}} is subject to the {{glossary('same-origin policy')}} if you want to send data to a third party web site. For cross-origin requests, you'll need CORS and HTTP access control.

+
+ +

Using XMLHttpRequest and the FormData object

+ +

Building an HTTP request by hand can be overwhelming. Fortunately, the XMLHttpRequest specification provides a newer, simpler way to handle form data requests with the {{domxref("XMLHttpRequest/FormData","FormData")}} object.

+ +

The {{domxref("XMLHttpRequest/FormData","FormData")}} object can be used to build form data for transmission, or to get the data within a form element to manage how it's sent. Note that {{domxref("XMLHttpRequest/FormData","FormData")}} objects are "write only", which means you can change them, but not retrieve their contents.

+ +

Using this object is detailed in Using FormData Objects, but here are two examples:

+ +

Using a standalone FormData object

+ +
<button>Click Me!</button>
+ +

You should be familiar with that HTML sample. Now for the JavaScript:

+ +
const btn = document.querySelector('button');
+
+function sendData( data ) {
+  const XHR = new XMLHttpRequest(),
+        FD  = new FormData();
+
+  // Push our data into our FormData object
+  for( name in data ) {
+    FD.append( name, data[ name ] );
+  }
+
+  // Define what happens on successful data submission
+  XHR.addEventListener( 'load', function( event ) {
+    alert( 'Yeah! Data sent and response loaded.' );
+  } );
+
+  // Define what happens in case of error
+  XHR.addEventListener(' error', function( event ) {
+    alert( 'Oops! Something went wrong.' );
+  } );
+
+  // Set up our request
+  XHR.open( 'POST', 'https://example.com/cors.php' );
+
+  // Send our FormData object; HTTP headers are set automatically
+  XHR.send( FD );
+}
+
+btn.addEventListener( 'click', function()
+  { sendData( {test:'ok'} );
+} )
+ +

Here's the live result:

+ +

{{EmbedLiveSample("Using_a_standalone_FormData_object", "100%", 50)}}

+ +

Using FormData bound to a form element

+ +

You can also bind a FormData object to an {{HTMLElement("form")}} element. This creates a FormData object that represents the data contained in the form.

+ +

The HTML is typical:

+ +
<form id="myForm">
+  <label for="myName">Send me your name:</label>
+  <input id="myName" name="name" value="John">
+  <input type="submit" value="Send Me!">
+</form>
+ +

But JavaScript takes over the form:

+ +
window.addEventListener( "load", function () {
+  function sendData() {
+    const XHR = new XMLHttpRequest();
+
+    // Bind the FormData object and the form element
+    const FD = new FormData( form );
+
+    // Define what happens on successful data submission
+    XHR.addEventListener( "load", function(event) {
+      alert( event.target.responseText );
+    } );
+
+    // Define what happens in case of error
+    XHR.addEventListener( "error", function( event ) {
+      alert( 'Oops! Something went wrong.' );
+    } );
+
+    // Set up our request
+    XHR.open( "POST", "https://example.com/cors.php" );
+
+    // The data sent is what the user provided in the form
+    XHR.send( FD );
+  }
+
+  // Access the form element...
+  const form = document.getElementById( "myForm" );
+
+  // ...and take over its submit event.
+  form.addEventListener( "submit", function ( event ) {
+    event.preventDefault();
+
+    sendData();
+  } );
+} );
+ +

Here's the live result:

+ +

{{EmbedLiveSample("Using_FormData_bound_to_a_form_element", "100%", 50)}}

+ +

You can even get more involved with the process by using the form's {{domxref("HTMLFormElement.elements", "elements")}} property to get a list of all of the data elements in the form and manually manage them one at a time. To learn more about that, see the example in {{SectionOnPage("/en-US/docs/Web/API/HTMLFormElement.elements", "Accessing the element list's contents")}}.

+ +

Dealing with binary data

+ +

If you use a {{domxref("XMLHttpRequest/FormData","FormData")}} object with a form that includes <input type="file"> widgets, the data will be processed automatically. But to send binary data by hand, there's extra work to do.

+ +

There are many sources for binary data, including {{domxref("FileReader")}}, {{domxref("HTMLCanvasElement","Canvas")}}, and WebRTC. Unfortunately, some legacy browsers can't access binary data or require complicated workarounds. To learn more about the FileReader API, see Using files from web applications.

+ +

The least complicated way of sending binary data is by using {{domxref("XMLHttpRequest/FormData","FormData")}}'s append() method, demonstrated above. If you have to do it by hand, it's trickier.

+ +

In the following example, we use the {{domxref("FileReader")}} API to access binary data and then build the multi-part form data request by hand:

+ +
<form id="theForm">
+  <p>
+    <label for="theText">text data:</label>
+    <input id="theText" name="myText" value="Some text data" type="text">
+  </p>
+  <p>
+    <label for="theFile">file data:</label>
+    <input id="theFile" name="myFile" type="file">
+  </p>
+  <button>Send Me!</button>
+</form>
+ +

As you see, the HTML is a standard <form>. There's nothing magical going on. The "magic" is in the JavaScript:

+ +
// Because we want to access DOM nodes,
+// we initialize our script at page load.
+window.addEventListener( 'load', function () {
+
+  // These variables are used to store the form data
+  const text = document.getElementById( "theText" );
+  const file = {
+        dom    : document.getElementById( "theFile" ),
+        binary : null
+      };
+
+  // Use the FileReader API to access file content
+  const reader = new FileReader();
+
+  // Because FileReader is asynchronous, store its
+  // result when it finishes to read the file
+  reader.addEventListener( "load", function () {
+    file.binary = reader.result;
+  } );
+
+  // At page load, if a file is already selected, read it.
+  if( file.dom.files[0] ) {
+    reader.readAsBinaryString( file.dom.files[0] );
+  }
+
+  // If not, read the file once the user selects it.
+  file.dom.addEventListener( "change", function () {
+    if( reader.readyState === FileReader.LOADING ) {
+      reader.abort();
+    }
+
+    reader.readAsBinaryString( file.dom.files[0] );
+  } );
+
+  // sendData is our main function
+  function sendData() {
+    // If there is a selected file, wait it is read
+    // If there is not, delay the execution of the function
+    if( !file.binary && file.dom.files.length > 0 ) {
+      setTimeout( sendData, 10 );
+      return;
+    }
+
+    // To construct our multipart form data request,
+    // We need an XMLHttpRequest instance
+    const XHR = new XMLHttpRequest();
+
+    // We need a separator to define each part of the request
+    const boundary = "blob";
+
+    // Store our body request in a string.
+    let data = "";
+
+    // So, if the user has selected a file
+    if ( file.dom.files[0] ) {
+      // Start a new part in our body's request
+      data += "--" + boundary + "\r\n";
+
+      // Describe it as form data
+      data += 'content-disposition: form-data; '
+      // Define the name of the form data
+            + 'name="'         + file.dom.name          + '"; '
+      // Provide the real name of the file
+            + 'filename="'     + file.dom.files[0].name + '"\r\n';
+      // And the MIME type of the file
+      data += 'Content-Type: ' + file.dom.files[0].type + '\r\n';
+
+      // There's a blank line between the metadata and the data
+      data += '\r\n';
+
+      // Append the binary data to our body's request
+      data += file.binary + '\r\n';
+    }
+
+    // Text data is simpler
+    // Start a new part in our body's request
+    data += "--" + boundary + "\r\n";
+
+    // Say it's form data, and name it
+    data += 'content-disposition: form-data; name="' + text.name + '"\r\n';
+    // There's a blank line between the metadata and the data
+    data += '\r\n';
+
+    // Append the text data to our body's request
+    data += text.value + "\r\n";
+
+    // Once we are done, "close" the body's request
+    data += "--" + boundary + "--";
+
+    // Define what happens on successful data submission
+    XHR.addEventListener( 'load', function( event ) {
+      alert( 'Yeah! Data sent and response loaded.' );
+    } );
+
+    // Define what happens in case of error
+    XHR.addEventListener( 'error', function( event ) {
+      alert( 'Oops! Something went wrong.' );
+    } );
+
+    // Set up our request
+    XHR.open( 'POST', 'https://example.com/cors.php' );
+
+    // Add the required HTTP header to handle a multipart form data POST request
+    XHR.setRequestHeader( 'Content-Type','multipart/form-data; boundary=' + boundary );
+
+    // And finally, send our data.
+    XHR.send( data );
+  }
+
+  // Access our form...
+  const form = document.getElementById( "theForm" );
+
+  // ...to take over the submit event
+  form.addEventListener( 'submit', function ( event ) {
+    event.preventDefault();
+    sendData();
+  } );
+} );
+ +

Here's the live result:

+ +

{{EmbedLiveSample("Dealing_with_binary_data", "100%", 150)}}

+ +

Conclusion

+ +

Depending on the browser and the type of data you are dealing with, sending form data through JavaScript can be easy or difficult. The {{domxref("XMLHttpRequest/FormData","FormData")}} object is generally the answer, and you can use a polyfill for it on legacy browsers.

+ +

See also

+ +

Learning path

+ + + +

Advanced Topics

+ + diff --git a/files/ru/learn/forms/styling_web_forms/index.html b/files/ru/learn/forms/styling_web_forms/index.html new file mode 100644 index 0000000000..f8cc1644dc --- /dev/null +++ b/files/ru/learn/forms/styling_web_forms/index.html @@ -0,0 +1,381 @@ +--- +title: Стили HTML форм +slug: Learn/HTML/Forms/Styling_HTML_forms +translation_of: Learn/Forms/Styling_web_forms +--- +

{{LearnSidebar}}{{PreviousMenuNext("Learn/HTML/Forms/HTML_forms_in_legacy_browsers", "Learn/HTML/Forms/Advanced_styling_for_HTML_forms", "Learn/HTML/Forms")}}

+ +

В этой статье Вы узнает, как использовать CSS с HTML-формами, чтобы сделать их (надеюсь) более красивыми. Удивительно, но это может быть немного сложнее. По историческим и техническим причинам виджеты форм плохо сочетаются с CSS. Из-за этих трудностей многие разработчики предпочитают создавать свои собственные HTML-виджеты, чтобы получить контроль над своим внешним видом. Однако в современных браузерах веб-дизайнеры все больше контролируют дизайн элементов формы. Давайте приступим!

+ +

Почему так сложно стилизовать виджеты форм с помощью CSS?

+ +

На заре Интернета, примерно в 1995 году, в HTML 2 были добавлены элементы управления формой. Из-за сложности виджетов форм разработчики решили полагаться на базовую операционную систему для управления ими и их рендеринга.

+ +

Несколько лет спустя был создан CSS, и то, что было технической необходимостью, то есть использование собственных виджетов для реализации элементов управления формой, стало требованием к стилю. В первые дни CSS, стилизация элементов управления формы не была приоритетом.

+ +

Поскольку пользователи привыкли к внешнему виду своих соответствующих платформ, поставщики браузеров неохотно делают элементы управления формами стилевыми; и по сей день все еще чрезвычайно трудно перестроить все элементы управления, чтобы сделать их стилизованными.

+ +

Даже сегодня ни один браузер полностью не реализует CSS 2.1. Однако со временем поставщики браузеров улучшили свою поддержку CSS для элементов формы, и, несмотря на плохую репутацию в отношении удобства использования, теперь вы можете использовать CSS для стилизации HTML форм.

+ +

Не все виджеты созданы равными, когда задействован CSS

+ +

В настоящее время некоторые трудности остаются при использовании CSS с формами. Эти проблемы можно разделить на три категории:

+ +

Хорошая

+ +

Некоторые элементы могут быть стилизованы с небольшим количеством проблем на разных платформах. К ним относятся следующие структурные элементы:

+ +
    +
  1. {{HTMLElement("form")}}
  2. +
  3. {{HTMLElement("fieldset")}}
  4. +
  5. {{HTMLElement("label")}}
  6. +
  7. {{HTMLElement("output")}}
  8. +
+ +

Сюда также входят все виджеты текстового поля (как однострочные, так и многострочные) и кнопки.

+ +

Плохая

+ +

Некоторые элементы редко могут быть стилизованы, и могут потребовать некоторых сложных уловок, иногда требующих углубленных знаний CSS3.

+ +

Они включают в себя элемент {{HTMLElement ("legend")}}, но его нельзя правильно расположить на всех платформах. Флажки и переключатели также не могут быть стилизованы напрямую, однако, благодаря CSS3 вы можете обойти это. Контент {{htmlattrxref ("placeholder", "input")}} не может быть стилизован каким-либо стандартным способом, однако все браузеры, которые его реализуют, также реализуют собственные псевдо-элементы CSS или псевдоклассы, которые позволяют его стилизовать.

+ +

Мы опишем, как обрабатывать эти более конкретные случаи, в статье «Расширенные стили для HTML-форм».

+ +

The ugly

+ +

Some elements simply can't be styled using CSS. These include: all advanced user interface widgets, such as range, color, or date controls; and all the dropdown widgets, including {{HTMLElement("select")}}, {{HTMLElement("option")}}, {{HTMLElement("optgroup")}} and {{HTMLElement("datalist")}} elements. The file picker widget is also known not to be stylable at all. The new {{HTMLElement("progress")}} and {{HTMLElement("meter")}} elements also fall in this category.

+ +

The main issue with all these widgets, comes from the fact that they have a very complex structure, and CSS is not currently expressive enough to style all the subtle parts of those widgets. If you want to customize those widgets, you have to rely on JavaScript to build a DOM tree you'll be able to style. We explore how to do this in the article How to build custom form widgets.

+ +

Basic styling

+ +

To style elements that are easy to style with CSS, you shouldn't face any difficulties, since they mostly behave like any other HTML element. However, the user-agent style sheet of every browser can be a little inconsistent, so there are a few tricks that can help you style them in an easier way.

+ +

Search fields

+ +

Search boxes are the only kind of text fields that can be a little tricky to style. On WebKit based browsers (Chrome, Safari, etc.), you'll have to tweak it with the -webkit-appearance proprietary property. We discuss this property further in the article: Advanced styling for HTML forms.

+ +

Example

+ +
<form>
+  <input type="search">
+</form>
+
+ +
input[type=search] {
+  border: 1px dotted #999;
+  border-radius: 0;
+
+  -webkit-appearance: none;
+}
+ +

This is a screenshot of a search filed on Chrome, with and without the use of -webkit-appearance

+ +

As you can see on this screenshot of the search field on Chrome, the two fields have a border set as in our example. The first field is rendered without using the -webkit-appearance property, whereas the second is rendered using -webkit-appearance:none. This difference is noticeable.

+ +

Fonts and text

+ +

CSS font and text features can be used easily with any widget (and yes, you can use {{cssxref("@font-face")}} with form widgets). However, browsers' behaviors are often inconsistent. By default, some widgets do not inherit {{cssxref("font-family")}} and {{cssxref("font-size")}} from their parents. Many browsers use the system default appearance instead. To make your forms' appearance consistent with the rest of your content, you can add the following rules to your stylesheet:

+ +
button, input, select, textarea {
+  font-family : inherit;
+  font-size   : 100%;
+}
+ +

The screenshot below shows the difference; on the left is the default rendering of the element in Firefox on Mac OS X, with the platform's default font style in use. On the right are the same elements, with our font harmonization style rules applied.

+ +

This is a screenshot of the main form widgets on Firefox on Mac OSX, with and without font harmonization

+ +

There's a lot of debate as to whether forms look better using the system default styles, or customized styles designed to match your content. This decision is yours to make, as the designer of your site, or Web application.

+ +

Box model

+ +

All text fields have complete support for every property related to the CSS box model ({{cssxref("width")}}, {{cssxref("height")}}, {{cssxref("padding")}}, {{cssxref("margin")}}, and {{cssxref("border")}}). As before, however, browsers rely on the system default styles when displaying these widgets. It's up to you to define how you wish to blend them into your content. If you want to keep the native look and feel of the widgets, you'll face a little difficulty if you want to give them a consistent size.

+ +

This is because each widget has their own rules for border, padding and margin. So if you want to give the same size to several different widgets, you have to use the {{cssxref("box-sizing")}} property:

+ +
input, textarea, select, button {
+  width : 150px;
+  margin: 0;
+
+  -webkit-box-sizing: border-box; /* For legacy WebKit based browsers */
+     -moz-box-sizing: border-box; /* For legacy (Firefox <29) Gecko based browsers */
+          box-sizing: border-box;
+}
+ +

This is a screenshot of the main form widgets on Chrome on Windows 7, with and without the use of box-sizing.

+ +

In the screenshot above, the left column is built without {{cssxref("box-sizing")}}, while the right column uses this property with the value border-box. Notice how this lets us ensure that all of the elements occupy the same amount of space, despite the platform's default rules for each kind of widget.

+ +

Positioning

+ +

Positioning of HTML form widgets is generally not a problem; however, there are two elements you should take special note of:

+ +

legend

+ +

The {{HTMLElement("legend")}} element is okay to style, except for positioning. In every browser, the {{HTMLElement("legend")}} element is positioned on top of the top border of its {{HTMLElement("fieldset")}} parent. There is absolutely no way to change it to be positioned within the HTML flow, away from the top border. You can, however, position it absolutely or relatively, using the {{cssxref("position")}} property. But otherwise it is part of the fieldset border.

+ +

Because the {{HTMLElement("legend")}} element is very important for accessibility reasons, it will be spoken by assistive technologies as part of the label of each form element inside the fieldset, it's quite often paired with a title, and then hidden in an accessible way. For example:

+ +
HTML
+ +
<fieldset>
+  <legend>Hi!</legend>
+  <h1>Hello</h1>
+</fieldset>
+ +
CSS
+ +
legend {
+  width: 1px;
+  height: 1px;
+  overflow: hidden;
+}
+ +

textarea

+ +

By default, all browsers consider the {{HTMLElement("textarea")}} element to be an inline block, aligned to the text bottom line. This is rarely what we actually want to see. To change from inline-block to block, it's pretty easy to use the {{cssxref("display")}} property. But if you want to use it inline, it's common to change the vertical alignment:

+ +
textarea {
+  vertical-align: top;
+}
+ +

Example

+ +

Let's look at a concrete example of how to style an HTML form. This will help make a lot of these ideas clearer. We will build the following "postcard" contact form:

+ +

This is what we want to achieve with HTML and CSS

+ +

If you want to follow along with this example, make a local copy of our postcard-start.html file, and follow the below instructions.

+ +

The HTML

+ +

The HTML is only slightly more involved than the example we used in the first article of this guide; it just has a few extra IDs and a title.

+ +
<form>
+  <h1>to: Mozilla</h1>
+
+  <div id="from">
+    <label for="name">from:</label>
+    <input type="text" id="name" name="user_name">
+  </div>
+
+  <div id="reply">
+    <label for="mail">reply:</label>
+    <input type="email" id="mail" name="user_email">
+  </div>
+
+  <div id="message">
+    <label for="msg">Your message:</label>
+    <textarea id="msg" name="user_message"></textarea>
+  </div>
+
+  <div class="button">
+    <button type="submit">Send your message</button>
+  </div>
+</form>
+ +

Add the above code into the body of your HTML.

+ +

Organizing your assets

+ +

This is where the fun begins! Before we start coding, we need three additional assets:

+ +
    +
  1. The postcard background — download this image and save it in the same directory as your working HTML file.
  2. +
  3. A typewriter font: The "Secret Typewriter" font from fontsquirrel.com — download the TTF file into the same directory as above.
  4. +
  5. A handdrawn font: The "Journal" font from fontsquirrel.com — download the TTF file into the same directory as above.
  6. +
+ +

Your fonts need some more processing before you start:

+ +
    +
  1. Go to the fontsquirrel Webfont Generator.
  2. +
  3. Using the form, upload both your font files and generate a webfont kit. Download the kit to your computer.
  4. +
  5. Unzip the provided zip file.
  6. +
  7. Inside the unzipped contents you will find two .woff files and two .woff2 files. Copy these four files into a directory called fonts, in the same directory as before. We are using two different files for each font to maximise browser compatibility; see our Web fonts article for a lot more information.
  8. +
+ +

The CSS

+ +

Now we can dig into the CSS for the example. Add all the code blocks shown below inside the {{htmlelement("style")}} element, one after another.

+ +

First, we prepare the ground by defining our {{cssxref("@font-face")}} rules, all the basics on the {{HTMLElement("body")}} element, and the {{HTMLElement("form")}} element:

+ +
@font-face {
+    font-family: 'handwriting';
+    src: url('fonts/journal-webfont.woff2') format('woff2'),
+         url('fonts/journal-webfont.woff') format('woff');
+    font-weight: normal;
+    font-style: normal;
+}
+
+@font-face {
+    font-family: 'typewriter';
+    src: url('fonts/veteran_typewriter-webfont.woff2') format('woff2'),
+         url('fonts/veteran_typewriter-webfont.woff') format('woff');
+    font-weight: normal;
+    font-style: normal;
+}
+
+body {
+  font  : 21px sans-serif;
+
+  padding : 2em;
+  margin  : 0;
+
+  background : #222;
+}
+
+form {
+  position: relative;
+
+  width  : 740px;
+  height : 498px;
+  margin : 0 auto;
+
+  background: #FFF url(background.jpg);
+}
+ +

Now we can position our elements, including the title and all the form elements:

+ +
h1 {
+  position : absolute;
+  left : 415px;
+  top  : 185px;
+
+  font : 1em "typewriter", sans-serif;
+}
+
+#from {
+  position: absolute;
+  left : 398px;
+  top  : 235px;
+}
+
+#reply {
+  position: absolute;
+  left : 390px;
+  top  : 285px;
+}
+
+#message {
+  position: absolute;
+  left : 20px;
+  top  : 70px;
+}
+ +

That's where we start working on the form elements themselves. First, let's ensure that the {{HTMLElement("label")}}s are given the right font:

+ +
label {
+  font : .8em "typewriter", sans-serif;
+}
+ +

The text fields require some common rules. Simply put, we remove their {{cssxref("border","borders")}} and {{cssxref("background","backgrounds")}}, and redefine their {{cssxref("padding")}} and {{cssxref("margin")}}:

+ +
input, textarea {
+  font    : .9em/1.5em "handwriting", sans-serif;
+
+  border  : none;
+  padding : 0 10px;
+  margin  : 0;
+  width   : 240px;
+
+  background: none;
+}
+ +

When one of these fields gains focus, we highlight them with a light grey, transparent, background. Note that it's important to add the {{cssxref("outline")}} property, in order to remove the default focus highlight added by some browsers:

+ +
input:focus, textarea:focus {
+  background   : rgba(0,0,0,.1);
+  border-radius: 5px;
+  outline      : none;
+}
+ +

Now that our text fields are complete, we need to adjust the display of the single and multiple line text fields to match, since they won't typically look the same using the defaults.

+ +

The single-line text field needs some tweaks to render nicely in Internet Explorer. Internet Explorer does not define the height of the fields based on the natural height of the font (which is the behavior of all other browsers). To fix this, we need to add an explicit height to the field, as follows:

+ +
input {
+    height: 2.5em; /* for IE */
+    vertical-align: middle; /* This is optional but it makes legacy IEs look better */
+}
+ +

{{HTMLElement("textarea")}} elements default to being rendered as a block element. The two important things here are the {{cssxref("resize")}} and {{cssxref("overflow")}} properties. Because our design is a fixed-size design, we will use the resize property to prevent users from resizing our multi-line text field. The {{cssxref("overflow")}} property is used to make the field render more consistently across browsers. Some browsers default to the value auto, while some default to the value scroll. In our case, it's better to be sure every one will use auto:

+ +
textarea {
+  display : block;
+
+  padding : 10px;
+  margin  : 10px 0 0 -10px;
+  width   : 340px;
+  height  : 360px;
+
+  resize  : none;
+  overflow: auto;
+}
+ +

The {{HTMLElement("button")}} element is really convenient with CSS; you can do whatever you want, even using pseudo-elements:

+ +
button {
+  position     : absolute;
+  left         : 440px;
+  top          : 360px;
+
+  padding      : 5px;
+
+  font         : bold .6em sans-serif;
+  border       : 2px solid #333;
+  border-radius: 5px;
+  background   : none;
+
+  cursor       : pointer;
+
+-webkit-transform: rotate(-1.5deg);
+   -moz-transform: rotate(-1.5deg);
+    -ms-transform: rotate(-1.5deg);
+     -o-transform: rotate(-1.5deg);
+        transform: rotate(-1.5deg);
+}
+
+button:after {
+  content: " >>>";
+}
+
+button:hover,
+button:focus {
+  outline   : none;
+  background: #000;
+  color   : #FFF;
+}
+ +

And voila!

+ +
+

Note: If your example does not work quite like you expected and you want to check it against our version, you can find it on GitHub — see it running live (also see the source code).

+
+ +

Conclusion

+ +

As you can see, as long as we want to build forms with just text fields and buttons, it's easy to style them using CSS. If you want to know more of the little CSS tricks that can make your life easier when working with form widgets, take a look at the form part of the normalize.css project.

+ +

In the next article, we will see how to handle form widgets which fall in the "bad" and "ugly" categories.

+ +

{{PreviousMenuNext("Learn/HTML/Forms/HTML_forms_in_legacy_browsers", "Learn/HTML/Forms/Advanced_styling_for_HTML_forms", "Learn/HTML/Forms")}}

+ +

In this module

+ + diff --git a/files/ru/learn/forms/your_first_form/index.html b/files/ru/learn/forms/your_first_form/index.html new file mode 100644 index 0000000000..b68d433739 --- /dev/null +++ b/files/ru/learn/forms/your_first_form/index.html @@ -0,0 +1,305 @@ +--- +title: Ваша первая HTML форма +slug: Learn/HTML/Forms/Ваша_первая_HTML_форма +tags: + - HTML-форма + - Веб-форма + - Форма +translation_of: Learn/Forms/Your_first_form +--- +
{{LearnSidebar}}{{NextMenu("Learn/HTML/Forms/How_to_structure_an_HTML_form", "Learn/HTML/Forms")}}
+ +

Первая статья в данной главе предоставит вам первый опыт создания веб-форм, в том числе проектирование простой формы, её реализацию с использованием HTML-элементов управления формой и других HTML-элементов, добавление стилей через CSS и описание того, как данные из формы отсылаются на сервер. Мы более подробно остановимся на каждой из этих подтем далее в статье.

+ + + + + + + + + + + + +
Необходимые знания:Базовое представление о компьютерах и базовое понимание HTML.
Цель:Ознакомиться с веб-формами, узнать, для чего они используются, как их проектировать, и какие базовые HTML-элементы могут понадобиться в простых ситуациях.
+ +

Что такое Веб-форма?

+ +

Веб-формы являются одним из основных элементов взаимодействия между пользователем и сайтом или приложением. Формы позволяют пользователю ввести данные, которые затем отправляются на сервер для их дальнейшей обработки и хранения или используются на стороне клиента для обновления интерфейса (например, добавление нового элемента в список или открытие и закрытие элемента интерфейса).

+ +

Веб-формы — их также часто называют HTML-формы — состоят из одного или нескольких элементов управления форм (иногда их также называют виджетами) и некоторых дополнительных элементов для структурирования формы. Элементами управления могут быть однострочные или многострочные текстовые поля, выпадающие списки, кнопки, чекбоксы, радио-баттоны, большинство из которых создаются через html-элемент {{htmlelement("input")}}, однако есть и другие элементы, о которых тоже стоит узнать.

+ +

В элементах управления форм можно задать правила, указывающие на определенный формат данных или значений, которые могут быть введены (валидация форм), а также к ним могут быть добавлены текстовые строки, описывающие эти элементы для зрячих и незрячих пользователей.

+ +

Проектирование формы

+ +

Перед тем, как начать программировать, всегда лучше остановиться и подумать о вашей форме. Создание быстрого наброска поможет определить верный набор данных, которые вы хотите получить от пользователя. С точки зрения UX, удобства использования интерфейса, важно помнить о том, что чем длиннее ваша форма, тем больше риск потерять пользователей. Сделайте форму краткой и лаконичной: спрашивайте только о той информации, которая вам действительно необходима.

+ +

Проектирование форм является важным этапом при создании сайта или приложения. Удобство использования форм (UX) выходит за рамки данной статьи, однако если вы хотите углубиться в эту тему, то вам следует прочитать следующие статьи:

+ + + +

В этой статье мы создадим простую контактную форму. Давайте сделаем набросок.

+ +

The form to build, roughly sketch

+ +

Наша форма будет состоять из трёх текстовых полей и одной кнопки. Мы узнаём у пользователя его имя, e-mail и сообщение, которое он хочет отправить. После нажатия на кнопку данные будут отправлены на веб-сервер.

+ +

Активное обучение: Реализация HTML-формы

+ +

Итак, теперь мы готовы обратиться к HTML и создать нашу форму. Для этого мы будем использовать следующие HTML-элементы: {{HTMLelement("form")}}, {{HTMLelement("label")}}, {{HTMLelement("input")}}, {{HTMLelement("textarea")}} и {{HTMLelement("button")}}.

+ +

Прежде, чем продолжить, скопируйте простой HTML-шаблон — вы будете создавать свою форму внутри него.

+ +

Элемент {{HTMLelement("form")}}

+ +

Создание форм начинается с элемента {{HTMLelement("form")}}:

+ +
<form action="/my-handling-form-page" method="post">
+
+</form>
+ +

Этот элемент формально определяет форму. Он является элементом-контейнером, как HTML-элементы {{HTMLelement("div")}} или {{HTMLelement("p")}}, но при этом он поддерживает некоторые специфические атрибуты для настройки поведения формы. Все атрибуты являются опциональными, но в стандартной практике принято указывать атрибуты action и method:

+ + + +
+

Примечание: Мы детальнее разберём работу этих атрибутов далее в статье Отправка данных формы.

+
+ +

Теперь добавьте указанный выше код с элементом {{htmlelement("form")}} внутрь тега {{htmlelement("body")}} в вашем HTML.

+ +

Элементы {{HTMLelement("label")}}, {{HTMLelement("input")}} и {{HTMLelement("textarea")}}

+ +

Наша контактная форма несложная: часть, в которую будут вводиться данные, состоит из трёх текстовых полей, каждое их которых связано с HTML-элементом {{HTMLelement("label")}}:

+ + + +

В терминах HTML нам нужен код наподобие представленного ниже, чтобы добавить виджеты форм:

+ +
<form action="/my-handling-form-page" method="post">
+  <ul>
+    <li>
+      <label for="name">Name:</label>
+      <input type="text" id="name" name="user_name">
+    </li>
+    <li>
+      <label for="mail">E-mail:</label>
+      <input type="email" id="mail" name="user_mail">
+    </li>
+    <li>
+      <label for="msg">Message:</label>
+      <textarea id="msg" name="user_message"></textarea>
+    </li>
+  </ul>
+</form>
+ +

Добавьте в вашу форму код, чтобы она выглядела так же, как форма выше.

+ +

Здесь элементы {{HTMLelement("li")}} используются для структурирования кода и облегчения стилизации (будет разобрано далее в статье). Для доступности и удобства использования мы указали определённый текст-подсказку для каждого элемента управления. Обратите внимание на использование атрибута for на каждом элементе {{HTMLelement("label")}}, который принимает в качестве значение id элемента управления формы, с которым он связан — этот подход позволяет привязать тексты-подсказки к форме.

+ +

Такой подход полезен тем, что позволяет пользователям с мышью, трекпадом и сенсорным устройством кликнуть на текст-подсказку для активации связанного с ним виджета формы, а также обеспечивает читабельное имя для пользователей скрин-ридеров. Вы найдёте более детальный разбор текстов-подсказок в статье Как структурировать HTML-форму.

+ +

В HTML-элементе {{HTMLelement("input")}} самым важным атрибутом является атрибут type. Этот атрибут чрезвычайно важен, потому что он определяет внешний вид и поведение элемента {{HTMLelement("input")}}. Вы найдёте больше информации об этом далее в статье Стандартные виджеты форм.

+ + + +

Последнее, но не менее важное, обратите внимание на разницу синтаксиса у HTML-элементов <input> и <textarea></textarea>. Это одна из странностей HTML. Тег <input> — это пустой элемент, то есть он не нуждается в закрывающем теге.  {{HTMLElement("textarea")}} — это непустой элемент, что говорит о том, что ему необходим закрывающий тег. Это важно при использовании одного из свойств форм: определения значения по умолчанию. Для определения начального значения для HTML-элемента {{HTMLElement("input")}} вам необходимо использовать атрибут value следующим образом:

+ +
<input type="text" value="по умолчанию в этом элементе находится этот текст" />
+ +

Если вы хотите определить значение по умолчанию для HTML-элемента {{HTMLElement("textarea")}}, вам просто нужно поместить это начальное значение между открывающим и закрывающим тегами:

+ +
<textarea>
+по умолчанию в этом элементе находится этот текст
+</textarea>
+ +

Элемент {{HTMLelement("button")}}

+ +

Разметка нашей формы почти готова, но нам ещё необходимо добавить кнопку, которая позволит пользователю отправлять или "представлять" информацию после заполнения формы. Это делается с помощью HTML-элемента {{HTMLelement("button")}}. Необходимо добавить следующий код перед закрывающим тегом </form>:

+ +
<li class="button">
+  <button type="submit">Send your message</button>
+</li>
+ +

HTML-элемент {{HTMLelement("button")}} также принимает атрибут type, который может быть равен одному из трёх значений: submit, reset или button.

+ + + +
+

Примечание: Вы также можете использовать HTML-элемент {{HTMLElement("input")}} с соответствующим атрибутом type , чтобы создать кнопку:  <input type="submit">. Главным преимуществом HTML-элемента {{HTMLelement("button")}} в сравнении с элементом {{HTMLelement("input")}} заключается в том, что {{HTMLelement("input")}} может принимать в себя только простой текст, в то время как {{HTMLelement("button")}} позволяет использовать весь HTML для создания более стилизованного текста внутри кнопки.

+
+ +

Базовая стилизация формы

+ +

Теперь после того, как вы закончили писать HTML-код формы, сохраните его и откройте в браузере. Вы увидите, что на данный момент форма выглядит достаточно не красиво.

+ +

+ +
+

Примечание: Если вам кажется, что ваш HTML-код работает не правильно, попробуйте сравнить его с нашим примером — посмотрите first-form.html (также можно посмотреть код вживую).

+
+ +

Красиво стилизовать формы достаточно сложно. Эта тема выходит за рамки этой статьи, поэтому на данный момент мы просто добавим некоторый CSS-код для приведения формы в нормальный вид.

+ +

Сначала необходимо добавить HTML-элемент {{htmlelement("style")}} на вашу страницу внутрь тега head в HTML. Это должно выглядить следущим образом:

+ +
<style>
+
+</style>
+ +

Внутри тега стилей добавьте следующий код:

+ +
form {
+  /* Расположим форму по центру страницы */
+  margin: 0 auto;
+  width: 400px;
+  /* Определим контур формы */
+  padding: 1em;
+  border: 1px solid #CCC;
+  border-radius: 1em;
+}
+
+ul {
+  list-style: none;
+  padding: 0;
+  margin: 0;
+}
+
+form li + li {
+  margin-top: 1em;
+}
+
+label {
+  /* Определим размер и выравнивание */
+  display: inline-block;
+  width: 90px;
+  text-align: right;
+}
+
+input,
+textarea {
+  /* Убедимся, что все поля имеют одинаковые настройки шрифта
+     По умолчанию в textarea используется моноширинный шрифт */
+  font: 1em sans-serif;
+
+  /* Определим размер полей */
+  width: 300px;
+  box-sizing: border-box;
+
+  /* Стилизуем границы полей */
+  border: 1px solid #999;
+}
+
+input:focus,
+textarea:focus {
+  /* Дополнительная подсветка для элементов в фокусе */
+  border-color: #000;
+}
+
+textarea {
+  /* Выровним многострочные текстовые поля с их текстами-подсказками */
+  vertical-align: top;
+
+  /* Предоставим пространство для ввода текста */
+  height: 5em;
+}
+
+.button {
+  /* Выровним кнопки с их текстами-подсказками */
+  padding-left: 90px; /* same size as the label elements */
+}
+
+button {
+  /* Этот дополнительный внешний отступ примерно равен расстоянию
+     между текстами-подсказками и текстовыми полями */
+  margin-left: .5em;
+}
+ +

Теперь наша форма выглядит намного лучше.

+ +

+ +
+

Примечание: Вы можете найти код на GitHub в first-form-styled.html (также можно посмотреть код вживую).

+
+ +

Отправка данных на сервер

+ +

Последняя и, наверно, самое сложное — это обработка данных формы на стороне сервера. HTML-элемент {{HTMLelement("form")}} определяет куда и каким способом отправить данные благодаря атрибутам action и method.

+ +

Мы определяем имя name для каждого виджета формы. Указание имён важно как для браузера, так и для сервера: браузер узнаёт, какие имена дать каждой части данных, а сервер может получить эти данные, обратясь к ним по заданному имени. Данные форму отправляются на сервер в виде пары имя/значение.

+ +

Чтобы проименовать данные, вам необходимо использовать атрибут name на каждом виджете формы, который будет собирать определённую часть информации. Давайте взглянем на код нашей формы ещё раз:

+ +
<form action="/my-handling-form-page" method="post">
+  <div>
+    <label for="name">Name:</label>
+    <input type="text" id="name" name="user_name" />
+  </div>
+  <div>
+    <label for="mail">E-mail:</label>
+    <input type="email" id="mail" name="user_email" />
+  </div>
+  <div>
+    <label for="msg">Message:</label>
+    <textarea id="msg" name="user_message"></textarea>
+  </div>
+
+  ...
+
+ +

В нашем примере форма отправит три куска данных с именами "user_name", "user_email" и "user_message". Эти данные будут отправлены на URL "/my-handling-form-page" через метод HTTP POST.

+ +

На стороне сервера скрипт, расположенный на URL "/my-handling-form-page" получит данные в виде списка из 3 элементов вида ключ/значение, содержащихся в HTTP-запросе. То, как скрипт будет обрабатывать данные, зависит от вас. Каждый язык серверного программирования (PHP, Python, Ruby, Java, C# и т.д.) имеет свой механизм обработки данных из формы. Эта тема выходит за рамки данной статьи, если вы хотите углубиться в неё, мы привели несколько примеров далее в статье Отправка данных формы.

+ +

Заключение

+ +

Поздравляем! Вы создали свою первую HTML-форму. Вживую это выглядит так: 

+ +

{{ EmbedLiveSample('A_simple_form', '100%', '240', '', 'Learn/HTML/Forms/Your_first_HTML_form/Example') }}

+ +

Однако это только начало — пришло время взглянуть глубже. HTML-формы намного мощнее, чем то, что мы видели здесь, и другие статьи этого раздела помогут освоить остальное.

+ +

{{NextMenu("Learn/HTML/Forms/How_to_structure_an_HTML_form", "Learn/HTML/Forms")}}

+ +

В этом разделе

+ + + +

Дополнительные темы

+ + diff --git a/files/ru/learn/front-end_web_developer/index.html b/files/ru/learn/front-end_web_developer/index.html new file mode 100644 index 0000000000..c219d6a069 --- /dev/null +++ b/files/ru/learn/front-end_web_developer/index.html @@ -0,0 +1,195 @@ +--- +title: Фронтенд разработчик +slug: Learn/Фронтенд_разработчик +tags: + - Начинающий + - Стандарты веб-разработки + - Фронт-енд +translation_of: Learn/Front-end_web_developer +--- +

{{learnsidebar}}
+
+ Добро пожаловать на курс обучения Фронтенд разработчика!
+
+ Здесь мы предлагаем вам структурированный курс, который научит вас всему, что вам необходимо знать, чтобы стать фронтенд разработчиком. Изучение в рекомендуемом порядке каждого раздела позволит получить новые навыки, или улучшить имеющиеся. Также в каждом разделе вы найдете упражнения и тесты. Прежде чем переходить к следующей теме обязательно проверьте себя.

+ +

Основные темы:

+ +

В курсе рассматриваются темы:

+ + + +

Различные разделы предназначены для проработки по порядку, но каждый из них также самодостаточен. Если вы, к примеру, уже хорошо знакомы с HTML, то можете перейти к разделу CSS.

+ +

Необходимые условия

+ +

Вам не нужно никаких предварительных знаний, чтобы начать этот курс. Всё, что вам необходимо – это компьютер, который может работать с современными браузерами, интернет соединение и готовность учиться.
+
+ Если вы не уверены, подходит ли вам фронтент разработка и/или вы хотите получить подробное представление, то прежде чем начинать полный курс, вам следует сначала изучить наш раздел Начало работы с веб модулем.

+ +

Получить помощь

+ +

Мы постарались сделать изучение фронтенд разработки настолько комфортным, насколько это возможно. Вероятно, вы всё равно рано или поздно попадёте в безвыходное положение, когда что-то будет непонятно или какой-то код не будет работать.

+ +

Не беспокойтесь. Мы все иногда застреваем, и начинающие, и профессиональные веб-разработчики. Статья Обучение и получение помощи предоставит вам серию советов и подсказок для поиска информации и помощи самому себе. Если вы всё ещё в замешательстве, задайте вопрос по возникшей проблеме на нашем Форуме.

+ +

Давайте начнём,

+ +

Удачи!

+ +

Путь обучения

+ +

Начало работы

+ +

Время изучения: 1–2 часа

+ +

Необходимые условия

+ +

Ничего, кроме базовой компьютерной грамотности.

+ +

Как понять, что я могу двигаться дальше?

+ +

В этой части курса нет оценок, но обязательно убедитесь, что вы ничего здесь не пропустили — важно всё настроить и подготовиться к выполнению упражнений в дальнейшем.

+ +

Основные руководства

+ + + +

Семантика и структура с HTML

+ +

Время завершения: 35–50 часов

+ +

Необходимые условия

+ +

Ничего, кроме базовой компьютерной грамотности и базовой среды разработки веб-приложений.

+ +

Как понять, что я могу двигаться дальше?

+ +

Оценки в каждом модуле предназначены для проверки ваших знаний по предмету - завершение каждого из них докажет, что вы можете перейти к следующему модулю.

+ +

Основные модули

+ + + +

Стилизация и размещение с помощью CSS

+ +

Время завершения: 90–120 часов

+ +

Необходимые условия

+ +

Рекомендуется иметь базовые знания HTML перед началом изучения CSS. Сначала вы должны изучить Введение в HTML.

+ +

Как понять, что я могу двигаться дальше?

+ +

Оценки в каждом модуле предназначены для проверки ваших знаний по предмету - завершение каждого из них докажет, что вы можете перейти к следующему модулю.

+ +

Основные модули

+ + + +

Дополнительные ресурсы

+ + + +

Интерактивность с JavaScript

+ +

Время завершения: 135–185 часов

+ +

Необходимые условия

+ +

Рекомендуется иметь базовые знания HTML перед началом изучения JavaScript. Сначала вы должны изучить Введение в HTML.

+ +

Как понять, что я могу двигаться дальше?

+ +

Оценки в каждом модуле предназначены для проверки ваших знаний по предмету - завершение каждого из них докажет, что вы можете перейти к следующему модулю.

+ +

Основные модули

+ + + +

Веб формы — Работаем с данными пользователя

+ +

Время завершения: 40–50 часов

+ +

Необходимые условия

+ +

Для эффективного использования форм требуется знание HTML, CSS и JavaScript. Они сложны и поэтому рассматриваются отдельно.

+ +

Как понять, что я могу двигаться дальше?

+ +

Упражнения и оценки в каждом модуле предназначены для проверки ваших знаний по предмету - завершение каждого из них докажет, что вы можете перейти к следующему модулю.

+ +

Основные модули

+ + + +

Заставляем веб работать для всех

+ +

Время завершения: 60–75 часов

+ +

Необходимые условия

+ +

Рекомендуется ознакомиться с HTML, CSS и JavaScript перед началом работы с этим разделом - многие из техник и лучших практик используются в нескольких технологиях.

+ +

Как понять, что я могу двигаться дальше?

+ +

Упражнения и оценки в каждом модуле предназначены для проверки ваших знаний по предмету - завершение каждого из них докажет, что вы можете перейти к следующему модулю.

+ +

Основные модули

+ + + +

Современные инструменты

+ +

Время завершения: 55–90 часов

+ +

Необходимые условия

+ +

Рекомендуется ознакомиться с HTML, CSS и JavaScript перед началом работы с этим разделом, так как обсуждаемые инструменты работают со многими из этих технологий.

+ +

Как понять, что я могу двигаться дальше?

+ +

В этом наборе модулей нет специальных статей для оценки, но учебные примеры в конце 2-го и 3-го модулей хорошо подготовят вас к пониманию основ современного инструментария.

+ +

Основные модули

+ + diff --git a/files/ru/learn/getting_started_with_the_web/installing_basic_software/index.html b/files/ru/learn/getting_started_with_the_web/installing_basic_software/index.html new file mode 100644 index 0000000000..40b4254712 --- /dev/null +++ b/files/ru/learn/getting_started_with_the_web/installing_basic_software/index.html @@ -0,0 +1,78 @@ +--- +title: Установка базового программного обеспечения +slug: Learn/Getting_started_with_the_web/Установка_базового_программного_обеспечения +tags: + - WebMechanics + - Браузер + - Интрументы + - Начинающий + - Новичку + - Обучение + - Текстовый редактор + - Установка +translation_of: Learn/Getting_started_with_the_web/Installing_basic_software +--- +
+
{{LearnSidebar}}
+ +
{{NextMenu("Learn/Getting_started_with_the_web/What_will_your_website_look_like", "Learn/Getting_started_with_the_web")}}
+
+ +
+

В Установке базового программного обеспечения, мы покажем вам, какие инструменты вам необходимы для простой веб-разработки, и как правильно установить их.

+
+ +

Какие инструменты используют профессионалы?

+ + + +

Какие инструменты на самом деле нужны мне прямо сейчас?

+ +

Этот список выглядит страшновато, но, к счастью, вы можете начать веб-разработку, не зная ничего о большинстве из того, что в нем написано. В этой статье мы установим базовый минимум - текстовый редактор и некоторые современные веб-браузеры.

+ +

Установка текстового редактора

+ +

У вас, наверное, уже есть базовый текстовый редактор на вашем компьютере. По умолчанию Windows включает Блокнот и Mac OS X поставляется с TextEdit. Linux дистрибутивы варьируются; Ubuntu поставляется с gedit по умолчанию.

+ +

Для веб-разработки вам, вероятно, понадобится больше, чем могут предложить Notepad или TextEdit. Мы рекомендуем начать с Visual Studio Code, который является бесплатным редактором, который предлагает предварительный просмотр и подсказки во время написания кода.

+ +

Установка современных веб-браузеров

+ +

На данный момент, мы установим только пару настольных веб-браузеров, чтобы проверять наш код. Выберите вашу операционную систему ниже и нажмите на соответствующие ссылки для загрузки установочных программ ваших любимых браузеров:

+ + + +

Прежде, чем идти дальше, вам следует установить, по крайней мере, два из этих браузеров, чтобы использовать их для тестирования.

+ +

Установка локального веб-сервера

+ +

Некоторые примеры для успешной работы необходимо будет запустить на веб-сервере. Вы можете узнать, как это сделать в статье How do you set up a local testing server?

+ +

{{NextMenu("Learn/Getting_started_with_the_web/What_will_your_website_look_like", "Learn/Getting_started_with_the_web")}}

+ +

В этом модуле

+ + diff --git a/files/ru/learn/getting_started_with_the_web/the_web_and_web_standards/index.html b/files/ru/learn/getting_started_with_the_web/the_web_and_web_standards/index.html new file mode 100644 index 0000000000..08fad617b5 --- /dev/null +++ b/files/ru/learn/getting_started_with_the_web/the_web_and_web_standards/index.html @@ -0,0 +1,167 @@ +--- +title: Всемирная сеть (веб) и веб-стандарты +slug: Learn/Getting_started_with_the_web/Веб_и_веб_стандарты +tags: + - Веб-стандарты + - Изучение +translation_of: Learn/Getting_started_with_the_web/The_web_and_web_standards +--- +

{{learnsidebar}}

+ +

Статья содержит общую информацию о всемирной сети (the Web) — откуда она взялась, что такое веб-стандарты, как они связанны, почему "веб разработчик" отличный карьерный выбор и чему полезному можно научиться изучая этот курс.

+ +

Краткая история сети веб

+ +

Мы постарались максимально кратко изложить здесь информацию. Если вы более детально заинтересованы в истории веб сети, то попробуйте поискать это в интернете.

+ +

В конце 1960-х военные США разработали коммуникационную сеть ARPANET. Вполне можно её рассматривать в качестве прародителя современной сети, так как она работала с помощью коммутации пакетов, и для неё впервые была внедрена сетевая модель TCP/IP. Эти две технологии послужили основой, на которой затем был построен интернет.

+ +

В 1980 году Тим Бернерс-Ли (aka TimBL) написал программу под названием ENQUIRE, которая позволяла устанавливать связь между двумя узлами. Ничего не напоминает?

+ +

В 1989 году TimBL выступил в организации ЦЕРН с идеями о методах структурирования, обработке и обмена информацией (Information Management: A Proposal), предложив при этом концепцию "гипертекста". Идеи Тима были одобрены и он начал воплощать в реальность свой проект. Современная сеть построена на основании его работ. 

+ +

К концу 1990-го года Тим Бернерс разработал все необходимые для запуска сети средства — HTTP, HTML, первый в мире веб браузер (WorldWideWeb), сервер HTTP и несколько веб страниц для наглядности.

+ +

В течение нескольких последующих лет веб сеть расширялась, выпускались новые браузеры, были установлены тысячи серверов и созданны миллионы веб страниц. Как и обещали, достаточно краткая история.

+ +

Стоит отметить, что в 1994 году TimBL основал консорциум Всемирной паутины (World Wide Web Consortium (W3C))  - организацию, связывающую множество компаний для сплочения усилий в области разработки веб технологий. После этого появились технологии, например, такие как CSS и JavaScript, которые преобразовали веб сеть в тот вид, в котором мы наблюдаем её сейчас.

+ +

Веб-стандарты

+ +

Веб-стандарты - это технологии, используемые для создания веб страниц. Стандарты существуют в виде технической документации (спецификаций), которая точно описывает как та, или иная технология должна работать. Документация никак не поможет изучить то, как пользоваться описываемыми в ней технологиями (вот почему существет сайт MDN Web Docs). Она используются разработчиками ПО для внендрения технологий (например, в веб браузеры).

+ +

В качестве примера приведем стандарт HTML Living Standard. Он описывает как HTML (все элементы HTML, связанные с ними API и остальные близкие технологии) должны быть реализованы.

+ +

Веб-стандарты создаются организациями стандартов — институтами, которые приглашают группы людей из различных компаний для согласования того, как технологии должны применяться наиболее эффективным образом в рассматриваемых случаях. Самая известная организация веб-стандартов - W3C. Существуют и другие: WHATWG (ответственны за модернизацию языка html), ECMA (выпускают стандарты языка ECMAScript, на котором построен JavaScript), Khronos (создают технологии для 3D графики, например WebGL).

+ +

"Open" standards

+ +

One of the key aspects of web standards, which TimBL and the W3C agreed on from the start, is that the web (and web technologies) should be free to both contribute and use, and not encumbered by patents/licensing. Therefore anyone can write the code to build a website for free, and anyone can contribute to the standards creation process, where the specs are written.

+ +

Because web technologies are created openly, in collaboration between many different companies, it means that no one company gets to control them, which is a really good thing. You wouldn't want a single company suddenly deciding to put the entire web behind a paywall, or releasing a new version of HTML that everyone has to buy to continue making web sites, or worse still, just deciding they aren't interested any more and just turning it off.

+ +

This allows the web to remain a freely-available public resource.

+ +

Не разорви сеть

+ +

Популярная в области веб-стандартов фраза гласит: "не разорви сеть". Это означает, что каждая новая веб-технология должна быть совместима со всеми предыдущими технологиями (поэтому старые сайты до сих пор работают), и со всеми последующими (разрабатываемые в последствии технологии, в свою очередь, должны быть совместимы с имеющимися). В процессе изучения представленного здесь материала вы начнете понимать каким образом это реализуется.

+ +

Being a web developer is good

+ +

The web industry is a very attractive market to enter if you are looking for a job. Recent published figures say that there are currently around 19 million web developers in the world, and that figure is set more than double in the next decade. And at the same time, there is a skill shortage in the industry — so what better time to learn web development?

+ +

It isn't all fun and games however — building web sites is a more complicated proposition than it used to be, and you'll have to put some time in to studying all the different technologies you need to use, all the techniques and best practices you need to know, and all the typical patterns you'll be called upon to implement. It'll take you a few months to really start to get into it, and then you'll need to keep learning so that your knowledge stays up-to-date with all the new tools and features that appear on the web platform, and keep practicing and refining your craft.

+ +

The only constant is change.

+ +

Does this sound hard? Don't worry — we aim to give you everything you need to know to get started, and things will get easier. Once you embrace the constant change and uncertainty of the web, you'll start to enjoy yourself. As a part of the web community, you'll have an entire web of contacts and useful material to help you, and you'll start to enjoy the creative possibilities it brings.

+ +

You're a digital creative now. Enjoy the experience, and the potential for earning a living.

+ +

Overview of modern web technologies

+ +

There are a number of technologies to learn if you want to be a front-end web developer. In this section we will describe them briefly. For a more detailed explanation of how some of them work together, read our article How the web works.

+ +

Browsers

+ +

You are probably reading these words inside a web browser in this very moment (unless you've printed it out, or are using assistive technology, such as a screenreader to read it out to you). Web browsers are the software programs people use to consume the web, and include Firefox, Chrome, Opera, Safari, and Edge.

+ +

HTTP

+ +

Hypertext Transfer Protocol, or HTTP, is a messaging protocol that allows web browsers to communicate with web servers (where web sites are stored). A typical conversation goes something like

+ +
"Hello web server. Can you give me the files I need to render bbc.co.uk"?
+
+"Sure thing web browser — here you go"
+
+[Downloads files and renders web page]
+ +

The actual syntax for HTTP messages (called requests and responses) is not that human-readable, but this gives you the basic idea.

+ +

HTML, CSS, and JavaScript

+ +

HTML, CSS, and JavaScript are the main three technologies you'll use to build a website:

+ + + +

Tooling

+ +

Once you've learned the "raw" technologies that can be used to build web pages (such as HTML, CSS, and JavaScript), you'll soon start to come across various tools that can be used to make your work easier or more efficient. Examples include:

+ + + +

Server-side languages and frameworks

+ +

HTML, CSS, and JavaScript are front-end (or client-side) languages, which means they are run by the browser to produce a website front-end that your users can use.

+ +

There are another class of languages called back-end (or server-side) languages, meaning that they are run on the server before the result is then sent to the browser to be displayed. A typical use for a server-side language is to get some data out of a database and generate some HTML to contain the data, before then sending the HTML over to the browser to display it to the user.

+ +

Example server-side languages include ASP.NET, Python, PHP, and NodeJS.

+ +

Web best practices

+ +

We have briefly talked about the technologies that you'll use to build websites. Now let's discuss the best practices you should employ to make sure you are using those technologies in the best way that you can.

+ +

When doing web development, the main cause of uncertainty comes from the fact that you don't know what combination of technology each user will use to view your web site:

+ + + +

Because you don't know exactly what your users will use, you need to design defensively — make your web site as flexible as possible, so that all of the above users can make use of it, even if they might not all get the same experience. In short, we are trying to make the web work for all, as much as possible.

+ +

You'll come across the below concepts at some point in your studies.

+ + + +

See also

+ + diff --git "a/files/ru/learn/getting_started_with_the_web/\320\262\320\265\320\261_\320\270_\320\262\320\265\320\261_\321\201\321\202\320\260\320\275\320\264\320\260\321\200\321\202\321\213/index.html" "b/files/ru/learn/getting_started_with_the_web/\320\262\320\265\320\261_\320\270_\320\262\320\265\320\261_\321\201\321\202\320\260\320\275\320\264\320\260\321\200\321\202\321\213/index.html" deleted file mode 100644 index 08fad617b5..0000000000 --- "a/files/ru/learn/getting_started_with_the_web/\320\262\320\265\320\261_\320\270_\320\262\320\265\320\261_\321\201\321\202\320\260\320\275\320\264\320\260\321\200\321\202\321\213/index.html" +++ /dev/null @@ -1,167 +0,0 @@ ---- -title: Всемирная сеть (веб) и веб-стандарты -slug: Learn/Getting_started_with_the_web/Веб_и_веб_стандарты -tags: - - Веб-стандарты - - Изучение -translation_of: Learn/Getting_started_with_the_web/The_web_and_web_standards ---- -

{{learnsidebar}}

- -

Статья содержит общую информацию о всемирной сети (the Web) — откуда она взялась, что такое веб-стандарты, как они связанны, почему "веб разработчик" отличный карьерный выбор и чему полезному можно научиться изучая этот курс.

- -

Краткая история сети веб

- -

Мы постарались максимально кратко изложить здесь информацию. Если вы более детально заинтересованы в истории веб сети, то попробуйте поискать это в интернете.

- -

В конце 1960-х военные США разработали коммуникационную сеть ARPANET. Вполне можно её рассматривать в качестве прародителя современной сети, так как она работала с помощью коммутации пакетов, и для неё впервые была внедрена сетевая модель TCP/IP. Эти две технологии послужили основой, на которой затем был построен интернет.

- -

В 1980 году Тим Бернерс-Ли (aka TimBL) написал программу под названием ENQUIRE, которая позволяла устанавливать связь между двумя узлами. Ничего не напоминает?

- -

В 1989 году TimBL выступил в организации ЦЕРН с идеями о методах структурирования, обработке и обмена информацией (Information Management: A Proposal), предложив при этом концепцию "гипертекста". Идеи Тима были одобрены и он начал воплощать в реальность свой проект. Современная сеть построена на основании его работ. 

- -

К концу 1990-го года Тим Бернерс разработал все необходимые для запуска сети средства — HTTP, HTML, первый в мире веб браузер (WorldWideWeb), сервер HTTP и несколько веб страниц для наглядности.

- -

В течение нескольких последующих лет веб сеть расширялась, выпускались новые браузеры, были установлены тысячи серверов и созданны миллионы веб страниц. Как и обещали, достаточно краткая история.

- -

Стоит отметить, что в 1994 году TimBL основал консорциум Всемирной паутины (World Wide Web Consortium (W3C))  - организацию, связывающую множество компаний для сплочения усилий в области разработки веб технологий. После этого появились технологии, например, такие как CSS и JavaScript, которые преобразовали веб сеть в тот вид, в котором мы наблюдаем её сейчас.

- -

Веб-стандарты

- -

Веб-стандарты - это технологии, используемые для создания веб страниц. Стандарты существуют в виде технической документации (спецификаций), которая точно описывает как та, или иная технология должна работать. Документация никак не поможет изучить то, как пользоваться описываемыми в ней технологиями (вот почему существет сайт MDN Web Docs). Она используются разработчиками ПО для внендрения технологий (например, в веб браузеры).

- -

В качестве примера приведем стандарт HTML Living Standard. Он описывает как HTML (все элементы HTML, связанные с ними API и остальные близкие технологии) должны быть реализованы.

- -

Веб-стандарты создаются организациями стандартов — институтами, которые приглашают группы людей из различных компаний для согласования того, как технологии должны применяться наиболее эффективным образом в рассматриваемых случаях. Самая известная организация веб-стандартов - W3C. Существуют и другие: WHATWG (ответственны за модернизацию языка html), ECMA (выпускают стандарты языка ECMAScript, на котором построен JavaScript), Khronos (создают технологии для 3D графики, например WebGL).

- -

"Open" standards

- -

One of the key aspects of web standards, which TimBL and the W3C agreed on from the start, is that the web (and web technologies) should be free to both contribute and use, and not encumbered by patents/licensing. Therefore anyone can write the code to build a website for free, and anyone can contribute to the standards creation process, where the specs are written.

- -

Because web technologies are created openly, in collaboration between many different companies, it means that no one company gets to control them, which is a really good thing. You wouldn't want a single company suddenly deciding to put the entire web behind a paywall, or releasing a new version of HTML that everyone has to buy to continue making web sites, or worse still, just deciding they aren't interested any more and just turning it off.

- -

This allows the web to remain a freely-available public resource.

- -

Не разорви сеть

- -

Популярная в области веб-стандартов фраза гласит: "не разорви сеть". Это означает, что каждая новая веб-технология должна быть совместима со всеми предыдущими технологиями (поэтому старые сайты до сих пор работают), и со всеми последующими (разрабатываемые в последствии технологии, в свою очередь, должны быть совместимы с имеющимися). В процессе изучения представленного здесь материала вы начнете понимать каким образом это реализуется.

- -

Being a web developer is good

- -

The web industry is a very attractive market to enter if you are looking for a job. Recent published figures say that there are currently around 19 million web developers in the world, and that figure is set more than double in the next decade. And at the same time, there is a skill shortage in the industry — so what better time to learn web development?

- -

It isn't all fun and games however — building web sites is a more complicated proposition than it used to be, and you'll have to put some time in to studying all the different technologies you need to use, all the techniques and best practices you need to know, and all the typical patterns you'll be called upon to implement. It'll take you a few months to really start to get into it, and then you'll need to keep learning so that your knowledge stays up-to-date with all the new tools and features that appear on the web platform, and keep practicing and refining your craft.

- -

The only constant is change.

- -

Does this sound hard? Don't worry — we aim to give you everything you need to know to get started, and things will get easier. Once you embrace the constant change and uncertainty of the web, you'll start to enjoy yourself. As a part of the web community, you'll have an entire web of contacts and useful material to help you, and you'll start to enjoy the creative possibilities it brings.

- -

You're a digital creative now. Enjoy the experience, and the potential for earning a living.

- -

Overview of modern web technologies

- -

There are a number of technologies to learn if you want to be a front-end web developer. In this section we will describe them briefly. For a more detailed explanation of how some of them work together, read our article How the web works.

- -

Browsers

- -

You are probably reading these words inside a web browser in this very moment (unless you've printed it out, or are using assistive technology, such as a screenreader to read it out to you). Web browsers are the software programs people use to consume the web, and include Firefox, Chrome, Opera, Safari, and Edge.

- -

HTTP

- -

Hypertext Transfer Protocol, or HTTP, is a messaging protocol that allows web browsers to communicate with web servers (where web sites are stored). A typical conversation goes something like

- -
"Hello web server. Can you give me the files I need to render bbc.co.uk"?
-
-"Sure thing web browser — here you go"
-
-[Downloads files and renders web page]
- -

The actual syntax for HTTP messages (called requests and responses) is not that human-readable, but this gives you the basic idea.

- -

HTML, CSS, and JavaScript

- -

HTML, CSS, and JavaScript are the main three technologies you'll use to build a website:

- - - -

Tooling

- -

Once you've learned the "raw" technologies that can be used to build web pages (such as HTML, CSS, and JavaScript), you'll soon start to come across various tools that can be used to make your work easier or more efficient. Examples include:

- - - -

Server-side languages and frameworks

- -

HTML, CSS, and JavaScript are front-end (or client-side) languages, which means they are run by the browser to produce a website front-end that your users can use.

- -

There are another class of languages called back-end (or server-side) languages, meaning that they are run on the server before the result is then sent to the browser to be displayed. A typical use for a server-side language is to get some data out of a database and generate some HTML to contain the data, before then sending the HTML over to the browser to display it to the user.

- -

Example server-side languages include ASP.NET, Python, PHP, and NodeJS.

- -

Web best practices

- -

We have briefly talked about the technologies that you'll use to build websites. Now let's discuss the best practices you should employ to make sure you are using those technologies in the best way that you can.

- -

When doing web development, the main cause of uncertainty comes from the fact that you don't know what combination of technology each user will use to view your web site:

- - - -

Because you don't know exactly what your users will use, you need to design defensively — make your web site as flexible as possible, so that all of the above users can make use of it, even if they might not all get the same experience. In short, we are trying to make the web work for all, as much as possible.

- -

You'll come across the below concepts at some point in your studies.

- - - -

See also

- - diff --git "a/files/ru/learn/getting_started_with_the_web/\321\203\321\201\321\202\320\260\320\275\320\276\320\262\320\272\320\260_\320\261\320\260\320\267\320\276\320\262\320\276\320\263\320\276_\320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\275\320\276\320\263\320\276_\320\276\320\261\320\265\321\201\320\277\320\265\321\207\320\265\320\275\320\270\321\217/index.html" "b/files/ru/learn/getting_started_with_the_web/\321\203\321\201\321\202\320\260\320\275\320\276\320\262\320\272\320\260_\320\261\320\260\320\267\320\276\320\262\320\276\320\263\320\276_\320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\275\320\276\320\263\320\276_\320\276\320\261\320\265\321\201\320\277\320\265\321\207\320\265\320\275\320\270\321\217/index.html" deleted file mode 100644 index 40b4254712..0000000000 --- "a/files/ru/learn/getting_started_with_the_web/\321\203\321\201\321\202\320\260\320\275\320\276\320\262\320\272\320\260_\320\261\320\260\320\267\320\276\320\262\320\276\320\263\320\276_\320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\275\320\276\320\263\320\276_\320\276\320\261\320\265\321\201\320\277\320\265\321\207\320\265\320\275\320\270\321\217/index.html" +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: Установка базового программного обеспечения -slug: Learn/Getting_started_with_the_web/Установка_базового_программного_обеспечения -tags: - - WebMechanics - - Браузер - - Интрументы - - Начинающий - - Новичку - - Обучение - - Текстовый редактор - - Установка -translation_of: Learn/Getting_started_with_the_web/Installing_basic_software ---- -
-
{{LearnSidebar}}
- -
{{NextMenu("Learn/Getting_started_with_the_web/What_will_your_website_look_like", "Learn/Getting_started_with_the_web")}}
-
- -
-

В Установке базового программного обеспечения, мы покажем вам, какие инструменты вам необходимы для простой веб-разработки, и как правильно установить их.

-
- -

Какие инструменты используют профессионалы?

- - - -

Какие инструменты на самом деле нужны мне прямо сейчас?

- -

Этот список выглядит страшновато, но, к счастью, вы можете начать веб-разработку, не зная ничего о большинстве из того, что в нем написано. В этой статье мы установим базовый минимум - текстовый редактор и некоторые современные веб-браузеры.

- -

Установка текстового редактора

- -

У вас, наверное, уже есть базовый текстовый редактор на вашем компьютере. По умолчанию Windows включает Блокнот и Mac OS X поставляется с TextEdit. Linux дистрибутивы варьируются; Ubuntu поставляется с gedit по умолчанию.

- -

Для веб-разработки вам, вероятно, понадобится больше, чем могут предложить Notepad или TextEdit. Мы рекомендуем начать с Visual Studio Code, который является бесплатным редактором, который предлагает предварительный просмотр и подсказки во время написания кода.

- -

Установка современных веб-браузеров

- -

На данный момент, мы установим только пару настольных веб-браузеров, чтобы проверять наш код. Выберите вашу операционную систему ниже и нажмите на соответствующие ссылки для загрузки установочных программ ваших любимых браузеров:

- - - -

Прежде, чем идти дальше, вам следует установить, по крайней мере, два из этих браузеров, чтобы использовать их для тестирования.

- -

Установка локального веб-сервера

- -

Некоторые примеры для успешной работы необходимо будет запустить на веб-сервере. Вы можете узнать, как это сделать в статье How do you set up a local testing server?

- -

{{NextMenu("Learn/Getting_started_with_the_web/What_will_your_website_look_like", "Learn/Getting_started_with_the_web")}}

- -

В этом модуле

- - diff --git a/files/ru/learn/how_the_internet_works/index.html b/files/ru/learn/how_the_internet_works/index.html deleted file mode 100644 index 19230a4042..0000000000 --- a/files/ru/learn/how_the_internet_works/index.html +++ /dev/null @@ -1,102 +0,0 @@ ---- -title: Как работает Интернет -slug: Learn/How_the_Internet_works -tags: - - Начинающий - - Руководство - - Учебник - - туториал -translation_of: Learn/Common_questions/How_does_the_Internet_work ---- -
{{LearnSidebar}}
- -
-

Эта статья о том, что такое Интернет, и как он работает.

-
- - - - - - - - - - - - -
Необходимые знания:Отсутствуют, но мы будем признательны, если вы сначала прочтете Материал о там как начать разрабатывать свой сайт
Цель: -

Вы изучите основы технической инфраструктуры Веба и поймете разницу между Вебом и интернетом. 

-
- -

Резюме

- -

Интернет является основой сети (the Web), технической инфраструктурой, благодаря которой и существует Всемирная Паутина. По своей сути, интернет - очень большая сеть компьютеров, которые могут взаимодействовать друг с другом.

- -

История интернета не до конца ясна. Проект по созданию интернета был начат в 60-х годах как исследовательский проект при поддержке министерства обороны США, но уже в 80-е годы вырос в сеть, которую поддерживали и развивали множество университетов и частных компаний. Технологии, лежащие в основе интернета, также продолжали развиваться со временем, но основной принцип работы не сильно изменился: Интернет - это способ подключить компьютеры в единую сеть и убедиться, что даже при серьезных сбоях, они все равно найдут способ связаться друг с другом.

- -

Активное изучение

- - - -

Погружаемся глубже

- -

Простая сеть

- -

Когда нужно связать между собой два компьютера, вы должны связать их в сеть либо проводным (обычно с помощью Ethernet кабеля), либо беспроводным способом (например, с помощью WiFi или Bluetooth). Современные компьютеры поддерживают любой из этих способов связи.

- -
-

Примечание: До конца этой статьи мы будем говорить только о физическом (проводном) способе подключения, но беспроводные сети работают аналогичным образом.

-
- -

Two computers linked together

- -

Таким способом Вы можете подключить более двух компьютеров, но с каждым новым это становится все сложнее. Если хочется подключить, скажем, 10 компьютеров, вам понадобится 45 кабелей и 9 сетевых плат в каждом компьютере!

- -

Ten computers all together

- -

Чтобы решить эту проблему, каждый компьютер в сети подключается к специальному маленькому компьютеру. Этот компьютер называют маршрутизатором. Маршрутизатор исполняет только одну роль: как сигнальщик на железной дороге он следит за тем, чтобы пакет, отправленный одним компьютером — источником — достиг пункта назначения. Чтобы отправить сообщение компьютеру B, компьютер A сначала должен отправить его маршрутизатору, который перенаправит его компьютеру B и проконтролирует, чтобы данные не попали компьютеру C.

- -

С добавлением маршрутизатора наша сеть здорово упрощается: чтобы соединить 10 компьютеров нам требуется только 10 кабелей (каждый кабель соединяет маршрутизатор с одним из компьютеров).

- -

Ten computers with a router

- -

Сеть сетей

- -

Пока все нормально. Но что нам делать, если нужно объединить в сеть сотни, тысячи или миллиарды компьютеров? Конечно, один маршрутизатор не справится с этой задачей, но если вы внимательно читали, то помните, что маршрутизатор — это обычный компьютер, и ничто не мешает нам соединить друг с другом 2 маршрутизатора. Давайте сделаем это.

- -

Two routers linked together

- -

Подключая компьютеры к маршрутизатору, а затем — маршрутизатор к другому маршрутизатору, мы можем увеличивать нашу сеть до сколь угодно больших размеров.

- -

Routers linked to routers

- -

Такая сеть уже очень похожа на то, что мы называем интернетом, но мы что-то упустили. Наша сеть построена для решения только наших задач. Но кроме нее есть и другие сети: наши друзья, соседи — кто угодно может создать свою сеть. Как же нам их объединить? Мы не можем протянуть кабели между нашим домом и всеми остальными сетями в мире. Чтобы решить эту проблему, мы можем воспользоваться уже существующими кабельными сетями. Ведь у нас дома уже есть кабели, например, электрические или телефонные. Телефонный провод уже соединяет ваш дом со всем остальным миром, так что он идеально подходит для решения нашей задачи. Чтобы подключить нашу сеть к глобальной сети с помощью телефонного провода, нам понадобится специальное оборудование, которое называется модем. Модем перекодирует информацию, поступающую из нашей сети в формат, который можно передавать через телефонную сеть, и наоборот, декодируют информацию из телефонной сети в формат, который распознают наши компьютеры.

- -

A router linked to a modem

- -

Итак, мы подключились к телефонной сети. Следующий шаг — передать сообщение из нашей сети в сеть, с которой мы хотим связаться. Чтобы сделать это, мы должны подключить нашу сеть к провайдеру услуг интернета (Internet Service Provider (ISP)). Провайдер — компания, которая обслуживает специальные маршрутизаторы, которые не только подключены друг к другу (объединяют в единую сеть всех клиентов провайдера), но также связаны с маршрутизаторами других провайдеров. Таким образом, наше сообщение, пройдя транзитом через сеть нескольких провайдеров, достигнет сеть назначения. Интернет — это сеть сетей, которая объединяет в себе всю вышеперечисленную инфраструктуру.

- -

Full Internet stack

- -

Поиск компьютера

- -

Чтобы послать сообщение какому-то компьютеру, необходимо как-то обратиться к нему, выделить среди других. Поэтому каждый компьютер, подключенный к сети, имеет свой уникальный адрес для связи: этот адрес называют IP-адресом (IP — сокращение для Internet Protocol, протокол интернета). В зависимости от версии протокола IP этот адрес может записываться по-разному. Самая широко используемая версия интернет-протокола — версия 4. Адреса IPv4 обычно записываются в виде четырёх чисел, разделенных точками, например: 192.168.2.10.

- -

Такие адреса отлично подходят для компьютеров, но людям очень сложно их запоминать. Чтобы упростить себе жизнь, мы можем присвоить каждому IP-адресу псевдоним с понятным для человека именем. Такой псевдоним называют доменным именем. Например, google.com — доменное имя, которое является псевдонимом IP-адреса 173.194.121.32. Использование доменного имени — самый простой способ обратиться к компьютеру в интернете.

- -

Show how a domain name can alias an IP address

- -

Интернет и веб

- -

Как вы уже заметили, когда мы просматриваем Веб с помощью браузера, обычно мы используем доменное имя, чтобы обратиться к веб-сайту. Означает ли это, что Интернет и Веб — это одно и то же? Ответ не так прост. Мы уже знаем, что Интернет — это техническая основа, которая позволяет миллиардам компьютеров связываться друг с другом. Среди этих компьютеров есть небольшая группа (называемая веб-серверами), которые могут отправлять сообщения, распознаваемые браузерами. Интернет —  это инфраструктура, а Веб — это сервис, построенный на основе этой инфраструктуры. Стоит отметить, что кроме Веба есть и другие сервисы, построенные на базе Интернета. Например, электронная почта или {{Glossary("IRC")}}.

- -

Что дальше

- - diff --git a/files/ru/learn/html/forms/how_to_build_custom_form_widgets/index.html b/files/ru/learn/html/forms/how_to_build_custom_form_widgets/index.html deleted file mode 100644 index 8a4ca2d6b8..0000000000 --- a/files/ru/learn/html/forms/how_to_build_custom_form_widgets/index.html +++ /dev/null @@ -1,792 +0,0 @@ ---- -title: Как создавать пользовательские виджеты форм -slug: Learn/HTML/Forms/How_to_build_custom_form_widgets -tags: - - HTML - - Web - - Пример - - Продвинутый - - Руководство - - Формы -translation_of: Learn/Forms/How_to_build_custom_form_controls ---- -
{{LearnSidebar}}{{PreviousMenuNext("Learn/HTML/Forms/Form_validation", "Learn/HTML/Forms/Sending_forms_through_JavaScript", "Learn/HTML/Forms")}}
- -

Существует много случаев, когда возможностей стандартных виджетов HTML форм недостаточно. Если вы хотите придать лучший вид каким-либо виджетам как, например, {{HTMLElement("select")}}, или вы хотите создать особое поведение виджета, то у вас нет другого выбора, кроме как создать собственные виджеты.

- -

В этой статье мы рассмотрим как создать такой виджет. Для этого мы возьмем пример: переделка элемента {{HTMLElement("select")}} .

- -
-

Замечание: Мы сфокусируемся на создании виджетов, а не на том чтобы сделать код  универсальным и многоразовым; поэтому будут использоваться некоторый нетривиальный JavaScript код и манипуляции DOM в неизвестном контексте, что выходит за рамки этой статьи.

-
- -

Дизайн, структура и семантика

- -

В начале создания пользовательского виджета необходимо обрисовать что именно вы хотите. Это сэкономит драгоценное время. Особенно важно четко определить все состояния вашего виджета. Чтобы это сделать, лучше начать с существущего виджета, состояния и реакции которго хорошо известны, так что вы сможете просто подражать им насколько это возможно.

- -

В нашем примере мы будем переделывать элемент {{HTMLElement("select")}}. Вот такой результат мы хотим достичь:

- -

The three states of a select box

- -

Этот скриншот показывает три основных состояния нашего виджета: нормальное состояние (слева); активное состояние (посередине) и развернутое состояние (справа).

- -

С точки зрения реакций нужно чтобы наш виджет взаимодействовал как с мышью, так и с клавиатурой, так же как и стандартный виджет. Давайте сначала определим, как виджет приходит в каждое состояние:

- -
-
Виджет в нормальном состоянии когда:
-
-
    -
  • страница загружается
  • -
  • виджет был активным и пользователь кликает где-то вне виджета
  • -
  • виджет был активным и пользователь перемещает фокус на другой виджет при помощи клавиатуры
  • -
- -
-

Замечание: Перемещение фокуса по странице обычно осуществялется клавишей "tab", но не везде. Например в Safari циклический переход между ссылками на странице осуществляется по усмолчанию комбинацией Option+Tab.

-
-
-
Виджет в активном состоянии когда:
-
-
    -
  • пользователь кликает на него
  • -
  • пользователь нажимает клавишу Tab, и он получает фокус
  • -
  • виджет был в развернутом состоянии и позователь кликает на виджет.
  • -
-
-
Виджет в развернутом состоянии:
-
-
    -
  • виджет в любом другом состоянии и пользователь кликает на него
  • -
-
-
- -

Теперь, когда мы знаем, как изменяются состояния, важно определить, как изменить значение виджета:

- -
-
Значение изменяется когда:
-
-
    -
  • пользователь кликает на один-из-вариантов когда виджет в развернутом состоянии
  • -
  • пользователь нажимает клавиши стрелка вверх или вниз когда виджет в активном состоянии
  • -
-
-
- -

Наконец, давайте определим, как будут вести себя варианты виджета:

- - - -

Для нашего примера остановимся на этом; но, если вы внимательный читатель, вы заметите, что некоторые реакции отсутствуют. Например, как вы думаете, что произойдет если пользователь нажмет клавишу "tab" когда виджет в развернутом состоянии? Ответом будет... ничего. OK, правильная реакция кажется очевидной, но поскольку она не определена в наших спецификациях, то очень легко пропустить реализацию этой реакции. Это особенно верно для командной работы, когда те, кто опеределяет какими должны быть реакции виджета сами не реализуют их.

- -

Другой забавный пример: что произойдет, если пользователь нажмет клавишу вверх или вниз когда виджет находитися в развернутом состоянии? Это немного сложнее. Если вы предположите, что активное и развернутое состояние полностью различны, то ответом снова будет "ничего не произойдет" , потому что мы не определили никаких взаимодействий с клавиатурой в открытом состоянии. С другой стороны, если вы предположите, что активное и развернутое состояние немного похожи, значение может изменится, но выбранный вариант точно не будет соответственно подсвечен, опять же потому, что мы не определили никаких действий с клавиатуры над вариантами когда виджет находится в развернутом состоянии (мы определили только то, что произойдет, когда виджет развернется, но ничего более).

- -

В нашем примере пропущенные спецификации очевидны, так что мы с ними справимся, но это может стать реальной проблемой для новых экзотических виджетов, когда никто не имеет ни малейшего представления о том как они должны реагировать. Всегда лучше потратить время на этом этапе дизайна, потому что если вы плохо определите, или забудете определить реакцию виджета, то будет очень сложно изменять ее, когда пользователи уже привыкнут. Если у вас есть сомнения - спросите мнения у окружающих, и, если позволяет бюджет,  не стесняйтесь выполнять пользовательские тесты. Этот процесс называется UX Design (Дизайн взаимодействия с пользователем). Если вы хотите узнать больше об этой теме, вам следует посетить следующие полезные ресурсы:

- - - -
-

Замечание:  Также, в большинстве систем, есть способ развернуть элемент {{HTMLElement("select")}} чтобы посмотреть все доступные варианты (это то-же что кликнуть мышью элемент {{HTMLElement("select")}} ).  Это возможно комбинацией Alt+Стрелка вниз для Windows и не реализовано в нашем примере —но это будет просто сделать, так как механизм уже реализован дл события click.

-
- -

Определение структуры и семантики HTML

- -

Теперь, когда основной функционал виджета определен, пора начать создание виджета. Первым делом определим его HTML структуру и придадим основную семантику. Вот все что нам нужно чтобы переделать элемент {{HTMLElement("select")}}:

- -
<!-- Это основной контейнер для нашего виджета.
-     Аттрибут tabindex позволяет пользователю переместить фокус на виджет.
-     Позже мы увидим, что лучше его установить через JavaScript. -->
-<div class="select" tabindex="0">
-
-  <!-- Этот контейнер послужит для отображения текущего значения виджета -->
-  <span class="value">Cherry</span>
-
-  <!-- Этот контейнер содержит все варинты. доступные для нашего виджета.
-       Так как это список, то есть смысл использовать элемент ul. -->
-  <ul class="optList">
-    <!-- Каждый вариант содержит то значение, которое будет отображено, позже мы увидим
-         как получить то значение, которое будет отппралено вместе с данными формы -->
-    <li class="option">Cherry</li>
-    <li class="option">Lemon</li>
-    <li class="option">Banana</li>
-    <li class="option">Strawberry</li>
-    <li class="option">Apple</li>
-  </ul>
-
-</div>
- -

Обратите внимание на использование имен классов: они описывают каждый соответствующий элемет независимо от фактически используемых базовых элементов HTML. Важно быть уверенными что нам не придется жестко привязывать наши CSS и JavaScript к HTML структуре,тогда мы сможем позже вносить изменения не нарушая код виджета. Например, если вы захотите создать эквивалент элемента {{HTMLElement("optgroup")}}.

- -

Создание внешнего вида с помощью CSS

- -

Теперь у нас есть структура и мы можем заняться дизайном нашего виджета. Весь смысл создания нашего собственного виджета в том, чтобы мы могли придать ему такой внешний вид, как мы захотим. Поэтому мы разделим нашу работу с CSS на две части: в первой части будут правила CSS абсолютно необходимые чтобы реакции нашего виджета были как у элемента {{HTMLElement("select")}} , а вторая чать будет состоять из красивеньких рюшечек, чтобы виджет выглядел так, как нам нравится.

- -

Обязательные стили

- -

Обязательные стили - это те, которые необходимы для обработки трех состояний нашего виджета..

- -
.select {
-  /* Это создаст контекст позиционирования для списка вариантов */
-  position: relative;
-
-  /* Это сделает наш виджет частью текстового потока и одновременно сделает его
-     изменяемого размера */
-  display : inline-block;
-}
- -

Еще нам нужен дополнительный класс active, чтобы определить, как будет выглядеть наш виджет в активном состоянии. Так как наш виджет может находится в фокусе, то мы укажем этот стиль еще и для псевдокласса {{cssxref(":focus")}} чтобы быть уверенными, что виджет будет вести себя одинаково.

- -
.select .active,
-.select:focus {
-  outline: none;
-
-  /* Это свойство - box-shadow - необязательно, однако нам важно видеть активное состояние
-    т.к. мы используем его по умолчанию. Можете спокойно его переопределить. */
-  box-shadow: 0 0 3px 1px #227755;
-}
- -

Теперь давайте стилизуем список опций:

- -
/* Селектор .select здесь применен для удобства (синтаксический сахар), чтобы быть уверенными,
-   что определяемые классы находятся в нашем виджете. */
-.select .optList {
-/* Это позволит нам быть уверенными, что список вариантов будет показан ниже значения
-   и вне HTML потока */
-  position : absolute;
-  top      : 100%;
-  left     : 0;
-}
- -

Еще нам нужен дополнительный класс, для обращения к списку вариантов, когда он скрыт. Это необходимо чтобы справиться с различиями активного и развернутого состояния, т.к. они не совсем совпадают.

- -
.select .optList.hidden {
-  /* Это самый простой из доступных способов путь скрыть список,
-     а о доступности мы еще поговрим в конце */
-  max-height: 0;
-  visibility: hidden;
-}
- -

Украшательства

- -

Теперь, когда основная функциональность на месте, можем начинать развлекаться. То, что мы сделаем дальше, является всего лишь примером того, что возможно, и будет соответствовать скриншоту в начале этой статьи. Но вы можете свободно эксперементировать и посмотреть на что вы способны.

- -
.select {
-  /* Все размеры будут выражены в em по соображениям удобства
-     (чтобы быть уверенными, что виджет будет изменять размер если пользователь будет
-     использовать увеличение в текстовом режиме браузера). Вычисления сделаны из расчета что
-     1em == 16px что является умолчанием для большинства браузеров.
-     Если вы затрудняетесь с преобразованием px в em, попробуйте http://riddle.pl/emcalc/ */
-  font-size   : 0.625em; /* это (10px) новый размер шрифта для нашего контекста для значения
-                            em в исходном контексте */
-  font-family : Verdana, Arial, sans-serif;
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  /* Нам нужно добавить дополнительное пространство для стрелки вниз */
-  padding : .1em 2.5em .2em .5em; /* 1px 25px 2px 5px */
-  width   : 10em; /* 100px */
-
-  border        : .2em solid #000; /* 2px */
-  border-radius : .4em; /* 4px */
-  box-shadow    : 0 .1em .2em rgba(0,0,0,.45); /* 0 1px 2px */
-
-  /* Первое объявление - для бразуеров не поддерживающих линейный градиент.
-     Второе объявление - потому что основанные на WebKit браузеры еще не избавились от префикса в нем.
-     Если вам нужна поддержка устаревших браузеров, попробуйте http://www.colorzilla.com/gradient-editor/ */
-  background : #F0F0F0;
-  background : -webkit-linear-gradient(90deg, #E3E3E3, #fcfcfc 50%, #f0f0f0);
-  background : linear-gradient(0deg, #E3E3E3, #fcfcfc 50%, #f0f0f0);
-}
-
-.select .value {
-  /* Так как значение может быть шире, чем наш виджет, нужно быть уверенными, что оно не изменит
-     ширину виджета */
-  display  : inline-block;
-  width    : 100%;
-  overflow : hidden;
-
-  vertical-align: top;
-
-  /* И, если содержимое слишком длинное, лучше иметь красивенькие точечки. */
-  white-space  : nowrap;
-  text-overflow: ellipsis;
-}
- -

Нам не нужен дополнительный элемент, чтобы создать стрелку вниз; вместо этого мы используем псевдоэлемент {{cssxref(":after")}}. Также её можно создать при помощи простого фонового изображения в классе select.

- -
.select:after {
-  content : "▼"; /* Мы используем Unicode символ U+25BC; смотрите http://www.utf8-chartable.de */
-  position: absolute;
-  z-index : 1; /* Важно чтобы стрелка не перекрывала элементы списка */
-  top     : 0;
-  right   : 0;
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  height  : 100%;
-  width   : 2em;  /* 20px */
-  padding-top : .1em; /* 1px */
-
-  border-left  : .2em solid #000; /* 2px */
-  border-radius: 0 .1em .1em 0;  /* 0 1px 1px 0 */
-
-  background-color : #000;
-  color : #FFF;
-  text-align : center;
-}
- -

Далее стилизуем список вариантов:

- -
.select .optList {
-  z-index : 2; /* Мы явно сказали, что список вариантов всегда будет перекрывать стрелку вниз */
-
-  /* это сбросит значения стиля по умолчанию для элемента ul */
-  list-style: none;
-  margin : 0;
-  padding: 0;
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  /* Это для того, чтобы убедиться что если значения будут короче виджета
-     то список вариантов останется таким же по размеру как и сам виджет */
-  min-width : 100%;
-
-  /* В случае, если список слишком длинный, его содержимое не будет помещаться по вертикали
-     (что автоматически добавит полосу прокрутки), но этого никогда не произойдет по горизонтали
-     (потому что мы не установили ширину и содержимое списка будет регулировать ее
-     автоматически. Если это будет невозможно - содержимое будет обрезано.) */
-  max-height: 10em; /* 100px */
-  overflow-y: auto;
-  overflow-x: hidden;
-
-  border: .2em solid #000; /* 2px */
-  border-top-width : .1em; /* 1px */
-  border-radius: 0 0 .4em .4em; /* 0 0 4px 4px */
-
-  box-shadow: 0 .2em .4em rgba(0,0,0,.4); /* 0 2px 4px */
-  background: #f0f0f0;
-}
- -

Для вариантов нам нужно добавить класс highlight чтобы сделать возможным индентифицировать значение которе пользователь выберет (или выбрал).

- -
.select .option {
-  padding: .2em .3em; /* 2px 3px */
-}
-
-.select .highlight {
-  background: #000;
-  color: #FFFFFF;
-}
- -

Итак, вот результат с нашими тремя состояниями:

- - - - - - - - - - - - - - - - - - - -
Основное состояниеАктивное состояниеРазвернутое состояние
{{EmbedLiveSample("Basic_state",120,130, "", "HTML/Forms/How_to_build_custom_form_widgets/Example_1")}}{{EmbedLiveSample("Active_state",120,130, "", "HTML/Forms/How_to_build_custom_form_widgets/Example_1")}}{{EmbedLiveSample("Open_state",120,130, "", "HTML/Forms/How_to_build_custom_form_widgets/Example_1")}}
Посмотреть исходный код
- -

Оживи свой виджет с JavaScript

- -

Теперь, когда наш дизайн и структура готовы, мы можем написать код на JavaScript чтобы виджет действительно заработал.

- -
-

Предупреждение: Следующий код представлен в образовательных целях и не может быть использован как-есть. Помимо прочего, как мы убедимся, он не пригоден для дальнейшего развития и не будет работать в устаревших браузерах. В нем также есть избыточность которую необходимо оптимизировать использования в рабочем режиме.

-
- -
-

Замечание: Создание многократно используемых виджетов может быть немного сложнее. W3C Web Component draft является одним из ответов на этот конкретный вопрос. The X-Tag project попытка реализовать эту спецификацию; пожалуйста, посмотрите этот проект.

-
- -

Почему он не работает?

- -

Прежде чем мы начнем, запомните одну важную вещь о JavaScript: в браузере это ненадежная технология. Когда вы создаете пользовательские виджеты, вы будете полагаться на JavaScript потому что это необходимое звено для связки. Однако во многих случаях  JavaScript невозможно запустить в браузере:

- - - -

Из-за этого очень важно серьезно подумать о том, что произойдет, если JavaScript не сработает. Детальное рассмотрение этой проблемы выходит за рамки данной статьи, поскольку эта проблема тесно связана с тем, насколько универсальным и многократно используемым вы хотите сделать свой сценарий, но мы рассмотрим основы этого в нашем примере.

- -

В нашем примере, если наш JavaScript код не работает, мы используем стандартный элемент {{HTMLElement("select")}}. Для этого, нам нужны две вещи.

- -

Во-первых нам нужно добавить стандартный элемент {{HTMLElement("select")}} перед каждым использованием нашего пользовательского виджета. Это также необходимо, чтобы отправить данные из нашего пользовательского виджета вместе с остальными данными формы; подробнее рассмотрим это позже.

- -
<body class="no-widget">
-  <form>
-    <select name="myFruit">
-      <option>Cherry</option>
-      <option>Lemon</option>
-      <option>Banana</option>
-      <option>Strawberry</option>
-      <option>Apple</option>
-    </select>
-
-    <div class="select">
-      <span class="value">Cherry</span>
-      <ul class="optList hidden">
-        <li class="option">Cherry</li>
-        <li class="option">Lemon</li>
-        <li class="option">Banana</li>
-        <li class="option">Strawberry</li>
-        <li class="option">Apple</li>
-      </ul>
-    </div>
-  </form>
-
-</body>
- -

Во-вторых нам нужно два новых класса, чтобы скрыть ненужные элементы (то есть  "настоящие" элементы {{HTMLElement("select")}}, если скрипт запустился, или наш пользовательский виджет, если скрипт не запустился). По умолчанию наш HTML код скрывает наш пользовательский виджет.

- -
.widget select,
-.no-widget .select {
-  /* Этот CSS селектор значит:
-     - или мы присваиваем классу body значение "widget" и таким образом мы скрываем элемент {{HTMLElement("select")}}
-     - или мы не меняем класс body, тогда класс body остается в значении "no-widget",
-       и элементы, чей класс "select" будут скрыты */
-  position : absolute;
-  left     : -5000em;
-  height   : 0;
-  overflow : hidden;
-}
- -

Теперь нам нужен модуль JavaScript, чтобы определить, запущен скрипт или нет. Этот модуль очень простой: если наш скрипт запустится во время загрузки страницы, то он удалит класс класс no-widget и добавит класс widget, чем поменяет видимость элемента  {{HTMLElement("select")}} и нашего пользовательского виджета.

- -
window.addEventListener("load", function () {
-  document.body.classList.remove("no-widget");
-  document.body.classList.add("widget");
-});
- - - - - - - - - - - - - - - - - -
Без JSС JS
{{EmbedLiveSample("No_JS",120,130, "", "HTML/Forms/How_to_build_custom_form_widgets/Example_2")}}{{EmbedLiveSample("JS",120,130, "", "HTML/Forms/How_to_build_custom_form_widgets/Example_2")}}
Посмотреть исходный код
- -
-

Замечание: Если вы действительно хотите сделать свой код универсальным и многоразовым, то вместо переключения классов гораздо лучше просто добавить класс элементам {{HTMLElement("select")}} чтобы их скрыть, и динамически добавлять дерево DOM представляющее пользовательский виджет после каждого элемента {{HTMLElement("select")}} на странице.

-
- -

Облегчение работы

- -

В коде который мы собираемся написать, для выполнения всех необходимых действий мы будем использовать стандартный DOM API. Однако, хотя поддержка DOM API в браузерах стала гораздо лучше, все еще есть нюансы с устраевшеними браузерами  (особенно со старым добрым Internet Explorer).

- -

Чтобы избежать неприятностей с устаревшими браузерами есть два способа: использовать отдельный фреймворк такой как jQuery, $dom, prototype, Dojo, YUI, и т.п., или самостоятельно реализовать недостающие функции которые вам нужны (что можно легко сделать через условную загрузку, например используя библиотеку yepnope).

- -

Мы планируем использовать следующие функции (от самых рискованных до самых безопасных):

- -
    -
  1. {{domxref("element.classList","classList")}}
  2. -
  3. {{domxref("EventTarget.addEventListener","addEventListener")}}
  4. -
  5. forEach (This is not DOM but modern JavaScript)
  6. -
  7. {{domxref("element.querySelector","querySelector")}} and {{domxref("element.querySelectorAll","querySelectorAll")}}
  8. -
- -

Помимо доступности этих специфических функций, остается еще одна проблема чтобы начать. Объект возвращаемый функцией {{domxref("element.querySelectorAll","querySelectorAll()")}} имеет тип {{domxref("NodeList")}} что отличается от Array. Это важно потому, что объекты  Array поддерживают функцию forEach, а {{domxref("NodeList")}} не поддерживает. Так как  {{domxref("NodeList")}} очень похож на Array и нам очень удобно использовать forEach, мы можем просто добавить forEach к объекту {{domxref("NodeList")}} чтобы облегчить нам жизнь, например так:

- -
NodeList.prototype.forEach = function (callback) {
-  Array.prototype.forEach.call(this, callback);
-}
- -

Мы не шутили, когда сказали, что это легко сделать.

- -

Создание процедур обработки событий

- -

Итак, начало положено, и мы можем приступить к функциям, которые будут использоваться для взаимодействия с пользователем.

- -
// Эта функция будет вызываться каждый раз, когда наш виджет будет деактивирован
-// Ей передается один параметр
-// select : DOM нода класса `select` который должен быть деактивирован
-function deactivateSelect(select) {
-
-  // Если виджет не активен, то и делать-то нечего
-  if (!select.classList.contains('active')) return;
-
-  // Получаем список опций для нашего виджета
-  var optList = select.querySelector('.optList');
-
-  // Закрываем список опций
-  optList.classList.add('hidden');
-
-  // и деактивируем сам виджет
-  select.classList.remove('active');
-}
-
-// Эта функция бедт вызываться какждый раз, когда пользователь захочет (де)активровать наш виджет
-// Ей передаются два параметра:
-// select : DOM нода класса `select` для активации
-// selectList : список всех DOM нод с классом `select`
-function activeSelect(select, selectList) {
-
-  // Если виджет активен, то и делать-то нечего
-  if (select.classList.contains('active')) return;
-
-  // Нам нужно отключить активное состояние всех наших виджетов
-  // Так как функция deactivateSelect соответствует всем требованиям
-  // функции forEach мы вызываем ее без использования промежуточной анонимной функции
-  selectList.forEach(deactivateSelect);
-
-  // А теперь мы возвращаем активное состояние нужного виджета
-  select.classList.add('active');
-}
-
-// Эта функция будет вызываться каждый раз, когда пользователь будет открывать/закрывать список вариантов
-// Ей передается один параметр:
-// select : DOM нода со списком для переключения состояния
-function toggleOptList(select) {
-
-  // Список хранится в виджете
-  var optList = select.querySelector('.optList');
-
-  // Мы меняем класс виджета чтобы показать/скрыть его
-  optList.classList.toggle('hidden');
-}
-
-// Эта функция будет вызываться каждый раз, когда нам нужно подсветить вариант
-// Ей передаются два параметра:
-// select : DOM нода класса `select` содержащая вариант для подсветки
-// option : DOM нода класса `option` для подсветки
-function highlightOption(select, option) {
-
-  // Мы получаем список всех вариантов доступных в нашем элементе
-  var optionList = select.querySelectorAll('.option');
-
-  // Мы удаляем подсветку всех вариантов
-  optionList.forEach(function (other) {
-    other.classList.remove('highlight');
-  });
-
-  // Подсвечиваем нужный вариант
-  option.classList.add('highlight');
-};
- -

Это все, что вам нужно для обработки различных состояний пользовательского виджета.

- -

Далее мы связываем эти функции с соответствующими событиями:

- -
// Мы обрабатываем событие при загрузке документа.
-window.addEventListener('load', function () {
-  var selectList = document.querySelectorAll('.select');
-
-  // Каждый наш собственный виджет должен быть проинициализирован
-  selectList.forEach(function (select) {
-
-    // также как и его элементы `option`
-    var optionList = select.querySelectorAll('.option');
-
-    // Когда пользователь проводит мышью над элементом `option`, мы подсвечиваем этот вариант
-    optionList.forEach(function (option) {
-      option.addEventListener('mouseover', function () {
-        // Замечание: использование переменных `select` и `option`
-        // ограничено рамками нашей функции.
-        highlightOption(select, option);
-      });
-    });
-
-    // Когда позоватль кликает на наш виджет
-    select.addEventListener('click', function (event) {
-       // Замечание: использование переменной `select`
-       // ограничено рамками нашей функции.
-
-       // Мы переключаем видимость списка вариантов
-      toggleOptList(select);
-    });
-
-    // Когда виджет получает фокус
-    // Виджет получает фокус когда пользователь кликает на него
-    // или переходит на него клавишей табуляции
-    select.addEventListener('focus', function (event) {
-      // Замечание: использование переменных `select` и `selectList`
-      // ограничено рамками нашей функции.
-
-      // Мы активируем наш виджет
-      activeSelect(select, selectList);
-    });
-
-    // Когда виджет теряет фокус
-    select.addEventListener('blur', function (event) {
-      // Замечание: использование переменной `select`
-      // ограничено рамками нашей функции.
-
-      // Мы деактивируем виджет
-      deactivateSelect(select);
-    });
-  });
-});
- -

В этот момент наш виджет будет изменятт состояние в соответствии с нашим дизайном, но не будет обновлять его значение. С этим мы разберемся дальше.

- - - - - - - - - - - - - - - -
Пример
{{EmbedLiveSample("Change_states",120,130, "", "HTML/Forms/How_to_build_custom_form_widgets/Example_3")}}
Посмотреть исходный код
- -

Обработка значения виджета

- -

Теперь, когда наш виджет работает, мы должны добавить код, чтобы обновить его значение в соответствии с выбором пользователя и сделать возможным отправку этого значения вместе с данными формы.

- -

Самый простой способ сделать это - использовать встроенный виджет который также есть в нашей форме. Такой виджет будет отслеживать значение со всеми встроенными элементами управления, предоставленными браузером, и значение будет отправлено, как обычно, при отправке формы. Нет смысла заново изобретать велосипед, когда все это уже сделано за нас.

- -

Как было показано ранее, у нас есть стандартный виджет {{HTMLElement("select")}} в качестве запасного варианта для повышения доступности; поэтому мы просто синхронизируем его значение с нашим собственнным виджетом:

- -
// Эта функция обновляет отображенное значение и синхронизирует его со стандартным виджетом
-// Ей передается два параметра:
-// select : DOM нода класса `select` содержащая значение которое будет обновлено
-// index  : индекс выбранного значения
-function updateValue(select, index) {
-  // Нам нужно получить стандартный виджет для данного пользовательского
-  // В нашем примере стандартный виджет является братом (sibling) пользовательского виджета
-  var nativeWidget = select.previousElementSibling;
-
-  // Нам также нужно получить значение заполнителя нашего пользовательского виджета
-  var value = select.querySelector('.value');
-
-  // И нам нужен весь список вариантов
-  var optionList = select.querySelectorAll('.option');
-
-  // Установим значение текущего номера выбранного элемента равным index
-  nativeWidget.selectedIndex = index;
-
-  // Соответственно установим значение заполнителя
-  value.innerHTML = optionList[index].innerHTML;
-
-  // И мы подсвечиваем соответствующий вариант нашего пользовательского виджета
-  highlightOption(select, optionList[index]);
-};
-
-// Эта функция возвращает текущий номер выбранного элемента в стандартном виджете
-// Ей передается один параметр:
-// select : DOM нода класса `select` соответствующая стандарному виджету
-function getIndex(select) {
-  // Нам нужно получить доступ к стандартному виджету соответствующему данному
-  // пользовательскому виджету
-  // В нашем примере стандартный виджет - брат (sibling) пользовательского виджета
-  var nativeWidget = select.previousElementSibling;
-
-  return nativeWidget.selectedIndex;
-};
- -

Исползуя эти две функции мы можем связать стандартный виджет с пользовательским:

- -
// Мы обрабатываем привязку события при загрузке документа.
-window.addEventListener('load', function () {
-  var selectList = document.querySelectorAll('.select');
-
-  // Каждый пользовательский виджет необходимсо инциализировать:
-  selectList.forEach(function (select) {
-    var optionList = select.querySelectorAll('.option'),
-        selectedIndex = getIndex(select);
-
-    // Мы делаем наш пользовательский виджет фокусируемым
-    select.tabIndex = 0;
-
-    // Мы делаем стандартный виджет более не фокусируемым
-    select.previousElementSibling.tabIndex = -1;
-
-    // Убеждаемся, что выбранное по умолчанию значение корректно отображено
-    updateValue(select, selectedIndex);
-
-    // Кажды раз когда пользователь кликает на вариант, мы соответсвенно обновляем значение
-    optionList.forEach(function (option, index) {
-      option.addEventListener('click', function (event) {
-        updateValue(select, index);
-      });
-    });
-
-    // Когда виджет находится в фокусе, с каждым нажатием на клаиатуре, мы соответственно
-    // обновляем  значение
-    select.addEventListener('keyup', function (event) {
-      var length = optionList.length,
-          index  = getIndex(select);
-
-      // Когда пользователь нажимает стрелку вниз, мы переходим на следующий вариант
-      if (event.keyCode === 40 && index < length - 1) { index++; }
-
-      // Когда пользователь нажимает стрелку вверх, мы переходим на предыдущий вариант
-      if (event.keyCode === 38 && index > 0) { index--; }
-
-      updateValue(select, index);
-    });
-  });
-});
- -

В приведенном выше коде стоить отметить совйство tabIndex. Использование этого свойства необходимо чтобы стандартный виджет никогда не получил фокус, и чтобы убедиться, что наш пользовательский виджет получает фокус когда пользователь использует клавиатуру или мышь.

- -

С этим мы закончили! Вот результат:

- - - - - - - - - - - - - - - -
Пример
{{EmbedLiveSample("Change_states",120,130, "", "HTML/Forms/How_to_build_custom_form_widgets/Example_4")}}
Посмотреть исходный код
- -

Но секундочку, мы точно закончили?

- -

Делаем доступным

- -

Мы создали нечто работающее, и, хотя это далеко от полнофункционального селектбокса, работает это хорошо. Однако то, что мы сделали, это не более, чем возня с DOM. У него нет настоящей семантики, и хотя оно выглыдит как селектбокс, с точки зрения браузера - это не так, поэтому вспомогательные технологии не смогут понять что это селектбокс. Короче говоря, этот хорошенький селектбокс не является доступным для людей с ограниченными возможностями!

- -

К счастью существует решение, и оно называется ARIA. ARIA - аббревиатура для "Accessible Rich Internet Application" (Доступное всем интернет приложение), и представляет собой W3C спецификацию специально разработанную для того, что мы здесь делаем: делаем веб приложения и пользовательские виджеты ассистивными (доступными для людей с ограниченными возможностями). В основном, это набор атрибутов, которые расширяют HTML, чтобы мы смогли лучше описать роли, состояния и свойства, так что только что изобретенный элемент выглядит как будто он был тем стандартным, за которого он себя выдает. Использовать эти атрибуты очень просто, поэтому давайте сделаем это.

- -

Аттрибут role

- -

Ключевой аттрибут используемый в ARIA - это role. Аттрибут role принимает значение, определяющее для чего используется элемент. Каждая роль определяет свои собственные требования и поведение. В нашем примере мы используем роль listbox. Это "составная роль" ("composite role"), т.е. элементы такой роли имеют потомков, у каждого из которых есть отдельная роль (в данном случае, как минимум один дочерний элемент с ролью option).

- -

Стоит также отметить что ARIA определяет роли, которые по умолчанию применяются к стандартной разметке HTML. Например, элемент {{HTMLElement("table")}} соответствует роли grid, а элемент {{HTMLElement("ul")}} соответствует роли list. Так как мы используем элемент {{HTMLElement("ul")}}, то нам необходимо убедиться что роль listbox нашего виджета заменит роль list элемента {{HTMLElement("ul")}}. С этой целью, мы будем использовать роль presentation. Эта роль разработана чтобы можно было отметить, что элемент не имеет особого значения, а используется исключительно чтобы представить информацию. Мы применим его к нашему элемету {{HTMLElement("ul")}}.

- -

Чтобы ввести роль listbox нам нужно просто внести следующие изменения в HTML:

- -
<!-- Мы добавили аттрибут role="listbox" в наш элемент верхнего уровня -->
-<div class="select" role="listbox">
-  <span class="value">Cherry</span>
-  <!-- Также мы добавили аттрибут role="presentation" в элемент ul -->
-  <ul class="optList" role="presentation">
-    <!-- И мы добавили аттрибут role="option" во все элементы li -->
-    <li role="option" class="option">Cherry</li>
-    <li role="option" class="option">Lemon</li>
-    <li role="option" class="option">Banana</li>
-    <li role="option" class="option">Strawberry</li>
-    <li role="option" class="option">Apple</li>
-  </ul>
-</div>
- -
-

Замечание: Включение как атрибута role так и атрибута class необходимо только если вы хотите обеспечить поддержку устаревших браузеров, которые не поддерживают  селекторы атрибутов CSS.

-
- -

Атрибут aria-selected 

- -

Использовать только аттрибут role недостаточно. ARIA также предоставляет множество атрибутов состояний и свойств. Чем больше и уместнее вы их используете, тем ваш виджет будет более понятен для вспомогательных технологий. В нашем случае мы ограничимся использованием одного аттрибута: aria-selected.

- -

Атрибут aria-selected используется для отметки текущего выбранного варианта; это позволяет ассистивным технологиям информировать пользователя о текущем выборе. Мы будем используя JavaScript динамически отмечать выбранный вариант каждый раз, когда пользователь его выбирает. С этой целью нам нужно пересмотреть нашу функцию updateValue():

- -
function updateValue(select, index) {
-  var nativeWidget = select.previousElementSibling;
-  var value = select.querySelector('.value');
-  var optionList = select.querySelectorAll('.option');
-
-  // Мы уверены что все варианты не выбраны
-  optionList.forEach(function (other) {
-    other.setAttribute('aria-selected', 'false');
-  });
-
-  // Мы уверены что выбранный вариант отмечен
-  optionList[index].setAttribute('aria-selected', 'true');
-
-  nativeWidget.selectedIndex = index;
-  value.innerHTML = optionList[index].innerHTML;
-  highlightOption(select, optionList[index]);
-};
- -

Вот окончательный результат всех этих изменений (вы сможете это лучше прочувствовать если испробуете это со вспомогательными технологиями, такими как NVDA или VoiceOver):

- - - - - - - - - - - - - - - -
Пример
{{EmbedLiveSample("Change_states",120,130, "", "HTML/Forms/How_to_build_custom_form_widgets/Example_5")}}
Посмотреть исходный код
- -

Заключение

- -

Мы рассмотрели все основы создания пользовательского виджета формы, и это, как вы видите, нетривиальная задача, и часто проще и лучше положиться на сторонние библиотеки, чем писать их самому с нуля (если, конечно, ваша цель - не создать такую библиотеку).

- -

Вот несколько библиотек, которые вам стоит рассмотреть перед тем как создавать собственную:

- - - -

Если вы хотите двигаться далее, то код в этом примере нуждается в некоторм улучшении прежде чем станет универсальным и многоразовым. Это упражнение, которое вы можете попробовать выполнить. Две подсказки, которые помогут вам в этом: первый аргумент всех наших функций одинаков, это значит что эти функции должны быть в одном контексте. Было бы разумным создать объект для совместного использования этого контекста. Также вам нужно сделать его функциональным; это значит, что ему необходимо одинаково хорошо работать с различными браузерами, чья соместимость с  Web стандартами  очень отличается. Повеселись!

- -

{{PreviousMenuNext("Learn/HTML/Forms/Form_validation", "Learn/HTML/Forms/Sending_forms_through_JavaScript", "Learn/HTML/Forms")}}

- -

В этом модуле

- - diff --git a/files/ru/learn/html/forms/how_to_structure_an_html_form/index.html b/files/ru/learn/html/forms/how_to_structure_an_html_form/index.html deleted file mode 100644 index 741d773dba..0000000000 --- a/files/ru/learn/html/forms/how_to_structure_an_html_form/index.html +++ /dev/null @@ -1,320 +0,0 @@ ---- -title: Как структурировать HTML-формы -slug: Learn/HTML/Forms/How_to_structure_an_HTML_form -tags: - - HTML-форма - - Веб-форма - - Изучение - - Новичок - - Структурирование - - Форма -translation_of: Learn/Forms/How_to_structure_a_web_form ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/HTML/Forms/Ваша_первая_HTML_форма", "Learn/HTML/Forms/Стандартные_виджеты_форм", "Learn/HTML/Forms")}}
- -

Получив базовые знания, теперь мы более подробно рассмотрим элементы, используемые для придания структуры и значения различным частям форм.

- - - - - - - - - - - - -
Уровень подготовки:Основы компьютерной грамотности, и базовые знания HTML.
Цель:Разобраться как структурировать HTML формы и задавать им семантику для того, чтобы они были удобны и доступны в использовании.
- -

Гибкость HTML форм делает их одной из самых сложных структур в HTML; вы можете создать любую форму, используя элементы и атрибуты форм. Использование правильной структуры, при создании HTML форм, поможет гарантировать их удобство и доступность.

- -

Элемент <form>

- -

Элемент {{HTMLElement("form")}} формально определяет форму и атрибуты, которые определяют поведение этой формы. Каждый раз, когда вы хотите создать HTML-форму, вам нужно начать с создания элемента {{HTMLElement("form")}}, поместив внутрь него всё содержимое. Многие вспомогательные технологии или браузерные плагины могут обнаруживать элементы {{HTMLElement("form")}} и реализовывать специальные хуки, чтобы их было проще использовать.

- -

Мы уже встречались с этим в предыдущей статье.

- -
-

Внимание: Строго запрещается размещать форму внутри другой формы. Такое размещение может привести к непредсказуемому поведению форм, в зависимости от браузера. 

-
- -

Стоит учесть, что всегда можно использовать элементы формы вне {{HTMLElement("form")}}. Тогда по умолчанию этот элемент формы не имеет ничего общего со всеми формами. Вы можете связать его с формой с помощью аттрибута form. В HTML5 был представлен аттрибут form для элементов HTML форм, который позволяет  явно связать элемент с формой, даже если он не заключён внутри {{ HTMLElement("form") }}.

- -

Элементы <fieldset> и <legend>

- -

Элемент {{HTMLElement("fieldset")}} - это удобный способ стилистической и семантической группировки элементов формы. Вы можете установить заголовок {{HTMLElement("fieldset")}}, добавив элемент {{HTMLElement("legend")}} сразу после открывающего тега {{HTMLElement("fieldset")}}. Текст элемента {{HTMLElement("legend")}} формально описывает назначение содержимого {{HTMLElement("fieldset")}}.

- -

Различные вспомогательные технологии будут использовать {{HTMLElement("legend")}} как часть метки label всех элементов внутри {{HTMLElement("fieldset")}}. Например, такие экранные дикторы как Jaws или NVDA произносят заголовок формы {{HTMLElement("legend")}} перед произношением названия меток элементов.

- -

Небольшой пример:

- -
<form>
-  <fieldset>
-    <legend>Fruit juice size</legend>
-    <p>
-      <input type="radio" name="size" id="size_1" value="small">
-      <label for="size_1">Small</label>
-    </p>
-    <p>
-      <input type="radio" name="size" id="size_2" value="medium">
-      <label for="size_2">Medium</label>
-    </p>
-    <p>
-      <input type="radio" name="size" id="size_3" value="large">
-      <label for="size_3">Large</label>
-    </p>
-  </fieldset>
-</form>
- -
-

Примечание: Вы можете найти этот пример в fieldset-legend.html (также посмотрите на результат).

-
- -

Читая эту форму, экранный диктор произнесёт "Fruit juice size small" для первого элемента, "Fruit juice size medium" - для второго, "Fruit juice size large" - для третьего.

- -

Вариант использования в этом примере является одним из наиболее важных. Каждый раз, когда у вас есть набор переключателей, вам нужно поместить их внутри {{HTMLElement("fieldset")}}. Также {{HTMLElement("fieldset")}} можно использовать для разделения формы. В идеале, длинную форму разделяют на несколько страниц, однако, если она должна находиться на одной странице, распределение связанных элементов в разные {{HTMLElement("fieldset")}} может повысить удобство использования.

- -

Из-за своего влияния на вспомогательные технологии элемент {{HTMLElement("fieldset")}} является одним из ключевых элементов для построения доступных форм; однако вы не должны им злоупотреблять. Если возможно, старайтесь проверять, как экранный диктор интерпретирует вашу форму. 

- -

Элемент <label>

- -

В предыдущей статье мы увидели, что элемент {{HTMLElement("label")}} принято использовать для указания текстов-подсказок (лейблов) в HTML-формах. Это самый важный элемент для построения доступных форм — при правильной реализации скринридеры будут озвучивать текст-подсказку вместе со связанными элементами. Посмотрите на этот пример из предущей статьи:

- -
<label for="name">Name:</label> <input type="text" id="name" name="user_name">
- -

При правильно связанном элементе <label> с элементом <input> через атрибуты for и id соответственно (атрибут for ссылается на атрибут id соответствующего виджета формы), скринридер прочтет вслух что-то наподобие "Name, edit text".

- -

Если <label> не правильно установлен, скринридер прочитает это как "Edit text blank", что не несет в себе никакой уточняющей информации, позволяющей понять предназначение данного текстового поля.

- -

Обратите внимание на то, что виджет формы может быть вложен в элемент {{HTMLElement("label")}}, как на примере:

- -
<label for="name">
-  Name: <input type="text" id="name" name="user_name">
-</label>
- -

Однако даже в таких случаях лучшей всё равно указывать атрибут for, так как некоторые вспомогательные технологии не распознают неявную связь между текстами-подсказками и виджетами.

- -

Лейблы тоже кликабельны!

- -

Ещё одно преимущество при правильно установленных текстах-подсказках заключается в том, что по ним можно кликнуть для активации связанных с ними виджетов. Это поддерживается во всех браузерах. Это удобно как для текстовых полей ввода, в которых устанавливается фокус при клике на текст-посказку, так и для радио-кнопок и чекбоксов — область попадания такого элемента управления может быть очень маленькой, поэтому полезно сделать ее как можно больше.

- -

Например:

- -
<form>
-  <p>
-    <label for="taste_1">I like cherry</label>
-    <input type="checkbox" id="taste_1" name="taste_cherry" value="1">
-  </p>
-  <p>
-    <label for="taste_2">I like banana</label>
-    <input type="checkbox" id="taste_2" name="taste_banana" value="2">
-  </p>
-</form>
- -
-

Примечание: Вы можете посмотреть этот пример тут checkbox-label.html (также можно посмотреть код вживую).

-
- -

Несколько лейблов

- -

На самом деле вы можете добавить несколько текстов-подсказок на один виджет формы, но это не очень хорошая идея, так как у некоторых вспомогательных технологий могут возникнуть проблемы с обработкой такой структуры. Вместо использования нескольких лейблов, лучше вложить виджет формы внутрь одного элемента {{htmlelement("label")}}. 

- -

Рассмотрим этот пример:

- -
<p>Required fields are followed by <abbr title="required">*</abbr>.</p>
-
-<!-- Тогда это: -->
-<div>
-  <label for="username">Name:</label>
-  <input type="text" name="username">
-  <label for="username"><abbr title="required">*</abbr></label>
-</div>
-
-<!-- лучше сделать таким образом: -->
-<div>
-  <label for="username">
-    <span>Name:</span>
-    <input id="username" type="text" name="username">
-    <abbr title="required">*</abbr>
-  </label>
-</div>
-
-<!-- Но этот вариант лучше всего: -->
-<div>
-  <label for="username">Name: <abbr title="required">*</abbr></label>
-  <input id="username" type="text" name="username">
-</div>
- -

{{EmbedLiveSample("Multiple_labels", 120, 120)}}

- -

Параграф на первой строке примера описывает правило для обязательных элементов. Вначале необходимо убедиться, что вспомогательные технологии, такие как программы чтения с экрана, отображают или озвучивают их пользователю, прежде чем он найдет требуемый элемент. Таким образом они будут знать, что означает звёздочка. Программа чтения с экрана будет произносить звёздочку как «звёздочку» или «обязательно», в зависимости от настроек программы чтения с экрана — в любом случае, первый абзац даёт понимание того, что будет означать звёздочка далее в форме.

- - - -
-

Примечение: В зависимости от программы для чтения с экрана результаты могут немного отличаться. В данной статье для тестирования использовался VoiceOver (NVDA ведет себя аналогично). Также мы были бы рады, если бы вы поделились своим опытом.

-
- -
-

Примечание: Вы можете найти этот пример на GitHub required-labels.html (также можно посмотреть вживую). Запускайте пример, закомментировав остальные, иначе скриридеры не смогут правильно распознать контент, если у вас будет несколько лейблов и несколько текстовых полей с одинаковым ID!

-
- -

Частоиспользуемые с формами HTML-структуры

- -

Помимо структур, характерных только для HTML-форм, хорошо помнить, что формы — это просто HTML. Это означает, что вы можете использовать всю мощь HTML для структурирования HTML-формы.

- -

Как вы можете заметить в примерах, оборачивать лейбл и виджет формы в элемент {{HTMLElement("div")}} — это общепринятая практика. Элемент {{HTMLElement("p")}} также часто используется, как и HTML-списки (последние часто используются для структурирования множественных чекбоксом или радио-кнопок).

- -

В добавок к элементу {{HTMLElement("fieldset")}} часто используют HTML-заголовки (например, {{HTMLElement("h1")}}, {{HTMLElement("h2")}}) и секционирование (например, {{HTMLElement("section")}}) для стуктурирования сложных форм.

- -

Прежде всего, вам нужно найти стиль, который будет удобен именно вам для программирования и который также позволит создавать доступные и удобные формы.

- -

Каждый отдельный раздел функциональности содержится в элементах {{HTMLElement ("section")}} и {{HTMLElement ("fieldset")}}, содержащий переключатели. Каждый отдельный раздел функциональности должен находиться в отдельном элементе {{HTMLElement ("section")}} с элементами {{HTMLElement ("fieldset")}}, содержащими переключатели.

- -

Активное обучение: построение структуры формы

- -

Давайте применим эти идеи на практике и построим более сложноструктурируемую форму — формы оплаты. Форма будет содержать некоторые типы виджетов формы, которые вы можете пока не понять — не переживайте об этом, вы найдёте информацию в следующей статье (Основные нативные элементы управления формами). А пока внимательно прочитайте описание, следуя приведенным ниже инструкциям, и начинайте формировать представление о том, какие элементы обёртки мы используем для структурирования формы и почему.

- -
    -
  1. Для начала сделайте локальную копию пустого шаблона и CSS для нашей платёжной формы в новой директории на вашем компьютере.
  2. -
  3. Сначала подключите CSS к HTML, добавив следующую строку кода внутрь HTML-елемента {{htmlelement("head")}}: -
    <link href="payment-form.css" rel="stylesheet">
    -
  4. -
  5. Далее начните создавать свою форму с добавления внешнего элемента {{htmlelement("form")}}: -
    <form>
    -
    -</form>
    -
  6. -
  7. Внутри тега <form>, добавьте заголовок и параграф, информирующий пользователей о том, как помечены поля, обязательные для заполнения: -
    <h1>Payment form</h1>
    -<p>Required fields are followed by <strong><abbr title="required">*</abbr></strong>.</p>
    -
  8. -
  9. Далее нам надо добавить более крупный кусок кода под нашей предыдущей записью. Здесь вы можете увидеть, что мы оборачиваем поля с контактной информацией в отдельный элемент {{htmlelement("section")}}. Более того, у нас есть набор из двух радио-кнопок, каждую из которых мы помещаем в отдельный элемент списка ({{htmlelement("li")}}). Наконец, у нас есть два текстовых поля {{htmlelement("input")}} и связанные с ними элементы {{htmlelement("label")}}, которые находятся внутри элементов {{htmlelement("p")}}, а также поле для ввода пароля. Добавьте этот код в вашу форму: -
    <section>
    -    <h2>Contact information</h2>
    -    <fieldset>
    -      <legend>Title</legend>
    -      <ul>
    -          <li>
    -            <label for="title_1">
    -              <input type="radio" id="title_1" name="title" value="M." >
    -              Mister
    -            </label>
    -          </li>
    -          <li>
    -            <label for="title_2">
    -              <input type="radio" id="title_2" name="title" value="Ms.">
    -              Miss
    -            </label>
    -          </li>
    -      </ul>
    -    </fieldset>
    -    <p>
    -      <label for="name">
    -        <span>Name: </span>
    -        <strong><abbr title="required">*</abbr></strong>
    -      </label>
    -      <input type="text" id="name" name="username">
    -    </p>
    -    <p>
    -      <label for="mail">
    -        <span>E-mail: </span>
    -        <strong><abbr title="required">*</abbr></strong>
    -      </label>
    -      <input type="email" id="mail" name="usermail">
    -    </p>
    -    <p>
    -      <label for="pwd">
    -        <span>Password: </span>
    -        <strong><abbr title="required">*</abbr></strong>
    -      </label>
    -      <input type="password" id="pwd" name="password">
    -    </p>
    -</section>
    -
  10. -
  11. Сейчас мы перейдём к второму разделу <section> нашей формы — платёжной информации. В этом разделе у нас есть три отдельных виджета формы со связанными с ними лейблами, находящимися внутри тега <p>. Первый — это выпадающее меню ({{htmlelement("select")}}) для выбора типа кредитной карты. Второй — это элемент <input> с типом number для ввода номера карты. Последний виджет — это элемент <input> с типом date для указания даты окончания действия карты (должен будет появиться виджет с выбором даты или обычное текстовое поле в браузерах, не поддерживающих данные тип). Более новые типы полей описаны в статье The HTML5 input types.
    -
    - Вставьте следующий код под предыдущим разделом: -
    <section>
    -    <h2>Payment information</h2>
    -    <p>
    -      <label for="card">
    -        <span>Card type:</span>
    -      </label>
    -      <select id="card" name="usercard">
    -        <option value="visa">Visa</option>
    -        <option value="mc">Mastercard</option>
    -        <option value="amex">American Express</option>
    -      </select>
    -    </p>
    -    <p>
    -      <label for="number">
    -        <span>Card number:</span>
    -        <strong><abbr title="required">*</abbr></strong>
    -      </label>
    -      <input type="number" id="number" name="cardnumber">
    -    </p>
    -    <p>
    -      <label for="date">
    -        <span>Expiration date:</span>
    -        <strong><abbr title="required">*</abbr></strong>
    -        <em>formatted as mm/yy</em>
    -      </label>
    -      <input type="date" id="date" name="expiration">
    -    </p>
    -</section>
    -
  12. -
  13. Последняя секция, которую мы добавим выглядит намного проще и содержит в себе только элемент {{htmlelement("button")}} с типом submit, для отправки данных. Добавьте этот код в конец вашей формы: -
    <p> <button type="submit">Validate the payment</button> </p>
    -
  14. -
- -

Вы можете увидеть законченную форму в действии ниже (также её можно найти на GitHub — посмотрите payment-form.html и живой пример):

- -

{{EmbedLiveSample("A_payment_form","100%",620, "", "Learn/HTML/Forms/How_to_structure_an_HTML_form/Example")}}

- -

Протестируйте себя!

- -

Вы дошли до конца статьи, но можете ли вспомнить самую важную информацию? Далее вы можете найти тест, который поможет убедиться, что вы усвоили знания прежде чем двигаться дальше — посмотрите Test your skills: Form structure.

- -

Заключение

- -

Теперь у вас есть все необходимые знания для того, чтобы правильно структурировать вашу HTML-форму. Мы подробнее раскроем затронутые здесь темы в нескольких последующих статьях. В следующей же статье мы изучим все возможные типы виджетов форм, которые могут понадобиться для сбора информации от ваших пользователей.

- -

Смотрите также

- - - -

{{PreviousMenuNext("Learn/HTML/Forms/Ваша_первая_HTML_форма", "Learn/HTML/Forms/Стандартные_виджеты_форм", "Learn/HTML/Forms")}}

- -

В этом разделе

- - - -

Дополнительные темы

- - diff --git a/files/ru/learn/html/forms/index.html b/files/ru/learn/html/forms/index.html deleted file mode 100644 index 02e36df560..0000000000 --- a/files/ru/learn/html/forms/index.html +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: Руководство по HTML-формам -slug: Learn/HTML/Forms -tags: - - HTML - - Web - - Начинающие - - Руководство - - Формы -translation_of: Learn/Forms ---- -

{{LearnSidebar}}

- -

Данное руководство представляет собой серию статей, которые помогут Вам освоить HTML-формы. HTML формы являются очень мощным инструментом для взаимодействия с пользователями; однако, в силу исторических и технических причин, не всегда очевидно, как использовать их в полной мере. В этом руководстве мы рассмотрим все аспекты HTML-форм, от структуры к стилизации, от обработки данных до пользовательских виджетов. Вы научитесь пользоваться Великой силой, которую они предлагают!

- -

Необходимые условия

- -

Перед началом этого модуля вам следует изучить хотя бы Введение в HTML. На данный момент у вас не должно возникнуть сложностей с пониманием Основных руководств и использованием нашего руководства по Стандартным виджетам форм.

- -

Остальные части модуля немного сложнее — легко поместить виджет формы на страницу, но вы не сможете много сделать без использования продвинутых особенностей форм, CSS и JavaScript. Поэтому, перед тем как вы перейдёте к другим частям модуля, мы рекомендуем изучить немного CSS и JavaScript.

- -
-

Примечание:Если компьютер/планшет/другое устройство, на котором вы работаете, не позволяет вам самостоятельно создавать файлы, то приводимые здесь примеры кода можно посмотреть в онлайновых программах для кодирования, например JSBin или Thimble.

-
- -

 Основные руководства

- -
-
Ваша первая HTML-форма
-
Первая статья в серии дает вам начальный опыт в создании HTML-форм, включая разработку простой формы, её реализация при помощи элементов HTML, стилизация при помощи CSS и то, как данные отправляются на сервер.
-
Как структурировать HTML-форму
-
Изучив основы, рассмотрим более подробно элементы, используемые для структурирования и придания смысла различным частям HTML-форм.
-
- -

Какие виджеты форм доступны?

- -
-
Стандартные виджеты форм
-
Рассмотрим подробнее функционал различных виджетов форм; какие варианты доступны для сбора различных типов данных.
-
- -

Валидация и подтверждение данных форм

- -
-
Отправка данных форм 
-
Данная статья рассматривает что происходит, когда пользователь подтверждает форму — куда отправляются данные и как мы их там обрабатываем. Мы также рассмотрим некоторые проблемы безопасности, связанные с отправкой данных формы.
-
Валидация данных форм
-
Одной отправки данных не достаточно — нам нужно убедиться что данные, введенные пользователем в формы, в правильном формате и не испортят наши приложения. Мы также хотим помочь пользователям правильно заполнить формы и не разочароваться при использовании наших приложений. Валидация форм поможет нам в достижении этих целей — эта статья расскажет вам всё, что нужно знать.
-
- -

 Продвинутые руководства

- -
-
Как создавать собственные виджеты форм
-
В некоторых случая стандартные виджеты форм не предоставляют того, что вам нужно, например из-за стиля или функционала. В таких случаях вам придётся создать собственный виджет формы из чистого HTML. В этой статье(с практическим примером) объясняется, как вы это сделаете, а также особенности, на которые необходимо обратить внимание.
-
Отправка форм при помощи JavaScript
-
В этой статье рассматриваются способы использования формы для сборки HTTP-запроса и отправки его через пользовательский JavaScript вместо стандартного представления формы. А также почему вы захотите это сделать и способы реализации (см. использование объектов FormData).
-
HTML-формы в старых браузерах
-
Статья раскрывает особенности обнаружения и т.д. (см. Кросс-браузерное тестирование для более глубокого понимания)
-
- -

Руководства по стилизации форм

- -
-
Стилизация HTML-форм
-
Вступительная статья по стилизации форм с помощью CSS, включая все необходимые основы.
-
Продвинутая стилизация HTML-форм
-
В этой статье мы рассмотрим продвинутые техники стилизации форм, которые необходимо использовать при работе с некоторыми более сложными для стилизации элементами.
-
Таблица совместимости свойств для виджетов форм
-
Последняя статья содержит удобный справочник, позволяющий узнать, с какими элементами формы совместимы свойства CSS.
-
- -

Смотри также

- - diff --git a/files/ru/learn/html/forms/sending_forms_through_javascript/index.html b/files/ru/learn/html/forms/sending_forms_through_javascript/index.html deleted file mode 100644 index d98ccea1ac..0000000000 --- a/files/ru/learn/html/forms/sending_forms_through_javascript/index.html +++ /dev/null @@ -1,391 +0,0 @@ ---- -title: Отправка форм при помощи JavaScript -slug: Learn/HTML/Forms/Sending_forms_through_JavaScript -translation_of: Learn/Forms/Sending_forms_through_JavaScript ---- -
{{LearnSidebar}}
- -

HTML формы могут декларативно отправлять HTTP-запросы. Но формы также могут подготовить HTTP-запросы для отправки с помощью JavaScript, например при помощи XMLHttpRequest. В этой статье исследуются подобные подходы.

- -

Формы не всегда формы

- -

В современных веб-приложениях, одностраничных приложениях и приложениях на основе фреймворков, обычно HTML-формы используются для отправки данных без загрузки нового документа при получении данных ответа. В начале поговорим о том почему это требует другого подхода.

- -

Получение контроля над глобальным интерфейсом

- -

Отправка стандартной HTML формы, как описывалось в предыдущей статье, загружает URL-адрес, по которому были отправлены данные, это означает, что окно браузера перемещается с полной загрузкой страницы. Если избегать полную перезагрузку страницы, можно обеспечить более плавную работу, за счет предотвращения задержек в сети и возможных визуальных проблем (например, мерцания).

- -

Многие современные пользовательские интерфейсы используют HTML формы только для сбора пользовательского ввода, а не для для отправки данных. Когда пользователь пытатся отправить свои данные, приложение берет контроль и асинхронно передает данные в фоновом режиме, обновляя только ту часть всего интерфейса пользователя, которой требуется обновление.

- -

Асинхронная отправка произвольных данных обычно называется AJAX, что означает "Asynchronous JavaScript And XML" (Асинхронный JavaScript и XML).

- -

Чем он отличается?

- -

Объект {{domxref("XMLHttpRequest")}} (XHR) DOM может создавать HTTP-запросы, отправлять их, и получать их результат. Исторически, {{domxref("XMLHttpRequest")}} был разработан для получения и отправки XML в качестве формата обмена, который со временем был заменен на JSON. Но ни XML, ни JSON не вписываются в кодировку запроса данных формы. Данные формы (application/x-www-form-urlencoded) состоят из списка пар ключ/значение в кодировке URL. Для передачи бинарных данных, HTTP-запрос преобразуется в multipart/form-data.

- -
-

Замечание: Сейчас Fetch API часто используется вместо XHR — это современная, обновленная версия XHR, которая работает в похожем стиле, но имеет несколько преимуществ. Большая часть XHR-кода, которую вы увидете в этой статье можно заменить на Fetch.

-
- -

Если вы управляете фронтендом (кодом, который выполняется в браузере) и бкендом (кодом, который выполняется на стороне сервера), вы можете отправлять JSON/XML и обрабатывать их как хотите.

- -

Но если вы хотите использовать сторонний сервис, то вам необходимо отправлять данные в формате, который требуется сервису.

- -

Так как нам следует отправлять подобные данные? Ниже обписаны различные необходимые вам техники.

- -

Отправка данных формы

- -

Есть три способа отправки данных формы:

- - - -

Давайте рассмотрим их подробнее:

- -

Создание  XMLHttpRequest вручную

- -

{{domxref("XMLHttpRequest")}} это самый безопасный и надежный способ создавать HTTPзапросы. Для отправки данных формы с помощью {{domxref("XMLHttpRequest")}}, подготовьте данные с помощью URL-кодирования, и соблюдайте специфику запросов данных формы.

- -

Посмотрите на пример:

- -
<button>Click Me!</button>
- -

И на JavaScript:

- -
const btn = document.querySelector('button');
-
-function sendData( data ) {
-  console.log( 'Sending data' );
-
-  const XHR = new XMLHttpRequest();
-
-  let urlEncodedData = "",
-      urlEncodedDataPairs = [],
-      name;
-
-  // Turn the data object into an array of URL-encoded key/value pairs.
-  for( name in data ) {
-    urlEncodedDataPairs.push( encodeURIComponent( name ) + '=' + encodeURIComponent( data[name] ) );
-  }
-
-  // Combine the pairs into a single string and replace all %-encoded spaces to
-  // the '+' character; matches the behaviour of browser form submissions.
-  urlEncodedData = urlEncodedDataPairs.join( '&' ).replace( /%20/g, '+' );
-
-  // Define what happens on successful data submission
-  XHR.addEventListener( 'load', function(event) {
-    alert( 'Yeah! Data sent and response loaded.' );
-  } );
-
-  // Define what happens in case of error
-  XHR.addEventListener( 'error', function(event) {
-    alert( 'Oops! Something went wrong.' );
-  } );
-
-  // Set up our request
-  XHR.open( 'POST', 'https://example.com/cors.php' );
-
-  // Add the required HTTP header for form data POST requests
-  XHR.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' );
-
-  // Finally, send our data.
-  XHR.send( urlEncodedData );
-}
-
-btn.addEventListener( 'click', function() {
-  sendData( {test:'ok'} );
-} )
-
- -

Это результат:

- -

{{EmbedLiveSample("Building_an_XMLHttpRequest_manually", "100%", 50)}}

- -
-

Note: This use of {{domxref("XMLHttpRequest")}} is subject to the {{glossary('same-origin policy')}} if you want to send data to a third party web site. For cross-origin requests, you'll need CORS and HTTP access control.

-
- -

Using XMLHttpRequest and the FormData object

- -

Building an HTTP request by hand can be overwhelming. Fortunately, the XMLHttpRequest specification provides a newer, simpler way to handle form data requests with the {{domxref("XMLHttpRequest/FormData","FormData")}} object.

- -

The {{domxref("XMLHttpRequest/FormData","FormData")}} object can be used to build form data for transmission, or to get the data within a form element to manage how it's sent. Note that {{domxref("XMLHttpRequest/FormData","FormData")}} objects are "write only", which means you can change them, but not retrieve their contents.

- -

Using this object is detailed in Using FormData Objects, but here are two examples:

- -

Using a standalone FormData object

- -
<button>Click Me!</button>
- -

You should be familiar with that HTML sample. Now for the JavaScript:

- -
const btn = document.querySelector('button');
-
-function sendData( data ) {
-  const XHR = new XMLHttpRequest(),
-        FD  = new FormData();
-
-  // Push our data into our FormData object
-  for( name in data ) {
-    FD.append( name, data[ name ] );
-  }
-
-  // Define what happens on successful data submission
-  XHR.addEventListener( 'load', function( event ) {
-    alert( 'Yeah! Data sent and response loaded.' );
-  } );
-
-  // Define what happens in case of error
-  XHR.addEventListener(' error', function( event ) {
-    alert( 'Oops! Something went wrong.' );
-  } );
-
-  // Set up our request
-  XHR.open( 'POST', 'https://example.com/cors.php' );
-
-  // Send our FormData object; HTTP headers are set automatically
-  XHR.send( FD );
-}
-
-btn.addEventListener( 'click', function()
-  { sendData( {test:'ok'} );
-} )
- -

Here's the live result:

- -

{{EmbedLiveSample("Using_a_standalone_FormData_object", "100%", 50)}}

- -

Using FormData bound to a form element

- -

You can also bind a FormData object to an {{HTMLElement("form")}} element. This creates a FormData object that represents the data contained in the form.

- -

The HTML is typical:

- -
<form id="myForm">
-  <label for="myName">Send me your name:</label>
-  <input id="myName" name="name" value="John">
-  <input type="submit" value="Send Me!">
-</form>
- -

But JavaScript takes over the form:

- -
window.addEventListener( "load", function () {
-  function sendData() {
-    const XHR = new XMLHttpRequest();
-
-    // Bind the FormData object and the form element
-    const FD = new FormData( form );
-
-    // Define what happens on successful data submission
-    XHR.addEventListener( "load", function(event) {
-      alert( event.target.responseText );
-    } );
-
-    // Define what happens in case of error
-    XHR.addEventListener( "error", function( event ) {
-      alert( 'Oops! Something went wrong.' );
-    } );
-
-    // Set up our request
-    XHR.open( "POST", "https://example.com/cors.php" );
-
-    // The data sent is what the user provided in the form
-    XHR.send( FD );
-  }
-
-  // Access the form element...
-  const form = document.getElementById( "myForm" );
-
-  // ...and take over its submit event.
-  form.addEventListener( "submit", function ( event ) {
-    event.preventDefault();
-
-    sendData();
-  } );
-} );
- -

Here's the live result:

- -

{{EmbedLiveSample("Using_FormData_bound_to_a_form_element", "100%", 50)}}

- -

You can even get more involved with the process by using the form's {{domxref("HTMLFormElement.elements", "elements")}} property to get a list of all of the data elements in the form and manually manage them one at a time. To learn more about that, see the example in {{SectionOnPage("/en-US/docs/Web/API/HTMLFormElement.elements", "Accessing the element list's contents")}}.

- -

Dealing with binary data

- -

If you use a {{domxref("XMLHttpRequest/FormData","FormData")}} object with a form that includes <input type="file"> widgets, the data will be processed automatically. But to send binary data by hand, there's extra work to do.

- -

There are many sources for binary data, including {{domxref("FileReader")}}, {{domxref("HTMLCanvasElement","Canvas")}}, and WebRTC. Unfortunately, some legacy browsers can't access binary data or require complicated workarounds. To learn more about the FileReader API, see Using files from web applications.

- -

The least complicated way of sending binary data is by using {{domxref("XMLHttpRequest/FormData","FormData")}}'s append() method, demonstrated above. If you have to do it by hand, it's trickier.

- -

In the following example, we use the {{domxref("FileReader")}} API to access binary data and then build the multi-part form data request by hand:

- -
<form id="theForm">
-  <p>
-    <label for="theText">text data:</label>
-    <input id="theText" name="myText" value="Some text data" type="text">
-  </p>
-  <p>
-    <label for="theFile">file data:</label>
-    <input id="theFile" name="myFile" type="file">
-  </p>
-  <button>Send Me!</button>
-</form>
- -

As you see, the HTML is a standard <form>. There's nothing magical going on. The "magic" is in the JavaScript:

- -
// Because we want to access DOM nodes,
-// we initialize our script at page load.
-window.addEventListener( 'load', function () {
-
-  // These variables are used to store the form data
-  const text = document.getElementById( "theText" );
-  const file = {
-        dom    : document.getElementById( "theFile" ),
-        binary : null
-      };
-
-  // Use the FileReader API to access file content
-  const reader = new FileReader();
-
-  // Because FileReader is asynchronous, store its
-  // result when it finishes to read the file
-  reader.addEventListener( "load", function () {
-    file.binary = reader.result;
-  } );
-
-  // At page load, if a file is already selected, read it.
-  if( file.dom.files[0] ) {
-    reader.readAsBinaryString( file.dom.files[0] );
-  }
-
-  // If not, read the file once the user selects it.
-  file.dom.addEventListener( "change", function () {
-    if( reader.readyState === FileReader.LOADING ) {
-      reader.abort();
-    }
-
-    reader.readAsBinaryString( file.dom.files[0] );
-  } );
-
-  // sendData is our main function
-  function sendData() {
-    // If there is a selected file, wait it is read
-    // If there is not, delay the execution of the function
-    if( !file.binary && file.dom.files.length > 0 ) {
-      setTimeout( sendData, 10 );
-      return;
-    }
-
-    // To construct our multipart form data request,
-    // We need an XMLHttpRequest instance
-    const XHR = new XMLHttpRequest();
-
-    // We need a separator to define each part of the request
-    const boundary = "blob";
-
-    // Store our body request in a string.
-    let data = "";
-
-    // So, if the user has selected a file
-    if ( file.dom.files[0] ) {
-      // Start a new part in our body's request
-      data += "--" + boundary + "\r\n";
-
-      // Describe it as form data
-      data += 'content-disposition: form-data; '
-      // Define the name of the form data
-            + 'name="'         + file.dom.name          + '"; '
-      // Provide the real name of the file
-            + 'filename="'     + file.dom.files[0].name + '"\r\n';
-      // And the MIME type of the file
-      data += 'Content-Type: ' + file.dom.files[0].type + '\r\n';
-
-      // There's a blank line between the metadata and the data
-      data += '\r\n';
-
-      // Append the binary data to our body's request
-      data += file.binary + '\r\n';
-    }
-
-    // Text data is simpler
-    // Start a new part in our body's request
-    data += "--" + boundary + "\r\n";
-
-    // Say it's form data, and name it
-    data += 'content-disposition: form-data; name="' + text.name + '"\r\n';
-    // There's a blank line between the metadata and the data
-    data += '\r\n';
-
-    // Append the text data to our body's request
-    data += text.value + "\r\n";
-
-    // Once we are done, "close" the body's request
-    data += "--" + boundary + "--";
-
-    // Define what happens on successful data submission
-    XHR.addEventListener( 'load', function( event ) {
-      alert( 'Yeah! Data sent and response loaded.' );
-    } );
-
-    // Define what happens in case of error
-    XHR.addEventListener( 'error', function( event ) {
-      alert( 'Oops! Something went wrong.' );
-    } );
-
-    // Set up our request
-    XHR.open( 'POST', 'https://example.com/cors.php' );
-
-    // Add the required HTTP header to handle a multipart form data POST request
-    XHR.setRequestHeader( 'Content-Type','multipart/form-data; boundary=' + boundary );
-
-    // And finally, send our data.
-    XHR.send( data );
-  }
-
-  // Access our form...
-  const form = document.getElementById( "theForm" );
-
-  // ...to take over the submit event
-  form.addEventListener( 'submit', function ( event ) {
-    event.preventDefault();
-    sendData();
-  } );
-} );
- -

Here's the live result:

- -

{{EmbedLiveSample("Dealing_with_binary_data", "100%", 150)}}

- -

Conclusion

- -

Depending on the browser and the type of data you are dealing with, sending form data through JavaScript can be easy or difficult. The {{domxref("XMLHttpRequest/FormData","FormData")}} object is generally the answer, and you can use a polyfill for it on legacy browsers.

- -

See also

- -

Learning path

- - - -

Advanced Topics

- - diff --git a/files/ru/learn/html/forms/styling_html_forms/index.html b/files/ru/learn/html/forms/styling_html_forms/index.html deleted file mode 100644 index f8cc1644dc..0000000000 --- a/files/ru/learn/html/forms/styling_html_forms/index.html +++ /dev/null @@ -1,381 +0,0 @@ ---- -title: Стили HTML форм -slug: Learn/HTML/Forms/Styling_HTML_forms -translation_of: Learn/Forms/Styling_web_forms ---- -

{{LearnSidebar}}{{PreviousMenuNext("Learn/HTML/Forms/HTML_forms_in_legacy_browsers", "Learn/HTML/Forms/Advanced_styling_for_HTML_forms", "Learn/HTML/Forms")}}

- -

В этой статье Вы узнает, как использовать CSS с HTML-формами, чтобы сделать их (надеюсь) более красивыми. Удивительно, но это может быть немного сложнее. По историческим и техническим причинам виджеты форм плохо сочетаются с CSS. Из-за этих трудностей многие разработчики предпочитают создавать свои собственные HTML-виджеты, чтобы получить контроль над своим внешним видом. Однако в современных браузерах веб-дизайнеры все больше контролируют дизайн элементов формы. Давайте приступим!

- -

Почему так сложно стилизовать виджеты форм с помощью CSS?

- -

На заре Интернета, примерно в 1995 году, в HTML 2 были добавлены элементы управления формой. Из-за сложности виджетов форм разработчики решили полагаться на базовую операционную систему для управления ими и их рендеринга.

- -

Несколько лет спустя был создан CSS, и то, что было технической необходимостью, то есть использование собственных виджетов для реализации элементов управления формой, стало требованием к стилю. В первые дни CSS, стилизация элементов управления формы не была приоритетом.

- -

Поскольку пользователи привыкли к внешнему виду своих соответствующих платформ, поставщики браузеров неохотно делают элементы управления формами стилевыми; и по сей день все еще чрезвычайно трудно перестроить все элементы управления, чтобы сделать их стилизованными.

- -

Даже сегодня ни один браузер полностью не реализует CSS 2.1. Однако со временем поставщики браузеров улучшили свою поддержку CSS для элементов формы, и, несмотря на плохую репутацию в отношении удобства использования, теперь вы можете использовать CSS для стилизации HTML форм.

- -

Не все виджеты созданы равными, когда задействован CSS

- -

В настоящее время некоторые трудности остаются при использовании CSS с формами. Эти проблемы можно разделить на три категории:

- -

Хорошая

- -

Некоторые элементы могут быть стилизованы с небольшим количеством проблем на разных платформах. К ним относятся следующие структурные элементы:

- -
    -
  1. {{HTMLElement("form")}}
  2. -
  3. {{HTMLElement("fieldset")}}
  4. -
  5. {{HTMLElement("label")}}
  6. -
  7. {{HTMLElement("output")}}
  8. -
- -

Сюда также входят все виджеты текстового поля (как однострочные, так и многострочные) и кнопки.

- -

Плохая

- -

Некоторые элементы редко могут быть стилизованы, и могут потребовать некоторых сложных уловок, иногда требующих углубленных знаний CSS3.

- -

Они включают в себя элемент {{HTMLElement ("legend")}}, но его нельзя правильно расположить на всех платформах. Флажки и переключатели также не могут быть стилизованы напрямую, однако, благодаря CSS3 вы можете обойти это. Контент {{htmlattrxref ("placeholder", "input")}} не может быть стилизован каким-либо стандартным способом, однако все браузеры, которые его реализуют, также реализуют собственные псевдо-элементы CSS или псевдоклассы, которые позволяют его стилизовать.

- -

Мы опишем, как обрабатывать эти более конкретные случаи, в статье «Расширенные стили для HTML-форм».

- -

The ugly

- -

Some elements simply can't be styled using CSS. These include: all advanced user interface widgets, such as range, color, or date controls; and all the dropdown widgets, including {{HTMLElement("select")}}, {{HTMLElement("option")}}, {{HTMLElement("optgroup")}} and {{HTMLElement("datalist")}} elements. The file picker widget is also known not to be stylable at all. The new {{HTMLElement("progress")}} and {{HTMLElement("meter")}} elements also fall in this category.

- -

The main issue with all these widgets, comes from the fact that they have a very complex structure, and CSS is not currently expressive enough to style all the subtle parts of those widgets. If you want to customize those widgets, you have to rely on JavaScript to build a DOM tree you'll be able to style. We explore how to do this in the article How to build custom form widgets.

- -

Basic styling

- -

To style elements that are easy to style with CSS, you shouldn't face any difficulties, since they mostly behave like any other HTML element. However, the user-agent style sheet of every browser can be a little inconsistent, so there are a few tricks that can help you style them in an easier way.

- -

Search fields

- -

Search boxes are the only kind of text fields that can be a little tricky to style. On WebKit based browsers (Chrome, Safari, etc.), you'll have to tweak it with the -webkit-appearance proprietary property. We discuss this property further in the article: Advanced styling for HTML forms.

- -

Example

- -
<form>
-  <input type="search">
-</form>
-
- -
input[type=search] {
-  border: 1px dotted #999;
-  border-radius: 0;
-
-  -webkit-appearance: none;
-}
- -

This is a screenshot of a search filed on Chrome, with and without the use of -webkit-appearance

- -

As you can see on this screenshot of the search field on Chrome, the two fields have a border set as in our example. The first field is rendered without using the -webkit-appearance property, whereas the second is rendered using -webkit-appearance:none. This difference is noticeable.

- -

Fonts and text

- -

CSS font and text features can be used easily with any widget (and yes, you can use {{cssxref("@font-face")}} with form widgets). However, browsers' behaviors are often inconsistent. By default, some widgets do not inherit {{cssxref("font-family")}} and {{cssxref("font-size")}} from their parents. Many browsers use the system default appearance instead. To make your forms' appearance consistent with the rest of your content, you can add the following rules to your stylesheet:

- -
button, input, select, textarea {
-  font-family : inherit;
-  font-size   : 100%;
-}
- -

The screenshot below shows the difference; on the left is the default rendering of the element in Firefox on Mac OS X, with the platform's default font style in use. On the right are the same elements, with our font harmonization style rules applied.

- -

This is a screenshot of the main form widgets on Firefox on Mac OSX, with and without font harmonization

- -

There's a lot of debate as to whether forms look better using the system default styles, or customized styles designed to match your content. This decision is yours to make, as the designer of your site, or Web application.

- -

Box model

- -

All text fields have complete support for every property related to the CSS box model ({{cssxref("width")}}, {{cssxref("height")}}, {{cssxref("padding")}}, {{cssxref("margin")}}, and {{cssxref("border")}}). As before, however, browsers rely on the system default styles when displaying these widgets. It's up to you to define how you wish to blend them into your content. If you want to keep the native look and feel of the widgets, you'll face a little difficulty if you want to give them a consistent size.

- -

This is because each widget has their own rules for border, padding and margin. So if you want to give the same size to several different widgets, you have to use the {{cssxref("box-sizing")}} property:

- -
input, textarea, select, button {
-  width : 150px;
-  margin: 0;
-
-  -webkit-box-sizing: border-box; /* For legacy WebKit based browsers */
-     -moz-box-sizing: border-box; /* For legacy (Firefox <29) Gecko based browsers */
-          box-sizing: border-box;
-}
- -

This is a screenshot of the main form widgets on Chrome on Windows 7, with and without the use of box-sizing.

- -

In the screenshot above, the left column is built without {{cssxref("box-sizing")}}, while the right column uses this property with the value border-box. Notice how this lets us ensure that all of the elements occupy the same amount of space, despite the platform's default rules for each kind of widget.

- -

Positioning

- -

Positioning of HTML form widgets is generally not a problem; however, there are two elements you should take special note of:

- -

legend

- -

The {{HTMLElement("legend")}} element is okay to style, except for positioning. In every browser, the {{HTMLElement("legend")}} element is positioned on top of the top border of its {{HTMLElement("fieldset")}} parent. There is absolutely no way to change it to be positioned within the HTML flow, away from the top border. You can, however, position it absolutely or relatively, using the {{cssxref("position")}} property. But otherwise it is part of the fieldset border.

- -

Because the {{HTMLElement("legend")}} element is very important for accessibility reasons, it will be spoken by assistive technologies as part of the label of each form element inside the fieldset, it's quite often paired with a title, and then hidden in an accessible way. For example:

- -
HTML
- -
<fieldset>
-  <legend>Hi!</legend>
-  <h1>Hello</h1>
-</fieldset>
- -
CSS
- -
legend {
-  width: 1px;
-  height: 1px;
-  overflow: hidden;
-}
- -

textarea

- -

By default, all browsers consider the {{HTMLElement("textarea")}} element to be an inline block, aligned to the text bottom line. This is rarely what we actually want to see. To change from inline-block to block, it's pretty easy to use the {{cssxref("display")}} property. But if you want to use it inline, it's common to change the vertical alignment:

- -
textarea {
-  vertical-align: top;
-}
- -

Example

- -

Let's look at a concrete example of how to style an HTML form. This will help make a lot of these ideas clearer. We will build the following "postcard" contact form:

- -

This is what we want to achieve with HTML and CSS

- -

If you want to follow along with this example, make a local copy of our postcard-start.html file, and follow the below instructions.

- -

The HTML

- -

The HTML is only slightly more involved than the example we used in the first article of this guide; it just has a few extra IDs and a title.

- -
<form>
-  <h1>to: Mozilla</h1>
-
-  <div id="from">
-    <label for="name">from:</label>
-    <input type="text" id="name" name="user_name">
-  </div>
-
-  <div id="reply">
-    <label for="mail">reply:</label>
-    <input type="email" id="mail" name="user_email">
-  </div>
-
-  <div id="message">
-    <label for="msg">Your message:</label>
-    <textarea id="msg" name="user_message"></textarea>
-  </div>
-
-  <div class="button">
-    <button type="submit">Send your message</button>
-  </div>
-</form>
- -

Add the above code into the body of your HTML.

- -

Organizing your assets

- -

This is where the fun begins! Before we start coding, we need three additional assets:

- -
    -
  1. The postcard background — download this image and save it in the same directory as your working HTML file.
  2. -
  3. A typewriter font: The "Secret Typewriter" font from fontsquirrel.com — download the TTF file into the same directory as above.
  4. -
  5. A handdrawn font: The "Journal" font from fontsquirrel.com — download the TTF file into the same directory as above.
  6. -
- -

Your fonts need some more processing before you start:

- -
    -
  1. Go to the fontsquirrel Webfont Generator.
  2. -
  3. Using the form, upload both your font files and generate a webfont kit. Download the kit to your computer.
  4. -
  5. Unzip the provided zip file.
  6. -
  7. Inside the unzipped contents you will find two .woff files and two .woff2 files. Copy these four files into a directory called fonts, in the same directory as before. We are using two different files for each font to maximise browser compatibility; see our Web fonts article for a lot more information.
  8. -
- -

The CSS

- -

Now we can dig into the CSS for the example. Add all the code blocks shown below inside the {{htmlelement("style")}} element, one after another.

- -

First, we prepare the ground by defining our {{cssxref("@font-face")}} rules, all the basics on the {{HTMLElement("body")}} element, and the {{HTMLElement("form")}} element:

- -
@font-face {
-    font-family: 'handwriting';
-    src: url('fonts/journal-webfont.woff2') format('woff2'),
-         url('fonts/journal-webfont.woff') format('woff');
-    font-weight: normal;
-    font-style: normal;
-}
-
-@font-face {
-    font-family: 'typewriter';
-    src: url('fonts/veteran_typewriter-webfont.woff2') format('woff2'),
-         url('fonts/veteran_typewriter-webfont.woff') format('woff');
-    font-weight: normal;
-    font-style: normal;
-}
-
-body {
-  font  : 21px sans-serif;
-
-  padding : 2em;
-  margin  : 0;
-
-  background : #222;
-}
-
-form {
-  position: relative;
-
-  width  : 740px;
-  height : 498px;
-  margin : 0 auto;
-
-  background: #FFF url(background.jpg);
-}
- -

Now we can position our elements, including the title and all the form elements:

- -
h1 {
-  position : absolute;
-  left : 415px;
-  top  : 185px;
-
-  font : 1em "typewriter", sans-serif;
-}
-
-#from {
-  position: absolute;
-  left : 398px;
-  top  : 235px;
-}
-
-#reply {
-  position: absolute;
-  left : 390px;
-  top  : 285px;
-}
-
-#message {
-  position: absolute;
-  left : 20px;
-  top  : 70px;
-}
- -

That's where we start working on the form elements themselves. First, let's ensure that the {{HTMLElement("label")}}s are given the right font:

- -
label {
-  font : .8em "typewriter", sans-serif;
-}
- -

The text fields require some common rules. Simply put, we remove their {{cssxref("border","borders")}} and {{cssxref("background","backgrounds")}}, and redefine their {{cssxref("padding")}} and {{cssxref("margin")}}:

- -
input, textarea {
-  font    : .9em/1.5em "handwriting", sans-serif;
-
-  border  : none;
-  padding : 0 10px;
-  margin  : 0;
-  width   : 240px;
-
-  background: none;
-}
- -

When one of these fields gains focus, we highlight them with a light grey, transparent, background. Note that it's important to add the {{cssxref("outline")}} property, in order to remove the default focus highlight added by some browsers:

- -
input:focus, textarea:focus {
-  background   : rgba(0,0,0,.1);
-  border-radius: 5px;
-  outline      : none;
-}
- -

Now that our text fields are complete, we need to adjust the display of the single and multiple line text fields to match, since they won't typically look the same using the defaults.

- -

The single-line text field needs some tweaks to render nicely in Internet Explorer. Internet Explorer does not define the height of the fields based on the natural height of the font (which is the behavior of all other browsers). To fix this, we need to add an explicit height to the field, as follows:

- -
input {
-    height: 2.5em; /* for IE */
-    vertical-align: middle; /* This is optional but it makes legacy IEs look better */
-}
- -

{{HTMLElement("textarea")}} elements default to being rendered as a block element. The two important things here are the {{cssxref("resize")}} and {{cssxref("overflow")}} properties. Because our design is a fixed-size design, we will use the resize property to prevent users from resizing our multi-line text field. The {{cssxref("overflow")}} property is used to make the field render more consistently across browsers. Some browsers default to the value auto, while some default to the value scroll. In our case, it's better to be sure every one will use auto:

- -
textarea {
-  display : block;
-
-  padding : 10px;
-  margin  : 10px 0 0 -10px;
-  width   : 340px;
-  height  : 360px;
-
-  resize  : none;
-  overflow: auto;
-}
- -

The {{HTMLElement("button")}} element is really convenient with CSS; you can do whatever you want, even using pseudo-elements:

- -
button {
-  position     : absolute;
-  left         : 440px;
-  top          : 360px;
-
-  padding      : 5px;
-
-  font         : bold .6em sans-serif;
-  border       : 2px solid #333;
-  border-radius: 5px;
-  background   : none;
-
-  cursor       : pointer;
-
--webkit-transform: rotate(-1.5deg);
-   -moz-transform: rotate(-1.5deg);
-    -ms-transform: rotate(-1.5deg);
-     -o-transform: rotate(-1.5deg);
-        transform: rotate(-1.5deg);
-}
-
-button:after {
-  content: " >>>";
-}
-
-button:hover,
-button:focus {
-  outline   : none;
-  background: #000;
-  color   : #FFF;
-}
- -

And voila!

- -
-

Note: If your example does not work quite like you expected and you want to check it against our version, you can find it on GitHub — see it running live (also see the source code).

-
- -

Conclusion

- -

As you can see, as long as we want to build forms with just text fields and buttons, it's easy to style them using CSS. If you want to know more of the little CSS tricks that can make your life easier when working with form widgets, take a look at the form part of the normalize.css project.

- -

In the next article, we will see how to handle form widgets which fall in the "bad" and "ugly" categories.

- -

{{PreviousMenuNext("Learn/HTML/Forms/HTML_forms_in_legacy_browsers", "Learn/HTML/Forms/Advanced_styling_for_HTML_forms", "Learn/HTML/Forms")}}

- -

In this module

- - diff --git "a/files/ru/learn/html/forms/\320\262\320\260\320\273\320\270\320\264\320\260\321\206\320\270\321\217_\321\204\320\276\321\200\320\274\321\213/index.html" "b/files/ru/learn/html/forms/\320\262\320\260\320\273\320\270\320\264\320\260\321\206\320\270\321\217_\321\204\320\276\321\200\320\274\321\213/index.html" deleted file mode 100644 index f2c5f362ac..0000000000 --- "a/files/ru/learn/html/forms/\320\262\320\260\320\273\320\270\320\264\320\260\321\206\320\270\321\217_\321\204\320\276\321\200\320\274\321\213/index.html" +++ /dev/null @@ -1,906 +0,0 @@ ---- -title: Проверка данных формы (проверка валидности формы на стороне клиента) -slug: Learn/HTML/Forms/Валидация_формы -translation_of: Learn/Forms/Form_validation ---- -

- -

- -
-
-
- -
-
- -
-
- -
-
-
<
- -
-
- -
<
-
-
-
- -
{{LearnSidebar}}{{PreviousMenuNext("Learn/HTML/Forms/Sending_and_retrieving_form_data", "Learn/HTML/Forms/How_to_build_custom_form_widgets", "Learn/HTML/Forms")}}
- -

Проверка данных формы позволяет нам удостовериться в том, что пользователи заполняют форму в  правильном формате, убедиться, что отправленные данные будут успешно работать с нашими приложениями. Эта статья расскажет, что вам нужно знать о проверке формы.

- - - - - - - - - - - - -
Предпосылки:Компьютерная грамотность, разумное понимание HTML, CSS, и JavaScript.
Задача:Понимать что такое проверка формы (валидация) формы, почему это важно и как это реализовать.
- -

Что такое валидация формы?

- -

Откройте любой популярный сайт с формой регистрации и вы заметите, что они дают вам обратную связь, когда вы вводите ваши данные не в том формате, который они ожидают от вас. Вы получите подобные сообщения:

- - - -

Это называется валидация формы — когда вы вводите данные,  веб-прилолжение проверяет, что данные корректны. Если данные верны, приложение позволяет данным быть отправленными на сервер и (как правило) быть сохраненными в базе данных; если нет -  оно выдает вам сообщение об ошибке, обьясняющее какие исправления необходимо внести. Проверка формы может быть реализована несколькими различными способами.

- -

Мы хотим сделать заполнение веб-форм максимально простым. Итак, почему мы настаиваем на подтверждении наших форм? Существуют три основные причины:

- - - -

Различные типы валидации формы

- -

Существует два разных типа проверки формы, с которыми вы столкнетесь в Интернете:

- - - -

В реальном мире разработчики склонны использовать комбинацию проверки на стороне клиента и сервера.

- -

Использование встроенной проверки формы

- -

Одной из особенностей HTML5 является возможность проверки большинства пользовательских данных без использования скриптов. Это делается с помощью атрибутов проверки элементов формы, которые позволяют вам указывать правила ввода формы, например, нужно ли заполнять значение, минимальная и максимальная длина данных, должно ли это быть число, адрес электронной почты, адрес или что-то еще, и шаблон, которому это должно соответствовать. Если введенные данные соответствуют всем этим правилам, данные считаются валидными; если нет -  невалидными.

- -

Когда элемент валидный, следующие утверждения верны:

- - - -

Когда элемент невалидный, следующие утверждения верны:

- - - -
-

Note: Вот несколько ошибок, которые не позволяют форме быть подтверждённой: {{domxref('validityState.badInput', 'badInput')}}, {{domxref('validityState.patternMismatch','patternMismatch')}}, {{domxref('validityState.rangeOverflow','rangeOverflow')}} or {{domxref('validityState.rangeUnderflow','rangeUnderflow')}}, {{domxref('validityState.stepMismatch','stepMismatch')}}, {{domxref('validityState.tooLong','tooLong')}} or {{domxref('validityState.tooShort','tooShort')}}, {{domxref('validityState.typeMismatch','typeMismatch')}}, {{domxref('validityState.valueMissing','valueMissing')}}, or a {{domxref('validityState.customError','customError')}}.

-
- -

Примеры встроенных форм валидации

- -

Ограничения проверки элементов input - простое начало

- -

В этом разделе мы рассмотрим некоторые функции HTML5, которые можно использовать для проверки {{HTMLElement("input")}} элементов.

- -

Начнем с простого примера - input, который позволяет вам выбирать ваш любимый плод между бананом и вишней. Он включает простой текст {{HTMLElement("input")}} соответствующий ярлык (label) и отправку (submit) {{htmlelement("button")}}. Вы можете найти исходный код на GitHub fruit-start.html,и живой пример ниже:

- -
<form>
-  <label for="choose">Would you prefer a banana or cherry?</label>
-  <input id="choose" name="i_like">
-  <button>Submit</button>
-</form>
- -
input:invalid {
-  border: 2px dashed red;
-}
-
-input:valid {
-  border: 2px solid black;
-}
-
- -

{{EmbedLiveSample("Simple_start_file", "100%", 80)}}

- -

Для начала сделаем копию fruit-start.htmlв новом каталоге на жестком диске.

- -

Требуемый атрибут (required)

- -

Простейшей функцией проверки HTML5 для использования является  {{htmlattrxref("required", "input")}} атрибут. Если вы хотите сделать ввод обязательным, вы можете пометить элемент, используя этот атрибут. Если этот атрибут установлен, форма не будет отправляться (и будет отображаться сообщение об ошибке), когда поле пустое (поле input также будет считаться невалидным).

- -

Добавьте атрибут required в ваш input, как показано ниже:

- -
<form>
-  <label for="choose">Would you prefer a banana or cherry?</label>
-  <input id="choose" name="i_like" required>
-  <button>Submit</button>
-</form>
- -

Также обратите внимание на CSS, включенный в файл примера:

- -
input:invalid {
-  border: 2px dashed red;
-}
-
-input:invalid:required {
-  background-image: linear-gradient(to right, pink, lightgreen);
-}
-
-input:valid {
-  border: 2px solid black;
-}
- -

В этом случае к input будет применяться ярко-красный пунктирный border, когда он невалидный, и более тонкая черная граница, когда он валидный. Попробуйте новое поведение в приведенном ниже примере:

- -

{{EmbedLiveSample("The_required_attribute", "100%", 80)}}

- -
-

Note: Вы можете найти этот пример на GitHub как fruit-validation.html (также смотрите source code.)

-
- -

Попробуйте эту форму без значения. Обратите внимание как невалидный ввод получает фокус, сообщение об ошибке ("Пожалуйста заполните поле") появляется, и форма не отправляется.

- -

Проверка с регулярными выражениями

- -

Другая полезная функция проверки - это pattern атрибут , который ожидает Regular Expression в качестве значения. Регулярное выражение (regex) - это шаблон который используется для проверки соответствия символов в текстовых строках, поэтому он идеально подходит для проверки формы, а также для многих других целей в JavaScript.

- -

Регулярные выражения довольно сложны, и мы не будем подробно разбирать их в этой статье. Ниже приведены некоторые примеры, чтобы вы представляли себе, как они работают:

- - - -

Вы также можете использовать числа и другие символы в этих выражениях, например:

- - - -

Вы можете комбинировать их практически, как хотите, указывая разные части, одну за другой:

- - - -

В любом случае, давайте реализуем пример - обновим ваш HTML, чтобы добавить атрибут шаблона, например:

- -
<form>
-  <label for="choose">Would you prefer a banana or a cherry?</label>
-  <input id="choose" name="i_like" required pattern="banana|cherry">
-  <button>Submit</button>
-</form>
- - - -

{{EmbedLiveSample("Validating_against_a_regular_expression", "100%", 50)}}

- -

В этом примере {{HTMLElement("input")}} элемент принимает одно из двух возможных значений: строку "banana" или строку "cherry".

- -

На этом этапе попробуйте изменить значение внутри атрибута pattern чтобы сопоставить некоторые из примеров, которые вы видели ранее, и посмотрите, как это влияет на значения, которые вы можете ввести, чтобы сделать входное значение валидным. Попробуйте написать свои собственные, и посмотрите, как это работает! Попробуйте сделать их связанными с фруктами, где это возможно, поэтому ваши примеры имеют смысл!

- -
-

Примечание: Некоторые {{HTMLElement("input")}} типы элементов не нуждаются в атрибуте {{htmlattrxref("pattern","input")}} чтобы быть валидными. Указание типа email например, проверяет введенное значение через регулярное выражение, соответствующее хорошо сформированному адресу электронной почты (или списку email адресов, разделенных запятыми, если в нем присутствует атрибут {{htmlattrxref("multiple","input")}} attribute). В качестве еще одного примера, поле с типом url автоматически требует правильно сформированного URL.

-
- -
-

Примечание: Элемент {{HTMLElement("textarea")}} не поддерживает атрибут {{htmlattrxref("pattern","input")}}.

-
- -

Ограничение длины ваших записей

- -

Все текстовые поля, созданные с помощью элементов ({{HTMLElement("input")}} или  {{HTMLElement("textarea")}}) могут быть ограничены по размеру, используя атрибуты {{htmlattrxref("minlength","input")}} и{{htmlattrxref("maxlength","input")}}. Поле невалидно если его значение короче чем {{htmlattrxref("minlength","input")}} или значение длиннее значения {{htmlattrxref("maxlength","input")}}. Браузеры часто не позволяют пользователю вводить более длинное значение, чем ожидалось, в текстовые поля в любом случае, но полезно иметь этот мелкозернистый элемент управления.

- -

Для числовых полей (например <input type="number">), атрибуты {{htmlattrxref("min","input")}} и {{htmlattrxref("max","input")}} также обеспечивают ограничение валидации. Если значение поля меньше атрибута {{htmlattrxref("min","input")}} или больше атрибута {{htmlattrxref("max","input")}}, поле будет невалидным.

- -

Давайте посмотрим на другой пример. Создайте новую копию файла fruit-start.html.

- -

Теперь удалите содержимое элемента <body>, и замените его следующим:

- -
<form>
-  <div>
-    <label for="choose">Would you prefer a banana or a cherry?</label>
-    <input id="choose" name="i_like" required minlength="6" maxlength="6">
-  </div>
-  <div>
-    <label for="number">How many would you like?</label>
-    <input type="number" id="number" name="amount" value="1" min="1" max="10">
-  </div>
-  <div>
-    <button>Submit</button>
-  </div>
-</form>
- - - - - -

Вот живой пример:

- -

{{EmbedLiveSample("Constraining_the_length_of_your_entries", "100%", 70)}}

- -
-

Примечание: <input type="number"> (и другие типы, например range) могут также содержать атрибут {{htmlattrxref("step", "input")}} который указывает, какой инкремент будет увеличиваться или уменьшаться, когда используются элементы управления входом (например, номерные кнопки вверх и вниз)

-
- -

Полный пример

- -

Вот полный пример, чтобы показать использование встроенных функций проверки HTML:

- -
<form>
-  <p>
-    <fieldset>
-      <legend>Title<abbr title="This field is mandatory">*</abbr></legend>
-      <input type="radio" required name="title" id="r1" value="Mr"><label for="r1">Mr.</label>
-      <input type="radio" required name="title" id="r2" value="Ms"><label for="r2">Ms.</label>
-    </fieldset>
-  </p>
-  <p>
-    <label for="n1">How old are you?</label>
-    <!-- The pattern attribute can act as a fallback for browsers which
-         don't implement the number input type but support the pattern attribute.
-         Please note that browsers that support the pattern attribute will make it
-         fail silently when used with a number field.
-         Its usage here acts only as a fallback -->
-    <input type="number" min="12" max="120" step="1" id="n1" name="age"
-           pattern="\d+">
-  </p>
-  <p>
-    <label for="t1">What's your favorite fruit?<abbr title="This field is mandatory">*</abbr></label>
-    <input type="text" id="t1" name="fruit" list="l1" required
-           pattern="[Bb]anana|[Cc]herry|[Aa]pple|[Ss]trawberry|[Ll]emon|[Oo]range">
-    <datalist id="l1">
-      <option>Banana</option>
-      <option>Cherry</option>
-      <option>Apple</option>
-      <option>Strawberry</option>
-      <option>Lemon</option>
-      <option>Orange</option>
-    </datalist>
-  </p>
-  <p>
-    <label for="t2">What's your e-mail?</label>
-    <input type="email" id="t2" name="email">
-  </p>
-  <p>
-    <label for="t3">Leave a short message</label>
-    <textarea id="t3" name="msg" maxlength="140" rows="5"></textarea>
-  </p>
-  <p>
-    <button>Submit</button>
-  </p>
-</form>
- -
body {
-  font: 1em sans-serif;
-  padding: 0;
-  margin : 0;
-}
-
-form {
-  max-width: 200px;
-  margin: 0;
-  padding: 0 5px;
-}
-
-p > label {
-  display: block;
-}
-
-input[type=text],
-input[type=email],
-input[type=number],
-textarea,
-fieldset {
-/* требуется для правильной формы формы
-    элементов в браузерах на основе WebKit*/
-  -webkit-appearance: none;
-
-  width : 100%;
-  border: 1px solid #333;
-  margin: 0;
-
-  font-family: inherit;
-  font-size: 90%;
-
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
-}
-
-input:invalid {
-  box-shadow: 0 0 5px 1px red;
-}
-
-input:focus:invalid {
-  outline: none;
-}
- -

{{EmbedLiveSample("Full_example", "100%", 420)}}

- -

Индивидуальные сообщения об ошибках

- -

Как видно из приведенных выше примеров, каждый раз, когда пользователь пытается отправить невалидную форму, браузер отображает сообщение об ошибке. Способ отображения этого сообщения зависит от браузера.

- -

Эти автоматизированные сообщения имеют два недостатка:

- - - - - - - - - - - - - - - - - - - - - - - - - -
Французская версия сообщений обратной связи на странице на английском языке
БраузерОтображение
Firefox 17 (Windows 7)Example of an error message with Firefox in French on an English page
Chrome 22 (Windows 7)Example of an error message with Chrome in French on an English page
Opera 12.10 (Mac OSX)Example of an error message with Opera in French on an English page
- -

Чтобы настроить внешний вид и текст этих сообщений, вы должны использовать JavaScript; нет способа сделать это, используя только HTML и CSS.

- -

HTML5 предоставляет API проверки ограничений (API - Application Programing interface, программный интерфейс приложения, англ.) для проверки и настройки состояния элемента формы. Помимо прочего, можно заменить текст сообщения об ошибке. Давайте посмотрим на небольшой пример:

- -
<form>
-  <label for="mail">I would like you to provide me an e-mail</label>
-  <input type="email" id="mail" name="mail">
-  <button>Submit</button>
-</form>
- -

В JavaScript вы вызываете метод setCustomValidity():

- -
var email = document.getElementById("mail");
-
-email.addEventListener("input", function (event) {
-  if (email.validity.typeMismatch) {
-    email.setCustomValidity("I expect an e-mail, darling!");
-  } else {
-    email.setCustomValidity("");
-  }
-});
- -

{{EmbedLiveSample("Customized_error_messages", "100%", 50)}}

- -

Проверка форм с использованием JavaScript

- -

Если вы хотите контролировать внешний вид собственных сообщений об ошибках или работать с браузерами, которые не поддерживают встроенную проверку формы HTML, вы должны использовать JavaScript.

- -

API проверки валидности HTML5

- -

Все больше браузеров теперь поддерживают API проверки ограничений, и он становится надежным. Этот API состоит из набора методов и свойств, доступных для каждого элемента формы.

- -

Свойства API проверки валидности

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
СвойствоОписание
validationMessageЛокализованное сообщение, описывающее ограничения валидности, которым элемент управления не соответствует (если есть), или пустая строка, если элемент управления не является кандидатом для проверки ограничений (willValidate is false), или значение элемента удовлетворяет его ограничениям.
validityобъект {{domxref("ValidityState")}} , описывающий состояние действительности элемента.
validity.customErrorВозвращает true если элемент содержит пользовательскую ошибку; false в противном случае.
validity.patternMismatchВозвращает true если значение элемента не соответствует предоставленному шаблону; false в противном случае.
-
- если возвращает true, элемент будет соответствовать CSS псевдо-классу {{cssxref(":invalid")}}.
validity.rangeOverflowВозвращает true если значение элемента выше заданного максимума; false в противном случае.
-
- Если возвращает true, элемент будет соответствовать {{cssxref(":invalid")}} и CSS псевдо-классу. {{cssxref(":out-of-range")}}.
validity.rangeUnderflowВозвращаетtrue если значение элемента меньше заданного минимума; false в противном случае.
-
- Если возвращает true, элемент будет соответствовать {{cssxref(":invalid")}} и CSS псевдо-классу {{cssxref(":out-of-range")}}.
validity.stepMismatchВозвращаетtrue, если значение элемента не соответствует правилам, предоставляемым атрибутом step; в противном случае false .
-
- Если возвращает true, элемент будет соответствовать {{cssxref(":invalid")}} и CSS псевдоклассу {{cssxref(":out-of-range")}}.
validity.tooLongВозвращает true если значение элемента больше заданной максимальной длины; иначе будет false
-
- Если возвращает true, элемент будет соответствовать {{cssxref(":invalid")}} и CSS псевдоклассу {{cssxref(":out-of-range")}}.
validity.typeMismatchВозвращает true если значение элемента не соответствует правильному синтаксису; в противном случае - false.
- Если возвращает true, элемент будет соответствовать CSS псевдоклассу {{cssxref(":invalid")}}.
validity.validВозвращае true если значение элемента не имеет проблем с валидностью; в противном случае false.
-
- Если возвращает true, элемент будет соответствовать CSS псевдоклассу {{cssxref(":valid")}} ; CSS псевдоклассу {{cssxref(":invalid")}} в противном случае.
validity.valueMissingВозвращает true если элемент не имеет значения, но является обязательным полем; в противном случае false.
-
- Если возвращает true, элемент будет соответствовать CSS псевдоклассу {{cssxref(":invalid")}}.
willValidateВозвращает true если элемент будет проверен при отправке формы; в противном случае false.
- -

Методы API проверки ограничений

- - - - - - - - - - - - - - - - - - -
МетодОписание
checkValidity()Возвращает true если значение элемента не имеет проблем с валидностью; иначе false. Если элемент невалидный, этот метод также вызывает событие {{event("invalid")}} в элементе .
setCustomValidity(message)Добавляет настраиваемое сообщение об ошибке в элемент; если вы установили собственное сообщение об ошибке, элемент считается невалидным, и отображается указанная ошибка. Это позволяет использовать код JavaScript для установления ошибки валидации, отличного от тех, которые предлагаются стандартным API ограничений валидности. Сообщение показывается пользователю при возникновении проблемы.
-
- Если аргументом является пустая строка, пользовательская ошибка очищается.
- -

Для устаревших браузеров можно использовать полифилл как Hyperform чтобы компенсировать отсутствие поддержки API ограничений валидности. Поскольку вы уже используете JavaScript, использование полифилла не является дополнительным бременем для вашего веб-сайта или дизайна или реализации веб-приложения.

- -

Пример использования API проверки ограничений

- -

Давайте посмотрим, как использовать этот API для создания настраиваемых сообщений об ошибках. Сначала HTML:

- -
<form novalidate>
-  <p>
-    <label for="mail">
-      <span>Please enter an email address:</span>
-      <input type="email" id="mail" name="mail">
-      <span class="error" aria-live="polite"></span>
-    </label>
-  </p>
-  <button>Submit</button>
-</form>
- -

Эта простая форма использует атрибут {{htmlattrxref("novalidate","form")}} для отключения автоматической валидации браузера, что позволяет нашему скрипту контролировать валидацию. Однако это не отключает поддержку API ограничений валидации или применения псевдоклассов CSS {{cssxref(":valid")}}, {{cssxref(":invalid")}}, {{cssxref(":in-range")}} и {{cssxref(":out-of-range")}}. Это означает, что, хотя браузер не проверяет правильность формы перед отправкой своих данных, вы все равно можете сделать это самостоятельно и соответствующим образом сформировать форму.

- -

Атрибут aria-live гарантирует, что наше индивидуальное сообщение об ошибке будет доступно всем, включая тех, кто использует вспомогательные технологии, такие как скрин-ридеры.

- -
CSS
- -

Этот CSS задает стили нашей форме и выводу ошибки, чтобы сделать их визуально более привлекательными.

- -
/* Это просто, чтобы сделать пример более приятным */
-body {
-  font: 1em sans-serif;
-  padding: 0;
-  margin : 0;
-}
-
-form {
-  max-width: 200px;
-}
-
-p * {
-  display: block;
-}
-
-input[type=email]{
-  -webkit-appearance: none;
-
-  width: 100%;
-  border: 1px solid #333;
-  margin: 0;
-
-  font-family: inherit;
-  font-size: 90%;
-
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
-}
-
-/* Наш стиль для невалидных полей */
-input:invalid{
-  border-color: #900;
-  background-color: #FDD;
-}
-
-input:focus:invalid {
-  outline: none;
-}
-
-/* Это стиль для сообщений об ошибке */
-.error {
-  width  : 100%;
-  padding: 0;
-
-  font-size: 80%;
-  color: white;
-  background-color: #900;
-  border-radius: 0 0 5px 5px;
-
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
-}
-
-.error.active {
-  padding: 0.3em;
-}
- -
JavaScript
- -

Следующий код JavaScript обрабатывает выборочную проверку ошибок.

- -
//Существует много способов выбрать DOM узел; здесь мы получаем форму и электронную почту
-//поле ввода, а также элемент span, в который мы поместим сообщение об ошибке.
-var form  = document.getElementsByTagName('form')[0];
-var email = document.getElementById('mail');
-var error = document.querySelector('.error');
-
-email.addEventListener("input", function (event) {
- // Каждый раз, когда пользователь вводит что-либо, мы проверяем,
-  // является ли корректным поле электронной почты.
-  if (email.validity.valid) {
-    // В случае появления сообщения об ошибке, если поле
-    // является корректным, мы удаляем сообщение об ошибке.
-    error.innerHTML = ""; // Сбросить содержимое сообщения
-    error.className = "error"; // Сбросить визуальное состояние сообщения
-  }
-}, false);
-form.addEventListener("submit", function (event) {
-  // Каждый раз, когда пользователь пытается отправить данные, мы проверяем
-   // валидность поля электронной почты.
-  if (!email.validity.valid) {
-
-    // Если поле невалидно, отображается пользовательское
-    // сообщение об ошибке.
-    error.innerHTML = "I expect an e-mail, darling!";
-    error.className = "error active";
-    // И мы предотвращаем отправку формы путем отмены события
-    event.preventDefault();
-  }
-}, false);
- -

Вот живой результат:

- -

{{EmbedLiveSample("Example_using_the_constraint_validation_API", "100%", 130)}}

- -

API ограничений валидации дает вам мощный инструмент для проверки формы, позволяя вам получить контроль над пользовательским интерфейсом больше и лучше того, что вы можете делать только при помощи HTML и CSS.

- -

Проверка форм без встроенного API

- -

Иногда, например, с устаревшими браузерами или пользовательскими виджетами, вы не сможете (или не захотите) использовать API проверки ограничений. В этом случае вы все еще можете использовать JavaScript для проверки вашей формы. Проверка формы - это скорее вопрос пользовательского интерфейса, чем проверка валидности данных.

- -

Чтобы проверить форму, вы должны задать себе несколько вопросов:

- -
-
Какую проверку я должен выполнить?
-
Вам нужно определить, как проверить ваши данные: операции со строками, преобразование типов, регулярные выражения и т. д. Это зависит от вас. Просто помните, что данные формы всегда являются текстовыми и всегда предоставляются вашему скрипту как строки.
-
Что делать, если форма не проверяется?
-
Это явно вопрос интерфейса. Вы должны решить, как будет выглядеть форма: формально ли отправляет данные? Должны ли вы выделять поля, которые содержат ошибки? Должны отображаться сообщения об ошибках?
-
Как я могу помочь пользователю исправить невалидные данные?
-
Чтобы уменьшить разочарование пользователя, очень важно предоставить как можно больше полезной информации, чтобы помочь им в исправлении их исходных данных. Вы должны предлагать предварительные предложения, чтобы они знали, что ожидается, а также ясные сообщения об ошибках. Если вы хотите вникнуть в требования к пользовательскому интерфейсу проверки формы, есть некоторые полезные статьи, которые вы должны прочитать: - -
-
- -

Пример, который не использует API валидации ограничений

- -

Чтобы проиллюстрировать это, давайте перестроим предыдущий пример, чтобы он работал с устаревшими браузерами:

- -
<form>
-  <p>
-    <label for="mail">
-        <span>Please enter an email address:</span>
-        <input type="text" class="mail" id="mail" name="mail">
-        <span class="error" aria-live="polite"></span>
-    </label>
-  <p>
-  <!-- Some legacy browsers need to have the `type` attribute
-       explicitly set to `submit` on the `button`element -->
-  <button type="submit">Submit</button>
-</form>
- -

Как вы можете видеть, HTML почти такой же; мы просто удалили функции проверки HTML. Обратите внимание, что ARIA является независимой спецификацией, которая специально не связана с HTML5.

- -
CSS
- -

Аналогично, CSS не нужно сильно менять; мы просто переводим CSS-псевдокласс {{cssxref(":invalid")}} в настоящий класс и избегаем использования селектора атрибутов, который не работает в Internet Explorer 6.

- -
/* This is just to make the example nicer */
-body {
-  font: 1em sans-serif;
-  padding: 0;
-  margin : 0;
-}
-
-form {
-  max-width: 200px;
-}
-
-p * {
-  display: block;
-}
-
-input.mail {
-  -webkit-appearance: none;
-
-  width: 100%;
-  border: 1px solid #333;
-  margin: 0;
-
-  font-family: inherit;
-  font-size: 90%;
-
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
-}
-
-/* This is our style for the invalid fields */
-input.invalid{
-  border-color: #900;
-  background-color: #FDD;
-}
-
-input:focus.invalid {
-  outline: none;
-}
-
-/* This is the style of our error messages */
-.error {
-  width  : 100%;
-  padding: 0;
-
-  font-size: 80%;
-  color: white;
-  background-color: #900;
-  border-radius: 0 0 5px 5px;
-
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
-}
-
-.error.active {
-  padding: 0.3em;
-}
- -
JavaScript
- -

Большие изменения в коде JavaScript, которые должны сделать намного больше тяжелой работы.

- -
// Существует меньше способов выбрать узел DOM с устаревшими браузерами
-var form  = document.getElementsByTagName('form')[0];
-var email = document.getElementById('mail');
-
-// Ниже приведен трюк для достижения следующего узла Element Element в DOM
-// Это опасно, потому что вы можете легко построить бесконечный цикл.
-// В современных браузерах вам следует использовать элемент element.nextElementSibling
-var error = email;
-while ((error = error.nextSibling).nodeType != 1);
-
-// As per the HTML5 Specification
-var emailRegExp = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
-
-// Многие устаревшие браузеры не поддерживают метод addEventListener.
-// Вот простой способ справиться с этим; это далеко не единственный.
-function addEvent(element, event, callback) {
-  var previousEventCallBack = element["on"+event];
-  element["on"+event] = function (e) {
-    var output = callback(e);
-
-    // Обратный вызов, который возвращает `false`, останавливает цепочку обратного вызова
-     // и прерывает выполнение обратного вызова события.
-    if (output === false) return false;
-
-    if (typeof previousEventCallBack === 'function') {
-      output = previousEventCallBack(e);
-      if(output === false) return false;
-    }
-  }
-};
-
-// Теперь мы можем перестроить наше ограничение валидации
-// Поскольку мы не полагаемся на псевдо-класс CSS, мы должны
-// явно установить допустимый / недопустимый класс в поле электронной почты
-addEvent(window, "load", function () {
-// Здесь мы проверяем, пусто ли поле (помните, что поле не требуется)
-   // Если это не так, мы проверяем, является ли его контент корректным адресом электронной почты.
-  var test = email.value.length === 0 || emailRegExp.test(email.value);
-
-  email.className = test ? "valid" : "invalid";
-});
-
-// Это определяет, что происходит, когда пользователь вводит в поле
-addEvent(email, "input", function () {
-  var test = email.value.length === 0 || emailRegExp.test(email.value);
-  if (test) {
-    email.className = "valid";
-    error.innerHTML = "";
-    error.className = "error";
-  } else {
-    email.className = "invalid";
-  }
-});
-
-// Это определяет, что происходит, когда пользователь пытается отправить данные
-addEvent(form, "submit", function () {
-  var test = email.value.length === 0 || emailRegExp.test(email.value);
-
-  if (!test) {
-    email.className = "invalid";
-    error.innerHTML = "I expect an e-mail, darling!";
-    error.className = "error active";
-
-    // Некоторые устаревшие браузеры не поддерживают метод event.preventDefault ()
-    return false;
-  } else {
-    email.className = "valid";
-    error.innerHTML = "";
-    error.className = "error";
-  }
-});
- -

Результат выглядит следующим образом:

- -

{{EmbedLiveSample("Example_that_doesn't_use_the_constraint_validation_API", "100%", 130)}}

- -

Как вы можете видеть, создать собственную систему проверки не сложно. Трудная часть состоит в том, чтобы сделать его достаточно общим, чтобы использовать его как в кросс-платформенной, так и в любой форме, которую вы могли бы создать. Существует множество библиотек для проверки формы; вы не должны колебаться, чтобы использовать их. Вот несколько примеров:

- - - -

Удаленная проверка

- -

В некоторых случаях может быть полезно выполнить некоторую удаленную проверку. Такая проверка необходима, когда данные, введенные пользователем, привязаны к дополнительным данным, хранящимся на стороне сервера вашего приложения. Одним из вариантов использования является регистрационные формы, в которых вы запрашиваете имя пользователя. Чтобы избежать дублирования, разумнее выполнить AJAX запрос для проверки доступности имени пользователя, а не попросить пользователя отправить данные, а затем отправить форму с ошибкой.

- -

Выполнение такой проверки требует принятия нескольких мер предосторожности:

- - - -

Заключение

- -

Проверка формы не требует сложного JavaScript, но она требует тщательного изучения пользователя. Всегда помните, чтобы помочь вашему пользователю исправить данные, которые они предоставляют. Для этого обязательно выполните следующие действия:

- - - -

{{PreviousMenuNext("Learn/HTML/Forms/Sending_and_retrieving_form_data", "Learn/HTML/Forms/How_to_build_custom_form_widgets", "Learn/HTML/Forms")}}

- -

В этом модуле

- - diff --git "a/files/ru/learn/html/forms/\320\262\320\260\321\210\320\260_\320\277\320\265\321\200\320\262\320\260\321\217_html_\321\204\320\276\321\200\320\274\320\260/index.html" "b/files/ru/learn/html/forms/\320\262\320\260\321\210\320\260_\320\277\320\265\321\200\320\262\320\260\321\217_html_\321\204\320\276\321\200\320\274\320\260/index.html" deleted file mode 100644 index b68d433739..0000000000 --- "a/files/ru/learn/html/forms/\320\262\320\260\321\210\320\260_\320\277\320\265\321\200\320\262\320\260\321\217_html_\321\204\320\276\321\200\320\274\320\260/index.html" +++ /dev/null @@ -1,305 +0,0 @@ ---- -title: Ваша первая HTML форма -slug: Learn/HTML/Forms/Ваша_первая_HTML_форма -tags: - - HTML-форма - - Веб-форма - - Форма -translation_of: Learn/Forms/Your_first_form ---- -
{{LearnSidebar}}{{NextMenu("Learn/HTML/Forms/How_to_structure_an_HTML_form", "Learn/HTML/Forms")}}
- -

Первая статья в данной главе предоставит вам первый опыт создания веб-форм, в том числе проектирование простой формы, её реализацию с использованием HTML-элементов управления формой и других HTML-элементов, добавление стилей через CSS и описание того, как данные из формы отсылаются на сервер. Мы более подробно остановимся на каждой из этих подтем далее в статье.

- - - - - - - - - - - - -
Необходимые знания:Базовое представление о компьютерах и базовое понимание HTML.
Цель:Ознакомиться с веб-формами, узнать, для чего они используются, как их проектировать, и какие базовые HTML-элементы могут понадобиться в простых ситуациях.
- -

Что такое Веб-форма?

- -

Веб-формы являются одним из основных элементов взаимодействия между пользователем и сайтом или приложением. Формы позволяют пользователю ввести данные, которые затем отправляются на сервер для их дальнейшей обработки и хранения или используются на стороне клиента для обновления интерфейса (например, добавление нового элемента в список или открытие и закрытие элемента интерфейса).

- -

Веб-формы — их также часто называют HTML-формы — состоят из одного или нескольких элементов управления форм (иногда их также называют виджетами) и некоторых дополнительных элементов для структурирования формы. Элементами управления могут быть однострочные или многострочные текстовые поля, выпадающие списки, кнопки, чекбоксы, радио-баттоны, большинство из которых создаются через html-элемент {{htmlelement("input")}}, однако есть и другие элементы, о которых тоже стоит узнать.

- -

В элементах управления форм можно задать правила, указывающие на определенный формат данных или значений, которые могут быть введены (валидация форм), а также к ним могут быть добавлены текстовые строки, описывающие эти элементы для зрячих и незрячих пользователей.

- -

Проектирование формы

- -

Перед тем, как начать программировать, всегда лучше остановиться и подумать о вашей форме. Создание быстрого наброска поможет определить верный набор данных, которые вы хотите получить от пользователя. С точки зрения UX, удобства использования интерфейса, важно помнить о том, что чем длиннее ваша форма, тем больше риск потерять пользователей. Сделайте форму краткой и лаконичной: спрашивайте только о той информации, которая вам действительно необходима.

- -

Проектирование форм является важным этапом при создании сайта или приложения. Удобство использования форм (UX) выходит за рамки данной статьи, однако если вы хотите углубиться в эту тему, то вам следует прочитать следующие статьи:

- - - -

В этой статье мы создадим простую контактную форму. Давайте сделаем набросок.

- -

The form to build, roughly sketch

- -

Наша форма будет состоять из трёх текстовых полей и одной кнопки. Мы узнаём у пользователя его имя, e-mail и сообщение, которое он хочет отправить. После нажатия на кнопку данные будут отправлены на веб-сервер.

- -

Активное обучение: Реализация HTML-формы

- -

Итак, теперь мы готовы обратиться к HTML и создать нашу форму. Для этого мы будем использовать следующие HTML-элементы: {{HTMLelement("form")}}, {{HTMLelement("label")}}, {{HTMLelement("input")}}, {{HTMLelement("textarea")}} и {{HTMLelement("button")}}.

- -

Прежде, чем продолжить, скопируйте простой HTML-шаблон — вы будете создавать свою форму внутри него.

- -

Элемент {{HTMLelement("form")}}

- -

Создание форм начинается с элемента {{HTMLelement("form")}}:

- -
<form action="/my-handling-form-page" method="post">
-
-</form>
- -

Этот элемент формально определяет форму. Он является элементом-контейнером, как HTML-элементы {{HTMLelement("div")}} или {{HTMLelement("p")}}, но при этом он поддерживает некоторые специфические атрибуты для настройки поведения формы. Все атрибуты являются опциональными, но в стандартной практике принято указывать атрибуты action и method:

- - - -
-

Примечание: Мы детальнее разберём работу этих атрибутов далее в статье Отправка данных формы.

-
- -

Теперь добавьте указанный выше код с элементом {{htmlelement("form")}} внутрь тега {{htmlelement("body")}} в вашем HTML.

- -

Элементы {{HTMLelement("label")}}, {{HTMLelement("input")}} и {{HTMLelement("textarea")}}

- -

Наша контактная форма несложная: часть, в которую будут вводиться данные, состоит из трёх текстовых полей, каждое их которых связано с HTML-элементом {{HTMLelement("label")}}:

- - - -

В терминах HTML нам нужен код наподобие представленного ниже, чтобы добавить виджеты форм:

- -
<form action="/my-handling-form-page" method="post">
-  <ul>
-    <li>
-      <label for="name">Name:</label>
-      <input type="text" id="name" name="user_name">
-    </li>
-    <li>
-      <label for="mail">E-mail:</label>
-      <input type="email" id="mail" name="user_mail">
-    </li>
-    <li>
-      <label for="msg">Message:</label>
-      <textarea id="msg" name="user_message"></textarea>
-    </li>
-  </ul>
-</form>
- -

Добавьте в вашу форму код, чтобы она выглядела так же, как форма выше.

- -

Здесь элементы {{HTMLelement("li")}} используются для структурирования кода и облегчения стилизации (будет разобрано далее в статье). Для доступности и удобства использования мы указали определённый текст-подсказку для каждого элемента управления. Обратите внимание на использование атрибута for на каждом элементе {{HTMLelement("label")}}, который принимает в качестве значение id элемента управления формы, с которым он связан — этот подход позволяет привязать тексты-подсказки к форме.

- -

Такой подход полезен тем, что позволяет пользователям с мышью, трекпадом и сенсорным устройством кликнуть на текст-подсказку для активации связанного с ним виджета формы, а также обеспечивает читабельное имя для пользователей скрин-ридеров. Вы найдёте более детальный разбор текстов-подсказок в статье Как структурировать HTML-форму.

- -

В HTML-элементе {{HTMLelement("input")}} самым важным атрибутом является атрибут type. Этот атрибут чрезвычайно важен, потому что он определяет внешний вид и поведение элемента {{HTMLelement("input")}}. Вы найдёте больше информации об этом далее в статье Стандартные виджеты форм.

- - - -

Последнее, но не менее важное, обратите внимание на разницу синтаксиса у HTML-элементов <input> и <textarea></textarea>. Это одна из странностей HTML. Тег <input> — это пустой элемент, то есть он не нуждается в закрывающем теге.  {{HTMLElement("textarea")}} — это непустой элемент, что говорит о том, что ему необходим закрывающий тег. Это важно при использовании одного из свойств форм: определения значения по умолчанию. Для определения начального значения для HTML-элемента {{HTMLElement("input")}} вам необходимо использовать атрибут value следующим образом:

- -
<input type="text" value="по умолчанию в этом элементе находится этот текст" />
- -

Если вы хотите определить значение по умолчанию для HTML-элемента {{HTMLElement("textarea")}}, вам просто нужно поместить это начальное значение между открывающим и закрывающим тегами:

- -
<textarea>
-по умолчанию в этом элементе находится этот текст
-</textarea>
- -

Элемент {{HTMLelement("button")}}

- -

Разметка нашей формы почти готова, но нам ещё необходимо добавить кнопку, которая позволит пользователю отправлять или "представлять" информацию после заполнения формы. Это делается с помощью HTML-элемента {{HTMLelement("button")}}. Необходимо добавить следующий код перед закрывающим тегом </form>:

- -
<li class="button">
-  <button type="submit">Send your message</button>
-</li>
- -

HTML-элемент {{HTMLelement("button")}} также принимает атрибут type, который может быть равен одному из трёх значений: submit, reset или button.

- - - -
-

Примечание: Вы также можете использовать HTML-элемент {{HTMLElement("input")}} с соответствующим атрибутом type , чтобы создать кнопку:  <input type="submit">. Главным преимуществом HTML-элемента {{HTMLelement("button")}} в сравнении с элементом {{HTMLelement("input")}} заключается в том, что {{HTMLelement("input")}} может принимать в себя только простой текст, в то время как {{HTMLelement("button")}} позволяет использовать весь HTML для создания более стилизованного текста внутри кнопки.

-
- -

Базовая стилизация формы

- -

Теперь после того, как вы закончили писать HTML-код формы, сохраните его и откройте в браузере. Вы увидите, что на данный момент форма выглядит достаточно не красиво.

- -

- -
-

Примечание: Если вам кажется, что ваш HTML-код работает не правильно, попробуйте сравнить его с нашим примером — посмотрите first-form.html (также можно посмотреть код вживую).

-
- -

Красиво стилизовать формы достаточно сложно. Эта тема выходит за рамки этой статьи, поэтому на данный момент мы просто добавим некоторый CSS-код для приведения формы в нормальный вид.

- -

Сначала необходимо добавить HTML-элемент {{htmlelement("style")}} на вашу страницу внутрь тега head в HTML. Это должно выглядить следущим образом:

- -
<style>
-
-</style>
- -

Внутри тега стилей добавьте следующий код:

- -
form {
-  /* Расположим форму по центру страницы */
-  margin: 0 auto;
-  width: 400px;
-  /* Определим контур формы */
-  padding: 1em;
-  border: 1px solid #CCC;
-  border-radius: 1em;
-}
-
-ul {
-  list-style: none;
-  padding: 0;
-  margin: 0;
-}
-
-form li + li {
-  margin-top: 1em;
-}
-
-label {
-  /* Определим размер и выравнивание */
-  display: inline-block;
-  width: 90px;
-  text-align: right;
-}
-
-input,
-textarea {
-  /* Убедимся, что все поля имеют одинаковые настройки шрифта
-     По умолчанию в textarea используется моноширинный шрифт */
-  font: 1em sans-serif;
-
-  /* Определим размер полей */
-  width: 300px;
-  box-sizing: border-box;
-
-  /* Стилизуем границы полей */
-  border: 1px solid #999;
-}
-
-input:focus,
-textarea:focus {
-  /* Дополнительная подсветка для элементов в фокусе */
-  border-color: #000;
-}
-
-textarea {
-  /* Выровним многострочные текстовые поля с их текстами-подсказками */
-  vertical-align: top;
-
-  /* Предоставим пространство для ввода текста */
-  height: 5em;
-}
-
-.button {
-  /* Выровним кнопки с их текстами-подсказками */
-  padding-left: 90px; /* same size as the label elements */
-}
-
-button {
-  /* Этот дополнительный внешний отступ примерно равен расстоянию
-     между текстами-подсказками и текстовыми полями */
-  margin-left: .5em;
-}
- -

Теперь наша форма выглядит намного лучше.

- -

- -
-

Примечание: Вы можете найти код на GitHub в first-form-styled.html (также можно посмотреть код вживую).

-
- -

Отправка данных на сервер

- -

Последняя и, наверно, самое сложное — это обработка данных формы на стороне сервера. HTML-элемент {{HTMLelement("form")}} определяет куда и каким способом отправить данные благодаря атрибутам action и method.

- -

Мы определяем имя name для каждого виджета формы. Указание имён важно как для браузера, так и для сервера: браузер узнаёт, какие имена дать каждой части данных, а сервер может получить эти данные, обратясь к ним по заданному имени. Данные форму отправляются на сервер в виде пары имя/значение.

- -

Чтобы проименовать данные, вам необходимо использовать атрибут name на каждом виджете формы, который будет собирать определённую часть информации. Давайте взглянем на код нашей формы ещё раз:

- -
<form action="/my-handling-form-page" method="post">
-  <div>
-    <label for="name">Name:</label>
-    <input type="text" id="name" name="user_name" />
-  </div>
-  <div>
-    <label for="mail">E-mail:</label>
-    <input type="email" id="mail" name="user_email" />
-  </div>
-  <div>
-    <label for="msg">Message:</label>
-    <textarea id="msg" name="user_message"></textarea>
-  </div>
-
-  ...
-
- -

В нашем примере форма отправит три куска данных с именами "user_name", "user_email" и "user_message". Эти данные будут отправлены на URL "/my-handling-form-page" через метод HTTP POST.

- -

На стороне сервера скрипт, расположенный на URL "/my-handling-form-page" получит данные в виде списка из 3 элементов вида ключ/значение, содержащихся в HTTP-запросе. То, как скрипт будет обрабатывать данные, зависит от вас. Каждый язык серверного программирования (PHP, Python, Ruby, Java, C# и т.д.) имеет свой механизм обработки данных из формы. Эта тема выходит за рамки данной статьи, если вы хотите углубиться в неё, мы привели несколько примеров далее в статье Отправка данных формы.

- -

Заключение

- -

Поздравляем! Вы создали свою первую HTML-форму. Вживую это выглядит так: 

- -

{{ EmbedLiveSample('A_simple_form', '100%', '240', '', 'Learn/HTML/Forms/Your_first_HTML_form/Example') }}

- -

Однако это только начало — пришло время взглянуть глубже. HTML-формы намного мощнее, чем то, что мы видели здесь, и другие статьи этого раздела помогут освоить остальное.

- -

{{NextMenu("Learn/HTML/Forms/How_to_structure_an_HTML_form", "Learn/HTML/Forms")}}

- -

В этом разделе

- - - -

Дополнительные темы

- - diff --git "a/files/ru/learn/html/forms/\320\276\321\202\320\277\321\200\320\260\320\262\320\272\320\260_\320\270_\320\277\320\276\320\273\321\203\321\207\320\265\320\275\320\270\320\265_\320\264\320\260\320\275\320\275\321\213\321\205_\321\204\320\276\321\200\320\274\321\213/index.html" "b/files/ru/learn/html/forms/\320\276\321\202\320\277\321\200\320\260\320\262\320\272\320\260_\320\270_\320\277\320\276\320\273\321\203\321\207\320\265\320\275\320\270\320\265_\320\264\320\260\320\275\320\275\321\213\321\205_\321\204\320\276\321\200\320\274\321\213/index.html" deleted file mode 100644 index 9e7900f783..0000000000 --- "a/files/ru/learn/html/forms/\320\276\321\202\320\277\321\200\320\260\320\262\320\272\320\260_\320\270_\320\277\320\276\320\273\321\203\321\207\320\265\320\275\320\270\320\265_\320\264\320\260\320\275\320\275\321\213\321\205_\321\204\320\276\321\200\320\274\321\213/index.html" +++ /dev/null @@ -1,352 +0,0 @@ ---- -title: Отправка данных формы -slug: Learn/HTML/Forms/Отправка_и_Получение_данных_формы -translation_of: Learn/Forms/Sending_and_retrieving_form_data ---- -
{{LearnSidebar}}{{PreviousMenuNext("Learn/HTML/Forms/The_native_form_widgets", "Learn/HTML/Forms/Form_validation", "Learn/HTML/Forms")}}
- -

В этой статье рассматривается, что происходит, когда пользователь отправляет форму - куда передаются данные и как мы их обрабатываем, когда они туда попадают? Мы также рассмотрим некоторые проблемы безопасности, связанные с отправкой данных формы.

- - - - - - - - - - - - -
Предварительные знания:Базовая компьютерная грамотность, понимание HTML и базовые знания по HTTP и программированию на стороне сервера.
Задача:Понять, что происходит при отправке данных формы, в том числе получить представление о том, как данные обрабатываются на стороне сервера.
- -

Куда отправляются данные?

- -

Здесь мы обсудим, что происходит с данными при отправке формы.

- -

О клиенсткой/серверной архитектуре

- -

WEB основан на очень простой клиент-серверной архитектуре, которую можно обобщить следующим образом: клиент (обычно веб-браузер) отправляет запрос на сервер (в основном веб-сервер, такой как Apache, Nginx, IIS, Tomcat, и т. д.), используя протокол HTTP. Сервер отвечает на запрос, используя тот же протокол.A basic schema of the Web client/server architecture

- -

На стороне клиента HTML-форма - это не более чем удобный способ настройки HTTP-запроса для отправки данных на сервер. Это позволяет пользователю предоставлять информацию для доставки в HTTP-запросе .

- -
-

Заметка: Для получения более полного представления о том, как работают клиент-серверные архитектуры, ознакомьтесь с модулем «Первые шаги в программировании на стороне сервера».

-
- -

На стороне клиента: определение способа отправки данных

- -

Элемент {{HTMLElement("form")}} определяет способ отправки данных. Все его атрибуты предназначены для того, чтобы вы могли настроить запрос на отправку, когда пользователь нажимает кнопку отправки. Двумя наиболее важными атрибутами являются  {{htmlattrxref("action","form")}}  и {{htmlattrxref("method","form")}}.

- -

Атрибут {{htmlattrxref("action","form")}}

- -

Этот атрибут определяет, куда отправляются данные. Его значение должно быть действительным URL. Если этот атрибут не указан, данные будут отправлены на URL-адрес страницы, содержащей форму.

- -

В этом примере данные отправляются на абсолютный URL — http://foo.com:

- -
<form action="http://foo.com">
- -

Здесь мы используем относительный URL - данные отправляются на другой URL на сервере:

- -
<form action="/somewhere_else">
- -

Если атрибуты не указаны, как показано ниже, данные из формы  {{HTMLElement("form")}} отправляются на ту же страницу, на которой размещается данная форма:

- -
<form>
- -

Многие старые страницы используют следующий синтаксис, чтобы указать, что данные должны быть отправлены на ту же страницу, которая содержит форму; это было необходимо, потому что до появления HTML5 атрибут {{htmlattrxref("action", "form")}} был обязательным. Это больше не нужно.

- -
<form action="#">
- -
-

Заметка: Можно указать URL, который использует протокол HTTPS (безопасный HTTP). Когда вы делаете это, данные шифруются вместе с остальной частью запроса, даже если сама форма размещается на небезопасной странице, доступ к которой осуществляется через HTTP. С другой стороны, если форма размещается на защищенной странице, но вы указываете небезопасный URL-адрес HTTP с атрибутом {{htmlattrxref("action","form")}}, все браузеры выдают пользователю предупреждение о безопасности при каждой попытке отправки данных, поскольку данные не шифруются.

-
- -

Атрибут {{htmlattrxref("method","form")}}

- -

Этот атрибут определяет способ отправки данных. Протокол HTTP предоставляет несколько способов выполнить запрос;  Данные HTML-формы могут передаваться несколькими различными способами, наиболее распространенными из которых являются метод GET и метод POST.

- -

Чтобы понять разницу между этими двумя методами, давайте вернёмся назад и рассмотрим, как работает HTTP. Каждый раз, когда вы хотите получить доступ к ресурсу в Интернете, браузер отправляет запрос на URL-адрес. HTTP-запрос состоит из двух частей: заголовка, который содержит набор глобальных метаданных о возможностях браузера, и тела, которое может содержать информацию, необходимую серверу для обработки конкретного запроса.

- -

Метод GET

- -

Метод GET - это метод, используемый браузером, который говорит серверу, что нужно отправить назад данный ресурс: «Эй, сервер, я хочу получить этот ресурс». В этом случае браузер отправляет пустое тело. Поскольку тело пустое, если форма отправляется с использованием данного метода, данные, отправляемые на сервер, добавляются к URL-адресу.

- -

Рассмотрим следующую форму:

- -
<form action="http://foo.com" method="get">
-  <div>
-    <label for="say">What greeting do you want to say?</label>
-    <input name="say" id="say" value="Hi">
-  </div>
-  <div>
-    <label for="to">Who do you want to say it to?</label>
-    <input name="to" id="to" value="Mom">
-  </div>
-  <div>
-    <button>Send my greetings</button>
-  </div>
-</form>
- -

Поскольку используется метод GET, вы увидите URL www.foo.com/?say=Hi&to=Mom, который появится в адресной строке браузера при отправке формы.

- -

Данные добавляются в URL как последовательность пар имя / значение. После того, как URL веб-адрес закончился, мы добавляем знак вопроса (?), за которым следуют пары имя / значение, каждая из которых разделена амперсандом (&). В этом случае мы передаем две части данных на сервер:

- - - -

HTTP-запрос имеет следующий вид:

- -
GET /?say=Hi&to=Mom HTTP/2.0
-Host: foo.com
- -
-

Заметка: Вы можете найти этот пример на GitHub — смотрите get-method.html (see it live also).

-
- -

Метод POST

- -

Метод POST немного отличается. Браузер использует этот метод для связи с сервером при запросе ответа с учётом данных, представленные в теле HTTP-запроса: «Эй, сервер, взгляни на эти данные и отправь мне соответствующий результат». Если форма отправляется с использованием этого метода, данные добавляются в тело HTTP-запроса.

- -

Давайте рассмотрим пример — это та же самая форма, которую мы рассматривали в разделе GET выше, но с атрибутом {{htmlattrxref("method","form")}}, установленным в post.

- -
<form action="http://foo.com" method="post">
-  <div>
-    <label for="say">What greeting do you want to say?</label>
-    <input name="say" id="say" value="Hi">
-  </div>
-  <div>
-    <label for="to">Who do you want to say it to?</label>
-    <input name="to" id="to" value="Mom">
-  </div>
-  <div>
-    <button>Send my greetings</button>
-  </div>
-</form>
- -

Когда форма отправляется с использованием метода POST, данные добавляются не к URL-адресу, а включаются в тело запроса. HTTP-запрос имеет следующий вид:

- -
POST / HTTP/2.0
-Host: foo.com
-Content-Type: application/x-www-form-urlencoded
-Content-Length: 13
-
-say=Hi&to=Mom
- -

Заголовок Content-Length указывает размер тела, а заголовок Content-Type указывает тип данных, отправляемых на сервер. Мы обсудим эти заголовки позже.

- -
-

Заметка: Вы можете найти этот пример на GitHub — смотрите post-method.html (see it live also).

-
- -

Просмотр HTTP-запросов

- -

HTTP-запросы никогда не отображаются пользователю (если вы хотите их видеть, Вам нужно использовать такие инструменты, как Firefox Network Monitor или Chrome Developer Tools). Например, данные формы можно увидеть на вкладке Сеть (Network) в Chrome следующим образом (после отправки формы):

- -
    -
  1. Нажмите F12
  2. -
  3. Выберите Network
  4. -
  5. Выберите "All"
  6. -
  7. Выберите "foo.com" во вкладке "Name"
  8. -
  9. Выберите "Headers"
  10. -
- -

Затем вы можете получить данные формы, как показано на рисунке ниже.

- -

- -

Единственное, что отображается пользователю — вызываемый URL. Как упоминалось раннее, запрос с методом GET позволит пользователю увидеть информацию из запроса в URL, а запрос с методом POST не позволит. Две причины, почему это может быть важно:

- -
    -
  1. Если необходимо отправить пароль (или любую другую важную информацию), никогда не используйте метод GET, иначе рискуете отобразить эту информацию в URL-строке, что небезопасно.
  2. -
  3. Если необходимо отправить большой объем информации, POST-метод является предпочтительным, так как некоторые браузеры ограничивают длину URL. К тому же, многие сервера так же ограничивают длину обрабатываемых URL.
  4. -
- -

На стороне сервера: получение данных

- -

Какой бы HTTP вы не выбрали, сервер возвращает строку, которая будет последовательно проанализирована для получения данных в формате листа с парами ключ/значение. Способ получения доступа к этому листу зависит от платформы разработки или особенностей фреймворка, который вы можете использовать. Технологии, которые вы используете, определяют, как обрабатываются скопированные ключи. Часто, приоритетным является последнее полученное значение для данного ключа.

- -

Пример: Чистый PHP

- -

PHP предлагает несколько глобальных объектов для доступа к данным. Например, вы используете POST-метод, в приведенном ниже примере данные просто получаются и показываются пользователю. Разумеется, как использовать данные — решать только вам. Вы можете отобразить эти данные, поместить в базу данных, отправить по почте или передать эти данные куда-либо еще.

- -
<?php
-  // The global $_POST variable allows you to access the data sent with the POST method by name
-  // To access the data sent with the GET method, you can use $_GET
-  $say = htmlspecialchars($_POST['say']);
-  $to  = htmlspecialchars($_POST['to']);
-
-  echo  $say, ' ', $to;
-?>
- -

Пример показывает страницу с данными, которые мы отправили. Вы можете посмотреть это в действии в нашем файле с примером: php-example.html — который содержит те же данные, которые вы видели раньше:  method : post и action из php-example.php. Когда данные переданы на отправку (submit), они переданы в форму php-example.php, которая содержит PHP код из примера выше. Когда код будет выполнен, браузер выведет (output) обработанное сообщение: Hi Mom.

- -

- -
-

Примечание: Этот пример не будет работать, когда вы загружаете его в браузер локально — браузер не может интерпретировать PHP код, после отправки данных из формы, браузер просто предложит загрузить PHP файл. Чтобы пример заработал, необходимо отправить его на PHP сервер. Для тестирования PHP на локальных серверах можете пробовать MAMP (Mac and Windows) и/или AMPPS (Mac, Windows, Linux).

-
- -

Пример: Python

- -

Этот пример показывает, как вы можете использовать Python для решения той же задачи — отобразить отправленные данные на странице. В этом примере используется Flask framework для визуализации шаблонов, поддерживающих форму отправки данных (смотри python-example.py).

- -
from flask import Flask, render_template, request
-
-app = Flask(__name__)
-
-@app.route('/', methods=['GET', 'POST'])
-def form():
-    return render_template('form.html')
-
-@app.route('/hello', methods=['GET', 'POST'])
-def hello():
-    return render_template('greeting.html', say=request.form['say'], to=request.form['to'])
-
-if __name__ == "__main__":
-    app.run()
- -

Два шаблона из коде выше взаимодействуют так:

- - - -
-

Примечание: Опять же, этот код не будет работать, если вы просто попробуете загрузить его прямо в браузер. Python работает немного иначе, чем PHP — чтобы запустить этот код, нужно установить Python/PIP, потом установить Flask используя команду: pip3 install flask. После этого, вы сможете запустить файл из примера, используя команду: python3 python-example.py, потом открыть localhost:5000 в своем браузере.

-
- -

Другие языки и фреймворки

- -

Существует множество других серверных технологий, которые вы можете использовать для работы с формами, включая языки Perl, Java, .Net, Ruby, и прочее. Выбирайте тот, который нравится больше. К тому же, использовать вышеупомянутые технологии непосредственно, без использования фреймворков, может быть сложно. Лучше использовать один из множества высококачественных фреймворков, таких как:

- - - -

Стоит отметить, что использование фреймворков и работа с формами - это не всегда легко. Но это намного легче, чем пытаться написать аналогичный функционал с нуля, и это определенно сэкономит время. 

- -
-

Примечание: Обучению фреймворкам и работе с серверами не входит в рамки этой статьи.  Если хотите узнать больше, ссылки ниже помогут в этом. 

-
- -

Особый случай: отправка файлов

- -

Отправка файлов с помощью форм HTML —  это особый случай. Файлы — это бинарные данные или рассматриваются как таковые, в то время как все остальные — это текстовые данные. Поскольку HTTP — это текстовый протокол, есть особые требования для работы с бинарными данными.

- -

Атрибут {{htmlattrxref("enctype","form")}} 

- -

Этот атрибут позволяет конкретизировать значение в Content-Type HTTP заголовок, включенный в запрос, при генерировании отпавки формы. Этот заголовок очень важен, потому что указывает серверу, какой тип данных отправляется. По умолчанию это: application/x-www-form-urlencoded. На человеческом это значит: "Это форма с данными, которые были закодированы в URL параметры."

- -

Если хотите отправить файл, нужно сделать следующие три шага:

- - - -

Пример:

- -
<form method="post" enctype="multipart/form-data">
-  <div>
-    <label for="file">Choose a file</label>
-    <input type="file" id="file" name="myFile">
-  </div>
-  <div>
-    <button>Send the file</button>
-  </div>
-</form>
- -
-

Примечание: Некоторые браузеры поддерживают {{htmlattrxref("multiple","input")}} атрибут элемента {{HTMLElement("input")}} , который позволяет выбрать больше одного файла для загрузки, при использовании одного элемента <input> . То, как сервер работает с этими файлами, напрямую зависит от технологий, используемых на сервере. Как упоминалось ранее, использование фреймворков сделает вашу жизнь намного легче. 

-
- -
-

Предупреждение: Многие сервера имеют заданные ограничения на размер загружаемых файлов и запросы от пользователей, чтобы защититься от возможных злоупотреблений. Важно проверять эти ограничения у администратора сервера, прежде чем загружать файлы.

-
- -

Проблемы безопасности

- -

Каждый раз, когда вы отправляете данные на сервер, вы должны учитывать безопасность. HTML-формы являются наиболее распространенными векторами атак на серверы(места, где могут происходить атаки). Проблемы вытекают не из самих форм HTML, а из-за того, как сервер обрабатывает данные из этих форм.

- -

В зависимости от того, что вы делаете, вы можете столкнуться с некоторыми очень известными проблемами безопасности:

- -

XSS "Межсайтовый скриптинг" и CSRF "Подделка межсайтовых запросов"

- -

Межсайтовый скриптинг (XSS "Сross Site Request Forgery") и подделка межсайтовых запросов (CSRF "Cross-Site Scripting") - это распространенные типы атак, которые происходят при отображении данных после ответа сервера или другого пользователя.

- -

Межсайтовый скриптинг (XSS "Сross Site Request Forgery") позволяет злоумышленникам внедрить клиентский скрипт в веб-страницы, просматриваемые другими пользователями. Подделка межсайтовых запросов (CSRF "Cross-Site Scripting") может использоваться злоумышленниками для обхода средств контроля доступа, таких как одна и та же политика происхождения. Последствие от этих атак может варьироваться от мелких неудобств до значительного риска безопасности.

- -

CSRF-атаки аналогичны XSS-атакам в том, что они начинаются одинаково - с внедрения клиентского скрипта в веб-страницы - но их конечные цели разные. Злоумышленники CSRF пытаются назначить права пользователям с более высоким уровнем прав доступа(например, администратору сайта), чтобы выполнить действие, которое они не должны выполнять (например, отправка данных ненадежному пользователю). Атаки XSS используют доверие пользователя к веб-сайту, в то время как атаки CSRF используют доверие веб-сайта к пользователю.

- -

Чтобы предотвратить эти атаки, вы всегда должны проверять данные, которые пользователь отправляет на ваш сервер, и (если вам нужно отобразить их) стараться не отображать HTML-контент, предоставленный пользователем. Вместо этого вы должны обработать предоставленные пользователем данные, чтобы не отображать их слово в слово. Сегодня почти все платформы на рынке реализуют минимальный "фильтр", который удаляет элементы HTML {{HTMLElement ("script")}}, {{HTMLElement ("iframe")}} и {{HTMLElement ("object")}} полученных от любого пользователя. Это помогает снизить риск, но не исключает его полностью.

- -

SQL - вброс

- -

SQL -вброс представляет собой тип атак, при которых осуществляется попытка выполнения действия с базой данных, используемой целевым веб-сайтом. В этих случаях обычно осуществляется отправка SQL-запроса в надежде, что сервер выполнит этот запрос (обычно при попытке сервера приложения сохранить данные, отправляемые пользователем). Данный вид атак является одним из самых направленных атак на веб-сайты.

- -

Последствия могут быть ужасающими, начиная от потери данных и заканчивая утратой контроля над всей инфраструктурой веб-сайта за счет повышения привилегий. Это очень серьезная угроза, поэтому никогда не сохраняйте данные, отправляемые пользователем, без выполнения санитизации данных (например, с помощью mysqli_real_escape_string().

- -

Вброс HTTP-заголовка и email

- -

Эти виды атак могут проявляться, когда ваше приложение создает заголовки HTTP или электронные почтовые адреса на основании данных, введенных пользователем в форму. Такие атаки напрямую не повреждают сервер или пользовалей, однако создают уязвимость для таких угроз, как перехват сессии, или для фишинговых атак.

- -

Такие атаки являются самыми незаметными, но при этом могут превратить ваш сервер в зомби.

- -

Будьте параноиком: никогда не доверяйте вашим пользователям

- -

Как вы боретесь с такими угрозами? Этот вопрос выходит далеко за рамки данной статьи, но есть несколько общих правил, которые следует всегда соблюдать. Самое важное из них - никогда не доверяйте вашим пользователям, в том числе себе; даже проверенный пользователь может быть атакован.

- -

Все данные, поступающие на ваш сервер, необходимо проверять и санитизировать. Все и всегда. Без исключений.

- - - -

Соблюдая эти три правила, вы сможете избежать многих/большинства проблем. При этом следует помнить, что периодически необходимо проводить анализ защищенности, желательно квалифицированной сторонней организацией. Не считайте, что вы уже сталкивались со всеми возможными угрозами.

- -
-

Примечание: В статье Безопасность веб-сайта нашего раздела серверного обучения приведено подробное обсуждение упомянутых угроз и возможных способов их устранения.

-
- -

Заключение

- -

Как мы увидели, отправлять формы просто, однако защитить приложение может быть довольно трудно. Просто помните, что фронтенд разработчики не должны задавать модель безопасности для приложения. Да, как мы увидим далее, мы можем проверить данные на стороне клиента, однако сервер не может доверять этой проверке, потому что он никогда не может по-настоящему узнать что происходит на стороне клиента.

- -

См. также

- -

Если вы хотите узнать больше об обеспечении безопасности веб-приложений, вы можете использовать следущие источники информации:

- - - -

{{PreviousMenuNext("Learn/HTML/Forms/The_native_form_widgets", "Learn/HTML/Forms/Form_validation", "Learn/HTML/Forms")}}

- -

В этом модуле

- - diff --git "a/files/ru/learn/html/forms/\321\201\321\202\320\260\320\275\320\264\320\260\321\200\321\202\320\275\321\213\320\265_\320\262\320\270\320\264\320\266\320\265\321\202\321\213_\321\204\320\276\321\200\320\274/index.html" "b/files/ru/learn/html/forms/\321\201\321\202\320\260\320\275\320\264\320\260\321\200\321\202\320\275\321\213\320\265_\320\262\320\270\320\264\320\266\320\265\321\202\321\213_\321\204\320\276\321\200\320\274/index.html" deleted file mode 100644 index eae3fbb32d..0000000000 --- "a/files/ru/learn/html/forms/\321\201\321\202\320\260\320\275\320\264\320\260\321\200\321\202\320\275\321\213\320\265_\320\262\320\270\320\264\320\266\320\265\321\202\321\213_\321\204\320\276\321\200\320\274/index.html" +++ /dev/null @@ -1,690 +0,0 @@ ---- -title: Стандартные виджеты форм -slug: Learn/HTML/Forms/Стандартные_виджеты_форм -translation_of: Learn/Forms/Basic_native_form_controls ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/HTML/Forms/How_to_structure_an_HTML_form", "Learn/HTML/Forms/Sending_and_retrieving_form_data", "Learn/HTML/Forms")}}
- -

Сейчас мы детально изучим возможности различных виджетов форм, посмотрим, какие функции доступны для получения информации в различных представлениях. Это исчерпывающая статья, описывающая все доступные стандартные виджеты форм.

- - - - - - - - - - - - -
Требования:Базовая компьютерная грамотность, базовое понимание HTML.
Цель:Понять, какие типы стандартных виджетов форм доступны в браузерах для сбора информации, как внедрять их, используя HTML.
- -

Сейчас мы сосредоточимся на виджетах форм, встроенных в браузеры, но поскольку формы HTML остаюстся несколько ограниченными и особенности их реализации различаются для разных браузеров, веб-разработчики иногда создают собственные виджеты форм - прочтите статью Как создать собственную форму позже в данном модуле для более подробного изучения.

- -
-

Note: Большая часть признаков обсуждаемых в этой статье имеют широкую поддержку в браузерах; мы отметим исключения из этого правила. Если вы хотите больше точных сведений, вам следует обратиться к HTML forms element reference, и в частости к нашей обширной ссылке <input> types.

-
- -

Стандартные атрибуты

- -

Многие элементы, используемые для определения виджетов форм, имеют собственные атрибуты. Однако, существует набор атрибутов, общих для всех элементов формы, которые предоставляют вам контроль над их виджетами. Вот список этих общих атрибутов:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Attribute nameDefault valueDescription
autofocus(false)Этот атрибут логического типа позволяет вам определить, должен ли элемент автоматически попадать в фокус при загрузке страницы, пока пользователь не изменит это, например, печатая в другом виджете. Этот атрибут может явно определяться только для одного элемента в документе, ассоциированного с формой.
disabled(false)Этот атрибут логического типа определяет, может ли пользователь взаимодействовать с элементом. Если этот атрибут не определён, то элемент наследует его значение от элемента-родителя. Если атрибут не определён, то по умолчанию пользователь может взаимодействовать с элементом.
formЭлемент формы, с которым ассоциирован виджет. Значением данного атрибута должен быть атрибут id элемента {{HTMLElement("form")}}  в том же документе. Теоретически, это позволяет вам помещать определение виджета за рамками элемента {{HTMLElement("form")}}. На практике, однако, не существует браузеров, поддерживающих данную функцию.
nameНазвание элемента; передаётся вместе с данными формы.
valueНачальное значение элемента.
- -

Поля ввода текста

- -

Текстовые поля {{htmlelement("input")}}  являются самыми базовыми виджетами форм. Эти поля наиболее удобны для пользовательского ввода различной информации. Однако, некоторые текстовые поля отличаются от данного и используются для специфических нужд. Мы уже видели нескольк простых примеров.

- -
-

Note: HTML form text fields are simple plain text input controls. This means that you cannot use them to perform rich editing (bold, italic, etc.). All rich text editors you'll encounter out there are custom widgets created with HTML, CSS, and JavaScript.

-
- -

Все текстовые поля имеют общие атрибуты:

- - - -
-

Note: The {{htmlelement("input")}} element is special because it can be almost anything. By simply setting its type attribute, it can change radically, and it is used for creating most types of form widget including single line text fields, controls without text input, time and date controls, and buttons. However, there are some exceptions, like {{htmlelement("textarea")}} for multi-line inputs. Take careful note of these as you read the article.

-
- -

Однострочные текстовые поля

- -

Однострочные текстовые поля создаются с использованием элемента {{HTMLElement("input")}}  чей атрибут {{htmlattrxref("type","input")}} имеет значение text (если вы не поставите другое значение атрибута {{htmlattrxref("type","input")}}, text является значением по умолчанию). Значение text для этого атрибута является возвратным, если значение которое вы определили для {{htmlattrxref("type","input")}} неизвестно браузеру (например, если вы определили type="date" а браузер не поддерживает выбор даты).

- -
-

Note: Вы можете найти примеры всех типов однострочных текстовых полей на GitHub at single-line-text-fields.html (see it live also).

-
- -

Пример базового одностраничного текстового поля:

- -
<input type="text" id="comment" name="comment" value="I'm a text field">
- -

Однострочное текстовое поле имеет только одно настоящее ограничение: если вы вводите текст с разрывами строки, браузер удаляет эти разрывы строк перед отправкой данных.

- -

Screenshots of single line text fields on several platforms.

- -

HTML5 enhances the basic single line text field by adding special values for the {{htmlattrxref("type","input")}} attribute. Those values still turn an {{HTMLElement("input")}} element into a single line text field but they add a few extra constraints and features to the field.

- -

E-mail address field

- -

Этот тип поля устонавливается со значеним email для атрибута {{htmlattrxref("type","input")}}:

- -
<input type="email" id="email" name="email" multiple>
- -

Когда используется этот type, пользователь должен ввести в поле валидный адрес электронной почты; любое другое содержание будет отображено браузером при отправке формы как ошибка. Заметьте, что это проверка ошибок на стороне клиента, выполняемая браузером:

- -

An invalid email input showing the message Please enter an email address.

- -

It's also possible to let the user type several e-mail addresses into the same input (separated by commas) by including the {{htmlattrxref("multiple","input")}} attribute.

- -

On some devices (especially on mobile), a different virtual keypad might be presented that is more suitable for entering email addresses.

- -
-

Note: You can find out more about form validation in the article Form data validation.

-
- -

Password field

- -

This type of field is set using the value password for the {{htmlattrxref("type","input")}} attribute:

- -
<input type="password" id="pwd" name="pwd">
- -

It doesn't add any special constraints to the entered text, but it does obscure the value entered into the field (e.g. with dots or asterisks) so it can't be read by others.

- -

Keep in mind this is just a user interface feature; unless you submit your form securely, it will get sent in plain text, which is bad for security — a malicious party could intercept your data and steal passwords, credit card details, or whatever else you've submitted. The best way to protect users from this is to host any pages involving forms over a secure connection (i.e. at an https:// ... address), so the data is encrypted before it is sent.

- -

Modern browsers recognize the security implications of sending form data over an insecure connection, and have implemented warnings to deter users from using insecure forms. For more information on what Firefox implements, see Insecure passwords.

- -

Search field

- -

This type of field is set by using the value search for the {{htmlattrxref("type","input")}} attribute:

- -
<input type="search" id="search" name="search">
- -

The main difference between a text field and a search field is how the browser styles it — often, search fields are rendered with rounded corners, and/or given an "x" to press to clear the entered value. However, there is another added feature worth noting: their values can be automatically saved to be auto completed across multiple pages on the same site.

- -

Screenshots of search fields on several platforms.

- -

Phone number field

- -

This type of field is set using tel as the value of the {{htmlattrxref("type","input")}} attribute:

- -
<input type="tel" id="tel" name="tel">
- -

Due to the wide variety of phone number formats around the world, this type of field does not enforce any constraints on the value entered by a user (this can include letters, etc.). This is primarily a semantic difference, although on some devices (especially on mobile), a different virtual keypad might be presented that is more suitable for entering phone numbers.

- -

URL field

- -

This type of field is set using the value url for the {{htmlattrxref("type","input")}} attribute:

- -
<input type="url" id="url" name="url">
- -

It adds special validation constraints to the field, with the browser reporting an error if invalid URLs are entered.

- -
Note: Just because the URL is well-formed doesn't necessarily mean that it refers to a location that actually exists.
- -
-

Note: Fields that have special constraints and are in error prevent the form from being sent; in addition, they can be styled so as to make the error clear. We will discuss this in detail in the article: Data form validation.

-
- -

Multi-line text fields

- -

A multi-line text field is specified using a {{HTMLElement("textarea")}} element, rather than using the {{HTMLElement("input")}} element.

- -
<textarea cols="30" rows="10"></textarea>
- -

The main difference between a textarea and a regular single line text field is that users are allowed to type text that includes hard line breaks (i.e. pressing return).

- -

Screenshots of multi-lines text fields on several platforms.

- -
-

Note: You can find an example of a multi-line text field on GitHub at multi-line-text-field.html (see it live also). Have a look at it, and notice how in most browsers, the text area is given a drag handle on the bottom right to allow the user to resize it. This resizing ability can be turned off by setting the text area's {{cssxref("resize")}} property to none using CSS.

-
- -

{{htmlelement("textarea")}} also accepts a few extra attributes to control its rendering across several lines (in addition to several others):

- - - - - - - - - - - - - - - - - - - - - - - - - - - -
Attributes for the {{HTMLElement("textarea")}} element
Attribute nameDefault valueDescription
{{htmlattrxref("cols","textarea")}}20The visible width of the text control, in average character widths.
{{htmlattrxref("rows","textarea")}}The number of visible text lines for the control.
{{htmlattrxref("wrap","textarea")}}softIndicates how the control wraps text. Possible values are: hard or soft
- -

Note that the {{HTMLElement("textarea")}} element is written a bit differently from the {{HTMLElement("input")}} element. The {{HTMLElement("input")}} element is an empty element, which means that it cannot contain any child elements. On the other hand, the {{HTMLElement("textarea")}} element is a regular element that can contain text content children.

- -

There are two key related points to note here:

- - - - - -

Drop-down widgets are a simple way to let users select one of many options without taking up much space in the user interface. HTML has two forms of drop down content: the select box, and autocomplete box. In both cases the interaction is the same — once the control is activated, the browser displays a list of values the user can select between.

- -
-

Note: You can find examples of all the drop-down box types on GitHub at drop-down-content.html (see it live also).

-
- -

Select box

- -

A select box is created with a {{HTMLElement("select")}} element with one or more {{HTMLElement("option")}} elements as its children, each of which specifies one of its possible values.

- -
<select id="simple" name="simple">
-  <option>Banana</option>
-  <option>Cherry</option>
-  <option>Lemon</option>
-</select>
- -

If required, the default value for the select box can be set using the {{htmlattrxref("selected","option")}} attribute on the desired {{HTMLElement("option")}} element — this option is then preselected when the page loads. The {{HTMLElement("option")}} elements can also be nested inside {{HTMLElement("optgroup")}} elements to create visually associated groups of values:

- -
<select id="groups" name="groups">
-  <optgroup label="fruits">
-    <option>Banana</option>
-    <option selected>Cherry</option>
-    <option>Lemon</option>
-  </optgroup>
-  <optgroup label="vegetables">
-    <option>Carrot</option>
-    <option>Eggplant</option>
-    <option>Potato</option>
-  </optgroup>
-</select>
- -

Screenshots of single line select box on several platforms.

- -

If an {{HTMLElement("option")}} element is set with a value attribute, that attribute's value is sent when the form is submitted. If the value attribute is omitted, the content of the {{HTMLElement("option")}} element is used as the select box's value.

- -

On the {{HTMLElement("optgroup")}} element, the label attribute is displayed before the values, but even if it looks somewhat like an option, it is not selectable.

- -

Multiple choice select box

- -

By default, a select box only lets the user select a single value. By adding the {{htmlattrxref("multiple","select")}} attribute to the {{HTMLElement("select")}} element, you can allow users to select several values, by using the default mechanism provided by the operating system (e.g. holding down Cmd/Ctrl and clicking multiple values).

- -

Note: In the case of multiple choice select boxes, the select box no longer displays the values as drop-down content — instead, they are all displayed at once in a list.

- -
<select multiple id="multi" name="multi">
-  <option>Banana</option>
-  <option>Cherry</option>
-  <option>Lemon</option>
-</select>
- -

Screenshots of multi-lines select box on several platforms.

- -
Note: All browsers that support the {{HTMLElement("select")}} element also support the {{htmlattrxref("multiple","select")}} attribute on it.
- -

Autocomplete box

- -

You can provide suggested, automatically-completed values for form widgets using the {{HTMLElement("datalist")}} element with some child {{HTMLElement("option")}} elements to specify the values to display.

- -

The data list is then bound to a text field (usually an <input> element) using the {{htmlattrxref("list","input")}} attribute.

- -

Once a data list is affiliated with a form widget, its options are used to auto-complete text entered by the user; typically, this is presented to the user as a drop-down box listing possible matches for what they've typed into the input.

- -
<label for="myFruit">What's your favorite fruit?</label>
-<input type="text" name="myFruit" id="myFruit" list="mySuggestion">
-<datalist id="mySuggestion">
-  <option>Apple</option>
-  <option>Banana</option>
-  <option>Blackberry</option>
-  <option>Blueberry</option>
-  <option>Lemon</option>
-  <option>Lychee</option>
-  <option>Peach</option>
-  <option>Pear</option>
-</datalist>
- -
Note: According to the HTML specification, the {{htmlattrxref("list","input")}} attribute and the {{HTMLElement("datalist")}} element can be used with any kind of widget requiring a user input. However, it is unclear how it should work with controls other than text (color or date for example), and different browsers behave differently from case to case. Because of that, be cautious using this feature with anything but text fields.
- -
Screenshots of datalist on several platforms.
- -
- -

Datalist support and fallbacks

- -

The  {{HTMLElement("datalist")}} element is a very recent addition to HTML forms, so browser support is a bit more limited than what we saw earlier. Most notably, it isn't supported in IE versions below 10, and Safari still doesn't support it at the time of writing.

- -

To handle this, here is a little trick to provide a nice fallback for those browsers:

- -
<label for="myFruit">What is your favorite fruit? (With fallback)</label>
-<input type="text" id="myFruit" name="fruit" list="fruitList">
-
-<datalist id="fruitList">
-  <label for="suggestion">or pick a fruit</label>
-  <select id="suggestion" name="altFruit">
-    <option>Apple</option>
-    <option>Banana</option>
-    <option>Blackberry</option>
-    <option>Blueberry</option>
-    <option>Lemon</option>
-    <option>Lychee</option>
-    <option>Peach</option>
-    <option>Pear</option>
-  </select>
-</datalist>
-
- -

Browsers that support the {{HTMLElement("datalist")}} element will ignore all the elements that are not {{HTMLElement("option")}} elements and will work as expected. On the other hand, browsers that do not support the {{HTMLElement("datalist")}} element will display the label and the select box. Of course, there are other ways to handle the lack of support for the {{HTMLElement("datalist")}} element, but this is the simplest (others tend to require JavaScript).

- - - - - - - - - - - - -
Safari 6Screenshot of the datalist element fallback with Safari on Mac OS
Firefox 18Screenshot of the datalist element with Firefox on Mac OS
- -

Checkable items

- -

Checkable items are widgets whose state you can change by clicking on them. There are two kinds of checkable item: the check box and the radio button. Both use the {{htmlattrxref("checked","input")}} attribute to indicate whether the widget is checked by default or not.

- -

It's worth noting that these widgets do not behave exactly like other form widgets. For most form widgets, once the form is submitted all widgets that have a {{htmlattrxref("name","input")}} attribute are sent, even if no value has been filled out. In the case of checkable items, their values are sent only if they are checked. If they are not checked, nothing is sent, not even their name.

- -
-

Note: You can find the examples from this section on GitHub as checkable-items.html (see it live also).

-
- -

For maximum usability/accessibility, you are advised to surround each list of related items in a {{htmlelement("fieldset")}}, with a {{htmlelement("legend")}} providing an overall description of the list.  Each individual pair of {{htmlelement("label")}}/{{htmlelement("input")}} elements should be contained in its own list item (or similar). This is shown in the examples. 

- -

You also need to provide values for these kinds of inputs inside the value attribute if you want them to be meaningful — if no value is provided, check boxes and radio buttons are given a value of on.

- -

Check box

- -

A check box is created using the {{HTMLElement("input")}} element with its {{htmlattrxref("type","input")}} attribute set to the value checkbox.

- -
<input type="checkbox" checked id="carrots" name="carrots" value="carrots">
-
- -

Including the checked attribute makes the checkbox checked automatically when the page loads.

- -

Screenshots of check boxes on several platforms.

- -

Radio button

- -

A radio button is created using the {{HTMLElement("input")}} element with its {{htmlattrxref("type","input")}} attribute set to the value radio.

- -
<input type="radio" checked id="soup" name="meal">
- -

Several radio buttons can be tied together. If they share the same value for their {{htmlattrxref("name","input")}} attribute, they will be considered to be in the same group of buttons. Only one button in a given group may be checked at the same time; this means that when one of them is checked all the others automatically get unchecked. When the form is sent, only the value of the checked radio button is sent. If none of them are checked, the whole pool of radio buttons is considered to be in an unknown state and no value is sent with the form.

- -
<fieldset>
-  <legend>What is your favorite meal?</legend>
-  <ul>
-    <li>
-      <label for="soup">Soup</label>
-      <input type="radio" checked id="soup" name="meal" value="soup">
-    </li>
-    <li>
-      <label for="curry">Curry</label>
-      <input type="radio" id="curry" name="meal" value="curry">
-    </li>
-    <li>
-      <label for="pizza">Pizza</label>
-      <input type="radio" id="pizza" name="meal" value="pizza">
-    </li>
-  </ul>
-</fieldset>
- -

Screenshots of radio buttons on several platforms.

- -

Buttons

- -

Within HTML forms, there are three kinds of button:

- -
-
Submit
-
Sends the form data to the server.
-
Reset
-
Resets all form widgets to their default values.
-
Anonymous
-
Buttons that have no automatic effect but can be customized using JavaScript code. If you omit the type attribute, this is the default value.
-
- -
-

Note: You can find the examples from this section on GitHub as button-examples.html (see it live also).

-
- -

A button is created using a {{HTMLElement("button")}} element or an {{HTMLElement("input")}} element. It's the value of the {{htmlattrxref("type","input")}} attribute that specifies what kind of button is displayed:

- -

submit

- -
<button type="submit">
-    This a <br><strong>submit button</strong>
-</button>
-
-<input type="submit" value="This is a submit button">
- -

reset

- -
<button type="reset">
-    This a <br><strong>reset button</strong>
-</button>
-
-<input type="reset" value="This is a reset button">
- -

anonymous

- -
<button type="button">
-    This an <br><strong>anonymous button</strong>
-</button>
-
-<input type="button" value="This is an anonymous button">
- -

Buttons always behave the same whether you use a {{HTMLElement("button")}} element or an {{HTMLElement("input")}} element. There are, however, some notable differences:

- - - -

Screenshots of buttons on several platforms.

- -

Technically speaking, there is almost no difference between a button defined with the {{HTMLElement("button")}} element or the {{HTMLElement("input")}} element. The only noticeable difference is the label of the button itself. Within an {{HTMLElement("input")}} element, the label can only be character data, whereas in a {{HTMLElement("button")}} element, the label can be HTML, so it can be styled accordingly.

- -

Advanced form widgets

- -

In this section we cover those widgets that let users input complex or unusual data. This includes exact or approximate numbers, dates and times, or colors.

- -
-

Note: You can find the examples from this section on GitHub as advanced-examples.html (see it live also).

-
- -

Numbers

- -

Widgets for numbers are created with the {{HTMLElement("input")}} element, with its {{htmlattrxref("type","input")}} attribute set to the value number. This control looks like a text field but allows only floating-point numbers, and usually provides some buttons to increase or decrease the value of the widget.

- -

It's also possible to:

- - - -

Example

- -
<input type="number" name="age" id="age" min="1" max="10" step="2">
- -

This creates a number widget whose value is restricted to any value between 1 and 10, and whose increase and decrease buttons change its value by 2.

- -

number inputs are not supported in versions of Internet Explorer below 10.

- -

Sliders

- -

Another way to pick a number is to use a slider. Visually speaking, sliders are less accurate than text fields, therefore they are used to pick a number whose exact value is not necessarily important.

- -

A slider is created by using the {{HTMLElement("input")}} with its {{htmlattrxref("type","input")}} attribute set to the value range. It's important to properly configure your slider; to that end, it's highly recommended that you set the {{htmlattrxref("min","input")}}, {{htmlattrxref("max","input")}}, and {{htmlattrxref("step","input")}} attributes.

- -

Example

- -
<input type="range" name="beans" id="beans" min="0" max="500" step="10">
- -

This example creates a slider whose value may range between 0 and 500, and whose increment/decrement buttons change the value by +10 and -10.

- -

One problem with sliders is that they don't offer any kind of visual feedback as to what the current value is. You need to add this yourself with JavaScript, but this is relatively easy to do. In this example we add an empty {{htmlelement("span")}} element, in which we will write the current value of the slider, updating it as it is changed.

- -
<label for="beans">How many beans can you eat?</label>
-<input type="range" name="beans" id="beans" min="0" max="500" step="10">
-<span class="beancount"></span>
- -

This can be implemented using some simple JavaScript:

- -
var beans = document.querySelector('#beans');
-var count = document.querySelector('.beancount');
-
-count.textContent = beans.value;
-
-beans.oninput = function() {
-  count.textContent = beans.value;
-}
- -

Here we store references to the range input and the span in two variables, then we immediately set the span's textContent to the current value of the input. Finally, we set up an oninput event handler so that every time the range slider is moved, the span textContent is updated to the new input value.

- -

range inputs are not supported in versions of Internet Explorer below 10.

- -

Date and time picker

- -

Gathering date and time values has traditionally been a nightmare for web developers. HTML5 brings some enhancements here by providing a special control to handle this specific kind of data.

- -

A date and time control is created using the {{HTMLElement("input")}} element and an appropriate value for the {{htmlattrxref("type","input")}} attribute, depending on whether you wish to collect dates, times, or both.

- -

datetime-local

- -

This creates a widget to display and pick a date with time, but without any specific time zone information.

- -
<input type="datetime-local" name="datetime" id="datetime">
- -

month

- -

This creates a widget to display and pick a month with a year.

- -
<input type="month" name="month" id="month">
- -

time

- -

This creates a widget to display and pick a time value.

- -
<input type="time" name="time" id="time">
- -

week

- -

This creates a widget to display and pick a week number and its year.

- -
<input type="week" name="week" id="week">
- -

All date and time control can be constrained using the {{htmlattrxref("min","input")}} and {{htmlattrxref("max","input")}} attributes.

- -
<label for="myDate">When are you available this summer?</label>
-<input type="date" name="myDate" min="2013-06-01" max="2013-08-31" id="myDate">
- -

Warning — The date and time widgets don't have the deepest support. At the moment, Chrome, Edge, Firefox, and Opera support them well, but there is no support in Internet Explorer and Safari has patchy support.

- -

Color picker

- -

Colors are always a bit difficult to handle. There are many ways to express them: RGB values (decimal or hexadecimal), HSL values, keywords, etc. The color widget lets users pick a color in both textual and visual ways.

- -

A color widget is created using the {{HTMLElement("input")}} element with its {{htmlattrxref("type","input")}} attribute set to the value color.

- -
<input type="color" name="color" id="color">
- -

Warning — Color widget support it currently not very good. There is no support in Internet Explorer, and Safari currently doesn't support it either. The other major browsers do support it.

- -

Other widgets

- -

There are a few other widgets that cannot be easily classified due to their very specific behaviors, but which are still very useful.

- -
-

Note: You can find the examples from this section on GitHub as other-examples.html (see it live also).

-
- -

File picker

- -

HTML forms are able to send files to a server; this specific action is detailed in the article Sending and retrieving form data. The file picker widget is how the user can choose one or more files to send.

- -

To create a file picker widget, you use the {{HTMLElement("input")}} element with its {{htmlattrxref("type","input")}} attribute set to file. The types of files that are accepted can be constrained using the {{htmlattrxref("accept","input")}} attribute. In addition, if you want to let the user pick more than one file, you can do so by adding the {{htmlattrxref("multiple","input")}} attribute.

- -

Example

- -

In this example, a file picker is created that requests graphic image files. The user is allowed to select multiple files in this case.

- -
<input type="file" name="file" id="file" accept="image/*" multiple>
- -

Hidden content

- -

It's sometimes convenient for technical reasons to have pieces of data that are sent with a form but not displayed to the user. To do this, you can add an invisible element in your form. Use an {{HTMLElement("input")}} with its {{htmlattrxref("type","input")}} attribute set to the value hidden.

- -

If you create such an element, it's required to set its name and value attributes:

- -
<input type="hidden" id="timestamp" name="timestamp" value="1286705410">
- -

Image button

- -

The image button control is one which is displayed exactly like an {{HTMLElement("img")}} element, except that when the user clicks on it, it behaves like a submit button (see above).

- -

An image button is created using an {{HTMLElement("input")}} element with its {{htmlattrxref("type","input")}} attribute set to the value image. This element supports exactly the same set of attributes as the {{HTMLElement("img")}} element, plus all the attributes supported by other form buttons.

- -
<input type="image" alt="Click me!" src="my-img.png" width="80" height="30" />
- -

If the image button is used to submit the form, this widget doesn't submit its value; instead the X and Y coordinates of the click on the image are submitted (the coordinates are relative to the image, meaning that the upper-left corner of the image represents the coordinate 0, 0). The coordinates are sent as two key/value pairs:

- - - -

So for example when you click on the image of this widget, you are sent to a URL like the following:

- -
http://foo.com?pos.x=123&pos.y=456
- -

This is a very convenient way to build a "hot map". How these values are sent and retrieved is detailed in the Sending and retrieving form data article.

- -

Meters and progress bars

- -

Meters and progress bars are visual representations of numeric values.

- -

Progress

- -

A progress bar represents a value that changes over time up to a maximum value specified by the {{htmlattrxref("max","progress")}} attribute. Such a bar is created using a {{ HTMLElement("progress")}} element.

- -
<progress max="100" value="75">75/100</progress>
- -

This is for implementing anything requiring progress reporting, such as the percentage of total files downloaded, or the number of questions filled in on a questionnaire.

- -

The content inside the {{HTMLElement("progress")}} element is a fallback for browsers that don't support the element and for assistive technologies to vocalize it.

- -

Meter

- -

A meter bar represents a fixed value in a range delimited by a {{htmlattrxref("min","meter")}} and a {{htmlattrxref("max","meter")}} value. This value is visualy rendered as a bar, and to know how this bar looks, we compare the value to some other set values:

- - - -

All browsers that implement the {{HTMLElement("meter")}} element use those values to change the color of the meter bar:

- - - -

Such a bar is created using a {{HTMLElement("meter")}} element. This is for implementing any kind of meter, for example a bar showing total space used on a disk, which turns red when it starts to get full.

- -
<meter min="0" max="100" value="75" low="33" high="66" optimum="50">75</meter>
- -

The content inside the {{HTMLElement("meter")}} element is a fallback for browsers that don't support the element and for assistive technologies to vocalize it.

- -

Support for progress and meter is fairly good — there is no support in Internet Explorer, but other browsers support it well.

- -

Conclusion

- -

As you'll have seen above, there are a lot of different types of available form elements — you don't need to remember all of these details at once, and can return to this article as often as you like to check up on details.

- -

See also

- -

To dig into the different form widgets, there are some useful external resources you should check out:

- - - -

{{PreviousMenuNext("Learn/HTML/Forms/How_to_structure_an_HTML_form", "Learn/HTML/Forms/Sending_and_retrieving_form_data", "Learn/HTML/Forms")}}

- -

In this module

- - diff --git a/files/ru/learn/html/howto/author_fast-loading_html_pages/index.html b/files/ru/learn/html/howto/author_fast-loading_html_pages/index.html new file mode 100644 index 0000000000..f34fe049f5 --- /dev/null +++ b/files/ru/learn/html/howto/author_fast-loading_html_pages/index.html @@ -0,0 +1,204 @@ +--- +title: Tips for authoring fast-loading HTML pages +slug: Web/Guide/HTML/Tips_for_authoring_fast-loading_HTML_pages +translation_of: Learn/HTML/Howto/Author_fast-loading_HTML_pages +--- +

Эти советы основаны на общих знаниях и экспериментах.

+ +

Оптимизированная веб-страница не только обеспечивает более отзывчивый сайт для ваших посетителей, но также снижает нагрузку на ваши веб-серверы и интернет-соединения. Это может иметь решающее значение для сайтов с большим объемом или сайтов, которые имеют всплеск трафика из-за необычных обстоятельств, таких как последние новости

+ +

Оптимизация производительности загрузки страницы нужна не только для контента, который будет просматриваться узкополосным модемом или посетителями мобильных устройств. Это так же важно для широкополосного контента и может привести к значительным улучшениям даже для ваших посетителей с самыми быстрыми подключениями.

+ +

Советы

+ +

Уменьшайте вес страницы

+ +

Веб-страницы - безусловно, самый важный фактор в производительности загрузки страницы.

+ +

Уменьшение веса страницы за счет устранения ненужных пробелов и комментариев, широко известна как минимизация, и перемещая встроенный скрипт и CSS во внешние файлы, можно улучшить производительность загрузки с минимальными потребностями в других изменениях в структуре страницы.

+ +

Такие инструменты, как HTML Tidy , могут автоматически убирать начальные пробелы и лишние пустые строки из допустимого источника HTML. Другие инструменты могут «сжимать» JavaScript, переформатируя источник или запутывая источник и заменяя длинные идентификаторы на более короткие версии

+ +

Минимизируйте количество файлов

+ +

Уменьшение количества файлов, на которые есть ссылки на веб-странице, уменьшает количество HTTP-соединений, необходимых для загрузки страницы, тем самым сокращая время отправки этих запросов и получения их ответов.

+ +

В зависимости от настроек кэша браузера он может отправить запрос с заголовком If-Modified-Since для каждого ссылочного файла, спрашивая, был ли файл изменен с момента последней загрузки. Слишком много времени, затрачиваемое на запрос времени последнего изменения указанных файлов, может задержать первоначальное отображение веб-страницы, так как браузер должен проверить время изменения каждого из этих файлов перед отображением страницы.

+ +

Если вы часто используете фоновые изображения в своем CSS, вы можете уменьшить количество запросов на поиск HTTP, объединив изображения в одно, называемое спрайтом изображения. Затем вы просто применяете одно и то же изображение каждый раз, когда вам это нужно для фона, и соответственно корректируете координаты x / y. Этот метод лучше всего работает с элементами, которые будут иметь ограниченные размеры, и не будет работать для каждого использования фонового изображения. Тем не менее, меньшее количество HTTP-запросов и кэширование одного изображения может помочь сократить время загрузки страницы.

+ +

Используйте сеть доставки (и дистрибуции) содержимого (Content Delivery Network (CDN))

+ +

Для целей этой статьи CDN - это средство уменьшения физического расстояния между вашим сервером и вашим посетителем. По мере увеличения расстояния между вашим сервером и посетителем время загрузки будет увеличиваться. Предположим, ваш сервер веб-сайта находится в Соединенных Штатах и имеет посетителя из Индии; время загрузки страницы будет намного выше для индийского посетителя по сравнению с посетителем из США.

+ +

CDN - это географически распределенная сеть серверов, которые работают вместе, чтобы сократить расстояние между пользователем и вашим сайтом. CDN хранят кэшированные версии вашего веб-сайта и предоставляют их посетителям через ближайший к пользователю сетевой узел, тем самым снижая задержку

+ +

Дальнейшее чтение:

+ + + +

Сократите поиск доменов

+ +

Поскольку каждый отдельный домен требует времени для поиска DNS, время загрузки страницы будет расти вместе с количеством отдельных доменов, отображаемых в ссылках CSS, а также в JavaScript и изображениях.

+ +

Это не всегда может быть практичным; однако вы всегда должны позаботиться об использовании только минимально необходимого количества разных доменов на своих страницах.

+ +

Кэшируйте повторно использованный контент

+ +

Убедитесь, что любой контент, который может быть кэширован, кэширован и имеет подходящее время истечения.

+ +

В частности, обратите внимание на  заголовок Last-Modified. Это позволяет эффективно кэшировать страницы; с помощью этого заголовка агенту пользователя передается информация о файле, который он хочет загрузить, например, когда он был последний раз изменен. Большинство веб-серверов автоматически добавляют заголовок Last-Modified к статическим страницам (напр. .html, .css), на основе даты последнего изменения, хранящейся в файловой системе. С динамическими страницами (напр. .php, .aspx), это, конечно, не может быть сделано, и заголовок не отправляется.

+ +

Так, в частности, для страниц, которые генерируются динамически, небольшое исследование по этой теме полезно. Это может быть несколько сложным, но это сэкономит много запросов страниц на страницах, которые обычно не могут быть кэшированы.

+ +

Больше информации:

+ +
    +
  1. HTTP Conditional Get for RSS Hackers
  2. +
  3. HTTP 304: Not Modified
  4. +
  5. On HTTP Last-Modified and ETag
  6. +
+ +

Оптимально размещайте компоненты на странице

+ +

Сначала загрузите содержимое страницы вместе с любым CSS или JavaScript, которые могут потребоваться для его первоначального отображения, чтобы пользователь получил самый быстрый очевидный ответ во время загрузки страницы. Этот контент, как правило, представляет собой текст, и поэтому может получить выгоду от сжатия текста при передаче, что обеспечивает еще более быстрый отклик для пользователя.

+ +

Любые динамические функции, требующие полной загрузки страницы перед использованием, должны быть изначально отключены, а затем включены только после загрузки страницы. Это приведет к загрузке JavaScript после содержимого страницы, что улучшит общий вид загрузки страницы.

+ +

Уменьшайте количество встроенных скриптов

+ +

Встроенные сценарии могут быть дорогими для загрузки страницы, так как синтаксический анализатор должен предполагать, что встроенный сценарий может изменить структуру страницы во время анализа. Сокращение использования встроенных сценариев в целом и сокращение использования document.write() для вывода контента, в частности, может улучшить общую загрузку страницы. Используйте современные методы AJAX для управления содержимым страницы, а не устаревшие подходы, которые основаны на  document.write().

+ +

Используйте современный CSS и корректную разметку

+ +

Использование современного CSS уменьшает количество текста, может уменьшить потребность в (разделительных) изображениях с точки зрения макета и очень часто может заменить изображения стилизованного текста - это «стоит» намного дороже, чем эквивалентный текст и CSS.

+ +

Использование корректной разметки имеет следующие преимущества. Во-первых, браузерам не нужно выполнять исправление ошибок при разборе HTML (это помимо философской проблемы: разрешить ли изменение формата при вводе пользователем, а затем программно «исправить» или нормализовать его; или вместо этого обеспечить строгий формат ввода без допусков).

+ +

Кроме того, корректная разметка позволяет спокойно использовать другие инструменты, которые могут предварительно обрабатывать ваши веб-страницы. Например, HTML Tidy может удалить пробелы и необязательные конечные теги; однако он откажется запускать страницу с серьезными ошибками разметки

+ +

Разделяйте ваш контент

+ +

Использование таблиц для вёрстки макетов устаревший метод, который не должен больше использоваться. Вместо этого для создания макетов нужно использовать <a href="/en-US/docs/Learn/CSS/CSS_layout/Floats">floats</a>, <a href="/en-US/docs/Learn/CSS/CSS_layout/Positioning">positioning</a>, <a href="/en-US/docs/Learn/CSS/CSS_layout/Flexbox">flexbox</a>, или <a href="/en-US/docs/Learn/CSS/CSS_layout/Grids">grids</a>.

+ +

Таблицы по-прежнему считаются допустимой разметкой, но их следует использовать для отображения табличных данных. Чтобы браузер быстрее отображал вашу страницу, вам следует избегать вложения таблиц.

+ +

Вместо глубоко вложенных таблиц, как в:

+ +
<TABLE>
+  <TABLE>
+    <TABLE>
+          ...
+    </TABLE>
+  </TABLE>
+</TABLE>
+ +

используйте невложенные таблицы как показано (или div'ы)

+ +
<TABLE>...</TABLE>
+<TABLE>...</TABLE>
+<TABLE>...</TABLE>
+
+ +

Смотри также: CSS3 Multi-column Layout Spec и CSS3 Flexible Box Layout

+ +

Сокращайте и сжимайте активы SVG

+ +

SVG, создаваемый большинством графических приложений, часто содержит ненужные метаданные, которые можно удалить. Настройте свои сервера, примените сжатие gzip для ресурсов SVG

+ +

Сокращайте и сжимайте ваши изображения

+ +

Большие изображения приводят к тому, что загрузка страницы занимает больше времени. Рассмотрите возможность сжатия ваших изображений перед добавлением их на свою страницу.  Есть онлайн-инструменты, такие как <a href="https://compressjpeg.com/">Compress Jpeg</a>, <a href="https://tinypng.com">Tiny PNG</a> и многие другие, доступны онлайн. Вы можете использовать офлайн-инструменты, такие как фотошоп и другие.

+ +

Указывайте размеры для изображений и таблиц 

+ +

Если браузер может немедленно определить высоту и/или ширину ваших изображений и таблиц, он сможет отображать веб-страницу без необходимости переформатировать содержимое. Это не только ускоряет отображение страницы, но и предотвращает раздражающие изменения в макете страницы после завершения загрузки страницы. По этой причине height и width  должны быть указаны для изображений всегда, когда это возможно.

+ +

Таблицы должны использовать CSS селектор: комбинация свойств

+ +
  table-layout: fixed;
+
+ +

и должны указывать ширину колонок используя HTML теги COL и COLGROUP

+ +

Мудро выбирайте требования к пользовательскому агенту

+ +

Чтобы добиться наибольших улучшений в дизайне страниц, убедитесь, что для проектов указаны разумные требования к пользовательским агентам. Не требуйте, чтобы ваш контент казался идеальным во всех браузерах, особенно в устаревших.

+ +

В идеале ваши базовые минимальные требования должны основываться на рассмотрении современных браузеров, поддерживающих соответствующие стандарты.Это может включать: Firefox 3.6+ на любой платформе, Internet Explorer 8.0+ на Windows, Opera 10+ на Windows, и Safari 4 на Mac OS X.

+ +

Примечание. Несмотря на то, что эти атрибуты очень помогают при первой загрузке страницы, вы должны использовать их, но не предполагать, что они будут работать во всех браузерах. Если вы уже следуете всем рекомендациям JavaScript, вам не нужно менять код.

+ +

Используйте async и defer, если это возможно

+ +

Сделайте сценарии JavaScript такими, чтобы они были совместимы как с async, так и с defer, и по возможности используйте async, особенно если у вас есть несколько тегов script.

+ +

При этом страница может перестать отображаться, пока JavaScript все еще загружается. В противном случае браузер не будет отображать ничего после тегов сценария, которые не имеют этих атрибутов.

+ +

Примечание. Несмотря на то, что эти атрибуты очень помогают при первой загрузке страницы, вы должны использовать их, но не предполагать, что они будут работать во всех браузерах. Если вы уже следуете всем рекомендациям JavaScript, вам не нужно менять код.

+ +

Пример структуры страницы

+ +

· HTML

+ +
+
· HEAD
+
+ +
+
+
+
· LINK ...
+ CSS файлы необходимы для отображения веб-страницы. Минимизируйте количество файлов для производительности, сохраняя несвязанные CSS в отдельных файлах для обслуживания.
+
+
+
+ +
+
+
+
· SCRIPT ...
+ Файлы JavaScript для функций, необходимых при загрузке страницы, но не для любого DHTML, который может работать только после загрузки страницы
+
Минимизируйте количество файлов для повышения производительности, сохраняя несвязанный JavaScript в отдельных файлах для обслуживания.
+
+
+
+ +
+
· BODY
+
· Видимое пользователем содержимое страницы небольшими порциями (tables / divs) что можно отобразить, не дожидаясь загрузки полной страницы.
+
+ +
+
+
+
· SCRIPT ...
+ Любые сценарии, которые будут использоваться для выполнения DHTML. Сценарий DHTML обычно может запускаться только после полной загрузки страницы и инициализации всех необходимых объектов. Нет необходимости загружать эти скрипты перед содержимым страницы. Это только замедляет первоначальный вид загрузки страницы.
+
Минимизируйте количество файлов для повышения производительности, сохраняя несвязанный JavaScript в отдельных файлах для обслуживания
+
Если какие-либо изображения используются для эффектов ролловера, вам следует предварительно загрузить их здесь после загрузки содержимого страницы.
+
+
+
+ + + + + +
+

Original Document Information

+ +
    +
  • Author(s): Bob Clary, Technology Evangelist, Netscape Communications
  • +
  • Last Updated Date: Published 04 Apr 2003
  • +
  • Copyright Information: Copyright © 2001-2003 Netscape. All rights reserved.
  • +
  • Note: This reprinted article was originally part of the DevEdge site.
  • +
+
+ +

 

diff --git a/files/ru/learn/html/howto/index.html b/files/ru/learn/html/howto/index.html new file mode 100644 index 0000000000..1a780e676b --- /dev/null +++ b/files/ru/learn/html/howto/index.html @@ -0,0 +1,153 @@ +--- +title: Использование HTML для решения общих задач +slug: Learn/HTML/Рецепты +tags: + - CodingScripting + - HTML + - На русском + - Программирование +translation_of: Learn/HTML/Howto +--- +

Следующие ссылки указывают на решения общих повседневных проблем, которые вам нужно решить с помощью HTML.

+ +
+
+

Основы структурирования

+ +

Основное применение HTML - это структура документа. Если вы новичок в HTML, вы должны начать с этого.

+ + + +

Основы организации гипертекста

+ +

HTML специализируется на предоставлении семантической информации для документа, поэтому HTML отвечает на многие вопросы, которые могут у вас возникнуть о том, как лучше донести ваше сообщение в документе.

+ + +
+ +
+

Гиперссылки

+ +

Одной из главных причин по которым навигация в HTML страницах столь проста являются гиперссылки, которые могут которые возможно использоваться различными способами:

+ + + +

Изображения и мультимедиа

+ + + +

Сценарии и стили

+ +

HTML определяет лишь структуру документа. Для улучшения внешнего вида документа обычно используется CSS. Чтобы добавить странице интерактивности вы также можете написать сценарий на одном из скриптовых языков (например JavaScript).

+ + + +

Встраиваемый контент

+ + +
+
+ +

Необычные или продвинутые проблемы

+ +

Помимо основ, HTML очень богат и предлагает расширенные возможности для решения сложных проблем. Эти статьи помогут вам разобраться с менее распространенными случаями использования, с которыми вы можете столкнуться:

+ +
+
+

Формы

+ +

Форма это сложная HTML структура предназначенная для отправки данных с веб-страницы на веб-сервер. Мы призываем вас просмотреть наше полное посвященное руководство. Вот где вы должны начать:

+ + + +

Таблицы

+ +

Некоторая информация удобнее всего представима в виде таблиц состоящих из строк и столбцов. Это одна из самых сложных структур в HTML, управлять которой не так просто как кажется:

+ + + +

Представление данных

+ + + +

Интерактивность

+ + +
+ +
+

Продвинутая организация текста

+ + + +

Продвинутые изображения и мультимедиа images & multimedia

+ + + +

Локализация

+ +

HTML не одноязычен. Он имеет поддержку средств локализации документов.

+ + + +

Производительность

+ + +
+
+ +

     

diff --git a/files/ru/learn/html/howto/use_data_attributes/index.html b/files/ru/learn/html/howto/use_data_attributes/index.html new file mode 100644 index 0000000000..cef001e25a --- /dev/null +++ b/files/ru/learn/html/howto/use_data_attributes/index.html @@ -0,0 +1,129 @@ +--- +title: Использование data-* атрибутов +slug: Web/Guide/HTML/Using_data_attributes +tags: + - Guide + - HTML +translation_of: Learn/HTML/Howto/Use_data_attributes +--- +

HTML5 спроектирован с возможностью расширения данных ассоциированных с каким-либо элементом, но в то же время не обязательно имеющих определённое значение. data-* атрибуты позволяют хранить дополнительную информацию в стандартных элементах HTML, без хаков вроде нестандартных атрибутов, лишних DOM-свойств или {{domxref("Node.setUserData()")}}.

+ +

Синтаксис HTML

+ +

Синтаксис прост — любой атрибут, чьё имя начинается с data-, является data-* атрибутом. Предположим у нас имеется статья и мы хотим сохранить дополнительную информацию без визуального представления. Для этого можно использовать data-атрибуты:

+ +
<article
+  id="electriccars"
+  data-columns="3"
+  data-index-number="12314"
+  data-parent="cars">
+...
+</article>
+ +

Доступ в JavaScript

+ +

Чтение data-атрибутов в JavaScript осуществляется также просто. Для этого можно использовать метод {{domxref("Element.getAttribute", "getAttribute()")}} с параметром, равным полному имени атрибута. Но есть и более простой способ, используя объект {{domxref("HTMLElement.dataset", "dataset")}}.

+ +

Чтобы получить data-атрибут можно взять свойство объекта dataset с именем, равным части имени атрибута после data- (обратите внимание, что дефисы в имени преобразуются в camelCase).

+ +
var article = document.getElementById('electriccars');
+
+article.dataset.columns // "3"
+article.dataset.indexNumber // "12314"
+article.dataset.parent // "cars"
+ +

Каждое свойство является строкой и может быть прочитано и записано. В приведённом выше примере выполнение кода article.dataset.columns = 5 приведёт к тому, что новое значение атрибута станет равным "5".

+ +

Доступ в CSS

+ +

Заметим, что data-атрибуты являются обычными HTML-аттрибутами, к которым можно получить доступ в CSS. Например, чтобы показать родительские данные о статье можно использовать генерируемый контент и CSS функцию {{cssxref("attr")}}:

+ +
article::before {
+  content: attr(data-parent);
+}
+ +

Также можно использовать селекторы атрибутов в CSS для изменения стилей в соответствии с данным:

+ +
article[data-columns='3']{
+  width: 400px;
+}
+article[data-columns='4']{
+  width: 600px;
+}
+ +

Увидеть как это работает можно в примере на JSBin.

+ +

Data-аттрибуты также могут использоваться для хранения информации, которая постоянно изменяется, например, счёт в игре. Используя CSS селекторы и возможности JavaScript можно создавать некоторые изящные эффекты, без необходимости писать свои функции отображения. Посмотрите скринкаст чтобы увидеть больше примеров использующих сгенерированный контент и переходы на CSS. Пример кода из скринкаста можно также посмотреть на JSBin.

+ +

Проблемы

+ +

Не храните данные, которые должны быть видимы и доступны в data-атрибутах. Дело в том, что вспомогательная техника (assistive technology) может не получить к ним доступ. В дополнение, поисковые роботы не индексируют данные, содержащиеся в data-атрибутах.

+ +

Печально, что всё простое и полезное в этой жизни не достаётся бесплатно. Internet Explorer 11+ поддерживает этот стандарт, но все более ранние версии не поддерживают dataset. Для поддержки IE 10 и более ранних версий получение доступа к data-атрибутам необходимо осуществлять через {{domxref("Element.getAttribute", "getAttribute()")}}. Также, производительность чтения data-атрибутов по сравнению с хранением этих данных в хранилище данных JS значительно хуже. Использование dataset ещё медленнее, чем чтение данных с getAttribute().

+ +

Тем не менее, для пользовательских метаданных, связанных с элементами, data-атрибуты являются отличным решением.

+ +

Поддержка в браузерах

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
caniuse
+

IE

+
+

Edge

+
+

Firefox

+
+

Chrome

+
+

Safari

+
+

Opera

+
+

iOS Safari

+
+

Opera Mini*

+
+

Android Browser

+
+

Chrome for Android

+
11+14+52+49+10.1+46+9.3+all4.4+59+
+ +

 

+ +

Тем не менее, для содержимого, которое не надо показывать это является отличным решением.

+ +

См. также

+ + diff --git a/files/ru/learn/html/introduction_to_html/advanced_text_formatting/index.html b/files/ru/learn/html/introduction_to_html/advanced_text_formatting/index.html new file mode 100644 index 0000000000..fdebae6e91 --- /dev/null +++ b/files/ru/learn/html/introduction_to_html/advanced_text_formatting/index.html @@ -0,0 +1,679 @@ +--- +title: Углубленное форматирование текста +slug: Learn/HTML/Введение_в_HTML/Advanced_text_formatting +tags: + - Beginner + - Guide + - HTML + - Начинающий + - Руководство +translation_of: Learn/HTML/Introduction_to_HTML/Advanced_text_formatting +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/Creating_hyperlinks", "Learn/HTML/Introduction_to_HTML/Document_and_website_structure", "Learn/HTML/Introduction_to_HTML")}}
+ +

В HTML для форматирования текста есть много других элементов, не рассмотренных  в статье Основы редактирования текста в HTML. Элементы, описанные в этой статье, не так часто используются, но все же полезны для понимания (и это всё ещё будет не полный список элементов). Здесь вы узнаете о цитатах, списках описания, компьютерном коде и другом виде текстовых элементов, подстрочном и надстрочном тексте, контактной информации и других типах текста.

+ + + + + + + + + + + + +
Предварительные требования: +

Базовое знакомство с HTML, раскрытое в 
+ Начало работы с HTML. Форматирование текста с помощью HTML, описанное в статье Основы редактирования текста в HTML.

+
Задача:Научиться использовать менее известные HTML-элементы для продвинутой семантической разметки текста.
+ +

Списки описания

+ +

В основах HTML-текста мы рассмотрели, как пометить привычные типы списков в HTML, но мы не упоминали о третьем типе списка, с которым вы иногда сталкиваетесь, — списке описания. Цель этих списков состоит в том, чтобы пометить набор элементов и их связанных описаний, таких как термины и определения или вопросы и ответы.

+ +

Давайте рассмотрим пример набора терминов и определений:

+ +
Солилоквий
+Драматическая речь, в которой персонаж разговаривает сам с собой, передавая свои ощущения и мысли публике (но не другим персонажам).
+Монолог
+Драматическая речь, в которой персонаж передаёт свои мысли публике и некоторым персонажам.
+Ремарка
+В драме: речь персонажа, при которой делается замечание с юмористическим или драматическим эффектом; чаще всего это чувства, мысли или предпосылки к чему-либо.
+ +

В списках описания используется иная оболочка, чем в других типах списков — {{htmlelement ("dl")}} (от description list); кроме того, каждый термин завёрнут в элемент {{htmlelement ("dt")}} (description term — термин для описания) и каждое определение завёрнуто в элемент {{htmlelement ("dd")}} (description definition — описание определения).

+ +

Закончим разметку нашего примера:

+ +
<dl>
+  <dt>Солилоквий</dt>
+  <dd>Драматическая речь, в которой персонаж разговаривает сам с собой, передавая свои ощущения и мысли публике (но не другим персонажам).</dd>
+  <dt>Монолог</dt>
+  <dd>Драматическая речь, в которой персонаж передаёт свои мысли публике и некоторым персонажам.</dd>
+  <dt>Ремарка</dt>
+  <dd>В драме: речь персонажа, при которой делается замечание с юмористическим или драматическим эффектом; чаще всего это чувства, мысли или предпосылки к чему-либо.</dd>
+</dl>
+ +

В стилях браузера по умолчанию будут отображаться списки описания с некоторыми отступами от терминов. Стили, определённые на MDN, довольно близки к этому соглашению, но также вносят некоторые изменения:

+ +
+
Солилоквий
+
Драматическая речь, в которой персонаж разговаривает сам с собой, передавая свои ощущения и мысли публике (но не другим персонажам).
+
Монолог
+
Драматическая речь, в которой персонаж передаёт свои мысли публике и некоторым персонажам.
+
Ремарка
+
В драме: речь персонажа, при которой делается замечание с юмористическим или драматическим эффектом; чаще всего это чувства, мысли или предпосылки к чему-либо.
+
+ +

Заметьте, что разрешено давать одному элементу несколько описаний:

+ +
+
Ремарка
+
В драме: речь персонажа, при которой делается замечание с юмористическим или драматическим эффектом; чаще всего это чувства, мысли или предпосылки к чему-либо.
+
В письменности: отметка, примечание (устар.).
+
+ +

Активное обучение: разметка набора определений

+ +

Пришло время попробовать свои силы в списках описания: добавьте элементы в исходный текст в поле Ввод, чтобы он отображался как список описания в поле Вывод. Вы можете попробовать использовать свои собственные термины и описания, если хотите.

+ +

Если Вы ошиблись, то всегда можете начать снова, воспользовавшись кнопкой Сбросить. Если упражнение вызывает у Вас затруднения, то нажмите кнопку Показать решение, чтобы увидеть правильный ответ.

+ + + +

{{ EmbedLiveSample('Playable_code', 700, 350, "", "", "hide-codepen-jsfiddle") }}

+ +

Цитаты

+ +

HTML также имеет функции, доступные для маркировки цитат; какой элемент вы используете, зависит от того, маркируете ли вы блочную или строчную цитату.

+ +

Блочные цитаты

+ +

Если часть содержимого уровня блока (будь то абзац, несколько абзацев, список и т. д.) цитируется из другого источника, вы должны обернуть ее внутри элемента {{htmlelement ("blockquote")}}, чтобы обозначить это, и указать URL-адрес, указывающий на источник цитаты, внутри атрибута {{htmlattrxref ("cite", "blockquote")}}.

+ +

Например, следующая разметка берется из страницы элемента MDN <blockquote>:

+ +
<p><strong>HTML-элемент<code>&lt;blockquote&gt;</code></strong> (от англ. <em>HTML Block
+Quotation Element</em>) указывает на то, что заключённый в нём текст является развёрнутой цитатой.</p>
+ +

Чтобы превратить её в блочную цитату, мы просто делаем следующее:

+ +
<blockquote cite="https://developer.mozilla.org/ru/docs/Web/HTML/Element/blockquote">
+  <p><strong>HTML-элемент<code>&lt;blockquote&gt;</code></strong> (от англ. <em>HTML Block Quotation Element</em>) указывает на то, что заключённый в нём текст является развёрнутой цитатой.</p>
+</blockquote>
+ +

Стиль браузера по умолчанию будет отображать это как абзац с отступом, как индикатор того, что это цитата; абзац над цитатой призван продемонстрировать это. MDN делает это, но также добавляет некоторый дополнительный стиль:

+ +
+

HTML-элемент <blockquote> (от англ. Block Quotation) указывает на то, что заключённый в нём текст является развёрнутой цитатой.

+
+ +

Строчные цитаты

+ +

Строчные цитаты работают точно так же, за исключением того, что они используют элемент {{htmlelement ("q")}}. Например, следующий кусочек разметки содержит цитату из страницы <q> MDN:

+ +
<p>Элемент цитирования — <code>&lt;q&gt;</code> — <q cite="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/q">предназначен
+для коротких цитат, не требующих прерывания абзаца</q>.</p>
+ +

Стиль браузера по умолчанию будет отображать это как обычный текст, заключенный в кавычки для обозначения цитаты, например:

+ +

Элемент цитирования — <q> — предназначен для коротких цитат, не требующих прерывания абзаца.

+ +

Цитирование

+ +

Содержание атрибута {{htmlattrxref ("cite", "blockquote")}} выглядит полезным, но, к сожалению, браузерам, программам чтения с экрана и т. д. оно на самом деле мало чем помогает. Невозможно заставить браузер отображать содержимое атрибута <cite> без написания собственного решения с использованием JavaScript или CSS. Если вы хотите, чтобы источник цитирования был доступен на странице, лучший способ его разметки - поместить элемент {{htmlelement ("cite")}} рядом с элементом цитаты (или внутри него). Это действительно будет означать то, что имя источника цитаты — то есть имя книги или имя человека, которое произвело цитату, — будет включено в текст. Нет причин, по которым вы не могли бы связать текст внутри <cite> с источником цитаты:

+ +
<p>Как указано в статье о <a href="https://developer.mozilla.org/ru/docs/Web/HTML/Element/blockquote">
+<cite>блочных цитатах</cite></a>:
+</p>
+
+<blockquote cite="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/blockquote">
+  <p><strong>HTML-элемент<code>&lt;blockquote&gt;</code></strong> (от англ. <em>HTML Block
+  Quotation Element</em>) указывает на то, что заключённый в нем текст является развёрнутой цитатой.</p>
+</blockquote>
+
+<p>Элемент цитирования — <code>&lt;q&gt;</code> — <q cite="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/q">предназначен
+для коротких цитат, не требующих прерывания абзаца</q>. -- <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/q">
+<cite>Строчные цитаты</cite></a>.</p>
+ +

По умолчанию цитаты стилизованы курсивом. Этот код можно увидеть в нашем примере quotations.html

+ +

Активное обучение: кто это сказал?

+ +

Время для другого примера активного обучения! В этом примере мы хотели бы, чтобы вы совершили следующие действия:

+ +
    +
  1. Преобразуйте средний абзац в блочную цитату (<blockquote>), который включает атрибут cite.
  2. +
  3. Заверните часть третьего абзаца в строчную цитату, которая включает атрибут cite.
  4. +
  5. Включите элемент <cite> для каждой ссылки.
  6. +
+ +

Источники цитирования, которые вам потребуются:

+ + + +

Если Вы ошиблись, то всегда можете начать снова, воспользовавшись кнопкой Сбросить. Если упражнение вызывает у Вас затруднения, то нажмите кнопку Показать решение, чтобы увидеть правильный ответ.

+ + + +

{{ EmbedLiveSample('Playable_code_2', 700, 450, "", "", "hide-codepen-jsfiddle") }}

+ +

Аббревиатуры

+ +

Другой довольно часто встречающийся элемент, который вы будете часто встречать в Интернете, — это {{htmlelement ("abbr")}}, используемый для обёртывания аббревиатур или акронимов и обеспечивающий полную расшифровку сокращения (с помощью атрибута {{htmlattrxref("title")}}.)

+ +

Давайте рассмотрим несколько примеров:

+ +
<p>Мы используем <abbr title="Hypertext Markup Language">HTML</abbr> для структурирования наших веб-документов.</p>
+
+<p>Я думаю, <abbr title="Почтенный">Почт.</abbr> Грин сделал это на кухне с бензопилой.</p>
+
+ +

Они будут выглядеть примерно так (расшифровка появится в подсказке при наведении курсора мыши на сокращение):

+ +

Мы используем HTML для структурирования наших веб-документов.

+ +

Я думаю, Почт. Грин сделал это на кухне с бензопилой.

+ +
+

Примечание: Существует еще один элемент {{htmlelement ("acronym")}}, который в основном делает то же самое, что и <abbr>, но предназначен специально для акронимов (тип аббревитатур). Это, однако, было излишним, — он не поддерживается в браузерах на том же уровне, что <abbr>, и имеет такую же функциональность, поэтому считается бессмысленным иметь оба. Просто используйте <abbr>.

+
+ +

Активное обучение: выделение аббревиатуры

+ +

В рамках этого простого упражнения мы хотели бы, чтобы вы просто указали аббревиатуру. Вы можете использовать наш образец ниже или заменить его на свой собственный.

+ + + +

{{ EmbedLiveSample('Playable_code_3', 700, 300, "", "", "hide-codepen-jsfiddle") }}

+ +

Разметка контактных данных

+ +

HTML имеет элемент для разметки контактных данных — {{htmlelement ("address")}}. Он просто обёртывает ваши контактные данные, например:

+ +
<address>
+  <p>Крис Миллс, Манчестер, Жестокий Север, РФ</p>
+</address>
+ +

Однако следует помнить, что элемент {{htmlelement ("address")}} предназначен для разметки контактных данных человека, который написал HTML-документ, а не любого адреса. Таким образом, написанное выше было бы корректным только в том случае, если бы Крис написал документ, на котором появляется разметка. Обратите внимание, что следующее также подойдет:

+ +
<address>
+  <p>Автор страницы — <a href="../authors/chris-mills/">Крис Миллс</a>.</p>
+</address>
+ +

Верхний и нижний индекс

+ +

Иногда вам понадобится использовать надстрочный или подстрочный индекс при разметке таких вещей, как даты, химические формулы и математические уравнения, чтобы они имели правильное представление. Элементы {{htmlelement ("sup")}} и {{htmlelement ("sub")}} созданы для таких ситуаций.

+ +

Приведем пример:

+ +
<p>Я просыпаюсь в 6<sup>35</sup> часов утра.</p>
+<p>Химическая формула кофеина: C<sub>8</sub>H<sub>10</sub>N<sub>4</sub>O<sub>2</sub>.</p>
+<p>Если x<sup>2</sup> равно 9, x должен равняться 3 или -3.</p>
+ +

Результат этого кода выглядит следующим образом:

+ +

Я просыпаюсь в 635 часов утра.

+ +

Химическая формула кофеина: C8H10N4O2.

+ +

Если x2 равно 9, x должен равняться 3 или -3.

+ +

Представление компьютерного кода

+ +

Существует несколько элементов для маркировки компьютерного кода с использованием HTML:

+ + + +

Давайте рассмотрим несколько примеров. Вы должны попробовать поиграть с ними (захватите копию нашего файла other-semantics.html):

+ +
<pre><code>var para = document.querySelector('p');
+
+para.onclick = function() {
+  alert('Owww, stop poking me!');
+}</code></pre>
+
+<p>You shouldn't use presentational elements like <code>&lt;font&gt;</code> and <code>&lt;center&gt;</code>.</p>
+
+<p>In the above JavaScript example, <var>para</var> represents a paragraph element.</p>
+
+
+<p>Select all the text with <kbd>Ctrl</kbd>/<kbd>Cmd</kbd> + <kbd>A</kbd>.</p>
+
+<pre>$ <kbd>ping mozilla.org</kbd>
+<samp>PING mozilla.org (63.245.215.20): 56 data bytes
+64 bytes from 63.245.215.20: icmp_seq=0 ttl=40 time=158.233 ms</samp></pre>
+ +

Вышеприведенный код будет выглядеть так:

+ +

{{ EmbedLiveSample('Representing_computer_code','100%',300, "", "", "hide-codepen-jsfiddle") }}

+ +

Разметка времени и даты

+ +

HTML также содержит элемент {{htmlelement ("time")}} для отметки времени и дат в машиночитаемом формате. Например:

+ +
<time datetime="2020-01-20">20 Января 2020</time>
+ +

Почему это полезно? Ну, есть много разных способов, которыми люди записывают даты. Вышеуказанная дата может быть записана как:

+ + + +

Но эти разные формы не могут быть легко распознаны компьютерами — что, если вы хотите автоматически захватить даты всех событий на странице и вставить их в календарь? Элемент {{htmlelement ("time")}} позволяет прикрепить к этой цели однозначное машиночитаемое время / дату.

+ +

В приведенном выше базовом примере приведена простая машиносчитываемая дата, но есть много других возможных вариантов, например:

+ +
<!-- Стандартная дата -->
+<time datetime="2020-01-20">20 Января 2020</time>
+<!-- Только год и месяц -->
+<time datetime="2020-01">Январь 2020</time>
+<!-- Только месяц и день -->
+<time datetime="01-20">20 Января</time>
+<!-- Только время, часы и минуты -->
+<time datetime="19:30">19:30</time>
+<!-- Также вы можете отобразить секунды и миллисекунды! -->
+<time datetime="19:30:01.856">19:30:01.856</time>
+<!-- Дата и время -->
+<time datetime="2020-01-20T19:30">7.30pm, 20 Января 2020</time>
+<!-- Дата и время со смещением по часовому поясу -->
+<time datetime="2020-01-20T19:30+01:00">7.30pm, 20 Января 2020, — это 8.30pm во Франции.</time>
+<!-- Вызов номера недели -->
+<time datetime="2020-W04">Четвертая неделя 2020</time>
+ +

Заключение

+ +

На этом мы подошли к концу нашего изучения семантики текста HTML. Имейте в виду, что то, что вы видели во время этого курса, не является исчерпывающим списком текстовых элементов HTML. Мы попытались охватить основные из них, с которыми вы, скорее всего, столкнетесь в практической деятельности или, по крайней мере, сочтёте их интересными. Чтобы найти больше элементов HTML, вы можете взглянуть на нашу ссылку на Элемент. В следующей статье мы рассмотрим элементы HTML, которые вы будете использовать для структурирования различных частей HTML-документа.

+ +

{{PreviousMenuNext ("Learn/HTML/Introduction_to_HTML/Create_hyperlinks", "Learn/HTML/Introduction_to_HTML/Document_and_website_structure", "Learn/HTML/Introduction_to_HTML")}}

+ +

В этом модуле

+ + diff --git a/files/ru/learn/html/introduction_to_html/creating_hyperlinks/index.html b/files/ru/learn/html/introduction_to_html/creating_hyperlinks/index.html new file mode 100644 index 0000000000..fcee7272e4 --- /dev/null +++ b/files/ru/learn/html/introduction_to_html/creating_hyperlinks/index.html @@ -0,0 +1,435 @@ +--- +title: Создание гиперссылок +slug: Learn/HTML/Введение_в_HTML/Создание_гиперссылок +tags: + - Абсолютные + - Гиперссылки + - Единый указатель ресурса + - Заголовок + - Начинающий + - Обучение + - Относительные + - Руководство + - Ссылки + - Язык гипертекстовой разметки +translation_of: Learn/HTML/Introduction_to_HTML/Creating_hyperlinks +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/HTML_text_fundamentals", "Learn/HTML/Introduction_to_HTML/Advanced_text_formatting", "Learn/HTML/Introduction_to_HTML")}}
+ +

Гиперссылки действительно важны — они делают Интернет Интернетом. В этой статье представлен синтаксис, необходимый для создания ссылки,  а также обсуждаются лучшие практики обращения со ссылками.

+ + + + + + + + + + + + +
Предварительные требования:Базовое знакомство с HTML, описаное в статье Начало работы c HTML. Форматирование текста в HTML, описанное в статье Основы редактирования текста в HTML.
Задача:Научиться эффективно использовать гиперссылки и связывать несколько файлов вместе.
+ +

Что такое гиперссылка?

+ +

Гиперссылки — одно из самых интересных нововведений Интернета. Они были особенностью Сети с самого начала, но именно они превращают Интернет в Интернет. Они позволяют нам связывать наши документы с любым другим документом (или ресурсом), с которым мы хотим. С их помощью мы также можем связывать документы с их конкретными частями, и мы можем сделать приложения доступными на простом веб-адресе (сравните это с локальными приложениями, которые должны быть установлены, и другими такими же вещами). Почти любой веб-контент может быть преобразован в ссылку, так что когда вы кликаете по ней (или иным образом активируете), она заставляет веб-браузер перейти на другой веб-адрес ({{glossary("URL")}}.)

+ +
+

Примечание: URL-адрес может указывать на файлы HTML, текстовые файлы, изображения, текстовые документы, видео и аудиофайлы и все остальное, что может жить в Интернете. Если веб-браузер не знает, как отображать или обрабатывать файл, он спросит вас, хотите ли вы открыть файл (в этом случае обязанность открытия или обработки файла передаётся в соответствующее локальное приложение на устройстве) или загрузить файл (в этом случае вы можете попытаться разобраться с ним позже).

+
+ +

Например, домашняя страница BBC содержит большое количество ссылок, которые указывают не только на множество новостей, но и на различные области сайта (меню), страницы входа / регистрации (пользовательские инструменты) и многое другое.

+ +

frontpage of bbc.co.uk, showing many news items, and navigation menu functionality

+ +

Анатомия ссылки

+ +

Простая ссылка создаётся путём обёртывания текста (или другого содержимого, смотрите  {{anch("Ссылки-блоки")}}), который вы хотите превратить в ссылку, в элемент {{htmlelement ("a")}}, и придания этому элементу атрибута {{htmlattrxref ("href", "a")}} (который также известен как гипертекстовая ссылка, или цель), который будет содержать веб-адрес, на который вы хотите указать ссылку.

+ +
<p>Я создал ссылку на
+  <a href="https://www.mozilla.org/ru/">домашнюю страницу Mozilla</a>.
+</p>
+ +

Это дало нам следующий результат:

+ +

Я создал ссылку на домашнюю страницу Mozilla.

+ +

Добавляем инфомацию через атрибут title

+ +

Другим атрибутом, который вы можете добавить к своим ссылкам, является — title. Он предназначен для хранения полезной информации о ссылке. Например, какую информацию содержит страница или другие вещи, о которых вам нужно знать. Например:

+ +
<p>Я создал ссылку на
+  <a href="https://www.mozilla.org/ru/"
+     title="Лучшее место для поиска дополнительной информации
+     о миссии Mozilla и о том, как внести свой вклад">домашнюю страницу Mozilla
+  </a>.
+</p>
+ +

Вот что получилось (описание появится, если навести курсор на ссылку):

+ +

Я создал ссылку на домашнюю страницу Mozilla.

+ +
+

Примечание: Описание из атрибута title отображается только при наведении курсора, значит люди, полагающиеся на клавиатурные элементы управления для навигации по веб-страницам, будут испытывать трудности с доступом к информации, которую содержит title. Если информация заголовка действительно важна для удобства использования страницы, то вы должны представить ее таким образом, который будет доступен для всех пользователей, например, поместив её в обычный текст.

+
+ +

Активное изучение: создаём собственную ссылку

+ +

Время упражнения: мы хотели бы, чтобы вы создали любой HTML-документ в текстовом редакторе на своём компьютере (наш базовый пример подойдёт.)

+ + + +

Ссылки-блоки

+ +

Как упоминалось ранее, вы можете превратить любой элемент в ссылку, даже блочный элемент. Если у вас есть изображение, которые вы хотели бы превратить в ссылку, вы можете просто поместить изображение между тегами <a></a>.

+ +
<a href="https://www.mozilla.org/ru/">
+  <img src="mozilla-image.png" alt="логотип mozilla со ссылкой на их домашнюю страницу">
+</a>
+ +
+

Примечание: Вы узнаете гораздо больше об использовании изображений в Интернете в следующей статье.

+
+ +

Краткое руководство по URL-адресам и путям

+ +

Чтобы полностью понять адреса ссылок, вам нужно понять несколько вещей про URL-адреса и пути к файлам. Этот раздел даст вам информацию, необходимую для достижения этой цели.

+ +

URL-адрес (Uniform Resource Locator, или единый указатель ресурса, но так его никто не называет) — это просто строка текста, которая определяет, где что-то находится в Интернете. Например, домашняя страница Mozilla находится по адресу https://www.mozilla.org/ru/.

+ +

URL-адреса используют пути для поиска файлов. Пути указывают, где в файловой системе находится файл, который вас интересует. Давайте рассмотрим простой пример структуры каталогов (смотрите каталог creating-hyperlinks.)

+ +

A simple directory structure. The parent directory is called creating-hyperlinks and contains two files called index.html and contacts.html, and two directories called projects and pdfs, which contain an index.html and a project-brief.pdf file, respectively

+ +

Корень структуры — каталог  creating-hyperlinks. При работе на локальном веб-сайте у вас будет один каталог, в который входит весь сайт. В корне у нас есть два файла — index.html и contacts.html. На настоящем веб-сайте index.html был бы нашей домашней, или лендинг-страницей (веб-страницей, которая служит точкой входа для веб-сайта или определенного раздела веб-сайта).

+ +

В корне есть ещё два каталога —  pdfs и projects. У каждого из них есть один файл внутри — project-brief.pdf и index.html, соответсвенно. Обратите внимание на то, что вы можете довольно успешно иметь два index.html файла в одном проекте, пока они находятся в разных местах файловой системы.  Многие веб-сайты так делают. Второй index.html, возможно, будет главной лендинг-страницей для связанной с проектом информации.

+ + + +
+

Примечание: Вы можете объединить несколько экземпляров этих функций в сложные URL-адреса, если необходимо, например: 
+ ../../../сложный/путь/к/моему/файлу.html.

+
+ +

Фрагменты документа

+ +

Можно ссылаться на определенную часть документа HTML (известную как фрагмент документа), а не только на верхнюю часть документа. Для этого вам сначала нужно назначить атрибут {{htmlattrxref("id")}} элементу, с которым вы хотите связаться. Обычно имеет смысл ссылаться на определённый заголовок, поэтому это выглядит примерно так:

+ +
<h2 id="Почтовый_адрес">Почтовый адрес</h2>
+ +

Затем, чтобы связаться с  этим конкретным  id, вы должны включить его в конец URL-адреса, которому предшествует знак решётки, например:

+ +
<p>Хотите написать мне письмо? Используйте наш
+  <a href="contacts.html#Почтовый_адрес">почтовый адрес</a>.
+</p>
+ +

Вы даже можете использовать ссылку на фрагмент документа отдельно для ссылки на другую часть того же документа:

+ +
<p>
+  <a href="#Почтовый_адрес">Почтовый адрес кампании</a>
+  можно найти в нижней части этой страницы.
+</p>
+ +

Абсолютные и относительные URL-адреса

+ +

Два понятия, с которыми вы столкнетесь в Интернете, — это абсолютный URL и относительный URL:

+ +
+
Абсолютный URL
+
Указывает на местоположение, определяемое его абсолютным местоположением в Интернете, включая {{glossary("protocol","протокол")}} и {{glossary("domain name","доменное имя")}}. Например, если страница index.html загружается в каталог, называемый projects, который находится внутри корня веб-сервера, а домен веб-сайта — http://www.example.com, страница будет доступна по адресу http://www.example.com/projects/index.html (или даже просто http://www.example.com/projects/), так как большинство веб-серверов просто ищет целевую страницу, такую ​​как index.html, для загрузки, если он не указан в URL-адресе.).
+
+ +

Абсолютный URL всегда будет указывать на одно и то же местоположение, независимо от того, где он используется.

+ +
+
Относительный URL
+
Указывает расположение относительно файла, с которого вы связываетесь, это больше похоже на случай, который мы рассматривали в предыдущей секции. Для примера, если мы хотим указать со страницы http://www.example.com/projects/index.html на PDF файл, находящийся в той же директории, наш URL может быть просто названием файла —  project-brief.pdf — никакой дополнительной информации не требуется. Если PDF расположен в поддериктории pdfs внутри каталога projects, относительная ссылка будет pdfs/project-brief.pdf (аналогичный абсолютный URL был бы http://www.example.com/projects/pdfs/project-brief.pdf.).
+
+ +

Относительный URL будет указывать на различные места, в зависимости от того, где находится файл, в котором он используется, — например, если мы переместим наш файл index.html из каталога projects в корневой каталог веб-сервера (верхний уровень, не в директорию) , то относительный URL pdfs/project-brief.pdf будет вести на http://www.example.com/pdfs/project-brief.pdf, а не на http://www.example.com/projects/pdfs/project-brief.pdf.

+ +

Советуем вам основательно разобраться в этой теме!

+ +

Практика написания хороших ссылок

+ +

При написании ссылок рекомендуется следовать некоторым правилам. Давайте рассмотрим их.

+ + + +

Используйте четкие формулировки описания ссылок

+ +

На вашей странице легко добавить ссылки. Но этого не совсем достаточно. Мы должны сделать наши ссылки доступными для всех читателей, независимо от их возможностей и инструментов просмотра страницы, которые они предпочитают. Например:

+ + + +

Взгляните на этот пример:

+ +

Хороший текст ссылки: Скачать Firefox

+ +
<p><a href="https://firefox.com/">
+  Скачать Firefox
+</a></p>
+ +

Плохой текст ссылки: Нажми сюда, чтобы скачать Firefox

+ +
<p><a href="https://firefox.com/">
+  Нажми сюда
+</a>
+чтобы скачать Firefox</p>
+
+ +

Советы:

+ + + +

Используйте относительные ссылки, где это возможно

+ +

Из прочитанного выше, вы можете подумать, что всё время использовать абсолютные ссылки — хорошая идея; в конце концов, они не ломаются, когда страница перемещается. Тем не менее, лучше использовать относительные ссылки везде, где это возможно, в пределах одного сайта  (при ссылке на другие сайты необходимо использовать абсолютную ссылку):

+ + + +

Создавая ссылки на не HTML ресурсы — добавляйте описание

+ +

Когда вы создаёте ссылку на файл, нажав на который можно загрузить документ PDF или Word или открыть просмотр видео, прослушивание аудио файла или перейти на страницу с другим, неожиданным для пользователя результатом (всплывающее окно или загрузка Flash-фильма), добавляйте четкую формулировку, чтобы уменьшить путаницу. Отсуствие описания может раздражать пользователя. Приведем пример:

+ + + +

Посмотрите на примеры, чтобы увидеть, как добавить описание:

+ +
<p><a href="http://www.example.com/large-report.pdf">
+  Скачать отчет о продажах (PDF, 10MB)
+</a></p>
+
+<p><a href="http://www.example.com/video-stream/">
+  Посмотреть видео (видео откроется в отдельном окне, HD качество)
+</a></p>
+
+<p><a href="http://www.example.com/car-game">
+  Играть в гонки (необходим Flash)
+</a></p>
+ +

Используйте атрибут download, когда создаете ссылку

+ +

Когда создаёте ссылку на файл, который должен быть загружен, а не открыт в браузере, можете использовать атрибут download, чтобы создать имя файла по умолчанию для сохранения . Приведем пример ссылки для загрузки браузера Firefox 39:

+ +
<a href="https://download.mozilla.org/?product=firefox-39.0-SSL&os=win&lang=en-US"
+   download="firefox-39-installer.exe">
+  Скачать Firefox 39 для Windows
+</a>
+ +

Активное изучение: создание меню навигации

+ +

Для этого упражнения мы хотим, чтобы вы создали ссылки на страницы в меню навигации в многостраничном сайте. Это один из распространенных способов создания сайта: на каждой странице используется одна и та же структура страниц, включая одно и то же меню навигации, поэтому при нажатии ссылок создается впечатление, что вы остаетесь в одном месте: меню остается на месте, а контент меняется.

+ +

Вам нужно скачать или создать следующие страницы в одном каталоге (Смотрите navigation-menu-start):

+ + + +

Что делать:

+ +
    +
  1. Добавьте неупорядоченный список в указанном месте в любом html-файле. Список должен состоять из имен страниц (index, projects и т.д.). Меню навигации обычно представляет собой список ссылок, поэтому создание неупорядоченного списка семантически верно.
  2. +
  3. Создайте ссылки каждому элементу списка, ведущие на эти страницы.
  4. +
  5. Скопируйте созданное меню в каждую страницу.
  6. +
  7. На каждой странице удалите только ссылку, которая указывает на эту же страницу (на странице index.html удалить ссылку index и так далее). Дело в том, что, находясь на странице index.html, нам незачем видеть ссылку в меню на эту же страницу. С одной стороны, нам незачем ещё раз переходить на эту же страницу, с другой, такой прием помогает визуально определить, смотря на меню, в какой части сайта мы находимся.
  8. +
+ +

Когда закончите задание, посмотрите, как это должно выглядеть:

+ +

An example of a simple HTML navigation menu, with home, pictures, projects, and social menu items

+ +
+

Если не удается сделать, или вы неуверены, что сделали верно, посмотрите наш вариант navigation-menu-marked-up.

+
+ +

Ссылки электронной почты

+ +

Можно создавать ссылки или кнопки, которые при нажатии открывают новое исходящее сообщение электронной почты, а не ссылку на ресурс или страницу. Для этого используется элемент {{HTMLElement("a")}} и mailto: — адрес почты.

+ +

Самыми простыми и часто используемыми формами mailto: являются  subject, cc, bcc и body; дальше прописываем адрес электронной почты. Например:

+ +
<a href="mailto:nowhere@mozilla.org">Отправить письмо для nowhere</a>
+
+ +

В результате полчим ссылку вида: Отправить письмо для nowhere.

+ +

Сам адрес электронной почты не является обязательным для заполнения. Если оставить это поле пустым (в поле {{htmlattrxref("href", "a")}} оставить только "mailto:"), откроется новое исходящее сообщение почтовой программой, в поле получателя будет пусто. Это можно использовать для кнопки "Поделиться".

+ +

Особенности и детали

+ +

Помимо адреса электронной почты, вы можете предоставить другую информацию. Фактически, любые стандартные поля для отправки почты могут быть добавлены к указанному вами адресу mailto. Часто используемыми из них являются «subject», «cc» и «body» (которые не являются истинным полем заголовка, но позволяют указать дополнительную информацию для нового сообщения электронной почты). Каждое поле и его значение задаются в качестве условия запроса.

+ +

Вот пример который включает cc(кому отправить копию сообщения, все получатели письма видят список тех кто это письмо получит), bcc(скрытый адрес получателя, никто из получателей не будет видеть полный список получателей письма), subject(тема письма) и body(текст сообщения):

+ +
<a href="mailto:nowhere@mozilla.org?cc=name2@rapidtables.com&bcc=name3@rapidtables.com&amp;subject=The%20subject%20of%20the%20email &amp;body=The%20body%20of%20the%20email">
+  Send mail with cc, bcc, subject and body
+</a>
+ +
+

Примечание: Значение каждого поля должно быть написано в URL-кодировке (то есть с непечатаемыми символами и пробелами percent-escaped). Обратите внимание на знак вопроса (?) для разделения основного адреса и дополнительных полей, амперсанд (&) для разделения каждого поля mailto: URL. Для этого используется стандартное описание URL запроса. Прочтите о методе GET, чтобы лучше понимать описание URL запроса.

+
+ +

Вот несколько примеров использования mailto URLs:

+ + + +

Заключение

+ +

Этой информации достаточно для создания ссылок! Вы вернётесь к ссылкам позже, когда начнёте изучать стили. Дальше вы рассмотрите семантику текста и более сложные и необычные возможности, которые будут полезны при создании контента сайта. В следующей главе будет рассматриваться продвинутое форматирование текста.

+ +

{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/HTML_text_fundamentals", "Learn/HTML/Introduction_to_HTML/Advanced_text_formatting", "Learn/HTML/Introduction_to_HTML")}}

+ +

В этом модуле

+ + + +
+ + + + + +
diff --git a/files/ru/learn/html/introduction_to_html/debugging_html/index.html b/files/ru/learn/html/introduction_to_html/debugging_html/index.html new file mode 100644 index 0000000000..1f3e03e508 --- /dev/null +++ b/files/ru/learn/html/introduction_to_html/debugging_html/index.html @@ -0,0 +1,181 @@ +--- +title: Отладка HTML +slug: Learn/HTML/Введение_в_HTML/Debugging_HTML +tags: + - Debugging + - Guide + - HTML + - Валидация + - Отладка +translation_of: Learn/HTML/Introduction_to_HTML/Debugging_HTML +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/Document_and_website_structure", "Learn/HTML/Introduction_to_HTML/Marking_up_a_letter", "Learn/HTML/Introduction_to_HTML")}}
+ +

Написать HTML — здорово, но как понять, где ошибка, когда что-то не работает? В этой статье описаны несколько инструментов, которые помогают искать и исправлять ошибки в HTML.

+ + + + + + + + + + + + +
Что нужно знать:Базовые знания HTML на уровне Начало работы с HTML, Основы редактирования текста в HTML, и Создание гиперссылок.
Чему вы научитесь:Искать проблемы в HTML с помощю инструментов отладки.
+ +

Отладка — это не страшно

+ +

Во время написания какого-нибудь кода, обычно все идет хорошо, пока не появляется тот момент, когда вы совершаете ошибку. Итак, ваш код не работает, или работает не так, как вы задумывали. Если вы попытаетесь скомпилировать неработающую программу на языке Rust, компилятор укажет на ошибку:

+ +

A console window showing the result of trying to compile a rust program with a missing quote around a string in a print statement. The error message reported is error: unterminated double quote string.В данном случае, сообщение об ошибке понять относительно просто — "unterminated double quote string". Если вы внимательно посмотрите на println!(Hello, world!"); , то заметите, что здесь отсутсвует двойная кавычка. Разумеется, сообщения об ошибках могут становиться куда более сложными для понимания по мере роста вашего кода, и даже самые простые случаи могут показаться пугающими для тех, кто ничего не знает о Rust.

+ +

Но не бойтесь отладки! Чтобы комфортно писать и отлаживать любой код, нужно понимать язык и его инструменты.

+ +

HTML и отладка

+ +

HTML не так сложен к пониманию, как Rust. HTML не компилируется в какую-либо другую форму перед тем, как браузер проанализирует это и покажет результат (он является интерпретируемым, а не компилируемым). Синтаксис HTML элементов  намного понятнее, чем у "настоящих языков программирования", таких как Rust, {{glossary("JavaScript")}}, или {{glossary("Python")}}. Способ, которым браузеры читают HTML более толерантен, чем у языков программирования, интерпретирующих свой код строже. Это одновременно и плохо, и хорошо.

+ +

Толерантный код

+ +

Так что же означает толерантный? В общих чертах, когда вы напортачили в коде, есть два типа ошибок, с которыми вы столкнетесь:

+ + + +

HTML не страдает от синтаксических ошибок, потому что браузер читает код толерантно, в том смысле, что страницы могут отображаться даже если синтаксические ошибки присутсвуют. Браузеры имеют встроенные правила по интерпретации неверно написанной разметки, и вы можете запустить что-либо, даже если вы имели в виду другое. Это может стать настоящей проблемой!

+ +
+

На заметку: HTML читается толерантно, потому что когда веб только появился, было решено позволить людям публиковать контент даже при условии некорректностей в коде, так как это куда более важно, чем уверенность в абсолютно верном синтаксисе. Веб не был бы сейчас так популярен, если бы относился к новичкам строго.

+
+ +

Активное обучение: Знакомство с толерантным кодом

+ +

Время изучить природу толерантного кода в HTML.

+ +
    +
  1. Для начала, скачайте наш пример отладки и сохраните локально. Эта демонстрация намеренно написана с ошибками, которые нам предстоит обнаружить.
  2. +
  3. Далее, откройте её в браузере. Вы увидите нечто вроде этого :A simple HTML document with a title of HTML debugging examples, and some information about common HTML errors, such as unclosed elements, badly nested elements, and unclosed attributes.
  4. +
  5. Сейчас документ выглядит не особо хорошо; Давайте посмотрим в код и выясним почему (Показано только тело документа): +
    <h1>HTML debugging examples</h1>
    +
    +<p>What causes errors in HTML?
    +
    +<ul>
    +  <li>Unclosed elements: If an element is <strong>not closed properly,
    +      then its effect can spread to areas you didn't intend
    +
    +  <li>Badly nested elements: Nesting elements properly is also very important
    +      for code behaving correctly. <strong>strong <em>strong emphasised?</strong>
    +      what is this?</em>
    +
    +  <li>Unclosed attributes: Another common source of HTML problems. Let's
    +      look at an example: <a href="https://www.mozilla.org/>link to Mozilla
    +      homepage</a>
    +</ul>
    +
  6. +
  7. Рассмотрим проблемы: +
      +
    • У {{htmlelement("p","параграфа")}} и {{htmlelement("li","элемента списка")}} не закрыты теги. На изображении выше видно, что разметка не пострадала, так как браузеру легко сделать вывод о том, где заканчивается один элемент и начинается другой.
    • +
    • Первый {{htmlelement("strong")}} элемент также не имеет закрывающего тега. Это уже более проблематично, так как сложно сказать, где элемент должен заканчиваться. На деле, весь оставшийся текст был выделен жирным.
    • +
    • Следующая часть нарушает правила вложенности: <strong>strong <em>strong emphasised?</strong> what is this?</em>. В этом случае код тоже сложно проинтерпретировать по причине, описанной выше.
    • +
    • В атрибуте {{htmlattrxref("href","a")}} отсутсвует закрывающая двойная кавычка. Это послужило причиной крупной проблемы — ссылка не воспроизвелась вовсе.
    • +
    +
  8. +
  9. Сейчас же посмотрим, как браузер сгенерировал собственную разметку, в противовес исходной разметке документа. Чтобы сделать это, воспользуемся инструментами разработчика. Если вы не знакомы с инструментами разработчика, потратьте несколько минут на Обзор инструментов разработки в браузерах.
  10. +
  11. В DOM инспекторе вы можете увидеть как сгенерировалась новая разметка: The HTML inspector in Firefox, with our example's paragraph highlighted, showing the text "What causes errors in HTML?" Here you can see that the paragraph element has been closed by the browser.
  12. +
  13. Используя DOM инспектор, давайте рассмотрим детали нашего кода, чтобы увидеть, как браузер пытается исправить наши ошибки в HTML (мы обозреваем в Firefox; другой современный браузер должен выдать те же результаты): +
      +
    • Параграфы и элементы списка получены с закрывающими тегами.
    • +
    • Было неочевидно, где элемент <strong> должен был закрыться, так что браузер обернул каждый отдельный блок текста своими собственными тегами strong, причем до самого низа документа!
    • +
    • Некорректная вложенность была исправлена браузером следующим образом: +
      <strong>strong
      +  <em>strong emphasised?</em>
      +</strong>
      +<em> what is this?</em>
      +
    • +
    • Ссылка с отсутсвующими двойными кавычками была удалена насовсем. Последний элемент списка будет выглядеть так: +
      <li>
      +  <strong>Unclosed attributes: Another common source of HTML problems.
      +  Let's look at an example: </strong>
      +</li>
      +
    • +
    +
  14. +
+ +

Валидация HTML

+ +

Из примера выше ясно, что стоит проверять валидность HTML. В простом примере сверху можно просто просмотреть весь код и найти ошибки, но как быть с огромными, сложными страницами?

+ +

Лучше всего проверить страницу в  сервисе валидации разметки. Его создал и поддерживает W3C — организация, которая занимается спецификациями HTML, CSS и других веб-технологий. Сервис проверит ваш HTML и составит отчет по ошибкам в нем.

+ +

The HTML validator homepage

+ +

HTML можно проверить по адресу, загрузив файл или напрямую ввести код HTML.

+ +

Активное обучение: Валидируем HTML-документ

+ +

Попробуем проверить документ-пример.

+ +
    +
  1. Откройте сервис валидации разметки в браузере.
  2. +
  3. Перейдите в режим Validate by Direct Input.
  4. +
  5. Скопируйте весь код документа (не только body) и вставьте в место для ввода.
  6. +
  7. Нажмите на Check (проверить).
  8. +
+ +

Вы увидите список ошибок и другую информацию.

+ +

A list of of HTML validation results from the W3C markup validation service

+ +

Работа с сообщениями об ошибках

+ +

Обычно сразу ясно, что значат сообщения, но иногда приходится постараться, чтобы понять, в чем дело. Сейчас мы пройдемся по всем ошибкам и разберем, что они значат. Обратите внимание, что в сообщениях указаны строка и столбец кода, чтобы ошибки было проще искать.

+ + + +

Если некоторые ошибки кажутся вам странными, начните исправление с остальных и проверьте документ еще раз. Иногда одна ошибка ломает большую часть документа.

+ +

Когда вы увидите эту надпись, в вашем документе больше нет ошибок:

+ +

Banner that reads "The document validates according to the specified schema(s) and to additional constraints checked by the validator."

+ +

Заключение

+ +

Теперь вы умеете отлаживать HTML. С новыми знаниями вам будет проще разобраться и в отладке более сложных языков — например, CSS и JavaScript. На этом мы заканчиваем вводный модуль курса HTML — время попробовать свои силы в упражнениях.

+ +

{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/Document_and_website_structure", "Learn/HTML/Introduction_to_HTML/Marking_up_a_letter", "Learn/HTML/Introduction_to_HTML")}}

+ +

В этом модуле

+ + diff --git a/files/ru/learn/html/introduction_to_html/document_and_website_structure/index.html b/files/ru/learn/html/introduction_to_html/document_and_website_structure/index.html new file mode 100644 index 0000000000..13f4f458d1 --- /dev/null +++ b/files/ru/learn/html/introduction_to_html/document_and_website_structure/index.html @@ -0,0 +1,291 @@ +--- +title: Структура документа и веб-сайта +slug: Learn/HTML/Введение_в_HTML/Структура_документа_и_веб-сайта +tags: + - Guide + - HTML + - Базовая разметка + - Гайд + - Для новичков + - С чего начать + - Структура сайта +translation_of: Learn/HTML/Introduction_to_HTML/Document_and_website_structure +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/Advanced_text_formatting", "Learn/HTML/Introduction_to_HTML/Debugging_HTML", "Learn/HTML/Introduction_to_HTML")}}
+ +

В дополнение к определению отдельных частей вашей страницы (таких как «абзац» или «изображение»), {{glossary("HTML")}} также содержит ряд элементов блочного уровня, используемых для определения областей вашего веб-сайта (такие как «заголовок», «навигационное меню», «колонка основного содержимого»). В этой статье рассматривается, как планировать базовую структуру сайта и писать HTML для представления этой структуры.

+ + + + + + + + + + + + +
Необходимые знания:Базовое знакомство с HTML, описано в разделе Начало работы с HTML. Форматирование текста в HTML, описано в разделе Основы текста в HTML. Как работают гиперссылки, описано в разделе Создание гиперссылок.
Задача:Изучить, как структурировать документ с помощью семантических тегов и как разработать структуру простого веб-сайта.
+ +

Основные составляющие документа

+ +

Веб-страницы могут и будут отличаться друг от друга, но все они, преимущественно, состоят из аналогичных стандартных компонентов, если только страница не отображает полноэкранное видео или игру, не является частью какого-либо художественного проекта или просто плохо структурирована:

+ +
+
Заголовок (колонтитул)
+
Обычно это большая полоса вверху страницы, с крупным заголовком и / или логотипом. Здесь указывается общая информация о веб-сайте, не меняющаяся от страницы к странице.
+
Навигационное меню
+
Ссылки на основные разделы сайта; обычно в виде кнопок, ссылок или вкладок. Также как и заголовок, навигация остается неизменной на всех страницах сайта — наличие непоследовательной навигации на Вашем сайте запутает и разочарует пользователей. Многие веб-дизайнеры считают панель навигации частью заголовка, а не отдельным компонентом, но это не является обязательным требованием; на самом деле, некоторые также утверждают, что их разделение на отдельные компоненты улучшает доступность, поскольку раздельная структура будет понятнее для людей, пользующихся считывателями экрана.
+
Основное содержимое
+
Большая область в центре страницы, содержащая, в основном, уникальный контент данной веб-страницы, например видео, которое вы хотите посмотреть, или рассказ, который вы читаете, или карту, которую вы хотите просмотреть, или заголовки новостей и т. д. Это одна из частей сайта, которая определенно будет меняться от страницы к странице!
+
Боковая панель
+
Как правило, содержит некоторую второстепенную информацию, ссылки, цитаты, рекламу и т.д. Обычно она относится к содержимому в основном контенте (например, на странице со статьей, боковая панель может содержать биографию автора или ссылки на связанные статьи), но в некоторых случаях здесь размещают и другие элементы, например, вторичную навигационную систему.
+
Нижний колонтитул (футер)
+
Полоса в нижней части страницы, которая обычно содержит уведомления об авторских правах или контактную информацию. Это место для размещения общей информации (например, заголовка), но обычно эта информация не является критичной или вторична для самого веб-сайта. Нижний колонтитул также иногда используется для {{Glossary("SEO")}} целей, предоставляя ссылки для быстрого доступа к популярному контенту.
+
+ +

"Типичный веб-сайт" может быть структурирован примерно так:

+ +

+ +

HTML для структурирования содержимого

+ +

Пример, показанный сверху, не красив и примитивен, но идеально подходит для иллюстрирования типичного макета веб-сайта. У некоторых веб-сайтов больше колонок, некоторые — более сложные, но идею Вы поняли. С правильным CSS Вы могли бы использовать практически любые элементы для обёртывания различных разделов и стилизовать их так, как Вам хочется, но, как обсуждалось ранее, нам нужно уважать семантику и использовать правильный элемент для правильной работы

+ +

Это потому, что визуальные эффекты — это ещё не самое главное. Мы используем цвет и размер шрифта для привлечения внимания посетителей к наиболее полезным частям содержимого, такого как навигационное меню или связанные ссылки, но что насчет людей со слабым зрением, к примеру, для которых концепция "розового" и "большого шрифта" не будет полезной?

+ +
+

Заметка: Люди с дальтонизмом составляют около 8% мирового населения. Слепые и слабовидящие люди составляют примерно 4-5% населения мира (в 2012 году в мире было 285 миллионов таких людей, а общая численность населения составляла около 7 миллиардов).

+
+ +

В своём HTML-коде Вы можете размечать разделы содержимого сайта на основе их функциональности — использовать элементы, которые представляют разделы контента, описанные выше, а вспомогательные технологии, такие как программы чтения с экрана, смогут распознавать эти элементы и помогать в таких задачах, как "найти основную навигацию" или "найти основное содержимое". Как мы упоминали ранее в ходе курса, существует ряд последствий неиспользования правильной структуры элементов и семантики для правильной работы.

+ +

Для реализации такой семантической разметки HTML предоставляет выделенные теги, которые можно использовать для создания таких разделов, например:

+ + + +

Активное обучение: исследование кода для нашего примера

+ +

Наш пример, представленный выше, содержит следующий код (Вы также можете найти пример в нашем репозитории Github). Мы хотели бы, чтобы Вы взгянули на приведенный выше пример, а затем просмотрели код ниже, чтобы узнать, из каких частей он состоит.

+ +
<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+
+    <title>Заголовок моей страницы</title>
+    <link href="https://fonts.googleapis.com/css?family=Open+Sans+Condensed:300|Sonsie+One" rel="stylesheet" type="text/css">
+    <link rel="stylesheet" href="style.css">
+
+    <!-- следующие 3 строки нужны для корректного отображения семантических элементов HTML5 в старых версиях Internet Explorer-->
+    <!--[if lt IE 9]>
+      <script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.js"></script>
+    <![endif]-->
+  </head>
+
+  <body>
+    <!-- Вот наш главный заголовок, который используется на всех страницах нашего веб-сайта -->
+
+    <header>
+      <h1>Заголовок</h1>
+    </header>
+
+    <nav>
+      <ul>
+        <li><a href="#">Домашняя страница</a></li>
+        <li><a href="#">Наша команда</a></li>
+        <li><a href="#">Проекты</a></li>
+        <li><a href="#">Контакты</a></li>
+      </ul>
+
+       <!-- Форма поиска — это еще один распространенный нелинейный способ навигации по веб-сайту. -->
+
+       <form>
+         <input type="search" name="q" placeholder="Search query">
+         <input type="submit" value="Go!">
+       </form>
+     </nav>
+
+    <!-- Здесь основное содержимое нашей страницы -->
+    <main>
+
+      <!-- Она содержит статью -->
+      <article>
+        <h2>Заголовок статьи</h2>
+
+        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Donec a diam lectus. Set sit amet ipsum mauris. Maecenas congue ligula as quam viverra nec consectetur ant hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur.</p>
+
+        <h3>Подраздел</h3>
+
+        <p>Donec ut librero sed accu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor.</p>
+
+        <p>Pelientesque auctor nisi id magna consequat sagittis. Curabitur dapibus, enim sit amet elit pharetra tincidunt feugiat nist imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros.</p>
+
+        <h3>Ещё один подраздел</h3>
+
+        <p>Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum soclis natoque penatibus et manis dis parturient montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est.</p>
+
+        <p>Vivamus fermentum semper porta. Nunc diam velit, adipscing ut tristique vitae sagittis vel odio. Maecenas convallis ullamcorper ultricied. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, is fringille sem nunc vet mi.</p>
+      </article>
+
+      <!-- Дополнительный контент также может быть вложен в основной контент -->
+      <aside>
+        <h2>Связанные темы</h2>
+
+        <ul>
+          <li><a href="#">Мне нравится стоять рядом с берегом моря</a></li>
+          <li><a href="#">>Мне нравится стоять рядом с морем</a></li>
+          <li><a href="#">Даже на севере Англии</a></li>
+          <li><a href="#">Здесь не перестаёт дождь</a></li>
+          <li><a href="#">Лаааадно...</a></li>
+        </ul>
+      </aside>
+
+    </main>
+
+    <!-- И вот наш главный нижний колонтитул, который используется на всех страницах нашего веб-сайта -->
+
+    <footer>
+      <p>©Авторские права никому не принадлежат, 2050. Все права защищены.</p>
+    </footer>
+
+  </body>
+</html>
+ +

Потратьте некоторое время, чтобы просмотреть код и понять его — комментарии внутри кода также помогут Вам в этом. Мы не просим Вас делать ничего больше в этом уроке, потому что ключ к пониманию макета документа заключается в написании осмысленной структуры HTML, а затем её развёртывании с помощью CSS. Мы подождем, пока вы не начнете изучать CSS-макет как часть темы CSS.

+ +

Подробнее об элементах HTML макета

+ +

Полезно понять общий смысл всех структурных элементов HTML — это то, над чем вы будете работать постепенно, когда начнёте получать больше опыта с веб-разработкой. Вы можете ознакомиться с деталями, прочитав статью HTML-элементы. Пока что это основные определения, которые вы должны попытаться понять:

+ + + +

Несемантические обертки

+ +

Иногда Вы будете сталкиваться с ситуацией, когда Вы не можете найти идеальный семантический элемент, чтобы сгруппировать некоторые элементы вместе или обернуть некоторый контент. Иногда Вам просто нужно будет сгруппировать несколько элементов вместе, чтобы применить к ним, как к единой сущности, {{glossary("CSS")}} или {{glossary("JavaScript")}}. Для таких случаев в HTML есть элементы {{HTMLElement("div")}} и {{HTMLElement("span")}}. Вам следует использовать их с подходящим значением атрибута {{htmlattrxref('class')}} или {{htmlattrxref('id')}}, чтобы можно было легко получить к ним доступ.

+ +

{{HTMLElement("span")}} — это строчный несемантический элемент, который стоит использовать только если Вы не можете подобрать более подходящий семантический текстовый элемент для обёртывания контента или если не хотите добавлять какие-либо конкретные значения. Например:

+ +
<p>Пьяный Король возвратился в свою комнату в 01:00
+и всё никак не мог войти в дверь: хмель мешал <span class="editor-note">[Примечание редактора: В этот момент
+свет на сцене должен быть приглушён]</span>.</p>
+ +

В этом примере примечание редактора просто сообщает дополнительные пожелания режиссёру пьесы. В нем нет особого семантического значения. Для слабовидящих пользователей, возможно, примечание будет отделено от основного содержимого с помощью CSS.

+ +

{{HTMLElement("div")}} — это блочный несемантический элемент, который следует использовать только если Вы не можете подобрать более подходящий семантический блочный элемент или если не хотите добавлять какие-либо конкретные значения. Например, представьте виджет корзины в интернет-магазине, который Вы можете открыть в любой момент нахождения на сайте:

+ +
<div class="shopping-cart">
+  <h2>Корзина</h2>
+  <ul>
+    <li>
+      <p><a href=""><strong>Silver earrings</strong></a>: $99.95.</p>
+      <img src="../products/3333-0985/thumb.png" alt="Серебряные серьги">
+    </li>
+    <li>
+      ...
+    </li>
+  </ul>
+  <p>Итого: $237.89</p>
+</div>
+ +

Ему не подходит <aside>, поскольку это не обязательно относится к основному содержимому страницы (Вы хотите, чтобы его можно было просматривать из любого места). Также не подходит и  <section>, т. к. это не часть основного содержимого страницы. Поэтому <div> подходит в этом случае. Мы включили заголовок в качестве указателя, чтобы помочь пользователям программ чтения с экрана в его поиске.

+ +
+

Внимание: div настолько просто использовать, что легко переборщить. Поскольку они не несут никакого семантического значения, они просто загромождают Ваш HTML-код. Старайтесь использовать их только тогда, когда нет лучшего семантического решения, и постарайтесь свести их использование к минимуму, иначе Вам будет трудно обновлять и поддерживать Ваши документы.

+
+ +

Перенос строки и горизонтальный разделитель

+ +

Два элемента, которые Вы будете периодически использовать или захотите узнать о них: {{htmlelement("br")}} и {{htmlelement("hr")}}:

+ +

<br> создает разрыв строки в абзаце, и это единственный способ изменить жёсткую структуру в ситуации, когда Вам нужна серия фиксированных коротких строк, например, в почтовом адресе или стихотворении. Пример:

+ +
<p>Жила-была девчушка Нелл,<br>
+Любившая писать HTML:<br>
+Её семантика ужасна была — <br>
+Она и сама прочитать ничего не могла.</p>
+ +

Без элемента <br> абзац  разместится в одну длинную линию (как было сказано ранее, HTML игнорирует переносы строк), а с ним в коде — разметка будет выглядеть следующим образом:

+ +

Жила-была девчушка Нелл,
+ Любившая писать HTML:
+ Её семантика ужасна была —
+ Она и сама прочитать ничего не могла.

+ +

<hr> создает горизонтальный разделитель в документе, это означает тематическое изменение текста (например, изменение темы или сцены). Визуально он просто похож на горизонтальную линию. В качестве примера:

+ +
<p>Рон был зажат в углу адскими тварями. Он боялся, но твёрдо решил защитить своих друзей, поднял свою волшебную палочку и приготовился к битве, надеясь, что справится со своим несчастьем.</p>
+<hr>
+<p>Тем временем Гарри сидел дома с раскрытым указом и размышлял о том, когда выйдут новые серии спин-оффов; в это время зачарованное письмо пархнуло в окно и приземлилось у него на коленях. Он прочитал его и подскочил на ноги; он подумал: "Думаю, самое время вернуться к работе".</p>
+ +

Будет выглядеть примерно так:

+ +

Рон был зажат в углу адскими тварями. Он боялся, но твёрдо решил защитить своих друзей, поднял свою волшебную палочку и приготовился к битве, надеясь, что справится со своим несчастьем.

+ +
+

Тем временем Гарри сидел дома с раскрытым указом и размышлял о том, когда выйдут новые серии спин-оффов; в это время зачарованное письмо пархнуло в окно и приземлилось у него на коленях. Он прочитал его и подскочил на ноги; он подумал: "Думаю, самое время вернуться к работе".

+ +

Планирование простого веб-сайта

+ +

Когда вы уже спланировали содержание одной веб-страницы, следующий логический шаг — продумать содержание всего веб-сайта: какие страницы нужны, как они будут устроены и связаны друг с другом для лучшего восприятия пользователем. Это называется {{glossary("Information architecture")}}. В большом, сложном веб-сайте на планирование может уходить много времени, однако спроектировать простой веб-сайт из нескольких страниц может быть очень легко и весело!

+ +
    +
  1. Имейте в виду, что у вас будет несколько элементов, общих для большинства (если не всех) страниц — например, меню навигации и содержимого нижнего колонтитула. Например, для сайта компании хорошая идея разместить контактные данные в нижнем колонтитуле на каждой странице. Составьте список элементов, общих для всех страниц. the common features of the travel site to go on every page: title and logo, contact, copyright, terms and conditions, language chooser, accessibility policy
  2. +
  3. Теперь набросайте структуру страниц (можно взять за образец наш простой дизайн, приведенный раннее). Что находится в этих блоках?A simple diagram of a sample site structure, with a header, main content area, two optional sidebars, and footer
  4. +
  5. Теперь составьте список остальной (уникальной для каждой страницы) информации, которую вы разместите на сайте.A long list of all the features that we could put on our travel site, from searching, to special offers and country-specific info
  6. +
  7. Сгруппируйте информацию по темам. Какие части можно разместить на одной странице? Это похоже на метод {{glossary("Card sorting")}}. The items that should appear on a holiday site sorted into 5 categories: Search, Specials, Country-specific info, Search results, and Buy things
  8. +
  9. Составьте карту сайта. Обведите каждую страницу рамкой, и продумайте перемещения пользователя между ними. Обычно в центре оказывается главная страница, с которой можно быстро перейти на все остальные. На небольшом сайте большинство страниц помещают в главную навигацию, но не обязательно класть туда все ссылки. Также можете пометить, как выглядят элементы страниц — ссылками, списками, карточками.
  10. +
+ +

A map of the site showing the homepage, country page, search results, specials page, checkout, and buy page

+ +

Самостоятельная работа: создайте свою собственную карту сайта

+ +

Приментие наш метод к своему сайту. О чем он будет?

+ +
+

Примечание: Сохраните свой код, он Вам ещё понадобится.

+
+ +

Заключение

+ +

Вы стали лучше понимаеть, как структурировать веб-страницу или сайт. В последней статье этого модуля мы узнаем, как отлаживать HTML.

+ +

Дополнительные материалы

+ + + +

{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/Advanced_text_formatting", "Learn/HTML/Introduction_to_HTML/Debugging_HTML", "Learn/HTML/Introduction_to_HTML")}}

+ +

В этом модуле

+ + diff --git a/files/ru/learn/html/introduction_to_html/getting_started/index.html b/files/ru/learn/html/introduction_to_html/getting_started/index.html new file mode 100644 index 0000000000..48904b9e17 --- /dev/null +++ b/files/ru/learn/html/introduction_to_html/getting_started/index.html @@ -0,0 +1,772 @@ +--- +title: Начало работы с HTML +slug: Learn/HTML/Введение_в_HTML/Начало_работы +tags: + - Guide + - HTML + - Аттрибуты + - Для начинающих + - Комментарии + - Пробелы + - Программирование + - Руководство + - Урок + - элементы +translation_of: Learn/HTML/Introduction_to_HTML/Getting_started +--- +
{{LearnSidebar}}
+ +
{{NextMenu("Learn/HTML/Introduction_to_HTML/The_head_metadata_in_HTML", "Learn/HTML/Введение_в_HTML/Начало_работы")}}
+ +

В этой статье мы охватим азы HTML, необходимые для начала работы. Дадим определение «элементам», «атрибутам», «тегам» и прочим важным понятиям, о которых вы, возможно, слышали, а также об их роли в языке. Мы также покажем, как устроены HTML-элементы, типичная HTML-страница, и объясним другие важные аспекты языка. По ходу дела, чтобы вы не заскучали, мы поиграем с настоящей HTML-страницей!

+ + + + + + + + + + + + +
Необходимые знания:Умение работать с компьютером, наличие необходимого ПО, базовые знания о работе с файлами.
Цель:Познакомиться с языком HTML и научиться описывать некоторые его элементы.
+ +

Что такое HTML?

+ +

{{glossary("HTML")}} (HyperText Markup Language - язык гипертекстовой разметки) не является языком программирования; это язык разметки, используемый для определения структуры веб-страниц, посещаемых пользователями. Они могут иметь сложную или простую структуру, всё зависит от замысла и желания веб-разработчика. HTML состоит из ряда {{glossary("Element", "элементов")}}, которые вы используете для того, чтобы охватить, обернуть или разметить различные части содержимого, чтобы оно имело определенный вид или срабатывало определенным способом. Встроенные {{glossary("Tag", "тэги")}} могут преобразовать часть содержимого в гиперссылку, по которой можно перейти на другую веб-страницу, выделить курсивом слова и так далее. Например, рассмотрим следующую строку:

+ +
Мой кот очень сердитый
+ +

Если мы хотим, чтобы строка отобразилась в таком же виде, мы можем определить её, как "параграф", заключив её в теги элемента "параграф"  ({{htmlelement("p")}}), например:

+ +
<p>Мой кот очень сердитый</p>
+ +
+

Примечание: Метки в HTML нечувствительны к регистру, то есть они могут быть записаны в верхнем или нижнем регистре. Например, тег {{htmlelement("title")}} может быть записан как <title>, <TITLE>, <Title>, <TiTlE>, и т.д., и он будет работать нормально. Лучшей практикой, однако, является запись всех тегов в нижнем регистре для обеспечения согласованности, удобочитаемости и других причин.

+
+ +

Структура HTML элементов

+ +

Давайте рассмотрим элемент "параграф" чуть подробнее:

+ +

+ +

Основными частями элемента являются:

+ +
    +
  1. Открывающий тег: Он состоит из названия (обозначения) элемента (в нашем случае, p), помещённого внутри угловых скобок. Данный тег служит признаком начала элемента, с этого момента тег начинает влиять на следующее после него содержимое.
  2. +
  3. Закрывающий тег: выглядит как и открывающий, но содержит слэш перед названием тега. Он служит признаком конца элемента. Пропуски закрывающих тегов — типичная ошибка новичков, которая может приводить к неопределённым результатам — в лучшем случае всё сработает правильно, в других страница может вовсе не прорисоваться или прорисоваться не как ожидалось.
  4. +
  5. Содержимое: Как видно, в нашем случае содержимым является простой текст.
  6. +
  7. Элемент: открывающий тег + закрывающий тег + содержимое = элемент.
  8. +
+ +

Активное изучение: создание вашего первого HTML элемента

+ +

Отредактируйте строку текста ниже в поле Ввод, обернув ее тегами <em> и </em> (вставьте <em> перед строкой, чтобы указать начало элемента, и </em> после нее, чтобы указать конец элемента) — эти действия должны выделить строку текста курсивом! Вы можете видеть изменения в реальном времени в поле Вывод.

+ +

Если Вы ошиблись, то всегда можете начать снова, воспользовавшись кнопкой Сбросить. Если упражнение вызывает у Вас затруднения, то нажмите кнопку Показать решение, чтобы увидеть правильный ответ.

+ + + +

{{ EmbedLiveSample('Playable_code', 700, 400, "", "", "hide-codepen-jsfiddle") }}

+ +

Вложенные элементы

+ + + +

Вы также можете вкладывать элементы внутрь других элементов — это называется вложенностью. Если мы хотим подчеркнуть, что наш кот очень сердитый, мы можем заключить слово "очень" в элемент {{htmlelement("strong")}} , который означает, что это слово крайне важно в данном контексте:

+ +
<p>Мой кот <strong>очень</strong>  сердитый.</p>
+ +

Вы должны удостовериться, что элементы вложены должным образом: в следующем примере мы открываем p элемент первым, затем элемент strong, затем мы закрываем элемент strong первым, затем p. Следующее писать неправильно:

+ +
<p>Мой кот <strong>очень сердитый.</p></strong>
+ +

Элементы должны открываться и закрываться правильно таким образом, чтобы явно находиться внутри или снаружи друг друга. Если они перекрываются так, как в примере выше, то ваш браузер попытается «додумать» за вас, что вы имели в виду, и вы получите непредсказуемый результат. Так что не делайте так!

+ +

Блочные и строчные элементы

+ + + +

Существует две важных категории элементов в HTML, которые вам стоит знать — элементы блочного уровня и строчные элементы.

+ + + +

Посмотрите на следующий пример:

+ +
<em>Первый</em><em>второй</em><em>третий</em>
+
+<p>четвертый</p><p>пятый</p><p>шестой</p>
+
+ +

{{htmlelement("em")}} — это строчный элемент, так что, как вы здесь видите, первые три элемента находятся на одной строке друг с другом без пробелов между ними. С другой стороны, {{htmlelement("p")}} — это элемент блочного уровня, так что каждый элемент находится на новой строке, с пространством выше и ниже каждого (этот интервал определяется CSS-оформлением по умолчанию, которое браузеры применяют к абзацам).

+ +

{{ EmbedLiveSample('Block_versus_inline_elements', 700, 200, "", "") }}

+ +
+

Примечание: HTML5 переопределил категории элементов в HTML: смотрите Категории типов содержимого элементов. Хотя эти определения точнее и однозначнее, чем те, которые были раньше, их гораздо сложнее понять, чем «блочный» и «строчный», поэтому мы будем придерживаться их в этом разделе.

+
+ +
+

Примечание: Не путайте термины «блочный» и «строчный», используемые в этом разделе, с одноименными типами отображения в CSS. Хотя по умолчанию они коррелируют, смена типа отображения в CSS не меняет категорию элемента и не влияет на то, во что его можно вкладывать и что можно вкладывать в него. Эта довольно частая путаница — одна из причин, почему HTML5 отказался от этих терминов.

+
+ +
+

Примечание: Вам могут пригодиться справочники, включающие списки блочных и строчных элементов — смотри Элементы блочного уровня и Строчные элементы.

+
+ +

Пустые элементы

+ + + +

Не все элементы соответствуют вышеупомянутому шаблону: открывающий тег, контент, закрывающий тег. Некоторые элементы состоят из одного тега и обычно используются для вставки чего-либо в то место документа, где размещены. Например, элемент {{htmlelement("img")}} вставляет картинку на страницу в том самом месте, где он расположен:

+ +
<img src="https://raw.githubusercontent.com/mdn/beginner-html-site/gh-pages/images/firefox-icon.png">
+ +

Это выведет на вашу страницу следующее:

+ +

{{ EmbedLiveSample('Empty_elements', 700, 300, "", "", "hide-codepen-jsfiddle") }}

+ +
+

Примечание: Пустые элементы иногда называют void-элементами.

+
+ +

Атрибуты

+ +

У элементов также могут быть атрибуты, которые выглядят так:

+ +

&amp;amp;lt;p class="editor-note">My cat is very grumpy&amp;amp;lt;/p>

+ +

Атрибуты содержат дополнительную информацию об элементе, которая, по вашему мнению, не должна отображаться в содержимом элемента. В данном случае атрибут class позволяет вам дать элементу идентификационное имя, которое в дальнейшем может быть использовано для обращения к элементу с информацией о стиле и прочими вещами.

+ +

Атрибут должен иметь:

+ +
    +
  1. Пробел между атрибутом и именем элемента (или предыдущим атрибутом, если у элемента уже есть один или несколько атрибутов).
  2. +
  3. Имя атрибута и следующий за ним знак равенства.
  4. +
  5. Значение атрибута, заключенное в кавычки.
  6. +
+ +

Активное изучение: Добавление атрибутов в элемент

+ + + +

Возьмём для примера элемент {{htmlelement("a")}} — означает anchor (якорь) и делает текст внутри него гиперссылкой. Может иметь несколько атрибутов, вот несколько из них:

+ + + +

Измените строку текста ниже в поле Ввод так, чтобы она вела на ваш любимый вебсайт. Сначала добавьте элемент <a>затем атрибут href и атрибут title. Наконец, укажите атрибут target чтобы открыть ссылку на новой вкладке. Вы можете наблюдать сделанные изменения в реальном времени в поле Вывод. Вы должны увидеть гиперссылку, при наведении курсора на которую появляется содержимое атрибута title, а при щелчке переходит по адресу в атрибуте href. Помните, что между именем элемента и каждым из атрибутов должен быть пробел.

+ +

Если Вы ошиблись, то всегда можете начать снова, воспользовавшись кнопкой Сбросить. Если упражнение вызывает у Вас затруднения, то нажмите кнопку Показать решение, чтобы увидеть правильный ответ.

+ + + +

{{ EmbedLiveSample('Playable_code2', 700, 400, "", "", "hide-codepen-jsfiddle") }}

+ +

Булевые атрибуты

+ + + +

Иногда вы будете видеть атрибуты, написанные без значения — это совершенно допустимо.  Такие атрибуты называются булевые, и они могут иметь только одно значение, которое в основном совпадает с его именем. В качестве примера возьмем атрибут {{htmlattrxref("disabled", "input")}}, который можно назначить для формирования элементов ввода, если вы хотите, чтобы они были отключены (неактивны), так что пользователь не может вводить какие-либо данные в них.

+ +
<input type="text" disabled="disabled">
+ +

Для краткости совершенно допустимо записывать их следующим образом (мы также для справки разместили не деактивированный элемент input, чтобы дать вам большее понимание происходящего):

+ +
<input type="text" disabled>
+
+<input type="text">
+
+ +

На выходе оба варианта будут выглядеть следующим образом:

+ +

{{ EmbedLiveSample('Boolean_attributes', 700, 100, "", "", "hide-codepen-jsfiddle") }}

+ +

Опускание кавычек вокруг значений атрибутов

+ + + +

Осматриваясь во всемирной сети, вы будете встречать различные незнакомые способы написания разметки, включая написание значений атрибутов без кавычек. Это допустимо при определенных условиях, но разрушит вашу разметку при других. Например, возвращаясь к нашему упражнению с гиперссылкой, мы можем написать основной вариант только с атрибутом href так:

+ +
<a href=https://www.mozilla.org/>любимый веб-сайт</a>
+ +

Однако, как только мы добавим атрибут title в таком же стиле, мы поступим неверно:

+ +
<a href=https://www.mozilla.org/ title=The Mozilla homepage>favorite website</a>
+ +

В этом месте браузер неверно истолкует вашу разметку, думая, что атрибут title — это на самом деле три разных атрибута — атрибут title со значением "The" и два булевых атрибута: Mozilla и homepage. Это, очевидно, не то, что имелось в виду, и приведёт к ошибке или неожиданному поведению кода, как это показано в живом примере ниже. Попробуйте навести курсор на ссылку, чтобы увидеть, на что похож текст title!

+ +

{{ EmbedLiveSample('Omitting_quotes_around_attribute_values', 700, 100, "", "", "hide-codepen-jsfiddle") }}

+ +

Наш совет: всегда используйте кавычки в атрибутах — это позволит избежать подобных проблем, и, следовательно, код будет более читабельным.

+ +

Одинарные или двойные кавычки?

+ + + +

В этой статье вы заметите, что все атрибуты заключены в двойные кавычки. Однако, вы можете видеть одинарные кавычки в HTML документах других людей. Это исключительно дело вкуса, и вы можете свободно выбирать, какие из них предпочитаете. Обе следующие строки эквивалентны:

+ +
<a href="http://www.example.com">Ссылка к моему примеру.</a>
+
+<a href='http://www.example.com'>Ссылка к моему примеру.</a>
+ +

Однако вы должны убедиться, что не смешиваете их вместе. Следующее будет неверным!

+ +
<a href="http://www.example.com'>Ссылка к моему примеру.</a>
+ +

Если вы используете один тип кавычек в своем HTML, то вы можете поместить внутрь их кавычки другого типа, не вызывая никаких проблем:

+ +
<a href="http://www.example.com" title="Isn't this fun?">A link to my example.</a>
+ +

Если вы хотите вставить кавычки того же типа, то вы должны использовать объекты HTML. Например, это работать не будет:

+ +
<a href='http://www.example.com' title='Isn't this fun?'>A link to my example.</a>
+ +

Поэтому вам нужно сделать так:

+ +
<a href='http://www.example.com' title='Isn&#39;t this fun?'>A link to my example.</a>
+ +

Структура HTML документа

+ +

Ниже дан пример оборачивания основных, самостоятельных HTML элементов, которые сами по себе не очень полезны. Давайте посмотрим, как самостоятельные элементы объединяются для формирования всей HTML страницы:

+ +
<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Тестовая страница</title>
+  </head>
+  <body>
+    <p>Это — моя страница</p>
+  </body>
+</html>
+ +

Вот что мы имеем:

+ +
    +
  1. <!DOCTYPE html>: Объявление типа документа. Очень давно, ещё когда HTML был молод (1991/2), типы документов использовались в качестве ссылок на набор правил, которым HTML-страница должна была следовать, чтобы она считалась хорошей, что может означать автоматическую проверку ошибок и другие полезные вещи. Объявление типа документа выглядело примерно вот так: + +
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    + Однако в наши дни никто особо не думает о них, и типы документа стали историческим артефактом, которые должны быть включены везде, чтобы всё работало правильно. <!DOCTYPE html> — это самый короткий вид типа документа, который считается действующим. На самом деле это всё, что нужно вам знать о типах документов .
  2. +
  3. <html></html>: Элемент {{htmlelement("html")}} содержит в себе всё содержимое на всей странице, и иногда его называют "корневой элемент". 
  4. +
  5. <head></head>: Элемент {{htmlelement("head")}}. Данный элемент выступает в качестве контейнера для всего содержимого, которое вы хотите включить в HTML документ, но не хотите показывать посетителям вашей страницы. Он включает такие вещи, как ключевые слова и описание страницы, которые вы хотели бы показывать в поисковых запросах, CSS для стилизирования вашего контента, объявление поддерживаемого набора символов и многое другое. Вы узнаете больше об этом из следующей статьи данного руководства.
  6. +
  7. <meta charset="utf-8">: Этот элемент устанавливает в качестве символьной кодировки для вашего документа utf-8 , который включает большинство символов из всех известных человечеству языков. По существу, теперь страница сможет отобразить любой текстовый контент, который вы сможете в неё вложить. Нет причин не устанавливать эту кодировку, это также позволит избежать некоторых проблем позднее.
  8. +
  9. <title></title>: Элемент {{htmlelement("title")}}. Этот элемент устанавливает заголовок вашей страницы, который появляется во вкладке браузера, загружающей эту страницу, также это заглавие используется при описании страницы, когда вы сохраняете её в закладках или избранном.
  10. +
  11. <body></body>: Элемент {{htmlelement("body")}}. Он содержит весь контент, который вы хотите показывать посетителям вашей страницы, — текст, изображения, видео, игры, проигрываемые аудио дорожки или что-то ещё.
  12. +
+ +

Активное изучение: Добавление элементов в ваш HTML-документ

+ + + +

Если вы хотите поэкспериментировать с написанием HTML на своём компьютере, то можете:

+ +
    +
  1. Скопировать пример HTML-страницы, расположенный выше.
  2. +
  3. Создать новый файл в текстовом редакторе.
  4. +
  5. Вставить код в ваш новый текстовый файл.
  6. +
  7. Сохранить файл как index.html.
  8. +
+ +
+

Примечание: Вы также можете найти этот базовый пример HTML на  MDN Learning Area Github repo.

+
+ +

Теперь можете открыть браузер и посмотреть, во что отрисовался код, а потом изменить его, обновить страницу и посмотреть, что получилось. Сначала страница выглядит так:

+ +

Скриншот примера тестовой страницы
+ Для этого упражнения вы можете редактировать код локально на своём компьютере, как предлагается выше, а можете работать в редакторе, расположенном ниже. В редакторе показано только содержимое элемента {{htmlelement("body")}}. Попробуйте сделать следующее:

+ + + +

Если вы запутались, всегда можно запустить пример сначала кнопкой Сбросить. Сдаётесь — посмотрите ответ, нажав на Показать решение.

+ + + +

{{ EmbedLiveSample('Playable_code3', 700, 600, "", "", "hide-codepen-jsfiddle") }}

+ +

Пробелы в HTML

+ + + +

Вы могли заметить, что в примерах кода из этой статьи много пробелов. Это вовсе не обязательно — следующие два примера эквивалентны:

+ +
<p>Собаки глупы.</p>
+
+<p>Собаки
+         глупы.</p>
+ +

Не важно, сколько пустого места вы используете в разметке (что может включать пробелы и сдвиги строк): браузер при анализе кода сократит всё пустое место до одного пробела. Зачем использовать много пробелов? Ответ: это доступность для понимания — гораздо легче разобраться, что происходит в вашем коде, если он удобно отформатирован, а не просто собран вместе в одном большом беспорядке. В нашем коде каждый вложенный элемент сдвинут на два пробела относительно элемента, в котором он находится. Вы можете использовать любое форматирование (в частности, количество пробелов для отступа), но лучше придерживаться одного стиля.

+ +

Ссылки на сущности: Включение специальных символов в HTML

+ + + +

В HTML символы <, >, ", ' и & являются специальными. Они являются частью самого синтаксиса HTML. Так как же включить в текст один из этих специальных символов? Например, если вы хотите использовать амперсанд или знак «меньше» и не интерпретировать его как код.

+ +

Мы должны использовать ссылки-мнемоники  — специальные коды, которые отображают спецсимволы, и могут быть использованы в необходимых позициях. Каждая ссылка-мнемоник начинается с ампресанда (&) и завершается точкой с запятой (;).

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Буквенный символСимвольный эквивалент
<&lt;
>&gt;
"&quot;
'&apos;
&&amp;
+ +

В  следующем примере вы видите два абзаца, которые рассказывают о веб-технологиях:

+ +
<p>В HTML вы определяете параграф элементом <p>.</p>
+
+<p>В HTML вы определяете параграф элементом &lt;p&gt;.</p>
+ +

В живом выводе ниже вы можете заметить, что первый абзац выводится неправильно, так как браузер считает, что второй элемент  <p> является началом нового абзаца! Второй абзац нашего кода выводится правильно, потому что мы заменили угловые скобки на ссылки-мнемоники.

+ +

{{ EmbedLiveSample('Entity_references_Including_special_characters_in_HTML', 700, 200, "", "", "hide-codepen-jsfiddle") }}

+ +
+

Примечание: Таблица всех доступных в  HTML символов-мнемоников — в Википедии: List of XML and HTML character entity references.

+
+ +

HTML комментарии

+ + + +

В HTML, как и в большинстве языков программирования, есть возможность писать комментарии в коде. Комментарии игнорируются обозревателем и не видны пользователю, их добавляют для того, чтобы пояснить, как работает написанный код, что делают отдельные его части и т. д. Такая практика полезна, если вы возвращаетесь к коду, который давно не видели или когда хотите передать его кому-то другому.

+ +

Чтобы превратить часть содержимого HTML-файла в комментарий, нужно поместить её в специальные маркеры <!-- и -->, например:

+ +
<p> Меня нет в комментариях( </p>
+
+<!-- <p>А теперь есть!</p> -->
+ +

Как вы увидете ниже, первый параграф будет отображён на экране, а второй нет.

+ +

{{ EmbedLiveSample('HTML_comments', 700, 100, "", "", "hide-codepen-jsfiddle") }}

+ +

Подведение итогов

+ +

Вы дошли до конца статьи — надемся, вам понравилось путешествие по основам HTML. На этом этапе вы уже должны немного разобраться, как выглядит язык, как он работает на базовом уровне и уметь описать несколько элементов и атрибутов. Сейчас идеальное время и место, чтобы продолжить изучать HTML. В последующих статьях мы рассмотрим некоторые из вещей, которые вы уже рассмотрели, но намного подробнее, а также представим некоторые новые функции языка. Оставайтесь с нами!

+ +
+

Примечание: Сейчас, когда вы начинаете больше узнавать о HTML, вы также можете начать изучать основы каскадных таблиц стилей Cascading Style Sheets, или CSS. CSS — это язык, который используется для стилизации веб-страниц (например, изменение шрифта или цветов или изменение макета страницы). Как вы скоро поймете, HTML и CSS созданы друг для друга.

+
+ +

Смотрите также

+ + + +
{{NextMenu("Learn/HTML/Introduction_to_HTML/The_head_metadata_in_HTML", "Learn/HTML/Введение_в_HTML/Начало_работы")}}
+ +
+ +

В этом модуле

+ + diff --git a/files/ru/learn/html/introduction_to_html/html_text_fundamentals/index.html b/files/ru/learn/html/introduction_to_html/html_text_fundamentals/index.html new file mode 100644 index 0000000000..711c0bfdf3 --- /dev/null +++ b/files/ru/learn/html/introduction_to_html/html_text_fundamentals/index.html @@ -0,0 +1,994 @@ +--- +title: Основы редактирования текста в HTML +slug: Learn/HTML/Введение_в_HTML/HTML_text_fundamentals +tags: + - Guide + - HTML + - Абзацы + - Введение в HTML + - Изучение + - Начинающий + - Параграфы + - Руководство + - Семантика + - Текст +translation_of: Learn/HTML/Introduction_to_HTML/HTML_text_fundamentals +--- +
+
 {{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/The_head_metadata_in_HTML", "Learn/HTML/Introduction_to_HTML/Creating_hyperlinks", "Learn/HTML/Introduction_to_HTML")}}
+
+ +

Одна из основных задач HTML — придавать тексту структуру и смысл, {{glossary("семантику")}}, так, чтобы браузер смог отобразить текст корректно. Эта статья покажет, как можно использовать {{glossary("HTML")}}, чтобы упорядочить текст на странице путём добавления заголовков и абзацев, выделения слов, создания списков и многое другое.

+ + + + + + + + + + + + +
Предварительные требования:Базовое знакомство с HTML , описанное в Начало работы с HTML.
Задача:Изучить базовые способы разметки текста путем добавлением на страницу структуры и значения — создать абзацы, заголовки, списки, акценты и цитаты..
+ +

Основы: Заголовки и абзацы / параграфы

+ +

Большинство структурированных текстов состоят из параграфов и заголовков, независимо от того, читаете ли вы рассказ, или газету, или учебник, журнал и т.д.

+ +

An example of a newspaper front cover, showing use of a top level heading, subheadings and paragraphs.

+ +

Упорядоченный контент делает чтение более легким и приятным.

+ +

В HTML каждый абзац заключен в элемент {{htmlelement("p")}}, подобно:

+ +
<p>Я параграф, да, это я.</p>
+ +

Каждый заголовок заключен в элемент заголовка {{htmlelement("h1")}}:

+ +
<h1>Я заголовок истории.</h1>
+ +

Имеется шесть элементов заголовка: {{htmlelement("h1")}}, {{htmlelement("h2")}}, {{htmlelement("h3")}}, {{htmlelement("h4")}}, {{htmlelement("h5")}} и {{htmlelement("h6")}}. Каждый элемент представляет разный уровень контента в документе; <h1> представляет главный заголовок, <h2> представляет подзаголовки, <h3> представляет под-подзаголовки и так далее.

+ +

Создание иерархической структуры

+ +

Например, в рассказе <h1> будет представлять заглавие рассказа, <h2> обозначит название каждой главы, <h3>  будет обозначать подзаголовки в каждой главе и так далее.

+ +
<h1> Сокрушительная скука </ h1>
+
+<p> Крис Миллс </ p>
+
+<h2> Глава 1: Темная ночь </ h2>
+
+<p> Это была темная ночь. Где-то кричала сова. Дождь обрушился на ... </ p>
+
+<h2> Глава 2: Вечное молчание </ h2>
+
+<p> Наш главный герой ничего не мог, когда шёпот из тёмной фигуры ... </ p>
+
+<h3> Призрак говорит </ h3>
+
+<p> Прошло ещё несколько часов, когда внезапно призрак выпрямился и воскликнул: «Пожалуйста, помилуй мою душу!» </ p>
+
+ +

Всё это действительно зависит от вас — что именно будут представлять собой элементы, пока существует иерархия. Вам просто нужно иметь в виду несколько хороших правил при создании таких структур.

+ + + +

Зачем нам необходима структура?

+ +

Чтобы ответить на этот вопрос, давайте посмотрим на text-start.html — отправную точку нашего примера для этой статьи (хороший рецепт хумуса). Вы должны сохранить копию этого файла на своем локальном компьютере, так как вам понадобится это для упражнений позже. Сейчас тело этого документа содержит несколько фрагментов контента — они не отмечены каким-либо образом, но они разделены разрывами строк (был нажат Enter / Return  для перехода на следующую строку).

+ +

Однако, когда вы откроете документ в своем браузере, вы увидите, что текст выглядит как один большой кусок!

+ +

A webpage that shows a wall of unformatted text, because there are no elements on the page to structure it.

+ +

Это связано с тем, что нет элементов для создания структуры контента, поэтому браузер не знает, где здесь заголовок и где абзац. Более того:

+ + + +

Поэтому нужно дать структурную разметку нашему контенту.

+ +

Активное изучение: создание структуры для нашего контента

+ +

Давайте рассмотрим это на живом примере. В приведённом ниже примере добавьте элементы в исходный текст в поле «Редактируемый код», чтобы он отображался как заголовок и два абзаца в поле «Результат».

+ +

Если вы допустили ошибку, вы всегда можете сбросить её с помощью кнопки Сбросить. Если вы застряли, нажмите кнопку Показать решение, чтобы увидеть ответ.

+ + + +

{{ EmbedLiveSample('Playable_code', 700, 500) }}

+ +

Почему мы нуждаемся в семантике?

+ +

Семантика проявляется всюду вокруг нас — мы полагаемся на опыт, который рассказывает нам, какова функция бытовых предметoв; когда мы что-то видим, мы знаем, какова его функция. Так, например, мы ожидаем, что красный свет на светофоре означает «стоп», а зеленый свет означает «идти». Жизнь станет очень сложной, если применяется неправильная семантика (какие-либо страны используют красный цвет для обозначения «идти»? Надеюсь, что нет.)

+ +

В подобном ключе нам нужно убедиться, что мы используем правильные элементы, придавая нашему контенту правильное значение, функцию или внешний вид. В этом контексте элемент {{htmlelement ("h1")}} также является семантическим элементом, который даёт тексту, который он обёртывает,  роль (или значение) «заголовка верхнего уровня на вашей странице».

+ +
<h1>Это заголовок верхнего уровня</h1>
+ +

По умолчанию браузер придаст ему большой размер шрифта, чтобы он выглядел как заголовок (хотя вы можете стилизовать его как угодно, используя CSS). Что ещё более важно, его семантическое значение будет использоваться несколькими способами, например, поисковыми системами и программами чтения с экрана (как упоминалось выше).

+ +

С другой стороны, вы можете сделать любой элемент похожим на заголовок верхнего уровня. Рассмотрим следующее:

+ +
<span style="font-size: 32px; margin: 21px 0;">Это заголовок верхнего уровня?</span>
+ +

Это элемент {{htmlelement ("span")}}. У него нет семантики. Вы используете его, когда хотите применить к контенту CSS (или сделать что-то с ним с помощью JavaScript), не придавая ему никакого дополнительного значения (об этом вы узнаете позже). Мы применили CSS, чтобы он выглядел как заголовок верхнего уровня, но поскольку он не имеет семантического значения, он не получит никаких дополнительных преимуществ, описанных выше. Рекомендуется использовать соответствующий элемент HTML на практике.

+ +

Списки

+ +

Теперь обратим наше внимание на списки. Списки есть везде вокруг нас — от вашего списка покупок до списка направлений, которым вы подсознательно следуете, чтобы каждый день добраться домой, и списка инструкций, которые вы выполняете в этом руководстве! Списки используются всюду в Интернете, и мы рассмотрим три разных типа списков.

+ +

Неупорядоченные

+ +

Неупорядоченные списки используются для элементов, для которых порядок не имеет значения, — возьмем, к примеру, список покупок:

+ +
молоко
+яйца
+хлеб
+хумус
+ +

Каждый неупорядоченный список начинается с элемента {{htmlelement ("ul")}} (unordered list) — он обёртывает все элементы списка: молоко, яйца, хлеб, хумус.

+ +

Последний шаг состоит в том, чтобы обернуть каждый элемент списка в элемент {{htmlelement ("li")}} (элемент списка):

+ +
<ul>
+  <li>молоко</li>
+  <li>яйца</li>
+  <li>хлеб</li>
+  <li>хумус</li>
+</ul>
+ +

Активное изучение: разметка неупорядоченного списка

+ +

Попробуйте отредактировать образец ниже, чтобы создать свой собственный неупорядоченный список HTML.

+ + + +

{{ EmbedLiveSample('Playable_code_2', 700, 400) }}

+ +

Упорядоченные

+ +

Упорядоченные списки — это списки, в которых порядок элементов имеет значение, — возьмем в качестве примера маршрут следования:

+ +
Доедьте до конца дороги
+Поверните направо
+Едьте прямо через первые два перекрестка с круговым движением
+Поверните налево на третьем перекрестке
+Школа справа от вас, 300 метров вверх по дороге
+ +

Структура разметки такая же, как для неупорядоченных списков, за исключением того, что вы должны обернуть элементы списка в элемент {{htmlelement ("ol")}} (ordered list), а не <ul>:

+ +
<ol>
+   <li>Доедьте до конца дороги</li>
+   <li>Поверните направо</li>
+   <li>Едьте прямо через первые два перекрестка с круговым движением</li>
+   <li>Поверните налево на третьем перекрестке</li>
+   <li>Школа справа от вас, в 300 метрах вверх по дороге</li>
+</ol>
+ +

Активное изучение: разметка упорядоченного списка

+ +

Попробуйте отредактировать образец ниже, чтобы создать свой собственный упорядоченный список HTML.

+ + + +

{{ EmbedLiveSample('Playable_code_3', 700, 500) }}

+ +

Активное изучение: разметка собственной страницы рецептов

+ +

Итак, в этот момент в статье у вас есть вся необходимая информация, чтобы разметить наш пример страницы рецепта. Вы можете либо сохранить локальную копию исходного файла text-start.html и выполнить в нём работу, либо сделать это в приведённом ниже примере. Делать это локально, вероятно, будет лучше, так как тогда вы сможете сохранить работу, которую вы делаете, тогда как если вы её добавите в редактируемый пример, она будет потеряна при следующем открытии страницы. У обоих способов есть плюсы и минусы.

+ + + +

{{ EmbedLiveSample('Playable_code_4', 700, 500) }}

+ +

Если вы застряли, вы всегда можете нажать кнопку Показать решение или проверить наш пример text-complete.html в нашем реестре github.

+ +

Вложенные списки

+ +

Вполне нормально вложить один список в другой. Возможно, вы захотите, чтобы один список распологался внутри другого. Давайте возьмем второй список из нашего примера рецепта:

+ +
<ol>
+  <li>Очистите чеснок от кожуры и крупно нарежьте.</li>
+  <li>Удалите стебель и семена у перца; крупно нарежьте перец.</li>
+  <li>Добавьте все ингредиенты в пищевой комбайн.</li>
+  <li>Измельчите все ингридиенты до состояния пасты.</li>
+  <li>Если вы хотите "грубый" хумус, измельчайте пару минут.</li>
+  <li>Если вам нужен гладкий хумус, измельчайте дольше.</li>
+</ol> 
+ +
+
Поскольку последние две строки очень тесно связаны с тем, что было до них (они читаются как вспомогательные инструкции или варианты, которые подходят под этой маркой), может иметь смысл вложить их в свой собственный неупорядоченный список и поместить этот список внутри текущего. Это будет выглядеть так:
+
+ +
<ol>
+  <li>Очистите чеснок от кожуры и крупно нарежьте.</li>
+  <li>Удалите стебель и семена у перца; крупно нарежьте перец.</li>
+  <li>Добавьте все ингредиенты в пищевой комбайн.</li>
+  <li>Измельчите все ингридиенты до состояния пасты.
+    <ul>
+      <li>Если вы хотите "грубый" хумус, измельчайте пару минут.</li>
+      <li>Если вам нужен гладкий хумус, измельчайте дольше.</li>
+    </ul>
+  </li>
+</ol>
+ +

Попробуйте вернуться к предыдущему примеру активного обучения и обновить второй список.

+ +

Акцент и важность

+ +
+
В обиходе мы часто подчеркиваем определённые слова, чтобы изменить смысл предложения и мы часто хотим отметить некоторые слова как важные или разные в некотором роде. HTML предоставляет различные семантические элементы, позволяющие нам добавлять текстовые материалы с такими эффектами, и в этом разделе мы рассмотрим несколько наиболее распространенных.
+ +
+
+ +

Акцент

+ +

Когда мы хотим добавить акцент в разговорный язык, мы подчеркиваем определенные слова, тонко изменяя смысл того, что мы говорим. Точно так же на письменном языке мы склонны подчеркивать слова, выделяя их курсивом. Например, следующие два предложения имеют разные значения.

+ +

Я рад, что ты не опоздал.

+ +

Я рад, что ты не опоздал.

+ +

В первом предложении звучит искреннее облегчение, что человек не опоздал. Во втором, напротив, звучит сарказм или пассивная агрессия: так выражена досада от того, что человек немного опоздал.

+ +

В таких случаях в HTML используется элемент {{htmlelement ("em")}} (выделение). Кроме того, чтобы сделать документ более интересным для чтения, они распознаются программами, считывающими с экрана, и произносятся другим тоном. Браузеры стилизуют это по умолчанию курсивом, но вы можете не использовать этот тег, чтобы получить курсив. Для выделения курсивом вы можете использовать элемент {{htmlelement ("span")}} и CSS, или, возможно, элемент {{htmlelement ("i")}} (смотрите ниже).

+ +
<p>Я <em>рад</em>, что ты не <em>опоздал</em>.</p>
+ +

Важное значение

+ +

Чтобы подчеркнуть важные слова, мы склонны подчеркивать их в устной речи и выделять жирным на письменном языке. Например:

+ +

Эта жидкость очень токсична.
+
+ Я рассчитываю на вас. Не опаздывай!

+ +

В таких случаях в HTML используется элемент {{htmlelement ("strong")}} (важное значение). Помимо того, что документ становится более полезным,  они распознаются программами, считывающими с экрана, и говорят другим тоном. Браузеры стилизуют это как полужирный текст по умолчанию, но вы можете не использовать этот тег, чтобы получить жирный шрифт. Для получения жирного шрифта вы можете использовать элемент {{htmlelement ("span")}} и CSS, или, возможно, элемент {{htmlelement ("b")}} (смотрите ниже).

+ +
<p>Эта жидкость <strong>очень токсична</strong>.</p>
+
+<p>Я рассчитываю на тебя. <strong>Не </strong>опаздывай!</p>
+ +

При желании вы можете вложить важные и акцентированные слова друг в друга:

+ +
<p>Эта жидкость <strong>очень токсична</strong> —
+если ты выпьешь её, <strong>то можешь<em>умереть</em></strong>.</p>
+ +

Активное изучение: Давайте будем важны!

+ +

В этом разделе активного обучения мы предоставили редактируемый пример. Внутри него мы хотели бы, чтобы вы попытались добавить акцент и большую важность для слов, которые, по вашему мнению, им нужны, просто для того, чтобы попрактиковаться.

+ + + +

{{ EmbedLiveSample('Playable_code_5', 700, 500) }}

+ +

Курсив, жирный шрифт, подчеркивание...

+ +
+
Элементы, которые мы обсуждали до сих пор, имеют четкую привязку к семантике. Ситуация с {{htmlelement ("b")}}, {{htmlelement ("i")}} и {{htmlelement ("u")}} несколько сложнее. Они появились в эпоху, когда CSS  поддерживался плохо или вообще не поддерживался, чтобы люди могли писать жирный текст, курсив или подчеркнутый текст. Такие элементы, которые влияют только на внешний вид, а не на семантику, известны как элементы представления и больше не должны использоваться, поскольку, как мы видели ранее, семантика очень важна для доступности людям с ограниченными возможностями, SEO и так далее.
+ +
+
+ +

HTML5 переопределил <b>, <i> и <u> с новыми, несколько запутанными, семантическими ролями.

+ +

Вот хорошее правило: предпочтительней использовать <b>, <i> или <u> для передачи значения, традиционно передаваемого жирным шрифтом, курсивом или подчеркиванием, при условии, что нет более подходящего элемента. Тем не менее, всегда важно сохранить менталитет доступности. Концепция курсива не очень помогает людям, использующим устройства для чтения с экрана, или людям, использующим систему письма, отличную от латинского алфавита.

+ + + +
+

Предупреждение о подчеркивании: люди сильно ассоциируют подчеркивание с гиперссылками. Поэтому в Интернете лучше всего подчеркнуть только ссылки. Используйте элемент <u>, когда он семантически подходит, но подумайте о том, чтобы использовать CSS для изменения подчеркивания по умолчанию для чего-то более подходящего в Интернете. Пример ниже иллюстрирует, как это можно сделать.

+
+ +
<!-- Научные наименования -->
+<p>
+  Колибри обыкновенный (<i>архилоус обыкновенный</i>) —
+наиболее часто встречающийся вид колибри в северо-восточной Америке.
+</p>
+
+<!-- Иностранные слова -->
+<p>
+  Случился прилив иностранных слов, таких как <i lang="uk-latn">vatrushka</i>,
+  <i lang="id">nasi goreng</i> и <i lang="fr">soupe à l'oignon</i>.
+</p>
+
+<!-- Явно неправильное произношение или написание -->
+<p>
+  Когда-нибудь я узнаю, как <u>гаварить</u> без ошибок.
+</p>
+
+<!-- Выделение ключевых слов в инструкциях -->
+<ol>
+  <li>
+    <b>Отрежьте</b> два ломтика хлеба.
+  </li>
+  <li>
+    <b>Добавьте</b> кусочек помидора и лист латука между ломтями хлеба.
+  </li>
+</ol>
+ +

Заключение

+ +

Вот и всё! Эта статья должна была дать вам хорошее представление о том, как начать разметку текста в HTML, и познакомить вас с некоторыми из наиболее важных элементов в этой области. В этой области есть намного больше семантических элементов, и мы рассмотрим их в нашей статье «Больше семантических элементов» позже в курсе. В следующей статье мы подробно рассмотрим, как создавать гиперссылки, возможно, самый важный элемент в Интернете. 

+ +

{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/The_head_metadata_in_HTML", "Learn/HTML/Introduction_to_HTML/Creating_hyperlinks", "Learn/HTML/Introduction_to_HTML")}}

+ +

В этом модуле

+ + diff --git a/files/ru/learn/html/introduction_to_html/index.html b/files/ru/learn/html/introduction_to_html/index.html new file mode 100644 index 0000000000..1ecf1eb84a --- /dev/null +++ b/files/ru/learn/html/introduction_to_html/index.html @@ -0,0 +1,67 @@ +--- +title: Введение в HTML +slug: Learn/HTML/Введение_в_HTML +tags: + - HTML + - Введение + - Для чайников + - Заголовок + - Начинающим + - Новичкам + - Основы HTML + - Семантика + - Ссылки + - Структура + - Текст +translation_of: Learn/HTML/Introduction_to_HTML +--- +
{{LearnSidebar}}
+ +

По сути, {{glossary("HTML")}} довольно простой язык, состоящий из элементов, которые могут быть применены к частям текста, чтобы придавать им различные значения (Это абзац? Это маркированный список? Это часть таблицы?), разделять документ на логические секции (есть ли у документа шапка? три столбца с контентом? меню навигации?) и добавлять контент на Вашу страницу, такой как фото и видео. Этот модуль расскажет Вам о первых двух возможностях HTML и научит фундаментальным концепциям и синтаксису, которые вам нужно знать, чтобы понять HTML.

+ +

Необходимые условия

+ +

Чтобы начать изучение этого модуля, вам не нужны никакие знания HTML, но вы должны иметь хотя бы базовые навыки обращения с компьютером и навыки пассивного использования Веба (т.е просто смотря на него, потребляя контент). У вас должна быть базовая рабочая среда, описанная в разделе Установка базового програмного обеспечения), а также понимание, как создавать и управлять файлами, что подробно описано в статье Работа с файлами — обе статьи являются частью нашего модуля Начало работы с сетью.

+ +
+

Примечание: если вы работаете на компьютере/планшете/другом устройстве, с отсутствием возможности создания собственных файлов, вы можете испробовать примеры кода (большинство) в онлайн-редакторах кода, таких как JSBin или Thimble.

+
+ +

Руководства

+ +

Этот модуль содержит следующие статьи, которые помогут изучить всю основную теорию HTML и предоставят широкие возможности для проверки некоторых навыков.

+ +
+
Начало работы с HTML
+
Охватывает базовые основы HTML, чтобы вы начали изучение - мы опишем элементы, атрибуты и все другие важные термины, о которых вы, возможно, уже слышали, а также где и как они располагаются в языке. Мы также покажем, структуру HTML элемента, как устроена типичная страница HTML, и объясним другие важные языковые особенности. По ходу мы будем играть с HTML так, чтобы вам было интересно!
+
Что такое заголовок? Метаданные в HTML
+
Заголовок HTML — это часть документа, которая не отображается в браузере при загрузке страницы. Он содержит информацию, такую как: страница {{htmlelement("title")}}, ссылки на {{glossary("CSS")}} (если вы хотите стилизовать свой HTML при помощи CSS), ссылки на пользовательские значки и метаданные (которые представляют собой данные о HTML, например, кто его написал или важные ключевые слова, которые описывают документ).
+
Основы редактирования текста в HTML
+
Основной задачей HTML является придание тексту значения (также известно, как семантика), чтобы браузер знал, как его правильно отображать. В этой статье расматривается то, как использовать HTML, чтобы разбить блок текста на структуру из заголовков и абзацев, добавить акцент/значение слов, создать списки и многое другое.
+
Создание гиперссылок
+
Гиперссылки очень важны — ведь именно они делают интернет интернетом. В этой статье описан синтаксис, необходимый для создания ссылок, а также описано их наилучшее применение на практике.
+
Углубленное форматирование текста
+
Существует множество других элементов HTML для редактирования текста, про которые мы вам не рассказали в статье Основы редактирования текста в HTML. Описанные здесь элементы менее известны, но о них также полезно знать. Здесь вы узнаете о разметке цитат, списках описания, компьютерном коде и другом сопутствующем тексте, нижнем и верхнем индексах, контактной информации и многом другом.
+
Структура документа и веб-сайта
+
Помимо определения отдельных частей страницы (таких как "абзац" или "изображение"), HTML также используется для определения отдельных зон веб-сайта (таких как "шапка", "меню навигации",  "столбец с основным содержимым".) В этой статье рассматривается, как планировать базовую структуру веб-сайта и писать HTML для представления этой структуры.
+
Отладка HTML
+
Писать на HTML хорошо, но что, если что-то идет не так, и вы не можете найти место ошибки в коде? В этой статье вы познакомитесь с некоторыми инструментами, которые могут Вам помочь.
+
+ +

Оценка

+ +

Следующие задания проверят ваше понимание основ HTML, описанных в приведенных выше руководствах.

+ +
+
Разметка письма
+
Все мы рано или поздно учимся писать письма; также это полезеный тест, для проверки ваших навыков форматирования текста! Поэтому, в этом задании вам будет предоставлено письмо для разметки.
+
Структурируем страницу
+
Этот тест проверит вашу способность использовать HTML для структурирования простой страницы, которая содержит шапку ("хедер") , нижний колонтитул ("футер"), меню навигации, основное содержимое и боковую панель.
+
+ +

Смотрите также

+ +
+
Основы интернет-грамотности
+
Отличный фундаментальный курс Mozilla, который дает множество тестов, проверяющих знания, о которых мы говорили в модуле Введение в HTML. Учащиееся знакомятся с чтением, письмом и использованием сети в модуле из 6 частей. Откройте для себя основы Интернета через производство и сотрудничество.
+
diff --git a/files/ru/learn/html/introduction_to_html/marking_up_a_letter/index.html b/files/ru/learn/html/introduction_to_html/marking_up_a_letter/index.html new file mode 100644 index 0000000000..c9ede9d116 --- /dev/null +++ b/files/ru/learn/html/introduction_to_html/marking_up_a_letter/index.html @@ -0,0 +1,101 @@ +--- +title: Разметка письма +slug: Learn/HTML/Введение_в_HTML/Marking_up_a_letter +tags: + - HTML +translation_of: Learn/HTML/Introduction_to_HTML/Marking_up_a_letter +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/Debugging_HTML", "Learn/HTML/Introduction_to_HTML/Structuring_a_page_of_content", "Learn/HTML/Introduction_to_HTML")}}
+ +

Мы все учимся писать письма рано или поздно; это также хороший способ испытать наши навыки форматирования! В этом задании у вас будет письмо для проверки ваших навыков форматирования текста HTML, использования гиперссылок и элемента <head>.

+ + + + + + + + + + + + +
Знания: +

Перед выполнением этого задания вы должны пройти Начало работы с HTML, Что такое заголовок? Метаданные в HTML, Основы редактирования текста в HTML, Создание гиперссылок, и Углубленное форматирование текста.

+
Цель: +

Проверить базовые и продвинутые навыки HTML форматирования и работы с гиперссылками, и знания о содержимом HTML тега <head>.

+
+ +

Отправная точка

+ +

Для начала задания, вы должны скачать текст, который вам надо отформатировать, и CSS стиль, который вы должны подключить к вашему HTML. Создайте .html файл используюя текстовый редактор, которым вы пользуетесь (или воспользуйтесь онлайн редактороми, таким как JSBin или Thimble).

+ +

Описание проекта

+ +

В этом проекте, ваша задача - отформатировать письмо, которое должно быть размещено во внутренней сети университета. Это письмо - ответ исследователя будущему PhD студенту о его заявлении на работу в университете.

+ +

Блочные элементы / структура:

+ + + +

Строчные элементы:

+ + + +

Заголовок документа:

+ + + +

Советы и подсказки

+ + + +

Пример

+ +

Это скриншот размеченного письма:

+ +

Example

+ +

Оценка

+ +

Если вам дали это задание на каком-то курсе, просто передайте свою страницу для проверки преподавателю. Если вы учитесь сами, обратитесь на форум, в тему этого задания, или по тегу #mdn в нашем IRC-канале (Mozilla IRC). Сделайте это задание сами — вам некого обманывать, кроме себя самого.

+ +

{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/Debugging_HTML", "Learn/HTML/Introduction_to_HTML/Structuring_a_page_of_content", "Learn/HTML/Introduction_to_HTML")}}

+ +

В этом модуле

+ + diff --git a/files/ru/learn/html/introduction_to_html/structuring_a_page_of_content/index.html b/files/ru/learn/html/introduction_to_html/structuring_a_page_of_content/index.html new file mode 100644 index 0000000000..b5bb7fa235 --- /dev/null +++ b/files/ru/learn/html/introduction_to_html/structuring_a_page_of_content/index.html @@ -0,0 +1,101 @@ +--- +title: Структурируем страницу +slug: Learn/HTML/Введение_в_HTML/Structuring_a_page_of_content +tags: + - HTML +translation_of: Learn/HTML/Introduction_to_HTML/Structuring_a_page_of_content +--- +
{{LearnSidebar}}
+ +
{{PreviousMenu("Learn/HTML/Introduction_to_HTML/Marking_up_a_letter", "Learn/HTML/Introduction_to_HTML")}}
+ +

Разметить страницу так, чтобы к ней было просто применить CSS — первое, чему должен научиться будущий веб-разработчик. В этом задании вам придется подумать о том, как должна выглядеть страница, и подобрать подходящую семантическую разметку.

+ + + + + + + + + + + + +
Что нужно знать:Вам пондобятся навыки из всего курса. Особое внимание уделите разделу Структура документа и веб-сайта.
Цель: +

Проверить знания структуры веб-страницы и ее перевода в разметку.

+
+ +

Отправная точка

+ +

Чтобы начать это, вы должны перейти и скачать архив содержаший все начальные активы. Архив содержит:

+ + + +

Создайте пример на вашем локальном компьютере или, альтернативно, используйте сайт, например JSBin или Thimble для исследования.

+ +

Краткое описание проекта

+ +

Для этого проекта ваша задача - взять контент для домашней страницы веб-сайта наблюдения за птицами и добавить к нему структурные элементы, чтобы он мог использовать макет страницы. Он должен иметь:

+ + + +

Вам необходимо добавить подходящую обертку для:

+ + + +

Вы также должны:

+ + + +

Советы и подсказки

+ + + +

Пример

+ +

Следующий скриншот показывает пример того, как может выглядеть домашняя страница после маркировки.

+ +

The finished example for the assessment; a simple webpage about birdwatching, including a heading of "Birdwatching", bird photos, and a welcome message

+ +

Оценивание

+ +

Если вам дали это задание на каком-то курсе, просто передайте свою страницу для проверки преподавателю. Если вы учитесь сами, обратитесь на форум, задав тему обсуждения этого упражнения, или в IRC-канале #mdn в IRC Mozilla, или в IRC-канале #mdn в IRC Mozilla. Попробуйте выполнить задание сами, ведь Вам некого обманывать, кроме себя самого!

+ +

{{PreviousMenu("Learn/HTML/Introduction_to_HTML/Marking_up_a_letter", "Learn/HTML/Introduction_to_HTML")}}

+ +

В этом модуле

+ + diff --git a/files/ru/learn/html/introduction_to_html/the_head_metadata_in_html/index.html b/files/ru/learn/html/introduction_to_html/the_head_metadata_in_html/index.html new file mode 100644 index 0000000000..dfb2840569 --- /dev/null +++ b/files/ru/learn/html/introduction_to_html/the_head_metadata_in_html/index.html @@ -0,0 +1,300 @@ +--- +title: Что внутри "head"? Метаданные в HTML +slug: Learn/HTML/Введение_в_HTML/The_head_metadata_in_HTML +tags: + - HTML + - Meta + - favicon + - head + - lang + - metadata + - Для начинающих + - Заголовок + - Руководство + - иконка + - метаданные + - язык +translation_of: Learn/HTML/Introduction_to_HTML/The_head_metadata_in_HTML +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/Getting_started", "Learn/HTML/Introduction_to_HTML/HTML_text_fundamentals", "Learn/HTML/Introduction_to_HTML")}}
+ +

Элемент {{glossary("Head", "head")}} HTML-документа не отображается на странице в веб-браузере. Он содержит такую информацию, как:

+ + + +

В этой статье мы рассмотрим всё вышеперечисленное и многое другое, чтобы дать вам хорошую основу для работы с разметкой.

+ + + + + + + + + + + + +
Предварительные требования:Базовое знакомство с HTML , описанное в Начало работы с HTML.
Задача:Узнать о заголовке HTML, его значении, важнейших элементах, которые содержатся в нём, и о том, как он может повлиять на HTML-документ.
+ +

Что такое <head>?

+ +

Давайте снова посмотрим на HTML-документ из прошлой статьи:

+ +
<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Моя тестовая страница</title>
+  </head>
+  <body>
+    <p>Это — моя страница</p>
+  </body>
+</html>
+ +

Содержимое {{htmlelement("head")}}, в отличие от содержимого элемента {{htmlelement("body")}}, не отображается на странице. Задача <head> — хранить {{glossary("Metadata", "метаданные")}} документа. В приведенном выше примере <head> совсем небольшой:

+ +
<head>
+  <meta charset="utf-8">
+  <title>Моя тестовая страница</title>
+</head>
+ +

Однако на больших страницах блок <head> может быть довольно объемным. Попробуйте зайти на какие-нибудь из ваших любимых сайтов и посмотреть содержимое <head> с помощью инструментов разработчика. Наша цель сейчас — не в том, чтобы показать вам, как использовать всё, что только можно добавить в head, а дать представление и научить вас, как использовать основные элементы. Давайте начнем.

+ +

Название страницы (title)

+ +

Мы уже видели, как работает элемент {{htmlelement("title")}}: его используют для добавления заголовка (названия страницы) в документ. Элемент {{htmlelement("h1")}} тоже иногда назвают заголовком страницы. Но это разные вещи!

+ + + +

Активное изучение: разбор простого примера

+ +
    +
  1. Чтобы приступить к активному изучению,  скачайте страницу title-example.html из нашего GitHub-репозитория. Это можно сделать двумя способами: + +
      +
    1. Скопируйте и вставьте код страницы в новый текстовый файл в своём редакторе кода, затем сохраните его в любом удобном месте.
    2. +
    3. Нажмите на странице кнопку "Raw", нажмите Файл > Сохранить Как... в меню браузера и выберите папку для сохранения.
    4. +
    +
  2. +
  3. Откройте файл в браузере. Вы увидите что-то вроде этого: +

    A simple web page with the title set to <title> element, and the <h1> set to <h1> element.Теперь должно стать совершенно ясно, в чём разница между <h1> и <title>!

    +
  4. +
  5. Откройте код страницы в редакторе, измените содержимое элементов и обновите страницу в браузере. Развлекайтесь!
  6. +
+ +

Содержимое элемента <title> используется и в других местах. Например, при добавлении страницы в избранное (Bookmarks > Bookmark This Page в Firefox), текст из <title> предлагается в качестве названия закладки.

+ +

A webpage being bookmarked in firefox; the bookmark name has been automatically filled in with the contents of the <title> element

+ +

Текст из <title> также появляется в результатах поиска, как мы скоро увидим.

+ +

Метаданные: Элемент <meta>

+ +

Метаданные — данные, которые описывают данные. У HTML есть «официальное» место для метаданных документа — элемент {{htmlelement("meta")}}. Конечно, другие вещи, о которых мы говорим в этой статье, тоже можно назвать метаданными. Существует множество разновидностей <meta>. Не станем пытаться охватить их все сразу — так недолго и запутаться, а рассмотрим несколько самых популярных, чтобы разобраться, что к чему.

+ +

Указываем кодировку текста документа

+ +

В заголовке примера выше есть следующая строка:

+ +
<meta charset="utf-8">
+ +

В этом элементе указана кодировка документа — набор символов, которые в нём можно использовать . utf-8 — универсальный набор символов, который включает почти все символы со всех языков человечества. Такая веб-страница сможет работать с любым языком. Установить эту кодировку на всех веб-страницов, которые вы создаёте — отличная идея! Страница в такой кодировке прекрасно отображает как английские, так и японские символы:

+ +

a web page containing English and Japanese characters, with the character encoding set to universal, or utf-8. Both languages display fine,Если использовать, скажем, кодировку ISO-8859-1 (набор символов для латиницы), текст страницы испортится:

+ +

a web page containing English and Japanese characters, with the character encoding set to latin. The Japanese characters don't display correctly

+ +
+

Примечание: Некоторые браузеры (например, Chrome) автоматически исправляют неправильную кодировку, поэтому, в зависимости от используемого вами браузера, вы можете не увидеть эту проблему. Несмотря на это вам всё равно необходимо указывать кодировку UTF-8 для вашей страницы, чтобы избежать возможных проблем в других браузерах.

+
+ +

Активное изучение: экспериментируем с символьными кодировками

+ +

Чтобы проверить это, вернитесь к HTML из примера <title> (странице title-example.html), поменяйте meta charset на ISO-8859-1 и попробуйте написать что-нибудь на японском или русском. Вот текст из нашего примера (кстати, там написано «рис горячий»):

+ +
<p>Пример на японском: ご飯が熱い。</p>
+ +

Указываем автора и описание

+ +

У элементов <meta> часто есть атрибуты name и content:

+ + + +

Два полезных элемента метаданных — указание автора страницы и краткое описание её содержимого. Рассмотрим эти элементы на примере:

+ +
<meta name="author" content="Крис Миллс">
+<meta name="description" content="Задача MDN — в том, чтобы обучить
+новичков всему тому, что нужно им для разработки веб-сайтов и приложений.">
+ +

По указанному имени автора (author) можно найти человека, который написал страницу, и связаться с ним. Некоторые системы управления содержимым (CMS) автоматически обрабатывают эту информацию и делают её доступной для таких целей.

+ +

Краткое описание (description) содержимого страницы учитывается поисковыми системами при совпадении ключевых слов. Такое называют поисковой оптимизацией, или {{glossary("SEO")}}.

+ +

Активное изучение: как поисковые системы используют описание

+ +

Описание из <meta name="description"> используется на страницах поисковой выдачи. Проведём небольшое исследование такого сценария.

+ +
    +
  1. Перейдите на главную страницу Mozilla Developer Network.
  2. +
  3. Откройте исходный код страницы (кликните правой кнопкой мыши и выберите Просмотреть код в контекстном меню.)
  4. +
  5. Найдите тег meta с описанием. Он выглядит так: +
    <meta name="description" content="Веб-документация на MDN
    +предоставляет собой информацию об открытых веб-технологиях,
    +включая HTML, CSS и различные API для веб-сайтов и
    +прогрессивных веб-приложений. Также на сайте содержатся материалы
    +для разработчиков о таких продуктах Mozilla, как Инструменты разработчика Firefox.">
    +
  6. +
  7. Теперь найдите "Mozilla Developer Network" в своём поисковике (мы использовали Google). Обратите внимание, что описание и название из <meta> и <title> используется в результатах поиска, — мы не зря указали их!
  8. +
+ +

Результат поиска в Google

+ +
+

Примечание: Google также показывает важные страницы MDN под ссылкой на главную страницу. Такие ссылки называются sitelinks, и их можно настроить через Google Search Console, чтобы пользователи могли сразу перейти к ним со страницы поиска.

+
+ +
+

Примечание: Многие типы <meta> больше не используются. Так, поисковые системы больше не используют данные из элемента <meta type="keywords" content="ваши, ключевые, слова, введите, здесь">, в котором указывали ключевые слова, по которым можно найти страницу: спамеры засовывали туда все слова, какие могли придумать, чтобы их сайты почаще появлялись в поиске.

+
+ +

Другие виды метаданных

+ +

В сети вы найдете также другие типы метаданных. Многие из них — это собственные форматы, созданные для предоставления определенным сайтам (например, социальных сетей) специальной информации, которую они могут использовать.

+ +

Например, Протокол Open Graph создан Facebook чтобы предоставить сайтам дополнительные возможности использования метеданных. В исходном коде MDN Web Docs вы можете найти строки:

+ +
<meta property="og:image" content="https://wiki.developer.mozilla.org/static/img/opengraph-logo.72382e605ce3.png">
+<meta property="og:description" content="Веб-документация на MDN предоставляет
+собой информацию об открытых веб-технологиях, включая HTML, CSS и различные API для веб-сайтов
+и прогрессивных веб-приложений. Также на сайте содержатся материалы для разработчиков о таких
+продуктах Mozilla, как Инструменты разработчика Firefox.">
+<meta property="og:title" content="MDN Web Docs">
+ +

Один из результатов добавления этих метеданных в том, что когда вы добавите ссылку MDN Web Docs на facebook, она отобразится с изображением и описанием, улучшая опыт взаимодействия (User eXperience, UX).

+ +

Open graph protocol data from the MDN homepage as displayed on facebook, showing an image, title, and description.У Twitter также есть собственный формат метаданных, с помощью которого  создается аналогичный эффект, при отображении URL сайта на twitter.com:

+ +
<meta name="twitter:title" content="MDN Web Docs">
+ +

Добавление иконок

+ +

Чтобы добавить своему сайту узнаваемости, можно указать в метаданных разные иконки.

+ +

Favicon, один из старожилов интернета, стал первой из таких иконок. Браузеры показывают её в заголовке вкладки и в списке избранных страниц.The Firefox bookmarks panel, showing a bookmarked example with a favicon displayed next to it.

+ +

Чтобы добавить на страницу favicon:

+ +
    +
  1. Сохраните изображение в формате .ico (многие браузеры поддерживают и в более привычных форматах, таких как .gif или .png) в папку со своим документом. Старые браузеры, например, Internet Explorer 6, поддерживают только формат .ico
  2. +
  3. Добавьте ссылку на иконку в <head> документа: +
    <link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
    +
  4. +
+ +

Для разных устройств можно указывать разные иконки. Например, на главной странице MDN:

+ +
<!-- Для iPad 3 с Retina-экраном высокого разрешения: -->
+<link rel="apple-touch-icon-precomposed" sizes="144x144" href="https://developer.cdn.mozilla.net/static/img/favicon144.a6e4162070f4.png">
+<!-- Для iPhone с Retina-экраном высокого разрешения: -->
+<link rel="apple-touch-icon-precomposed" sizes="114x114" href="https://developer.cdn.mozilla.net/static/img/favicon114.0e9fabd44f85.png">
+<!-- Для iPad первого и второго поколения: -->
+<link rel="apple-touch-icon-precomposed" sizes="72x72" href="https://developer.cdn.mozilla.net/static/img/favicon72.8ff9d87c82a0.png">
+<!-- Для iPhone, iPod Touch без Retina и устройств с Android 2.1+: -->
+<link rel="apple-touch-icon-precomposed" href="https://developer.cdn.mozilla.net/static/img/favicon57.a2490b9a2d76.png">
+<!-- Для других случаев - обычный favicon -->
+<link rel="shortcut icon" href="https://developer.cdn.mozilla.net/static/img/favicon32.e02854fdcf73.png">
+ +

В комментариях указано, для чего используется каждая иконка — например, при добавлении страницы на домашний экран iPad будет использована иконка в высоком разрешении. 

+ +

Не беспокойтесь о реализации всех этих типов значков — это довольно продвинутая функция, и мы не станем возвращаться к ней в курсе. Основная цель — показать вам, что это такое, если вы столкнетесь с ними при просмотре исходного кода других веб-сайтов.

+ +

Подключение CSS и JavaScript

+ +

Современные сайты используют {{glossary("CSS")}}, чтобы выглядеть привлекательнее, и добавляют интерактивные функции через {{glossary("JavaScript")}}: видеоплееры, карты, игры. Обычно связянные стили добавляют на страницу через элемент {{htmlelement("link")}}, а скрипты — через элемент {{htmlelement("script")}} .

+ + + +

Активное изучение: добавляем на страницу CSS и JavaScript

+ +
    +
  1. Для этого упражнения скачайте файлы meta-example.html, script.js и style.css и положите их в одну папку на своём компьютере. Проверьте, что они сохранились с правильными именами и расширениями.
  2. +
  3. Откройте HTML в браузере и текстовом редакторе.
  4. +
  5. Следуя изученному материалу, добавьте на страницу скрипт и стиль с помощью элементов {{htmlelement("link")}} и {{htmlelement("script")}}.
  6. +
+ +

Если всё получилось, когда вы сохраните HTML и обновите страницу в браузере, вы увидите кое-что новенькое:

+ +

Example showing a page with CSS and JavaScript applied to it. The CSS has made the page go green, whereas the JavaScript has added a dynamic list to the page.

+ + + +
+

Примечание: Если вам никак не удаётся подключить CSS или JS, посмотрите на наш готовый пример — страницу css-and-js.html.

+
+ +

Основной язык HTML страницы

+ +

Наконец, стоит отметить, что вы можете (и действительно должны) установить язык для своей страницы. Это можно сделать, добавив атрибут lang в открывающий HTML-тег (как в примере meta-example.html: и как показано ниже):

+ +
<html lang="en-US">
+ +
<html lang="ru">
+
+ +

Это полезно во многих случаях. Ваш HTML-документ будет более эффективно индексироваться поисковыми системами, если его язык установлен (что позволяет ему правильно отображаться в языковых результатах), и он полезен людям с нарушением зрения, которые используют программы, читающие страницы вслух (например, слово "шесть" пишется одинаково как на французском, так и на английском языках, но произносится по-разному.).

+ +

Можно также указать язык для части документа. Например, мы могли бы установить язык для части страницы на японском:

+ +
<p>Пример на японском: <span lang="jp">ご飯が熱い。</span>.</p>
+ +

Коды языков определены в стандарте ISO 639-1. Подробнее о работе с языками можно узнать в Языковые тэги в HTML и XML.

+ +

Заключение

+ +

На этом заканчивается наш беглый обзор по HTML-блоку head  —  с его помощью вы можете делать гораздо больше, но исчерпывающий обзор будет скучным и запутанным на этом этапе, мы же сейчас хотели дать вам представление о самых распространённых вещах, которые вы можете там найти! В следующей статье мы рассмотрим основы разметки текста в HTML.

+ +

{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/Getting_started", "Learn/HTML/Introduction_to_HTML/HTML_text_fundamentals", "Learn/HTML/Introduction_to_HTML")}}

+ +

В этом модуле

+ + diff --git a/files/ru/learn/html/multimedia_and_embedding/adding_vector_graphics_to_the_web/index.html b/files/ru/learn/html/multimedia_and_embedding/adding_vector_graphics_to_the_web/index.html new file mode 100644 index 0000000000..a3a445dfc7 --- /dev/null +++ b/files/ru/learn/html/multimedia_and_embedding/adding_vector_graphics_to_the_web/index.html @@ -0,0 +1,351 @@ +--- +title: Добавление векторной графики в веб-документ +slug: Learn/HTML/Multimedia_and_embedding/Добавление_r_graphics_to_the_Web +translation_of: Learn/HTML/Multimedia_and_embedding/Adding_vector_graphics_to_the_Web +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/HTML/Multimedia_and_embedding/Other_embedding_technologies", "Learn/HTML/Multimedia_and_embedding/Responsive_images", "Learn/HTML/Multimedia_and_embedding")}}
+ +
+

Векторная графика очень полезна во многих случаях. Она имеет малые размеры файла и высокую масштабируемость – при увеличении масштаба пиксели не увеличиваются вместе с графикой. В данной статье мы покажем, как встраивать векторную графику на Вашу страницу.

+
+ + + + + + + + + + + + +
Навыки:Знание основ HTML и умение добавлять изображение в веб-документ.
Цель:Изучить как встроить SVG (векторное) изображение на вебстраницу.
+ +
+

Примечание: Данная статья не научит Вас векторной графике, а даст понимание что это и как ее использовать в веб-документах.

+
+ +

Что такое векторная графика?

+ +

В веб-разработке Вы будете сталкиваться с двумя типами изображений - растровым и векторным:

+ + + +

Для демонстрации различий между типами изображений, давайте взглянем на пример. Вы можете найти данный пример на Github как vector-versus-raster.html — в нем демонстрируются два, на первый взгляд, одинаковых изображения, расположенных рядом друг с другом. Каждое из изображений представляет собой красную звезду с тенью. Различие их в том, что левое изображение имеет формат PNG, а правое - SVG.

+ +

Различия становятся заметны, когда Вы изменяете масштаб страницы — PNG изображение становится неровным (становятся видны пиксели), потому что оно содержит информацию о положении и цвете каждого пикселя. При увеличении каждый пиксель также увеличивается, охватывая несколько пикселей дисплея, поэтому становятся заметны "кирпичики". Векторное изображение продолжает выглядеть ровным и красивым, потому что фигуры, масштабируются совместно с ним. 

+ +

Two star images

+ +

Two star images zoomed in, one crisp and the other blurry

+ +
+

Примечание: Оба изображения сверху имеют формат PNG — слева показано растровое изображение, справа условно показано векторное изображение. Напоминаем, что пример с реальными растровым и веркторным изображениями находится по ссылке: vector-versus-raster.html !

+
+ +

Более того, файлы векторных изображений намного меньше растровых, т.к. в них содержится алгоритмы построения вместо информации о каждом пикселе.

+ +

Что такое SVG?

+ +

SVG это язык на базе {{glossary("XML")}} для описания векторных изображений. По сути это язык разметки, как и HTML, только содержащий множество различных элементов для определения фигур вашего изображения, а также параметров их отображения. SVG предназначен для разметки графики, а не содержимого. В простейшем случае,  Вы можете использовать элементы для создания простых фигур, таких как {{svgelement("circle")}}(круг) и {{svgelement("rect")}}(прямоугольник). Более сложные SVG элементы включают {{svgelement("feColorMatrix")}} (разложение цвета с использованием матрицы), {{svgelement("animate")}} (анимация частей Вашего векторного изображения) и {{svgelement("mask")}} (примение маски к изображению.)

+ +

В качестве простого примера, следующий код создает круг и прямоугольник:

+ +
<svg version="1.1"
+     baseProfile="full"
+     width="300" height="200"
+     xmlns="http://www.w3.org/2000/svg">
+  <rect width="100%" height="100%" fill="black" />
+  <circle cx="150" cy="100" r="90" fill="blue" />
+</svg>
+ +

В результате получается следующее:

+ +

{{ EmbedLiveSample('What_is_SVG', 300, 200, "", "", "hide-codepen-jsfiddle") }}

+ +

Исходя из примера выше, может показаться, что SVG легко создавать вручную. Да, простые SVG можно создавать, используя текстовый редактор, но в случае сложного изображения это становится сложным. Для создания SVG изображений используются редакторы векторной графики, такие как Inkscape или Illustrator. Данные приложения позволяют создавать различные изображения, используя множество графических инструментов, и создавать приближения фотографий (например опция Trace Bitmap feature приложения Inkscape.)

+ +

Дополнительные преимущества SVG:

+ + + +

Так почему же тогда вообще используют растровые изображения, а не только SVG? Дело в том, что SVG имеет ряд недостатков:

+ + + +

В целом, растровая графика лучше подходит для сложных изображений, например, фотографий.

+ +
+

Примечание: В приложении Inkscape сохраняйте файлы как Plain SVG, для экономии места. Также, пожалуйста перейдите на статью, описывающую как подготовить SVG изображение для веб-документа.

+
+ +

Добавление SVG на страницы

+ +

В данном разделе мы рассмотрим различные варианты, с помощью которых можно добавить SVG векторную графику на веб-страницу.

+ +

Быстрый путь: {{htmlelement("img")}}

+ +

Чтобы встроить SVG используя элемент {{htmlelement ("img")}}, вам просто нужно сослаться на него в атрибуте src, как и следовало ожидать. Вам понадобится атрибут height или width (или оба, если ваш SVG не имеет собственного соотношения сторон). Если вы еще этого не делали, пожалуйста, прочтите Изображения в HTML.

+ +
<img
+    src="equilateral.svg"
+    alt="triangle with all three sides equal"
+    height="87px"
+    width="100px" />
+ +

Плюсы

+ + + +

Минусы

+ + + +

Устранение неполадок и кросс-браузерная поддержка

+ +

Для браузеров которые не поддерживают SVG (IE 8 и ниже, Android 2.3 и ниже), вы можете ссылаться на PNG или JPG в src атрибуте и использовать {{htmlattrxref("srcset", "img")}} атрибут (который распознают только последние браузеры) чтобы сослаться на SVG. В этом случае SVG будут загружаться только поддерживающими браузерами - старые же браузеры будут загружать PNG:

+ +
<img src="equilateral.png" alt="triangle with equal sides" srcset="equilateral.svg">
+ +

Также вы можете использовать SVG в качестве фоновых изображение CSS, как показано ниже. В приведенном коде ниже старые браузеры будут придерживаться PNG, который они понимают, тогда как новые браузеры будут загружать SVG:

+ +
background: url("fallback.png") no-repeat center;
+background-image: url("image.svg");
+background-size: contain;
+ +

Подобно методу <img>, описанному выше, вставка SVG с использлованием фоновых изображений CSS означает, что SVG нельзя манипулировать при помощи JavaScript, и что SVG будет иметь те же ограничения, что и CSS.

+ +

Если ваши SVG не отображаются вовсе, возможно, ваш сервер не настроен должным образом. Если проблема в этом, то данная статья укажет вам верное направление.

+ +

Как включить SVG в ваш HTML код

+ +

Вы можете открыть файл SVG в текстовом редакторе, скопировать этот код и вставить его в ваш HTML документ — такой прием иногда называют встраиванием SVG (SVG inline или inlining SVG). Убедитесь, что фрагмент вашего SVG кода начинается и заканчивается с тегов <svg></svg> (не включайте ничего, кроме них). Вот очень простой пример того, что вы можете вставить в ваш документ:

+ +
<svg width="300" height="200">
+    <rect width="100%" height="100%" fill="green" />
+</svg>
+
+ +

Плюсы

+ + + +

Минусы

+ + + + + +

Как встраивать SVG при помощи {{htmlelement("iframe")}}

+ +

Вы можете открывать ваши SVG изображения в браузере просто как веб-страницы. Таким образом встраивание SVG документа с помощью <iframe> выполняется как мы изучали ранее в главе От <object> к <iframe> — другие технологии внедрения.

+ +

Вот краткий обзор:

+ +
<iframe src="triangle.svg" width="500" height="500" sandbox>
+    <img src="triangle.png" alt="Triangle with three unequal sides" />
+</iframe>
+ +

Это - определенно не самый лучший метод для выбора:

+ +

Минусы

+ + + +

Активное изучение: поиграйте с SVG

+ +

В этом разделе ативного изучения мы бы хотели, чтобы вы просто попробовали поиграть с SVG. Ниже, в областе Input, вы увидите, что мы уже предоставили некий пример для того, чтобы вы начали. А еще вы можете посетить SVG Element Reference, чтобы узнать больше деталей о других игрушках, которые могут быть использованы в SVG, и тоже попробовать их. Этот раздел полностью посвящен практике ваших исследовательских навыков и вашему развлечению.

+ +

Если Вы где-то застряли и ваш код не работает, Вы всегда можете начать сначала, нажав кнопку Reset.

+ + + +

{{ EmbedLiveSample('Playable_code', 700, 500, "", "", "hide-codepen-jsfiddle") }}

+ +

Заключение

+ +

Эта статья предоставила вам краткий обзор по тому, что такое векторная графика и SVG, почему полезно знать о них и как внедрять SVG в вашу веб-страницу. Эта статья не является полным руководством по изучению SVG, а всего лишь указатель, чтоб вы знали что такое SVG, на случай, если вы встретите его во время странствий по Сети. Так что не переживайте, если вы еще не чувствуете себя экспертом в SVG. Ниже мы включили несколько ссылок, которые могут вам помочь, если вы хотите узнать больше о том, как это работает.

+ +

В последней статье этого модуля мы будем исследовать адаптивные изображения в деталях, рассматривая инструменты HTML, которые позволяют делать ваши изображения так, чтоб они могли лучше работать на разных устройствах.

+ +

See also

+ + + +

{{PreviousMenuNext("Learn/HTML/Multimedia_and_embedding/Other_embedding_technologies", "Learn/HTML/Multimedia_and_embedding/Responsive_images", "Learn/HTML/Multimedia_and_embedding")}}

+ +

In this module

+ + diff --git a/files/ru/learn/html/multimedia_and_embedding/images_in_html/index.html b/files/ru/learn/html/multimedia_and_embedding/images_in_html/index.html new file mode 100644 index 0000000000..d96558e3da --- /dev/null +++ b/files/ru/learn/html/multimedia_and_embedding/images_in_html/index.html @@ -0,0 +1,364 @@ +--- +title: Изображения в HTML +slug: Learn/HTML/Multimedia_and_embedding/Изображения_в_HTML +translation_of: Learn/HTML/Multimedia_and_embedding/Images_in_HTML +--- +
{{LearnSidebar}}
+ +
{{NextMenu("Learn/HTML/Multimedia_and_embedding/Video_and_audio_content", "Learn/HTML/Multimedia_and_embedding")}}
+ +

В начале Web был просто текстом, что было довольно скучно. К счастью, это продолжалось не долго - до появления возможности вставлять изображения (и другие, более интересные, типы контента) в веб-страницы. Существуют и другие типы мультимедиа, однако логичнее начать со скромного {{htmlelement("img")}}  элемента, используемого для вставки простого изображения в веб-страницу. В этой статье мы рассмотрим, как использовать элемент, начиная с основ, снабжать примечаниями, используя  {{htmlelement("figure")}}, и разберём, как это относится к фоновым изображениям {{glossary("CSS")}}. 

+ + + + + + + + + + + + +
Необходимы:Базовые знания компьютера, установленное базовое ПО, базовые знания по работе с файлами, знания основ HTML (как описано в статье Начало работы с HTML).
Цель:Узнать, как встраивать изображения в HTML, как добавлять к ним описания и как изображения HTML связаны с фоновыми изображениями CSS.
+ +

Как разместить картинку на странице?

+ +

Чтобы разместить изображение на странице, нужно использовать тег {{htmlelement("img")}}. Это пустой элемент (имеется ввиду, что не содержит текста и закрывающего тега), который требует минимум один атрибут для использования — src (произносится эс-ар-си, иногда говорят его полное название, source). Атрибут src содержит путь к изображению, которое вы хотите встроить в страницу, и может быть относительным или абсолютным URL, точно так же, как значения атрибута href для элемента {{htmlelement("a")}}.

+ +
+

Примечание: Перед тем как продолжить, вам стоит вспомнить про типы адресов URL, чтобы обновить в памяти про относительные и абсолютные адресса.

+
+ +

Например, если ваше изображение называется dinosaur.jpg, и оно находится в той же директории что и ваша HTML страница, вы можете встроить это изображение как:

+ +
<img src="dinosaur.jpg">
+ +

Если изображение было в поддиректории images , находящаяся внутри той же директории, что и HTML страница (что рекомендует Google для индексации и целей SEO), тогда вы можете встроить его так:

+ +
<img src="images/dinosaur.jpg">
+ +

И так далее.

+ +
+

Примечание: Поисковые системы также читают имена изображений и считают их для оптимизации поискового запроса. Поэтому присваивайте вашим изображениям смысловые имена: dinosaur.jpg лучше, чем img835.png.

+
+ +

Вы можете встроить изображение используя абсолютный URL, например:

+ +
<img src="https://www.example.com/images/dinosaur.jpg">
+ +

Но это бесмыссленно, так как он просто заставляет браузер делать больше работы, запрашивая каждый раз IP-адрес от DNS-сервера.  Вы почти всегда будете держать свои изображения для сайта на том же сервере, что и ваш HTML.

+ +
+

Внимание: Большиство изображений защищены. Не отображайте изображения на вашем сайте пока:

+ +
    +
  • вы не будете владеть изображением
  • +
  • у вас не будет письменного разрешения владельца изображения, или
  • +
  • пока у вас не будет достаточно доказательств что изображение находится в открытом доступе.
  • +
+ +

Нарушение авторских прав является незаконным. Кроме того, никогда не указывайте в своем атрибуте src ссылку на изображение, размещенное на чужом сайте. Это называется "хотлинкинг" (с англ. 'hotlinking' - 'горячая ссылка'). Запомните, кража пропускной способности чужого сайта незаконна. Это также замедляет вашу страницу и не позволяет вам контролировать, будет ли изображение удалено или заменено чем-то неприятным.

+
+ +

Наш код выше даст нам следующий результат:

+ +

A basic image of a dinosaur, embedded in a browser, with Images in HTML written above it

+ +
+

Примечание: Такие элементы как {{htmlelement("img")}} и {{htmlelement("video")}} иногда называются замещаемыми элементами. Это потому что содержание элемента и размер, определяет внешний ресурс (как изображение или видео файл), а не содержание самого элемента. Вы можете узнать о них больше в Замещаемых элементах.

+
+ +
+

Примечание: Вы можете найти готовый пример этого раздела, размещённый на Github (смотрите также исходный код).

+
+ +

Альтернативный текст

+ +

Следующий атрибут, который мы рассмотрим — alt. Его значением должно быть текстовое описание изображения для использования в ситуациях, когда изображение не может быть просмотрено / отображено или отрисовка занимает много времени из-за медленного интернет-соединения. Чтобы продемонстрировать использование атрибута alt на практике, внесем изменения в код из предыдущего примера:

+ +
<img src="images/dinosaur.jpg"
+     alt="Голова и туловище скелета динозавра;
+         у него большая голова с длинными острыми зубами">
+ +

Самый простой способ увидеть атрибут alt в действии — это сделать намеренную ошибку в имени файла. Например, если бы мы написали имя изображения как dinosooooor.jpg, браузер не смог бы его отобразить, и на экране появился бы текст из атрибута alt:

+ +

The Images in HTML title, but this time the dinosaur image is not displayed, and alt text is in its place.Итак, в каких случаях текст из атрибута alt может быть нам полезен? Приведем несколько примеров:

+ + + +

Что именно вы должны писать в атрибут alt? В первую очередь, это зависит от того, зачем изображение вообще находится на странице. Другими словами, что вы потеряете, если ваше изображение не появится:

+ + + +

По существу, главная идея здесь это предоставить нечто полезное, для случая когда изображения не видны. Это гарантирует что все пользователи не упустят ничего из содержимого страницы. Попробуйте отключить изображения в своём браузере и посмотрите как всё выглядит. Вы вскоре выясните насколько полезным является альтернативный текст, если изображения не видны.

+ +
+

Примечание: Более подробную информацию, смотрите здесь: Альтернативный текст.

+
+ +

Ширина и высота

+ +

Вы можете использовать атрибуты width и height, чтобы указать ширину и высоту вашего изображения. Ширину и высоту вашего избражение можете найти различными способами. Например, на Mac можно использовать  Cmd + I  чтобы  получить информацию по изображению. Повторяя наш пример, мы можем сделать так:

+ +
<img src="images/dinosaur.jpg"
+     alt="The head and torso of a dinosaur skeleton;
+          it has a large head with long sharp teeth"
+     width="400"
+     height="341">
+ +

Это не приводит к большой разнице в отображении при нормальных обстоятельствах. Но если изображение не будет показано, например, когда пользователь только что перешёл на страницу, а оно ещё не успело загрузится, вы укажите браузеру оставить место для отрисовки изображения:

+ +

The Images in HTML title, with dinosaur alt text, displayed inside a large box that results from width and height settings

+ +

Это хорошая практика, в результате страница загрузится быстрее и более гладко.

+ +

Однако, вы не должны изменять размеры ваших изображений используя HTML аттрибуты. Если вы установите размер изображения слишком большим, то в конечном итоге вы сталкнётесь с изображениями, которые выглядят зернистыми, размытыми или слишком маленькими, и потратите трафик для загрузки изображения, которое не будет соответствовать нуждам пользователя. Конечное изображение может также выглядеть искажённым, если вы не сохраните правильное соотношение сторон. Рекомендуется использовать графический редактор для подгонки изображения к нужному размеру, перед вставкой его на вашу вэб-страницу.

+ +
+

Примечание: Если вам действительно нужно изменить размер изображения, вы должны использовать вместо этого CSS.

+
+ +

Заголовок изображения

+ +

Как и для ссылок, вы также можете добавить атрибут title для изображений, чтобы при необходимости предоставить дополнительную информацию. В нашем примере мы могли бы сделать это так:

+ +
<img src="images/dinosaur.jpg"
+     alt="The head and torso of a dinosaur skeleton;
+          it has a large head with long sharp teeth"
+     width="400"
+     height="341"
+     title="A T-Rex on display in the Manchester University Museum">
+ +

Это дает нам всплывающую подсказку при наведении курсора мыши, также как и в ссылках:

+ +

The dinosaur image, with a tooltip title on top of it that reads A T-Rex on display at the Manchester University Museum

+ +

Однако это не рекомендуется - title имеет ряд проблем с доступностью, в основном из-за того, что поддержка программ чтения с экрана очень непредсказуема, и большинство браузеров не будут отображать её, если вы не наведёте курсор мыши (например, нет доступа для пользователей клавиатуры). Зачастую лучше включить такого рода вспомогательную информацию в основной текст статьи, чем прикреплять её к изображению. Однако, она полезна в некоторых обстоятельствах; например, в галереях изображений, когда у вас нет места для их заголовков.

+ +

Активное обучение: встраивание изображения

+ +

Наступила очередь немного поиграть! Этот раздел активного обучения поможет вам выполнить простое упражнение по встраиванию. Вы будете обеспечены простым {{htmlelement("img")}} тэгом; мы хотели бы чтобы вы встроили изображение расположенное по следующей ссылке:

+ +

https://raw.githubusercontent.com/mdn/learning-area/master/html/multimedia-and-embedding/images-in-html/dinosaur_small.jpg

+ +

Ранее мы говорили никогда не используйте горячие ссылки на изображения с других серверов, данный случай только для целей обучения, итак мы позволим вам пренебречь этим один разок.

+ +

Мы также хотели бы, чтобы вы:

+ + + +

Если вы сделаете ошибку, вы всегда можете очистить код, используя кнопку Reset. Если вы реально не будете понимать как сделать, нажмите кнопку Show solution, чтобы увидеть ответ:

+ + + +

{{ EmbedLiveSample('Playable_code', 700, 500) }}

+ +

Придание изображению структуры и установка заголовка

+ +

Начиная разговор о заголовках, есть множество путей как вы можете добавить заголовок к своему изображению. Для примера, нет ничего, что может вас остановить сделать это таким образом:

+ +
<div class="figure">
+  <img src="images/dinosaur.jpg"
+       alt="The head and torso of a dinosaur skeleton;
+            it has a large head with long sharp teeth"
+       width="400"
+       height="341">
+
+  <p>A T-Rex on display in the Manchester University Museum.</p>
+</div>
+ +

Это нормально. Это содержит всё что вам нужно, и красиво стилизуется с помощью CSS. Но, есть проблема: здесь нет ничего, что семантически связывает изображение с его заголовком, и это может вызвать сложности для читателей. Например, когда у вас есть 50 изображений и заголовков, какой заголовок идёт вместе с каким изображением?

+ +

Лучшим решением будет использование элементов HTML5 {{htmlelement("figure")}} и {{htmlelement("figcaption")}}. Они были созданы исключительно для этой цели: предоставить семантический контейнер для рисунков и четко связать рисунок с заголовком. Наш пример выше мог бы быть переписан так:

+ +
<figure>
+  <img src="images/dinosaur.jpg"
+       alt="The head and torso of a dinosaur skeleton;
+            it has a large head with long sharp teeth"
+       width="400"
+       height="341">
+
+  <figcaption>A T-Rex on display in the Manchester University Museum.</figcaption>
+</figure>
+ +

Элемент {{htmlelement("figcaption")}} говорит браузерам и вспомогательной технологии, что заголовок описывает содержимое элемента {{htmlelement("figure")}}.

+ +
+

Замечание: С точки зрения доступности, заголовки и {{htmlattrxref('alt','img')}} имеют различные предназначения. Заголовки помогают даже тем, кто имеет возможность просматривать изображение, тогда как {{htmlattrxref('alt','img')}} обеспечивает замену функционала отсутствующего изображения. Таким образом, заголовки и alt не подразумевают под собой одни и те же вещи, потому что оба используются браузером при отсутствии изображения. Попробуйте отключить изображения в своём браузере, чтобы увидеть как это выглядит.

+
+ +

Тег <figure> не является изображением. Он представляет собой независимый структурный элемент, который: 

+ + + +

Тег <figure> может быть несколькими изображениями, куском кода, аудио, видео, уравнением, таблицей, либо чем-то другим.

+ +

Активное изучение: создание <figure>

+ +

В этом разделе активного изучения мы хотели бы, чтобы вы взяли текст из предыдущего раздела активного изучения и преобразовали его в <figure>:

+ + + +

В случае допущения ошибки, вы всегда можете набрать код повторно, нажав кнопку Reset. Если вы застряли, нажмите кнопку Show solution, чтобы увидеть ответ:

+ + + +

{{ EmbedLiveSample('Playable_code_2', 700, 500) }}

+ +

Фоновые изображения CSS

+ +

Вы можете использовать CSS для встраивания изображений в веб-страницы (или JavaScript, но это совсем другая история). Параметры CSS {{cssxref("background-image")}} и другие background-* применяются для контроля размещения фонового изображения. К примеру, чтобы залить фон каждого параграфа страницы, необходимо сделать следующее:

+ +
p {
+  background-image: url("images/dinosaur.jpg");
+}
+ +

Получившееся в конечном итоге изображение можно легко позиционировать и контролировать, в отличие от его HTML аналога. Так зачем же возиться с HTML изображениями? Как указано выше, фоновые изображения CSS предназначены только для украшения. Если вы просто хотите добавить что-то красивое на свою страницу, чтобы улучшить визуальные эффекты, это нормально. Тем не менее, такого рода изображения не имеют семантического смысла вообще. Они не могут иметь каких-то текстовых эквивалентов, видимых посетителю, они невидимы для программ чтения с экрана. Вот где блистают HTML-изображения!

+ +

Итог: если изображение имеет важность, в контексте содержимого вашей страницы, вам следует использовать HTML изображения. Если же картинка является банальной декорацией, используйте фоновые изображения CSS.

+ +
+

Замечание: Вы можете узнать больше о фоновых изображениях CSS в нашей теме о CSS.

+
+ +

Проверьте свои навыки!

+ +

Вы дошли до конца этой статьи, но можете ли вы вспомнить самую важную информацию? Вы можете найти дополнительные тесты, чтобы убедиться, что вы усвоили эту информацию, прежде чем двигаться дальше. Смотрите Проверьте знания по изображениям в HTML.

+ +

Резюме

+ +

На этом пока все. Мы подробно рассмотрели изображения и их заголовки. В следующей статье мы рассмотрим, как использовать HTML для встраивания видео и аудио на веб-страницы.

+ +

{{NextMenu("Learn/HTML/Multimedia_and_embedding/Video_and_audio_content", "Learn/HTML/Multimedia_and_embedding")}}

diff --git a/files/ru/learn/html/multimedia_and_embedding/images_in_html/test_your_skills_colon__html_images/index.html b/files/ru/learn/html/multimedia_and_embedding/images_in_html/test_your_skills_colon__html_images/index.html new file mode 100644 index 0000000000..e00777dabe --- /dev/null +++ b/files/ru/learn/html/multimedia_and_embedding/images_in_html/test_your_skills_colon__html_images/index.html @@ -0,0 +1,74 @@ +--- +title: 'Проверьте свои знания: Изображения в HTML' +slug: >- + Learn/HTML/Multimedia_and_embedding/Изображения_в_HTML/Проверьте_свои_знания:_Изображения_в_HTML +translation_of: >- + Learn/HTML/Multimedia_and_embedding/Images_in_HTML/Test_your_skills:_HTML_images +--- +
{{learnsidebar}}
+ +

Цель этого теста навыков - оценить, поняли ли вы нашу статью Изображения в HTML.

+ +
+

Примечание: Вы можете опробовать решения в интерактивных редакторах ниже, однако может быть полезно загрузить код и использовать онлайн-инструмент, такой как CodePen, jsFiddle или Glitch для работы с задачами.

+
+ +

Изображения в HTML №1

+ +

В этой задаче мы хотим, чтобы вы вставили на страницу простое изображение ягоды черники. Вам необходимо:

+ + + +

Попробуйте обновить живой код ниже, чтобы воссоздать готовый пример:

+ +

{{EmbedGHLiveSample("learning-area/html/multimedia-and-embedding/tasks/images/images1.html", '100%', 700)}}

+ +
+

Загрузите файл для этой задачи, чтобы работать в вашем редакторе или в онлайн-редакторе.

+
+ +

Изображения в HTML №2

+ +

В этой задаче у вас уже есть полнофункциональное изображение, но мы хотели бы, чтобы вы добавили всплывающую подсказку, которая появляется при наведении курсора на изображение. Вы должны ввести некоторую соответствующую информацию во всплывающую подсказку.

+ +

Попробуйте обновить живой код ниже, чтобы воссоздать законченный пример:

+ +

{{EmbedGHLiveSample("learning-area/html/multimedia-and-embedding/tasks/images/images2.html", '100%', 700)}}

+ +
+

Загрузите файл для этой задачи, чтобы работать в вашем редакторе или в онлайн-редакторе.

+
+ +

Изображения в HTML №3

+ +

В этой последней задаче вам предоставляется как полнофункциональное изображение, так и текст заголовка. Здесь вам нужно добавить элементы, которые будут связывать изображение с его заголовком.

+ +

Попробуйте обновить живой код ниже, чтобы воссоздать готовый пример:

+ +

{{EmbedGHLiveSample("learning-area/html/multimedia-and-embedding/tasks/images/images3.html", '100%', 700)}}

+ +
+

Загрузите файл для этой задачи, чтобы работать в вашем редакторе или в онлайн-редакторе.

+
+ +

Оценка или дополнительная помощь

+ +

Вы можете попрактиковаться с этими примерами в интерактивных редакторах выше.

+ +

Если вы хотите, чтобы ваша работа была оценена, или если вы застряли и хотите обратиться за помощью:

+ +
    +
  1. Поместите свою работу в онлайн-редактор, например CodePen, jsFiddle или Glitch. Вы можете написать код самостоятельно или использовать файлы, ссылки на которые приведены в приведенных выше разделах.
  2. +
  3. Напишите сообщение с просьбой об оценке и / или помощи в MDN Discourse forum Learning category. Ваш пост должен включать: +
      +
    • Описательный заголовок, например "Требуется оценка для проверки навыков 1 по основам изображений HTML".
    • +
    • Подробная информация о том, что вы уже пробовали, и что бы вы хотели, чтобы мы сделали, например если вы застряли и нуждаетесь в помощи или хотите пройти оценку.
    • +
    • Ссылка на пример, который вы хотите оценить или с которым вам нужна помощь, в онлайн-редакторе (как указано в шаге 1 выше). Это хорошая практика - очень сложно помочь кому-то с проблемой кодирования, если вы не видите его код.
    • +
    • Ссылка на страницу фактического задания или оценки, чтобы мы могли найти вопрос, в котором вам нужна помощь.
    • +
    +
  4. +
diff --git a/files/ru/learn/html/multimedia_and_embedding/mozilla_splash_page/index.html b/files/ru/learn/html/multimedia_and_embedding/mozilla_splash_page/index.html new file mode 100644 index 0000000000..4171780730 --- /dev/null +++ b/files/ru/learn/html/multimedia_and_embedding/mozilla_splash_page/index.html @@ -0,0 +1,106 @@ +--- +title: Заставка Mozilla +slug: Learn/HTML/Multimedia_and_embedding/заставка_Mozilla +translation_of: Learn/HTML/Multimedia_and_embedding/Mozilla_splash_page +--- +
{{LearnSidebar}}
+ +
{{PreviousMenu("Learn/HTML/Multimedia_and_embedding/Responsive_images", "Learn/HTML/Multimedia_and_embedding")}}
+ +

В этом задании мы проверим ваши знания приёмов, рассмотренных в статьях этого модуля, через добавление изображений и видео на забавную страницу о Mozilla!

+ + + + + + + + + + + + +
Предпосылки:Прежде чем приступить к этому заданию, вы должны проработать остальную часть модуля мультимедиа и встраивания.
Задача:Для проверки знаний о встраивании изображений и видео в веб-страницы, фреймы и методы визуального восприятия HTML.
+ +

Отправная точка

+ +

Для начала этого задания скачайте все HTML файлы и изображения, доступные на github(mdn-splash-page-start). Сохраните содержимое index.html в файле с именем index.html на вашем диске в новой папке. Затем сохраните pattern.png в той же папке (правый клик на изображении для выбора опции сохранения).

+ +

Сохраните изображения из папки originals тем же способом; возможно вы захотите сохранить их в другой папке пока не обработаете (некоторые из них) с помощью графического редактора.

+ +
+

Note: Приведенный для примера HTML файл содержит довольно много CSS для стилизации страницы. Вам не нужно изменять CSS, только HTML внутри {{htmlelement("body")}} элемента — пока вы используете корректную разметку, CSS будет придавать правильный внешний вид.

+
+ +

Описание проекта

+ +

В этом задании мы представляем вам почти законченый сайт-визитку Mozilla, цель которого - рассказать что-нибудь интересное о принципах Mozilla и предоставить несколько ссылок для углубленного ознакомления. К сожалению, изображения или видео не добавлены - это ваша работа! Вам нужно добавить несколько медиа-файлов для того, чтобы страница смотрелась лучше и имела больше смысла. В следующих подразделах подробно объяснено, что вам требуется сделать:

+ +

Подготовка изображений

+ +

Используя ваш любимый редактор изображений, создайте версии шириной 400px и 120px, следующих изображений:

+ + + +

Назовите их как-нибудь разумно, например firefoxlogo400.pngи firefoxlogo120.png.

+ +

Вместе с mdn.svg, эти изображения будут иконками для ссылок на другие ресурсы внутри секции further-info. Вы также дадите ссылку на логотип Firefox в шапке сайта. Сохраните все копии внутри той же папки, что и index.html.

+ +

Затем создайте фоновую версию  red-panda.jpg шириной 1200px и портретную версию шириной 600px, которая показывает панду более крупным планом. Снова назовите их разумно, чтобы легко распозновать их. Сохраните обе копии внутри той же папки, что и index.html.

+ +
+

Note: Следует  обрабатывать JPG и PNG изображения, чтобы делать их как можно меньше по весу, при сохранении хорошего вида. tinypng.com - отличный сервис для этого.

+
+ +

Добавление логотипа в шапку

+ +

Добавьте внутрь элемента {{htmlelement("header")}} элемент {{htmlelement("img")}}, который вставит уменьшенную версию логотипа Firefox в шапку.

+ +

Добавление видео к основному содержанию статьи

+ +

Внутри элемента {{htmlelement("article")}} (сразу после открывающего тэга), вставьте ролик с YouTube по ссылке https://www.youtube.com/watch?v=ojcNcvb1olg, используя подходящие инструменты YouTube для генерации кода. Видео должно быть 400px в ширину.

+ +

Добавление отзывчивых изображений к ссылкам с доп. информацей

+ +

Внутри {{htmlelement("div")}} с классом further-info вы найдёте четыре элемента {{htmlelement("a")}}  — каждый из которых ссылается на интересную страницу, связанную с Mozilla. Для завершения этой секции вам необходимо поместить элемент {{htmlelement("img")}} внутрь каждого элемента {{htmlelement("a")}} дополнив подходящими атрибутами {{htmlattrxref("src", "img")}}, {{htmlattrxref("alt", "img")}}, {{htmlattrxref("srcset", "img")}} и {{htmlattrxref("sizes", "img")}}.

+ +

В каждом случае (кроме одного - какой из них по сути отзывчивый?) мы хотим, чтобы браузер использовал изображение шириной 120px , когда экран меньше или равен 480px, либо шириной 400px в других случаях.

+ +

Убедитесь, что вы использовали изображения, соответствующие ссылкам.

+ +
+

Note: Для проверки правильности работы srcset/sizes , вам нужно загрузить ваш сайт на сервер (используйте Github pages - простое и бесплатное решение). Затем  вы сможете проверить правильность их работы используя инструменты разработчика в браузере, как описано в Responsive images: useful developer tools.

+
+ +

Искусственно измененная красная панда

+ +

Внутри элемента {{htmlelement("div")}} с классом red-panda, мы хотим поместить элемент {{htmlelement("picture")}} , который использует маленькое портретное изображение панды, если экран меньше или равен 600px, либо большое фоновое изображение.

+ +

Пример

+ +

Следующие скриншоты демонстрируют, как сайт-визитка выглядит, при правильной разметке, на широких и узких экранах.

+ +

A wide shot of our example splash page

+ +

A narrow shot of our example splash page

+ +

Заключение

+ +

Если вы выполняете это задание как часть организованного курса вам следует передать вашу работу учителю/наставнику для оценки. Если вы обучаетесь самостоятельно, то вы легко можете получить отметку в ветке форума этого упражнения, либо в IRC канале #mdn на Mozilla IRC. Сначала попробуйте выполнить упражнение - жульничеством ничего не добиться! 

+ +

{{PreviousMenu("Learn/HTML/Multimedia_and_embedding/Responsive_images", "Learn/HTML/Multimedia_and_embedding")}}

+ +

В этом модуле

+ + diff --git "a/files/ru/learn/html/multimedia_and_embedding/\320\264\320\276\320\261\320\260\320\262\320\273\320\265\320\275\320\270\320\265_r_graphics_to_the_web/index.html" "b/files/ru/learn/html/multimedia_and_embedding/\320\264\320\276\320\261\320\260\320\262\320\273\320\265\320\275\320\270\320\265_r_graphics_to_the_web/index.html" deleted file mode 100644 index a3a445dfc7..0000000000 --- "a/files/ru/learn/html/multimedia_and_embedding/\320\264\320\276\320\261\320\260\320\262\320\273\320\265\320\275\320\270\320\265_r_graphics_to_the_web/index.html" +++ /dev/null @@ -1,351 +0,0 @@ ---- -title: Добавление векторной графики в веб-документ -slug: Learn/HTML/Multimedia_and_embedding/Добавление_r_graphics_to_the_Web -translation_of: Learn/HTML/Multimedia_and_embedding/Adding_vector_graphics_to_the_Web ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/HTML/Multimedia_and_embedding/Other_embedding_technologies", "Learn/HTML/Multimedia_and_embedding/Responsive_images", "Learn/HTML/Multimedia_and_embedding")}}
- -
-

Векторная графика очень полезна во многих случаях. Она имеет малые размеры файла и высокую масштабируемость – при увеличении масштаба пиксели не увеличиваются вместе с графикой. В данной статье мы покажем, как встраивать векторную графику на Вашу страницу.

-
- - - - - - - - - - - - -
Навыки:Знание основ HTML и умение добавлять изображение в веб-документ.
Цель:Изучить как встроить SVG (векторное) изображение на вебстраницу.
- -
-

Примечание: Данная статья не научит Вас векторной графике, а даст понимание что это и как ее использовать в веб-документах.

-
- -

Что такое векторная графика?

- -

В веб-разработке Вы будете сталкиваться с двумя типами изображений - растровым и векторным:

- - - -

Для демонстрации различий между типами изображений, давайте взглянем на пример. Вы можете найти данный пример на Github как vector-versus-raster.html — в нем демонстрируются два, на первый взгляд, одинаковых изображения, расположенных рядом друг с другом. Каждое из изображений представляет собой красную звезду с тенью. Различие их в том, что левое изображение имеет формат PNG, а правое - SVG.

- -

Различия становятся заметны, когда Вы изменяете масштаб страницы — PNG изображение становится неровным (становятся видны пиксели), потому что оно содержит информацию о положении и цвете каждого пикселя. При увеличении каждый пиксель также увеличивается, охватывая несколько пикселей дисплея, поэтому становятся заметны "кирпичики". Векторное изображение продолжает выглядеть ровным и красивым, потому что фигуры, масштабируются совместно с ним. 

- -

Two star images

- -

Two star images zoomed in, one crisp and the other blurry

- -
-

Примечание: Оба изображения сверху имеют формат PNG — слева показано растровое изображение, справа условно показано векторное изображение. Напоминаем, что пример с реальными растровым и веркторным изображениями находится по ссылке: vector-versus-raster.html !

-
- -

Более того, файлы векторных изображений намного меньше растровых, т.к. в них содержится алгоритмы построения вместо информации о каждом пикселе.

- -

Что такое SVG?

- -

SVG это язык на базе {{glossary("XML")}} для описания векторных изображений. По сути это язык разметки, как и HTML, только содержащий множество различных элементов для определения фигур вашего изображения, а также параметров их отображения. SVG предназначен для разметки графики, а не содержимого. В простейшем случае,  Вы можете использовать элементы для создания простых фигур, таких как {{svgelement("circle")}}(круг) и {{svgelement("rect")}}(прямоугольник). Более сложные SVG элементы включают {{svgelement("feColorMatrix")}} (разложение цвета с использованием матрицы), {{svgelement("animate")}} (анимация частей Вашего векторного изображения) и {{svgelement("mask")}} (примение маски к изображению.)

- -

В качестве простого примера, следующий код создает круг и прямоугольник:

- -
<svg version="1.1"
-     baseProfile="full"
-     width="300" height="200"
-     xmlns="http://www.w3.org/2000/svg">
-  <rect width="100%" height="100%" fill="black" />
-  <circle cx="150" cy="100" r="90" fill="blue" />
-</svg>
- -

В результате получается следующее:

- -

{{ EmbedLiveSample('What_is_SVG', 300, 200, "", "", "hide-codepen-jsfiddle") }}

- -

Исходя из примера выше, может показаться, что SVG легко создавать вручную. Да, простые SVG можно создавать, используя текстовый редактор, но в случае сложного изображения это становится сложным. Для создания SVG изображений используются редакторы векторной графики, такие как Inkscape или Illustrator. Данные приложения позволяют создавать различные изображения, используя множество графических инструментов, и создавать приближения фотографий (например опция Trace Bitmap feature приложения Inkscape.)

- -

Дополнительные преимущества SVG:

- - - -

Так почему же тогда вообще используют растровые изображения, а не только SVG? Дело в том, что SVG имеет ряд недостатков:

- - - -

В целом, растровая графика лучше подходит для сложных изображений, например, фотографий.

- -
-

Примечание: В приложении Inkscape сохраняйте файлы как Plain SVG, для экономии места. Также, пожалуйста перейдите на статью, описывающую как подготовить SVG изображение для веб-документа.

-
- -

Добавление SVG на страницы

- -

В данном разделе мы рассмотрим различные варианты, с помощью которых можно добавить SVG векторную графику на веб-страницу.

- -

Быстрый путь: {{htmlelement("img")}}

- -

Чтобы встроить SVG используя элемент {{htmlelement ("img")}}, вам просто нужно сослаться на него в атрибуте src, как и следовало ожидать. Вам понадобится атрибут height или width (или оба, если ваш SVG не имеет собственного соотношения сторон). Если вы еще этого не делали, пожалуйста, прочтите Изображения в HTML.

- -
<img
-    src="equilateral.svg"
-    alt="triangle with all three sides equal"
-    height="87px"
-    width="100px" />
- -

Плюсы

- - - -

Минусы

- - - -

Устранение неполадок и кросс-браузерная поддержка

- -

Для браузеров которые не поддерживают SVG (IE 8 и ниже, Android 2.3 и ниже), вы можете ссылаться на PNG или JPG в src атрибуте и использовать {{htmlattrxref("srcset", "img")}} атрибут (который распознают только последние браузеры) чтобы сослаться на SVG. В этом случае SVG будут загружаться только поддерживающими браузерами - старые же браузеры будут загружать PNG:

- -
<img src="equilateral.png" alt="triangle with equal sides" srcset="equilateral.svg">
- -

Также вы можете использовать SVG в качестве фоновых изображение CSS, как показано ниже. В приведенном коде ниже старые браузеры будут придерживаться PNG, который они понимают, тогда как новые браузеры будут загружать SVG:

- -
background: url("fallback.png") no-repeat center;
-background-image: url("image.svg");
-background-size: contain;
- -

Подобно методу <img>, описанному выше, вставка SVG с использлованием фоновых изображений CSS означает, что SVG нельзя манипулировать при помощи JavaScript, и что SVG будет иметь те же ограничения, что и CSS.

- -

Если ваши SVG не отображаются вовсе, возможно, ваш сервер не настроен должным образом. Если проблема в этом, то данная статья укажет вам верное направление.

- -

Как включить SVG в ваш HTML код

- -

Вы можете открыть файл SVG в текстовом редакторе, скопировать этот код и вставить его в ваш HTML документ — такой прием иногда называют встраиванием SVG (SVG inline или inlining SVG). Убедитесь, что фрагмент вашего SVG кода начинается и заканчивается с тегов <svg></svg> (не включайте ничего, кроме них). Вот очень простой пример того, что вы можете вставить в ваш документ:

- -
<svg width="300" height="200">
-    <rect width="100%" height="100%" fill="green" />
-</svg>
-
- -

Плюсы

- - - -

Минусы

- - - - - -

Как встраивать SVG при помощи {{htmlelement("iframe")}}

- -

Вы можете открывать ваши SVG изображения в браузере просто как веб-страницы. Таким образом встраивание SVG документа с помощью <iframe> выполняется как мы изучали ранее в главе От <object> к <iframe> — другие технологии внедрения.

- -

Вот краткий обзор:

- -
<iframe src="triangle.svg" width="500" height="500" sandbox>
-    <img src="triangle.png" alt="Triangle with three unequal sides" />
-</iframe>
- -

Это - определенно не самый лучший метод для выбора:

- -

Минусы

- - - -

Активное изучение: поиграйте с SVG

- -

В этом разделе ативного изучения мы бы хотели, чтобы вы просто попробовали поиграть с SVG. Ниже, в областе Input, вы увидите, что мы уже предоставили некий пример для того, чтобы вы начали. А еще вы можете посетить SVG Element Reference, чтобы узнать больше деталей о других игрушках, которые могут быть использованы в SVG, и тоже попробовать их. Этот раздел полностью посвящен практике ваших исследовательских навыков и вашему развлечению.

- -

Если Вы где-то застряли и ваш код не работает, Вы всегда можете начать сначала, нажав кнопку Reset.

- - - -

{{ EmbedLiveSample('Playable_code', 700, 500, "", "", "hide-codepen-jsfiddle") }}

- -

Заключение

- -

Эта статья предоставила вам краткий обзор по тому, что такое векторная графика и SVG, почему полезно знать о них и как внедрять SVG в вашу веб-страницу. Эта статья не является полным руководством по изучению SVG, а всего лишь указатель, чтоб вы знали что такое SVG, на случай, если вы встретите его во время странствий по Сети. Так что не переживайте, если вы еще не чувствуете себя экспертом в SVG. Ниже мы включили несколько ссылок, которые могут вам помочь, если вы хотите узнать больше о том, как это работает.

- -

В последней статье этого модуля мы будем исследовать адаптивные изображения в деталях, рассматривая инструменты HTML, которые позволяют делать ваши изображения так, чтоб они могли лучше работать на разных устройствах.

- -

See also

- - - -

{{PreviousMenuNext("Learn/HTML/Multimedia_and_embedding/Other_embedding_technologies", "Learn/HTML/Multimedia_and_embedding/Responsive_images", "Learn/HTML/Multimedia_and_embedding")}}

- -

In this module

- - diff --git "a/files/ru/learn/html/multimedia_and_embedding/\320\267\320\260\321\201\321\202\320\260\320\262\320\272\320\260_mozilla/index.html" "b/files/ru/learn/html/multimedia_and_embedding/\320\267\320\260\321\201\321\202\320\260\320\262\320\272\320\260_mozilla/index.html" deleted file mode 100644 index 4171780730..0000000000 --- "a/files/ru/learn/html/multimedia_and_embedding/\320\267\320\260\321\201\321\202\320\260\320\262\320\272\320\260_mozilla/index.html" +++ /dev/null @@ -1,106 +0,0 @@ ---- -title: Заставка Mozilla -slug: Learn/HTML/Multimedia_and_embedding/заставка_Mozilla -translation_of: Learn/HTML/Multimedia_and_embedding/Mozilla_splash_page ---- -
{{LearnSidebar}}
- -
{{PreviousMenu("Learn/HTML/Multimedia_and_embedding/Responsive_images", "Learn/HTML/Multimedia_and_embedding")}}
- -

В этом задании мы проверим ваши знания приёмов, рассмотренных в статьях этого модуля, через добавление изображений и видео на забавную страницу о Mozilla!

- - - - - - - - - - - - -
Предпосылки:Прежде чем приступить к этому заданию, вы должны проработать остальную часть модуля мультимедиа и встраивания.
Задача:Для проверки знаний о встраивании изображений и видео в веб-страницы, фреймы и методы визуального восприятия HTML.
- -

Отправная точка

- -

Для начала этого задания скачайте все HTML файлы и изображения, доступные на github(mdn-splash-page-start). Сохраните содержимое index.html в файле с именем index.html на вашем диске в новой папке. Затем сохраните pattern.png в той же папке (правый клик на изображении для выбора опции сохранения).

- -

Сохраните изображения из папки originals тем же способом; возможно вы захотите сохранить их в другой папке пока не обработаете (некоторые из них) с помощью графического редактора.

- -
-

Note: Приведенный для примера HTML файл содержит довольно много CSS для стилизации страницы. Вам не нужно изменять CSS, только HTML внутри {{htmlelement("body")}} элемента — пока вы используете корректную разметку, CSS будет придавать правильный внешний вид.

-
- -

Описание проекта

- -

В этом задании мы представляем вам почти законченый сайт-визитку Mozilla, цель которого - рассказать что-нибудь интересное о принципах Mozilla и предоставить несколько ссылок для углубленного ознакомления. К сожалению, изображения или видео не добавлены - это ваша работа! Вам нужно добавить несколько медиа-файлов для того, чтобы страница смотрелась лучше и имела больше смысла. В следующих подразделах подробно объяснено, что вам требуется сделать:

- -

Подготовка изображений

- -

Используя ваш любимый редактор изображений, создайте версии шириной 400px и 120px, следующих изображений:

- - - -

Назовите их как-нибудь разумно, например firefoxlogo400.pngи firefoxlogo120.png.

- -

Вместе с mdn.svg, эти изображения будут иконками для ссылок на другие ресурсы внутри секции further-info. Вы также дадите ссылку на логотип Firefox в шапке сайта. Сохраните все копии внутри той же папки, что и index.html.

- -

Затем создайте фоновую версию  red-panda.jpg шириной 1200px и портретную версию шириной 600px, которая показывает панду более крупным планом. Снова назовите их разумно, чтобы легко распозновать их. Сохраните обе копии внутри той же папки, что и index.html.

- -
-

Note: Следует  обрабатывать JPG и PNG изображения, чтобы делать их как можно меньше по весу, при сохранении хорошего вида. tinypng.com - отличный сервис для этого.

-
- -

Добавление логотипа в шапку

- -

Добавьте внутрь элемента {{htmlelement("header")}} элемент {{htmlelement("img")}}, который вставит уменьшенную версию логотипа Firefox в шапку.

- -

Добавление видео к основному содержанию статьи

- -

Внутри элемента {{htmlelement("article")}} (сразу после открывающего тэга), вставьте ролик с YouTube по ссылке https://www.youtube.com/watch?v=ojcNcvb1olg, используя подходящие инструменты YouTube для генерации кода. Видео должно быть 400px в ширину.

- -

Добавление отзывчивых изображений к ссылкам с доп. информацей

- -

Внутри {{htmlelement("div")}} с классом further-info вы найдёте четыре элемента {{htmlelement("a")}}  — каждый из которых ссылается на интересную страницу, связанную с Mozilla. Для завершения этой секции вам необходимо поместить элемент {{htmlelement("img")}} внутрь каждого элемента {{htmlelement("a")}} дополнив подходящими атрибутами {{htmlattrxref("src", "img")}}, {{htmlattrxref("alt", "img")}}, {{htmlattrxref("srcset", "img")}} и {{htmlattrxref("sizes", "img")}}.

- -

В каждом случае (кроме одного - какой из них по сути отзывчивый?) мы хотим, чтобы браузер использовал изображение шириной 120px , когда экран меньше или равен 480px, либо шириной 400px в других случаях.

- -

Убедитесь, что вы использовали изображения, соответствующие ссылкам.

- -
-

Note: Для проверки правильности работы srcset/sizes , вам нужно загрузить ваш сайт на сервер (используйте Github pages - простое и бесплатное решение). Затем  вы сможете проверить правильность их работы используя инструменты разработчика в браузере, как описано в Responsive images: useful developer tools.

-
- -

Искусственно измененная красная панда

- -

Внутри элемента {{htmlelement("div")}} с классом red-panda, мы хотим поместить элемент {{htmlelement("picture")}} , который использует маленькое портретное изображение панды, если экран меньше или равен 600px, либо большое фоновое изображение.

- -

Пример

- -

Следующие скриншоты демонстрируют, как сайт-визитка выглядит, при правильной разметке, на широких и узких экранах.

- -

A wide shot of our example splash page

- -

A narrow shot of our example splash page

- -

Заключение

- -

Если вы выполняете это задание как часть организованного курса вам следует передать вашу работу учителю/наставнику для оценки. Если вы обучаетесь самостоятельно, то вы легко можете получить отметку в ветке форума этого упражнения, либо в IRC канале #mdn на Mozilla IRC. Сначала попробуйте выполнить упражнение - жульничеством ничего не добиться! 

- -

{{PreviousMenu("Learn/HTML/Multimedia_and_embedding/Responsive_images", "Learn/HTML/Multimedia_and_embedding")}}

- -

В этом модуле

- - diff --git "a/files/ru/learn/html/multimedia_and_embedding/\320\270\320\267\320\276\320\261\321\200\320\260\320\266\320\265\320\275\320\270\321\217_\320\262_html/index.html" "b/files/ru/learn/html/multimedia_and_embedding/\320\270\320\267\320\276\320\261\321\200\320\260\320\266\320\265\320\275\320\270\321\217_\320\262_html/index.html" deleted file mode 100644 index d96558e3da..0000000000 --- "a/files/ru/learn/html/multimedia_and_embedding/\320\270\320\267\320\276\320\261\321\200\320\260\320\266\320\265\320\275\320\270\321\217_\320\262_html/index.html" +++ /dev/null @@ -1,364 +0,0 @@ ---- -title: Изображения в HTML -slug: Learn/HTML/Multimedia_and_embedding/Изображения_в_HTML -translation_of: Learn/HTML/Multimedia_and_embedding/Images_in_HTML ---- -
{{LearnSidebar}}
- -
{{NextMenu("Learn/HTML/Multimedia_and_embedding/Video_and_audio_content", "Learn/HTML/Multimedia_and_embedding")}}
- -

В начале Web был просто текстом, что было довольно скучно. К счастью, это продолжалось не долго - до появления возможности вставлять изображения (и другие, более интересные, типы контента) в веб-страницы. Существуют и другие типы мультимедиа, однако логичнее начать со скромного {{htmlelement("img")}}  элемента, используемого для вставки простого изображения в веб-страницу. В этой статье мы рассмотрим, как использовать элемент, начиная с основ, снабжать примечаниями, используя  {{htmlelement("figure")}}, и разберём, как это относится к фоновым изображениям {{glossary("CSS")}}. 

- - - - - - - - - - - - -
Необходимы:Базовые знания компьютера, установленное базовое ПО, базовые знания по работе с файлами, знания основ HTML (как описано в статье Начало работы с HTML).
Цель:Узнать, как встраивать изображения в HTML, как добавлять к ним описания и как изображения HTML связаны с фоновыми изображениями CSS.
- -

Как разместить картинку на странице?

- -

Чтобы разместить изображение на странице, нужно использовать тег {{htmlelement("img")}}. Это пустой элемент (имеется ввиду, что не содержит текста и закрывающего тега), который требует минимум один атрибут для использования — src (произносится эс-ар-си, иногда говорят его полное название, source). Атрибут src содержит путь к изображению, которое вы хотите встроить в страницу, и может быть относительным или абсолютным URL, точно так же, как значения атрибута href для элемента {{htmlelement("a")}}.

- -
-

Примечание: Перед тем как продолжить, вам стоит вспомнить про типы адресов URL, чтобы обновить в памяти про относительные и абсолютные адресса.

-
- -

Например, если ваше изображение называется dinosaur.jpg, и оно находится в той же директории что и ваша HTML страница, вы можете встроить это изображение как:

- -
<img src="dinosaur.jpg">
- -

Если изображение было в поддиректории images , находящаяся внутри той же директории, что и HTML страница (что рекомендует Google для индексации и целей SEO), тогда вы можете встроить его так:

- -
<img src="images/dinosaur.jpg">
- -

И так далее.

- -
-

Примечание: Поисковые системы также читают имена изображений и считают их для оптимизации поискового запроса. Поэтому присваивайте вашим изображениям смысловые имена: dinosaur.jpg лучше, чем img835.png.

-
- -

Вы можете встроить изображение используя абсолютный URL, например:

- -
<img src="https://www.example.com/images/dinosaur.jpg">
- -

Но это бесмыссленно, так как он просто заставляет браузер делать больше работы, запрашивая каждый раз IP-адрес от DNS-сервера.  Вы почти всегда будете держать свои изображения для сайта на том же сервере, что и ваш HTML.

- -
-

Внимание: Большиство изображений защищены. Не отображайте изображения на вашем сайте пока:

- -
    -
  • вы не будете владеть изображением
  • -
  • у вас не будет письменного разрешения владельца изображения, или
  • -
  • пока у вас не будет достаточно доказательств что изображение находится в открытом доступе.
  • -
- -

Нарушение авторских прав является незаконным. Кроме того, никогда не указывайте в своем атрибуте src ссылку на изображение, размещенное на чужом сайте. Это называется "хотлинкинг" (с англ. 'hotlinking' - 'горячая ссылка'). Запомните, кража пропускной способности чужого сайта незаконна. Это также замедляет вашу страницу и не позволяет вам контролировать, будет ли изображение удалено или заменено чем-то неприятным.

-
- -

Наш код выше даст нам следующий результат:

- -

A basic image of a dinosaur, embedded in a browser, with Images in HTML written above it

- -
-

Примечание: Такие элементы как {{htmlelement("img")}} и {{htmlelement("video")}} иногда называются замещаемыми элементами. Это потому что содержание элемента и размер, определяет внешний ресурс (как изображение или видео файл), а не содержание самого элемента. Вы можете узнать о них больше в Замещаемых элементах.

-
- -
-

Примечание: Вы можете найти готовый пример этого раздела, размещённый на Github (смотрите также исходный код).

-
- -

Альтернативный текст

- -

Следующий атрибут, который мы рассмотрим — alt. Его значением должно быть текстовое описание изображения для использования в ситуациях, когда изображение не может быть просмотрено / отображено или отрисовка занимает много времени из-за медленного интернет-соединения. Чтобы продемонстрировать использование атрибута alt на практике, внесем изменения в код из предыдущего примера:

- -
<img src="images/dinosaur.jpg"
-     alt="Голова и туловище скелета динозавра;
-         у него большая голова с длинными острыми зубами">
- -

Самый простой способ увидеть атрибут alt в действии — это сделать намеренную ошибку в имени файла. Например, если бы мы написали имя изображения как dinosooooor.jpg, браузер не смог бы его отобразить, и на экране появился бы текст из атрибута alt:

- -

The Images in HTML title, but this time the dinosaur image is not displayed, and alt text is in its place.Итак, в каких случаях текст из атрибута alt может быть нам полезен? Приведем несколько примеров:

- - - -

Что именно вы должны писать в атрибут alt? В первую очередь, это зависит от того, зачем изображение вообще находится на странице. Другими словами, что вы потеряете, если ваше изображение не появится:

- - - -

По существу, главная идея здесь это предоставить нечто полезное, для случая когда изображения не видны. Это гарантирует что все пользователи не упустят ничего из содержимого страницы. Попробуйте отключить изображения в своём браузере и посмотрите как всё выглядит. Вы вскоре выясните насколько полезным является альтернативный текст, если изображения не видны.

- -
-

Примечание: Более подробную информацию, смотрите здесь: Альтернативный текст.

-
- -

Ширина и высота

- -

Вы можете использовать атрибуты width и height, чтобы указать ширину и высоту вашего изображения. Ширину и высоту вашего избражение можете найти различными способами. Например, на Mac можно использовать  Cmd + I  чтобы  получить информацию по изображению. Повторяя наш пример, мы можем сделать так:

- -
<img src="images/dinosaur.jpg"
-     alt="The head and torso of a dinosaur skeleton;
-          it has a large head with long sharp teeth"
-     width="400"
-     height="341">
- -

Это не приводит к большой разнице в отображении при нормальных обстоятельствах. Но если изображение не будет показано, например, когда пользователь только что перешёл на страницу, а оно ещё не успело загрузится, вы укажите браузеру оставить место для отрисовки изображения:

- -

The Images in HTML title, with dinosaur alt text, displayed inside a large box that results from width and height settings

- -

Это хорошая практика, в результате страница загрузится быстрее и более гладко.

- -

Однако, вы не должны изменять размеры ваших изображений используя HTML аттрибуты. Если вы установите размер изображения слишком большим, то в конечном итоге вы сталкнётесь с изображениями, которые выглядят зернистыми, размытыми или слишком маленькими, и потратите трафик для загрузки изображения, которое не будет соответствовать нуждам пользователя. Конечное изображение может также выглядеть искажённым, если вы не сохраните правильное соотношение сторон. Рекомендуется использовать графический редактор для подгонки изображения к нужному размеру, перед вставкой его на вашу вэб-страницу.

- -
-

Примечание: Если вам действительно нужно изменить размер изображения, вы должны использовать вместо этого CSS.

-
- -

Заголовок изображения

- -

Как и для ссылок, вы также можете добавить атрибут title для изображений, чтобы при необходимости предоставить дополнительную информацию. В нашем примере мы могли бы сделать это так:

- -
<img src="images/dinosaur.jpg"
-     alt="The head and torso of a dinosaur skeleton;
-          it has a large head with long sharp teeth"
-     width="400"
-     height="341"
-     title="A T-Rex on display in the Manchester University Museum">
- -

Это дает нам всплывающую подсказку при наведении курсора мыши, также как и в ссылках:

- -

The dinosaur image, with a tooltip title on top of it that reads A T-Rex on display at the Manchester University Museum

- -

Однако это не рекомендуется - title имеет ряд проблем с доступностью, в основном из-за того, что поддержка программ чтения с экрана очень непредсказуема, и большинство браузеров не будут отображать её, если вы не наведёте курсор мыши (например, нет доступа для пользователей клавиатуры). Зачастую лучше включить такого рода вспомогательную информацию в основной текст статьи, чем прикреплять её к изображению. Однако, она полезна в некоторых обстоятельствах; например, в галереях изображений, когда у вас нет места для их заголовков.

- -

Активное обучение: встраивание изображения

- -

Наступила очередь немного поиграть! Этот раздел активного обучения поможет вам выполнить простое упражнение по встраиванию. Вы будете обеспечены простым {{htmlelement("img")}} тэгом; мы хотели бы чтобы вы встроили изображение расположенное по следующей ссылке:

- -

https://raw.githubusercontent.com/mdn/learning-area/master/html/multimedia-and-embedding/images-in-html/dinosaur_small.jpg

- -

Ранее мы говорили никогда не используйте горячие ссылки на изображения с других серверов, данный случай только для целей обучения, итак мы позволим вам пренебречь этим один разок.

- -

Мы также хотели бы, чтобы вы:

- - - -

Если вы сделаете ошибку, вы всегда можете очистить код, используя кнопку Reset. Если вы реально не будете понимать как сделать, нажмите кнопку Show solution, чтобы увидеть ответ:

- - - -

{{ EmbedLiveSample('Playable_code', 700, 500) }}

- -

Придание изображению структуры и установка заголовка

- -

Начиная разговор о заголовках, есть множество путей как вы можете добавить заголовок к своему изображению. Для примера, нет ничего, что может вас остановить сделать это таким образом:

- -
<div class="figure">
-  <img src="images/dinosaur.jpg"
-       alt="The head and torso of a dinosaur skeleton;
-            it has a large head with long sharp teeth"
-       width="400"
-       height="341">
-
-  <p>A T-Rex on display in the Manchester University Museum.</p>
-</div>
- -

Это нормально. Это содержит всё что вам нужно, и красиво стилизуется с помощью CSS. Но, есть проблема: здесь нет ничего, что семантически связывает изображение с его заголовком, и это может вызвать сложности для читателей. Например, когда у вас есть 50 изображений и заголовков, какой заголовок идёт вместе с каким изображением?

- -

Лучшим решением будет использование элементов HTML5 {{htmlelement("figure")}} и {{htmlelement("figcaption")}}. Они были созданы исключительно для этой цели: предоставить семантический контейнер для рисунков и четко связать рисунок с заголовком. Наш пример выше мог бы быть переписан так:

- -
<figure>
-  <img src="images/dinosaur.jpg"
-       alt="The head and torso of a dinosaur skeleton;
-            it has a large head with long sharp teeth"
-       width="400"
-       height="341">
-
-  <figcaption>A T-Rex on display in the Manchester University Museum.</figcaption>
-</figure>
- -

Элемент {{htmlelement("figcaption")}} говорит браузерам и вспомогательной технологии, что заголовок описывает содержимое элемента {{htmlelement("figure")}}.

- -
-

Замечание: С точки зрения доступности, заголовки и {{htmlattrxref('alt','img')}} имеют различные предназначения. Заголовки помогают даже тем, кто имеет возможность просматривать изображение, тогда как {{htmlattrxref('alt','img')}} обеспечивает замену функционала отсутствующего изображения. Таким образом, заголовки и alt не подразумевают под собой одни и те же вещи, потому что оба используются браузером при отсутствии изображения. Попробуйте отключить изображения в своём браузере, чтобы увидеть как это выглядит.

-
- -

Тег <figure> не является изображением. Он представляет собой независимый структурный элемент, который: 

- - - -

Тег <figure> может быть несколькими изображениями, куском кода, аудио, видео, уравнением, таблицей, либо чем-то другим.

- -

Активное изучение: создание <figure>

- -

В этом разделе активного изучения мы хотели бы, чтобы вы взяли текст из предыдущего раздела активного изучения и преобразовали его в <figure>:

- - - -

В случае допущения ошибки, вы всегда можете набрать код повторно, нажав кнопку Reset. Если вы застряли, нажмите кнопку Show solution, чтобы увидеть ответ:

- - - -

{{ EmbedLiveSample('Playable_code_2', 700, 500) }}

- -

Фоновые изображения CSS

- -

Вы можете использовать CSS для встраивания изображений в веб-страницы (или JavaScript, но это совсем другая история). Параметры CSS {{cssxref("background-image")}} и другие background-* применяются для контроля размещения фонового изображения. К примеру, чтобы залить фон каждого параграфа страницы, необходимо сделать следующее:

- -
p {
-  background-image: url("images/dinosaur.jpg");
-}
- -

Получившееся в конечном итоге изображение можно легко позиционировать и контролировать, в отличие от его HTML аналога. Так зачем же возиться с HTML изображениями? Как указано выше, фоновые изображения CSS предназначены только для украшения. Если вы просто хотите добавить что-то красивое на свою страницу, чтобы улучшить визуальные эффекты, это нормально. Тем не менее, такого рода изображения не имеют семантического смысла вообще. Они не могут иметь каких-то текстовых эквивалентов, видимых посетителю, они невидимы для программ чтения с экрана. Вот где блистают HTML-изображения!

- -

Итог: если изображение имеет важность, в контексте содержимого вашей страницы, вам следует использовать HTML изображения. Если же картинка является банальной декорацией, используйте фоновые изображения CSS.

- -
-

Замечание: Вы можете узнать больше о фоновых изображениях CSS в нашей теме о CSS.

-
- -

Проверьте свои навыки!

- -

Вы дошли до конца этой статьи, но можете ли вы вспомнить самую важную информацию? Вы можете найти дополнительные тесты, чтобы убедиться, что вы усвоили эту информацию, прежде чем двигаться дальше. Смотрите Проверьте знания по изображениям в HTML.

- -

Резюме

- -

На этом пока все. Мы подробно рассмотрели изображения и их заголовки. В следующей статье мы рассмотрим, как использовать HTML для встраивания видео и аудио на веб-страницы.

- -

{{NextMenu("Learn/HTML/Multimedia_and_embedding/Video_and_audio_content", "Learn/HTML/Multimedia_and_embedding")}}

diff --git "a/files/ru/learn/html/multimedia_and_embedding/\320\270\320\267\320\276\320\261\321\200\320\260\320\266\320\265\320\275\320\270\321\217_\320\262_html/\320\277\321\200\320\276\320\262\320\265\321\200\321\214\321\202\320\265_\321\201\320\262\320\276\320\270_\320\267\320\275\320\260\320\275\320\270\321\217_colon__\320\270\320\267\320\276\320\261\321\200\320\260\320\266\320\265\320\275\320\270\321\217_\320\262_html/index.html" "b/files/ru/learn/html/multimedia_and_embedding/\320\270\320\267\320\276\320\261\321\200\320\260\320\266\320\265\320\275\320\270\321\217_\320\262_html/\320\277\321\200\320\276\320\262\320\265\321\200\321\214\321\202\320\265_\321\201\320\262\320\276\320\270_\320\267\320\275\320\260\320\275\320\270\321\217_colon__\320\270\320\267\320\276\320\261\321\200\320\260\320\266\320\265\320\275\320\270\321\217_\320\262_html/index.html" deleted file mode 100644 index e00777dabe..0000000000 --- "a/files/ru/learn/html/multimedia_and_embedding/\320\270\320\267\320\276\320\261\321\200\320\260\320\266\320\265\320\275\320\270\321\217_\320\262_html/\320\277\321\200\320\276\320\262\320\265\321\200\321\214\321\202\320\265_\321\201\320\262\320\276\320\270_\320\267\320\275\320\260\320\275\320\270\321\217_colon__\320\270\320\267\320\276\320\261\321\200\320\260\320\266\320\265\320\275\320\270\321\217_\320\262_html/index.html" +++ /dev/null @@ -1,74 +0,0 @@ ---- -title: 'Проверьте свои знания: Изображения в HTML' -slug: >- - Learn/HTML/Multimedia_and_embedding/Изображения_в_HTML/Проверьте_свои_знания:_Изображения_в_HTML -translation_of: >- - Learn/HTML/Multimedia_and_embedding/Images_in_HTML/Test_your_skills:_HTML_images ---- -
{{learnsidebar}}
- -

Цель этого теста навыков - оценить, поняли ли вы нашу статью Изображения в HTML.

- -
-

Примечание: Вы можете опробовать решения в интерактивных редакторах ниже, однако может быть полезно загрузить код и использовать онлайн-инструмент, такой как CodePen, jsFiddle или Glitch для работы с задачами.

-
- -

Изображения в HTML №1

- -

В этой задаче мы хотим, чтобы вы вставили на страницу простое изображение ягоды черники. Вам необходимо:

- - - -

Попробуйте обновить живой код ниже, чтобы воссоздать готовый пример:

- -

{{EmbedGHLiveSample("learning-area/html/multimedia-and-embedding/tasks/images/images1.html", '100%', 700)}}

- -
-

Загрузите файл для этой задачи, чтобы работать в вашем редакторе или в онлайн-редакторе.

-
- -

Изображения в HTML №2

- -

В этой задаче у вас уже есть полнофункциональное изображение, но мы хотели бы, чтобы вы добавили всплывающую подсказку, которая появляется при наведении курсора на изображение. Вы должны ввести некоторую соответствующую информацию во всплывающую подсказку.

- -

Попробуйте обновить живой код ниже, чтобы воссоздать законченный пример:

- -

{{EmbedGHLiveSample("learning-area/html/multimedia-and-embedding/tasks/images/images2.html", '100%', 700)}}

- -
-

Загрузите файл для этой задачи, чтобы работать в вашем редакторе или в онлайн-редакторе.

-
- -

Изображения в HTML №3

- -

В этой последней задаче вам предоставляется как полнофункциональное изображение, так и текст заголовка. Здесь вам нужно добавить элементы, которые будут связывать изображение с его заголовком.

- -

Попробуйте обновить живой код ниже, чтобы воссоздать готовый пример:

- -

{{EmbedGHLiveSample("learning-area/html/multimedia-and-embedding/tasks/images/images3.html", '100%', 700)}}

- -
-

Загрузите файл для этой задачи, чтобы работать в вашем редакторе или в онлайн-редакторе.

-
- -

Оценка или дополнительная помощь

- -

Вы можете попрактиковаться с этими примерами в интерактивных редакторах выше.

- -

Если вы хотите, чтобы ваша работа была оценена, или если вы застряли и хотите обратиться за помощью:

- -
    -
  1. Поместите свою работу в онлайн-редактор, например CodePen, jsFiddle или Glitch. Вы можете написать код самостоятельно или использовать файлы, ссылки на которые приведены в приведенных выше разделах.
  2. -
  3. Напишите сообщение с просьбой об оценке и / или помощи в MDN Discourse forum Learning category. Ваш пост должен включать: -
      -
    • Описательный заголовок, например "Требуется оценка для проверки навыков 1 по основам изображений HTML".
    • -
    • Подробная информация о том, что вы уже пробовали, и что бы вы хотели, чтобы мы сделали, например если вы застряли и нуждаетесь в помощи или хотите пройти оценку.
    • -
    • Ссылка на пример, который вы хотите оценить или с которым вам нужна помощь, в онлайн-редакторе (как указано в шаге 1 выше). Это хорошая практика - очень сложно помочь кому-то с проблемой кодирования, если вы не видите его код.
    • -
    • Ссылка на страницу фактического задания или оценки, чтобы мы могли найти вопрос, в котором вам нужна помощь.
    • -
    -
  4. -
diff --git "a/files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/advanced_text_formatting/index.html" "b/files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/advanced_text_formatting/index.html" deleted file mode 100644 index fdebae6e91..0000000000 --- "a/files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/advanced_text_formatting/index.html" +++ /dev/null @@ -1,679 +0,0 @@ ---- -title: Углубленное форматирование текста -slug: Learn/HTML/Введение_в_HTML/Advanced_text_formatting -tags: - - Beginner - - Guide - - HTML - - Начинающий - - Руководство -translation_of: Learn/HTML/Introduction_to_HTML/Advanced_text_formatting ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/Creating_hyperlinks", "Learn/HTML/Introduction_to_HTML/Document_and_website_structure", "Learn/HTML/Introduction_to_HTML")}}
- -

В HTML для форматирования текста есть много других элементов, не рассмотренных  в статье Основы редактирования текста в HTML. Элементы, описанные в этой статье, не так часто используются, но все же полезны для понимания (и это всё ещё будет не полный список элементов). Здесь вы узнаете о цитатах, списках описания, компьютерном коде и другом виде текстовых элементов, подстрочном и надстрочном тексте, контактной информации и других типах текста.

- - - - - - - - - - - - -
Предварительные требования: -

Базовое знакомство с HTML, раскрытое в 
- Начало работы с HTML. Форматирование текста с помощью HTML, описанное в статье Основы редактирования текста в HTML.

-
Задача:Научиться использовать менее известные HTML-элементы для продвинутой семантической разметки текста.
- -

Списки описания

- -

В основах HTML-текста мы рассмотрели, как пометить привычные типы списков в HTML, но мы не упоминали о третьем типе списка, с которым вы иногда сталкиваетесь, — списке описания. Цель этих списков состоит в том, чтобы пометить набор элементов и их связанных описаний, таких как термины и определения или вопросы и ответы.

- -

Давайте рассмотрим пример набора терминов и определений:

- -
Солилоквий
-Драматическая речь, в которой персонаж разговаривает сам с собой, передавая свои ощущения и мысли публике (но не другим персонажам).
-Монолог
-Драматическая речь, в которой персонаж передаёт свои мысли публике и некоторым персонажам.
-Ремарка
-В драме: речь персонажа, при которой делается замечание с юмористическим или драматическим эффектом; чаще всего это чувства, мысли или предпосылки к чему-либо.
- -

В списках описания используется иная оболочка, чем в других типах списков — {{htmlelement ("dl")}} (от description list); кроме того, каждый термин завёрнут в элемент {{htmlelement ("dt")}} (description term — термин для описания) и каждое определение завёрнуто в элемент {{htmlelement ("dd")}} (description definition — описание определения).

- -

Закончим разметку нашего примера:

- -
<dl>
-  <dt>Солилоквий</dt>
-  <dd>Драматическая речь, в которой персонаж разговаривает сам с собой, передавая свои ощущения и мысли публике (но не другим персонажам).</dd>
-  <dt>Монолог</dt>
-  <dd>Драматическая речь, в которой персонаж передаёт свои мысли публике и некоторым персонажам.</dd>
-  <dt>Ремарка</dt>
-  <dd>В драме: речь персонажа, при которой делается замечание с юмористическим или драматическим эффектом; чаще всего это чувства, мысли или предпосылки к чему-либо.</dd>
-</dl>
- -

В стилях браузера по умолчанию будут отображаться списки описания с некоторыми отступами от терминов. Стили, определённые на MDN, довольно близки к этому соглашению, но также вносят некоторые изменения:

- -
-
Солилоквий
-
Драматическая речь, в которой персонаж разговаривает сам с собой, передавая свои ощущения и мысли публике (но не другим персонажам).
-
Монолог
-
Драматическая речь, в которой персонаж передаёт свои мысли публике и некоторым персонажам.
-
Ремарка
-
В драме: речь персонажа, при которой делается замечание с юмористическим или драматическим эффектом; чаще всего это чувства, мысли или предпосылки к чему-либо.
-
- -

Заметьте, что разрешено давать одному элементу несколько описаний:

- -
-
Ремарка
-
В драме: речь персонажа, при которой делается замечание с юмористическим или драматическим эффектом; чаще всего это чувства, мысли или предпосылки к чему-либо.
-
В письменности: отметка, примечание (устар.).
-
- -

Активное обучение: разметка набора определений

- -

Пришло время попробовать свои силы в списках описания: добавьте элементы в исходный текст в поле Ввод, чтобы он отображался как список описания в поле Вывод. Вы можете попробовать использовать свои собственные термины и описания, если хотите.

- -

Если Вы ошиблись, то всегда можете начать снова, воспользовавшись кнопкой Сбросить. Если упражнение вызывает у Вас затруднения, то нажмите кнопку Показать решение, чтобы увидеть правильный ответ.

- - - -

{{ EmbedLiveSample('Playable_code', 700, 350, "", "", "hide-codepen-jsfiddle") }}

- -

Цитаты

- -

HTML также имеет функции, доступные для маркировки цитат; какой элемент вы используете, зависит от того, маркируете ли вы блочную или строчную цитату.

- -

Блочные цитаты

- -

Если часть содержимого уровня блока (будь то абзац, несколько абзацев, список и т. д.) цитируется из другого источника, вы должны обернуть ее внутри элемента {{htmlelement ("blockquote")}}, чтобы обозначить это, и указать URL-адрес, указывающий на источник цитаты, внутри атрибута {{htmlattrxref ("cite", "blockquote")}}.

- -

Например, следующая разметка берется из страницы элемента MDN <blockquote>:

- -
<p><strong>HTML-элемент<code>&lt;blockquote&gt;</code></strong> (от англ. <em>HTML Block
-Quotation Element</em>) указывает на то, что заключённый в нём текст является развёрнутой цитатой.</p>
- -

Чтобы превратить её в блочную цитату, мы просто делаем следующее:

- -
<blockquote cite="https://developer.mozilla.org/ru/docs/Web/HTML/Element/blockquote">
-  <p><strong>HTML-элемент<code>&lt;blockquote&gt;</code></strong> (от англ. <em>HTML Block Quotation Element</em>) указывает на то, что заключённый в нём текст является развёрнутой цитатой.</p>
-</blockquote>
- -

Стиль браузера по умолчанию будет отображать это как абзац с отступом, как индикатор того, что это цитата; абзац над цитатой призван продемонстрировать это. MDN делает это, но также добавляет некоторый дополнительный стиль:

- -
-

HTML-элемент <blockquote> (от англ. Block Quotation) указывает на то, что заключённый в нём текст является развёрнутой цитатой.

-
- -

Строчные цитаты

- -

Строчные цитаты работают точно так же, за исключением того, что они используют элемент {{htmlelement ("q")}}. Например, следующий кусочек разметки содержит цитату из страницы <q> MDN:

- -
<p>Элемент цитирования — <code>&lt;q&gt;</code> — <q cite="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/q">предназначен
-для коротких цитат, не требующих прерывания абзаца</q>.</p>
- -

Стиль браузера по умолчанию будет отображать это как обычный текст, заключенный в кавычки для обозначения цитаты, например:

- -

Элемент цитирования — <q> — предназначен для коротких цитат, не требующих прерывания абзаца.

- -

Цитирование

- -

Содержание атрибута {{htmlattrxref ("cite", "blockquote")}} выглядит полезным, но, к сожалению, браузерам, программам чтения с экрана и т. д. оно на самом деле мало чем помогает. Невозможно заставить браузер отображать содержимое атрибута <cite> без написания собственного решения с использованием JavaScript или CSS. Если вы хотите, чтобы источник цитирования был доступен на странице, лучший способ его разметки - поместить элемент {{htmlelement ("cite")}} рядом с элементом цитаты (или внутри него). Это действительно будет означать то, что имя источника цитаты — то есть имя книги или имя человека, которое произвело цитату, — будет включено в текст. Нет причин, по которым вы не могли бы связать текст внутри <cite> с источником цитаты:

- -
<p>Как указано в статье о <a href="https://developer.mozilla.org/ru/docs/Web/HTML/Element/blockquote">
-<cite>блочных цитатах</cite></a>:
-</p>
-
-<blockquote cite="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/blockquote">
-  <p><strong>HTML-элемент<code>&lt;blockquote&gt;</code></strong> (от англ. <em>HTML Block
-  Quotation Element</em>) указывает на то, что заключённый в нем текст является развёрнутой цитатой.</p>
-</blockquote>
-
-<p>Элемент цитирования — <code>&lt;q&gt;</code> — <q cite="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/q">предназначен
-для коротких цитат, не требующих прерывания абзаца</q>. -- <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/q">
-<cite>Строчные цитаты</cite></a>.</p>
- -

По умолчанию цитаты стилизованы курсивом. Этот код можно увидеть в нашем примере quotations.html

- -

Активное обучение: кто это сказал?

- -

Время для другого примера активного обучения! В этом примере мы хотели бы, чтобы вы совершили следующие действия:

- -
    -
  1. Преобразуйте средний абзац в блочную цитату (<blockquote>), который включает атрибут cite.
  2. -
  3. Заверните часть третьего абзаца в строчную цитату, которая включает атрибут cite.
  4. -
  5. Включите элемент <cite> для каждой ссылки.
  6. -
- -

Источники цитирования, которые вам потребуются:

- - - -

Если Вы ошиблись, то всегда можете начать снова, воспользовавшись кнопкой Сбросить. Если упражнение вызывает у Вас затруднения, то нажмите кнопку Показать решение, чтобы увидеть правильный ответ.

- - - -

{{ EmbedLiveSample('Playable_code_2', 700, 450, "", "", "hide-codepen-jsfiddle") }}

- -

Аббревиатуры

- -

Другой довольно часто встречающийся элемент, который вы будете часто встречать в Интернете, — это {{htmlelement ("abbr")}}, используемый для обёртывания аббревиатур или акронимов и обеспечивающий полную расшифровку сокращения (с помощью атрибута {{htmlattrxref("title")}}.)

- -

Давайте рассмотрим несколько примеров:

- -
<p>Мы используем <abbr title="Hypertext Markup Language">HTML</abbr> для структурирования наших веб-документов.</p>
-
-<p>Я думаю, <abbr title="Почтенный">Почт.</abbr> Грин сделал это на кухне с бензопилой.</p>
-
- -

Они будут выглядеть примерно так (расшифровка появится в подсказке при наведении курсора мыши на сокращение):

- -

Мы используем HTML для структурирования наших веб-документов.

- -

Я думаю, Почт. Грин сделал это на кухне с бензопилой.

- -
-

Примечание: Существует еще один элемент {{htmlelement ("acronym")}}, который в основном делает то же самое, что и <abbr>, но предназначен специально для акронимов (тип аббревитатур). Это, однако, было излишним, — он не поддерживается в браузерах на том же уровне, что <abbr>, и имеет такую же функциональность, поэтому считается бессмысленным иметь оба. Просто используйте <abbr>.

-
- -

Активное обучение: выделение аббревиатуры

- -

В рамках этого простого упражнения мы хотели бы, чтобы вы просто указали аббревиатуру. Вы можете использовать наш образец ниже или заменить его на свой собственный.

- - - -

{{ EmbedLiveSample('Playable_code_3', 700, 300, "", "", "hide-codepen-jsfiddle") }}

- -

Разметка контактных данных

- -

HTML имеет элемент для разметки контактных данных — {{htmlelement ("address")}}. Он просто обёртывает ваши контактные данные, например:

- -
<address>
-  <p>Крис Миллс, Манчестер, Жестокий Север, РФ</p>
-</address>
- -

Однако следует помнить, что элемент {{htmlelement ("address")}} предназначен для разметки контактных данных человека, который написал HTML-документ, а не любого адреса. Таким образом, написанное выше было бы корректным только в том случае, если бы Крис написал документ, на котором появляется разметка. Обратите внимание, что следующее также подойдет:

- -
<address>
-  <p>Автор страницы — <a href="../authors/chris-mills/">Крис Миллс</a>.</p>
-</address>
- -

Верхний и нижний индекс

- -

Иногда вам понадобится использовать надстрочный или подстрочный индекс при разметке таких вещей, как даты, химические формулы и математические уравнения, чтобы они имели правильное представление. Элементы {{htmlelement ("sup")}} и {{htmlelement ("sub")}} созданы для таких ситуаций.

- -

Приведем пример:

- -
<p>Я просыпаюсь в 6<sup>35</sup> часов утра.</p>
-<p>Химическая формула кофеина: C<sub>8</sub>H<sub>10</sub>N<sub>4</sub>O<sub>2</sub>.</p>
-<p>Если x<sup>2</sup> равно 9, x должен равняться 3 или -3.</p>
- -

Результат этого кода выглядит следующим образом:

- -

Я просыпаюсь в 635 часов утра.

- -

Химическая формула кофеина: C8H10N4O2.

- -

Если x2 равно 9, x должен равняться 3 или -3.

- -

Представление компьютерного кода

- -

Существует несколько элементов для маркировки компьютерного кода с использованием HTML:

- - - -

Давайте рассмотрим несколько примеров. Вы должны попробовать поиграть с ними (захватите копию нашего файла other-semantics.html):

- -
<pre><code>var para = document.querySelector('p');
-
-para.onclick = function() {
-  alert('Owww, stop poking me!');
-}</code></pre>
-
-<p>You shouldn't use presentational elements like <code>&lt;font&gt;</code> and <code>&lt;center&gt;</code>.</p>
-
-<p>In the above JavaScript example, <var>para</var> represents a paragraph element.</p>
-
-
-<p>Select all the text with <kbd>Ctrl</kbd>/<kbd>Cmd</kbd> + <kbd>A</kbd>.</p>
-
-<pre>$ <kbd>ping mozilla.org</kbd>
-<samp>PING mozilla.org (63.245.215.20): 56 data bytes
-64 bytes from 63.245.215.20: icmp_seq=0 ttl=40 time=158.233 ms</samp></pre>
- -

Вышеприведенный код будет выглядеть так:

- -

{{ EmbedLiveSample('Representing_computer_code','100%',300, "", "", "hide-codepen-jsfiddle") }}

- -

Разметка времени и даты

- -

HTML также содержит элемент {{htmlelement ("time")}} для отметки времени и дат в машиночитаемом формате. Например:

- -
<time datetime="2020-01-20">20 Января 2020</time>
- -

Почему это полезно? Ну, есть много разных способов, которыми люди записывают даты. Вышеуказанная дата может быть записана как:

- - - -

Но эти разные формы не могут быть легко распознаны компьютерами — что, если вы хотите автоматически захватить даты всех событий на странице и вставить их в календарь? Элемент {{htmlelement ("time")}} позволяет прикрепить к этой цели однозначное машиночитаемое время / дату.

- -

В приведенном выше базовом примере приведена простая машиносчитываемая дата, но есть много других возможных вариантов, например:

- -
<!-- Стандартная дата -->
-<time datetime="2020-01-20">20 Января 2020</time>
-<!-- Только год и месяц -->
-<time datetime="2020-01">Январь 2020</time>
-<!-- Только месяц и день -->
-<time datetime="01-20">20 Января</time>
-<!-- Только время, часы и минуты -->
-<time datetime="19:30">19:30</time>
-<!-- Также вы можете отобразить секунды и миллисекунды! -->
-<time datetime="19:30:01.856">19:30:01.856</time>
-<!-- Дата и время -->
-<time datetime="2020-01-20T19:30">7.30pm, 20 Января 2020</time>
-<!-- Дата и время со смещением по часовому поясу -->
-<time datetime="2020-01-20T19:30+01:00">7.30pm, 20 Января 2020, — это 8.30pm во Франции.</time>
-<!-- Вызов номера недели -->
-<time datetime="2020-W04">Четвертая неделя 2020</time>
- -

Заключение

- -

На этом мы подошли к концу нашего изучения семантики текста HTML. Имейте в виду, что то, что вы видели во время этого курса, не является исчерпывающим списком текстовых элементов HTML. Мы попытались охватить основные из них, с которыми вы, скорее всего, столкнетесь в практической деятельности или, по крайней мере, сочтёте их интересными. Чтобы найти больше элементов HTML, вы можете взглянуть на нашу ссылку на Элемент. В следующей статье мы рассмотрим элементы HTML, которые вы будете использовать для структурирования различных частей HTML-документа.

- -

{{PreviousMenuNext ("Learn/HTML/Introduction_to_HTML/Create_hyperlinks", "Learn/HTML/Introduction_to_HTML/Document_and_website_structure", "Learn/HTML/Introduction_to_HTML")}}

- -

В этом модуле

- - diff --git "a/files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/debugging_html/index.html" "b/files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/debugging_html/index.html" deleted file mode 100644 index 1f3e03e508..0000000000 --- "a/files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/debugging_html/index.html" +++ /dev/null @@ -1,181 +0,0 @@ ---- -title: Отладка HTML -slug: Learn/HTML/Введение_в_HTML/Debugging_HTML -tags: - - Debugging - - Guide - - HTML - - Валидация - - Отладка -translation_of: Learn/HTML/Introduction_to_HTML/Debugging_HTML ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/Document_and_website_structure", "Learn/HTML/Introduction_to_HTML/Marking_up_a_letter", "Learn/HTML/Introduction_to_HTML")}}
- -

Написать HTML — здорово, но как понять, где ошибка, когда что-то не работает? В этой статье описаны несколько инструментов, которые помогают искать и исправлять ошибки в HTML.

- - - - - - - - - - - - -
Что нужно знать:Базовые знания HTML на уровне Начало работы с HTML, Основы редактирования текста в HTML, и Создание гиперссылок.
Чему вы научитесь:Искать проблемы в HTML с помощю инструментов отладки.
- -

Отладка — это не страшно

- -

Во время написания какого-нибудь кода, обычно все идет хорошо, пока не появляется тот момент, когда вы совершаете ошибку. Итак, ваш код не работает, или работает не так, как вы задумывали. Если вы попытаетесь скомпилировать неработающую программу на языке Rust, компилятор укажет на ошибку:

- -

A console window showing the result of trying to compile a rust program with a missing quote around a string in a print statement. The error message reported is error: unterminated double quote string.В данном случае, сообщение об ошибке понять относительно просто — "unterminated double quote string". Если вы внимательно посмотрите на println!(Hello, world!"); , то заметите, что здесь отсутсвует двойная кавычка. Разумеется, сообщения об ошибках могут становиться куда более сложными для понимания по мере роста вашего кода, и даже самые простые случаи могут показаться пугающими для тех, кто ничего не знает о Rust.

- -

Но не бойтесь отладки! Чтобы комфортно писать и отлаживать любой код, нужно понимать язык и его инструменты.

- -

HTML и отладка

- -

HTML не так сложен к пониманию, как Rust. HTML не компилируется в какую-либо другую форму перед тем, как браузер проанализирует это и покажет результат (он является интерпретируемым, а не компилируемым). Синтаксис HTML элементов  намного понятнее, чем у "настоящих языков программирования", таких как Rust, {{glossary("JavaScript")}}, или {{glossary("Python")}}. Способ, которым браузеры читают HTML более толерантен, чем у языков программирования, интерпретирующих свой код строже. Это одновременно и плохо, и хорошо.

- -

Толерантный код

- -

Так что же означает толерантный? В общих чертах, когда вы напортачили в коде, есть два типа ошибок, с которыми вы столкнетесь:

- - - -

HTML не страдает от синтаксических ошибок, потому что браузер читает код толерантно, в том смысле, что страницы могут отображаться даже если синтаксические ошибки присутсвуют. Браузеры имеют встроенные правила по интерпретации неверно написанной разметки, и вы можете запустить что-либо, даже если вы имели в виду другое. Это может стать настоящей проблемой!

- -
-

На заметку: HTML читается толерантно, потому что когда веб только появился, было решено позволить людям публиковать контент даже при условии некорректностей в коде, так как это куда более важно, чем уверенность в абсолютно верном синтаксисе. Веб не был бы сейчас так популярен, если бы относился к новичкам строго.

-
- -

Активное обучение: Знакомство с толерантным кодом

- -

Время изучить природу толерантного кода в HTML.

- -
    -
  1. Для начала, скачайте наш пример отладки и сохраните локально. Эта демонстрация намеренно написана с ошибками, которые нам предстоит обнаружить.
  2. -
  3. Далее, откройте её в браузере. Вы увидите нечто вроде этого :A simple HTML document with a title of HTML debugging examples, and some information about common HTML errors, such as unclosed elements, badly nested elements, and unclosed attributes.
  4. -
  5. Сейчас документ выглядит не особо хорошо; Давайте посмотрим в код и выясним почему (Показано только тело документа): -
    <h1>HTML debugging examples</h1>
    -
    -<p>What causes errors in HTML?
    -
    -<ul>
    -  <li>Unclosed elements: If an element is <strong>not closed properly,
    -      then its effect can spread to areas you didn't intend
    -
    -  <li>Badly nested elements: Nesting elements properly is also very important
    -      for code behaving correctly. <strong>strong <em>strong emphasised?</strong>
    -      what is this?</em>
    -
    -  <li>Unclosed attributes: Another common source of HTML problems. Let's
    -      look at an example: <a href="https://www.mozilla.org/>link to Mozilla
    -      homepage</a>
    -</ul>
    -
  6. -
  7. Рассмотрим проблемы: -
      -
    • У {{htmlelement("p","параграфа")}} и {{htmlelement("li","элемента списка")}} не закрыты теги. На изображении выше видно, что разметка не пострадала, так как браузеру легко сделать вывод о том, где заканчивается один элемент и начинается другой.
    • -
    • Первый {{htmlelement("strong")}} элемент также не имеет закрывающего тега. Это уже более проблематично, так как сложно сказать, где элемент должен заканчиваться. На деле, весь оставшийся текст был выделен жирным.
    • -
    • Следующая часть нарушает правила вложенности: <strong>strong <em>strong emphasised?</strong> what is this?</em>. В этом случае код тоже сложно проинтерпретировать по причине, описанной выше.
    • -
    • В атрибуте {{htmlattrxref("href","a")}} отсутсвует закрывающая двойная кавычка. Это послужило причиной крупной проблемы — ссылка не воспроизвелась вовсе.
    • -
    -
  8. -
  9. Сейчас же посмотрим, как браузер сгенерировал собственную разметку, в противовес исходной разметке документа. Чтобы сделать это, воспользуемся инструментами разработчика. Если вы не знакомы с инструментами разработчика, потратьте несколько минут на Обзор инструментов разработки в браузерах.
  10. -
  11. В DOM инспекторе вы можете увидеть как сгенерировалась новая разметка: The HTML inspector in Firefox, with our example's paragraph highlighted, showing the text "What causes errors in HTML?" Here you can see that the paragraph element has been closed by the browser.
  12. -
  13. Используя DOM инспектор, давайте рассмотрим детали нашего кода, чтобы увидеть, как браузер пытается исправить наши ошибки в HTML (мы обозреваем в Firefox; другой современный браузер должен выдать те же результаты): -
      -
    • Параграфы и элементы списка получены с закрывающими тегами.
    • -
    • Было неочевидно, где элемент <strong> должен был закрыться, так что браузер обернул каждый отдельный блок текста своими собственными тегами strong, причем до самого низа документа!
    • -
    • Некорректная вложенность была исправлена браузером следующим образом: -
      <strong>strong
      -  <em>strong emphasised?</em>
      -</strong>
      -<em> what is this?</em>
      -
    • -
    • Ссылка с отсутсвующими двойными кавычками была удалена насовсем. Последний элемент списка будет выглядеть так: -
      <li>
      -  <strong>Unclosed attributes: Another common source of HTML problems.
      -  Let's look at an example: </strong>
      -</li>
      -
    • -
    -
  14. -
- -

Валидация HTML

- -

Из примера выше ясно, что стоит проверять валидность HTML. В простом примере сверху можно просто просмотреть весь код и найти ошибки, но как быть с огромными, сложными страницами?

- -

Лучше всего проверить страницу в  сервисе валидации разметки. Его создал и поддерживает W3C — организация, которая занимается спецификациями HTML, CSS и других веб-технологий. Сервис проверит ваш HTML и составит отчет по ошибкам в нем.

- -

The HTML validator homepage

- -

HTML можно проверить по адресу, загрузив файл или напрямую ввести код HTML.

- -

Активное обучение: Валидируем HTML-документ

- -

Попробуем проверить документ-пример.

- -
    -
  1. Откройте сервис валидации разметки в браузере.
  2. -
  3. Перейдите в режим Validate by Direct Input.
  4. -
  5. Скопируйте весь код документа (не только body) и вставьте в место для ввода.
  6. -
  7. Нажмите на Check (проверить).
  8. -
- -

Вы увидите список ошибок и другую информацию.

- -

A list of of HTML validation results from the W3C markup validation service

- -

Работа с сообщениями об ошибках

- -

Обычно сразу ясно, что значат сообщения, но иногда приходится постараться, чтобы понять, в чем дело. Сейчас мы пройдемся по всем ошибкам и разберем, что они значат. Обратите внимание, что в сообщениях указаны строка и столбец кода, чтобы ошибки было проще искать.

- - - -

Если некоторые ошибки кажутся вам странными, начните исправление с остальных и проверьте документ еще раз. Иногда одна ошибка ломает большую часть документа.

- -

Когда вы увидите эту надпись, в вашем документе больше нет ошибок:

- -

Banner that reads "The document validates according to the specified schema(s) and to additional constraints checked by the validator."

- -

Заключение

- -

Теперь вы умеете отлаживать HTML. С новыми знаниями вам будет проще разобраться и в отладке более сложных языков — например, CSS и JavaScript. На этом мы заканчиваем вводный модуль курса HTML — время попробовать свои силы в упражнениях.

- -

{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/Document_and_website_structure", "Learn/HTML/Introduction_to_HTML/Marking_up_a_letter", "Learn/HTML/Introduction_to_HTML")}}

- -

В этом модуле

- - diff --git "a/files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/html_text_fundamentals/index.html" "b/files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/html_text_fundamentals/index.html" deleted file mode 100644 index 711c0bfdf3..0000000000 --- "a/files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/html_text_fundamentals/index.html" +++ /dev/null @@ -1,994 +0,0 @@ ---- -title: Основы редактирования текста в HTML -slug: Learn/HTML/Введение_в_HTML/HTML_text_fundamentals -tags: - - Guide - - HTML - - Абзацы - - Введение в HTML - - Изучение - - Начинающий - - Параграфы - - Руководство - - Семантика - - Текст -translation_of: Learn/HTML/Introduction_to_HTML/HTML_text_fundamentals ---- -
-
 {{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/The_head_metadata_in_HTML", "Learn/HTML/Introduction_to_HTML/Creating_hyperlinks", "Learn/HTML/Introduction_to_HTML")}}
-
- -

Одна из основных задач HTML — придавать тексту структуру и смысл, {{glossary("семантику")}}, так, чтобы браузер смог отобразить текст корректно. Эта статья покажет, как можно использовать {{glossary("HTML")}}, чтобы упорядочить текст на странице путём добавления заголовков и абзацев, выделения слов, создания списков и многое другое.

- - - - - - - - - - - - -
Предварительные требования:Базовое знакомство с HTML , описанное в Начало работы с HTML.
Задача:Изучить базовые способы разметки текста путем добавлением на страницу структуры и значения — создать абзацы, заголовки, списки, акценты и цитаты..
- -

Основы: Заголовки и абзацы / параграфы

- -

Большинство структурированных текстов состоят из параграфов и заголовков, независимо от того, читаете ли вы рассказ, или газету, или учебник, журнал и т.д.

- -

An example of a newspaper front cover, showing use of a top level heading, subheadings and paragraphs.

- -

Упорядоченный контент делает чтение более легким и приятным.

- -

В HTML каждый абзац заключен в элемент {{htmlelement("p")}}, подобно:

- -
<p>Я параграф, да, это я.</p>
- -

Каждый заголовок заключен в элемент заголовка {{htmlelement("h1")}}:

- -
<h1>Я заголовок истории.</h1>
- -

Имеется шесть элементов заголовка: {{htmlelement("h1")}}, {{htmlelement("h2")}}, {{htmlelement("h3")}}, {{htmlelement("h4")}}, {{htmlelement("h5")}} и {{htmlelement("h6")}}. Каждый элемент представляет разный уровень контента в документе; <h1> представляет главный заголовок, <h2> представляет подзаголовки, <h3> представляет под-подзаголовки и так далее.

- -

Создание иерархической структуры

- -

Например, в рассказе <h1> будет представлять заглавие рассказа, <h2> обозначит название каждой главы, <h3>  будет обозначать подзаголовки в каждой главе и так далее.

- -
<h1> Сокрушительная скука </ h1>
-
-<p> Крис Миллс </ p>
-
-<h2> Глава 1: Темная ночь </ h2>
-
-<p> Это была темная ночь. Где-то кричала сова. Дождь обрушился на ... </ p>
-
-<h2> Глава 2: Вечное молчание </ h2>
-
-<p> Наш главный герой ничего не мог, когда шёпот из тёмной фигуры ... </ p>
-
-<h3> Призрак говорит </ h3>
-
-<p> Прошло ещё несколько часов, когда внезапно призрак выпрямился и воскликнул: «Пожалуйста, помилуй мою душу!» </ p>
-
- -

Всё это действительно зависит от вас — что именно будут представлять собой элементы, пока существует иерархия. Вам просто нужно иметь в виду несколько хороших правил при создании таких структур.

- - - -

Зачем нам необходима структура?

- -

Чтобы ответить на этот вопрос, давайте посмотрим на text-start.html — отправную точку нашего примера для этой статьи (хороший рецепт хумуса). Вы должны сохранить копию этого файла на своем локальном компьютере, так как вам понадобится это для упражнений позже. Сейчас тело этого документа содержит несколько фрагментов контента — они не отмечены каким-либо образом, но они разделены разрывами строк (был нажат Enter / Return  для перехода на следующую строку).

- -

Однако, когда вы откроете документ в своем браузере, вы увидите, что текст выглядит как один большой кусок!

- -

A webpage that shows a wall of unformatted text, because there are no elements on the page to structure it.

- -

Это связано с тем, что нет элементов для создания структуры контента, поэтому браузер не знает, где здесь заголовок и где абзац. Более того:

- - - -

Поэтому нужно дать структурную разметку нашему контенту.

- -

Активное изучение: создание структуры для нашего контента

- -

Давайте рассмотрим это на живом примере. В приведённом ниже примере добавьте элементы в исходный текст в поле «Редактируемый код», чтобы он отображался как заголовок и два абзаца в поле «Результат».

- -

Если вы допустили ошибку, вы всегда можете сбросить её с помощью кнопки Сбросить. Если вы застряли, нажмите кнопку Показать решение, чтобы увидеть ответ.

- - - -

{{ EmbedLiveSample('Playable_code', 700, 500) }}

- -

Почему мы нуждаемся в семантике?

- -

Семантика проявляется всюду вокруг нас — мы полагаемся на опыт, который рассказывает нам, какова функция бытовых предметoв; когда мы что-то видим, мы знаем, какова его функция. Так, например, мы ожидаем, что красный свет на светофоре означает «стоп», а зеленый свет означает «идти». Жизнь станет очень сложной, если применяется неправильная семантика (какие-либо страны используют красный цвет для обозначения «идти»? Надеюсь, что нет.)

- -

В подобном ключе нам нужно убедиться, что мы используем правильные элементы, придавая нашему контенту правильное значение, функцию или внешний вид. В этом контексте элемент {{htmlelement ("h1")}} также является семантическим элементом, который даёт тексту, который он обёртывает,  роль (или значение) «заголовка верхнего уровня на вашей странице».

- -
<h1>Это заголовок верхнего уровня</h1>
- -

По умолчанию браузер придаст ему большой размер шрифта, чтобы он выглядел как заголовок (хотя вы можете стилизовать его как угодно, используя CSS). Что ещё более важно, его семантическое значение будет использоваться несколькими способами, например, поисковыми системами и программами чтения с экрана (как упоминалось выше).

- -

С другой стороны, вы можете сделать любой элемент похожим на заголовок верхнего уровня. Рассмотрим следующее:

- -
<span style="font-size: 32px; margin: 21px 0;">Это заголовок верхнего уровня?</span>
- -

Это элемент {{htmlelement ("span")}}. У него нет семантики. Вы используете его, когда хотите применить к контенту CSS (или сделать что-то с ним с помощью JavaScript), не придавая ему никакого дополнительного значения (об этом вы узнаете позже). Мы применили CSS, чтобы он выглядел как заголовок верхнего уровня, но поскольку он не имеет семантического значения, он не получит никаких дополнительных преимуществ, описанных выше. Рекомендуется использовать соответствующий элемент HTML на практике.

- -

Списки

- -

Теперь обратим наше внимание на списки. Списки есть везде вокруг нас — от вашего списка покупок до списка направлений, которым вы подсознательно следуете, чтобы каждый день добраться домой, и списка инструкций, которые вы выполняете в этом руководстве! Списки используются всюду в Интернете, и мы рассмотрим три разных типа списков.

- -

Неупорядоченные

- -

Неупорядоченные списки используются для элементов, для которых порядок не имеет значения, — возьмем, к примеру, список покупок:

- -
молоко
-яйца
-хлеб
-хумус
- -

Каждый неупорядоченный список начинается с элемента {{htmlelement ("ul")}} (unordered list) — он обёртывает все элементы списка: молоко, яйца, хлеб, хумус.

- -

Последний шаг состоит в том, чтобы обернуть каждый элемент списка в элемент {{htmlelement ("li")}} (элемент списка):

- -
<ul>
-  <li>молоко</li>
-  <li>яйца</li>
-  <li>хлеб</li>
-  <li>хумус</li>
-</ul>
- -

Активное изучение: разметка неупорядоченного списка

- -

Попробуйте отредактировать образец ниже, чтобы создать свой собственный неупорядоченный список HTML.

- - - -

{{ EmbedLiveSample('Playable_code_2', 700, 400) }}

- -

Упорядоченные

- -

Упорядоченные списки — это списки, в которых порядок элементов имеет значение, — возьмем в качестве примера маршрут следования:

- -
Доедьте до конца дороги
-Поверните направо
-Едьте прямо через первые два перекрестка с круговым движением
-Поверните налево на третьем перекрестке
-Школа справа от вас, 300 метров вверх по дороге
- -

Структура разметки такая же, как для неупорядоченных списков, за исключением того, что вы должны обернуть элементы списка в элемент {{htmlelement ("ol")}} (ordered list), а не <ul>:

- -
<ol>
-   <li>Доедьте до конца дороги</li>
-   <li>Поверните направо</li>
-   <li>Едьте прямо через первые два перекрестка с круговым движением</li>
-   <li>Поверните налево на третьем перекрестке</li>
-   <li>Школа справа от вас, в 300 метрах вверх по дороге</li>
-</ol>
- -

Активное изучение: разметка упорядоченного списка

- -

Попробуйте отредактировать образец ниже, чтобы создать свой собственный упорядоченный список HTML.

- - - -

{{ EmbedLiveSample('Playable_code_3', 700, 500) }}

- -

Активное изучение: разметка собственной страницы рецептов

- -

Итак, в этот момент в статье у вас есть вся необходимая информация, чтобы разметить наш пример страницы рецепта. Вы можете либо сохранить локальную копию исходного файла text-start.html и выполнить в нём работу, либо сделать это в приведённом ниже примере. Делать это локально, вероятно, будет лучше, так как тогда вы сможете сохранить работу, которую вы делаете, тогда как если вы её добавите в редактируемый пример, она будет потеряна при следующем открытии страницы. У обоих способов есть плюсы и минусы.

- - - -

{{ EmbedLiveSample('Playable_code_4', 700, 500) }}

- -

Если вы застряли, вы всегда можете нажать кнопку Показать решение или проверить наш пример text-complete.html в нашем реестре github.

- -

Вложенные списки

- -

Вполне нормально вложить один список в другой. Возможно, вы захотите, чтобы один список распологался внутри другого. Давайте возьмем второй список из нашего примера рецепта:

- -
<ol>
-  <li>Очистите чеснок от кожуры и крупно нарежьте.</li>
-  <li>Удалите стебель и семена у перца; крупно нарежьте перец.</li>
-  <li>Добавьте все ингредиенты в пищевой комбайн.</li>
-  <li>Измельчите все ингридиенты до состояния пасты.</li>
-  <li>Если вы хотите "грубый" хумус, измельчайте пару минут.</li>
-  <li>Если вам нужен гладкий хумус, измельчайте дольше.</li>
-</ol> 
- -
-
Поскольку последние две строки очень тесно связаны с тем, что было до них (они читаются как вспомогательные инструкции или варианты, которые подходят под этой маркой), может иметь смысл вложить их в свой собственный неупорядоченный список и поместить этот список внутри текущего. Это будет выглядеть так:
-
- -
<ol>
-  <li>Очистите чеснок от кожуры и крупно нарежьте.</li>
-  <li>Удалите стебель и семена у перца; крупно нарежьте перец.</li>
-  <li>Добавьте все ингредиенты в пищевой комбайн.</li>
-  <li>Измельчите все ингридиенты до состояния пасты.
-    <ul>
-      <li>Если вы хотите "грубый" хумус, измельчайте пару минут.</li>
-      <li>Если вам нужен гладкий хумус, измельчайте дольше.</li>
-    </ul>
-  </li>
-</ol>
- -

Попробуйте вернуться к предыдущему примеру активного обучения и обновить второй список.

- -

Акцент и важность

- -
-
В обиходе мы часто подчеркиваем определённые слова, чтобы изменить смысл предложения и мы часто хотим отметить некоторые слова как важные или разные в некотором роде. HTML предоставляет различные семантические элементы, позволяющие нам добавлять текстовые материалы с такими эффектами, и в этом разделе мы рассмотрим несколько наиболее распространенных.
- -
-
- -

Акцент

- -

Когда мы хотим добавить акцент в разговорный язык, мы подчеркиваем определенные слова, тонко изменяя смысл того, что мы говорим. Точно так же на письменном языке мы склонны подчеркивать слова, выделяя их курсивом. Например, следующие два предложения имеют разные значения.

- -

Я рад, что ты не опоздал.

- -

Я рад, что ты не опоздал.

- -

В первом предложении звучит искреннее облегчение, что человек не опоздал. Во втором, напротив, звучит сарказм или пассивная агрессия: так выражена досада от того, что человек немного опоздал.

- -

В таких случаях в HTML используется элемент {{htmlelement ("em")}} (выделение). Кроме того, чтобы сделать документ более интересным для чтения, они распознаются программами, считывающими с экрана, и произносятся другим тоном. Браузеры стилизуют это по умолчанию курсивом, но вы можете не использовать этот тег, чтобы получить курсив. Для выделения курсивом вы можете использовать элемент {{htmlelement ("span")}} и CSS, или, возможно, элемент {{htmlelement ("i")}} (смотрите ниже).

- -
<p>Я <em>рад</em>, что ты не <em>опоздал</em>.</p>
- -

Важное значение

- -

Чтобы подчеркнуть важные слова, мы склонны подчеркивать их в устной речи и выделять жирным на письменном языке. Например:

- -

Эта жидкость очень токсична.
-
- Я рассчитываю на вас. Не опаздывай!

- -

В таких случаях в HTML используется элемент {{htmlelement ("strong")}} (важное значение). Помимо того, что документ становится более полезным,  они распознаются программами, считывающими с экрана, и говорят другим тоном. Браузеры стилизуют это как полужирный текст по умолчанию, но вы можете не использовать этот тег, чтобы получить жирный шрифт. Для получения жирного шрифта вы можете использовать элемент {{htmlelement ("span")}} и CSS, или, возможно, элемент {{htmlelement ("b")}} (смотрите ниже).

- -
<p>Эта жидкость <strong>очень токсична</strong>.</p>
-
-<p>Я рассчитываю на тебя. <strong>Не </strong>опаздывай!</p>
- -

При желании вы можете вложить важные и акцентированные слова друг в друга:

- -
<p>Эта жидкость <strong>очень токсична</strong> —
-если ты выпьешь её, <strong>то можешь<em>умереть</em></strong>.</p>
- -

Активное изучение: Давайте будем важны!

- -

В этом разделе активного обучения мы предоставили редактируемый пример. Внутри него мы хотели бы, чтобы вы попытались добавить акцент и большую важность для слов, которые, по вашему мнению, им нужны, просто для того, чтобы попрактиковаться.

- - - -

{{ EmbedLiveSample('Playable_code_5', 700, 500) }}

- -

Курсив, жирный шрифт, подчеркивание...

- -
-
Элементы, которые мы обсуждали до сих пор, имеют четкую привязку к семантике. Ситуация с {{htmlelement ("b")}}, {{htmlelement ("i")}} и {{htmlelement ("u")}} несколько сложнее. Они появились в эпоху, когда CSS  поддерживался плохо или вообще не поддерживался, чтобы люди могли писать жирный текст, курсив или подчеркнутый текст. Такие элементы, которые влияют только на внешний вид, а не на семантику, известны как элементы представления и больше не должны использоваться, поскольку, как мы видели ранее, семантика очень важна для доступности людям с ограниченными возможностями, SEO и так далее.
- -
-
- -

HTML5 переопределил <b>, <i> и <u> с новыми, несколько запутанными, семантическими ролями.

- -

Вот хорошее правило: предпочтительней использовать <b>, <i> или <u> для передачи значения, традиционно передаваемого жирным шрифтом, курсивом или подчеркиванием, при условии, что нет более подходящего элемента. Тем не менее, всегда важно сохранить менталитет доступности. Концепция курсива не очень помогает людям, использующим устройства для чтения с экрана, или людям, использующим систему письма, отличную от латинского алфавита.

- - - -
-

Предупреждение о подчеркивании: люди сильно ассоциируют подчеркивание с гиперссылками. Поэтому в Интернете лучше всего подчеркнуть только ссылки. Используйте элемент <u>, когда он семантически подходит, но подумайте о том, чтобы использовать CSS для изменения подчеркивания по умолчанию для чего-то более подходящего в Интернете. Пример ниже иллюстрирует, как это можно сделать.

-
- -
<!-- Научные наименования -->
-<p>
-  Колибри обыкновенный (<i>архилоус обыкновенный</i>) —
-наиболее часто встречающийся вид колибри в северо-восточной Америке.
-</p>
-
-<!-- Иностранные слова -->
-<p>
-  Случился прилив иностранных слов, таких как <i lang="uk-latn">vatrushka</i>,
-  <i lang="id">nasi goreng</i> и <i lang="fr">soupe à l'oignon</i>.
-</p>
-
-<!-- Явно неправильное произношение или написание -->
-<p>
-  Когда-нибудь я узнаю, как <u>гаварить</u> без ошибок.
-</p>
-
-<!-- Выделение ключевых слов в инструкциях -->
-<ol>
-  <li>
-    <b>Отрежьте</b> два ломтика хлеба.
-  </li>
-  <li>
-    <b>Добавьте</b> кусочек помидора и лист латука между ломтями хлеба.
-  </li>
-</ol>
- -

Заключение

- -

Вот и всё! Эта статья должна была дать вам хорошее представление о том, как начать разметку текста в HTML, и познакомить вас с некоторыми из наиболее важных элементов в этой области. В этой области есть намного больше семантических элементов, и мы рассмотрим их в нашей статье «Больше семантических элементов» позже в курсе. В следующей статье мы подробно рассмотрим, как создавать гиперссылки, возможно, самый важный элемент в Интернете. 

- -

{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/The_head_metadata_in_HTML", "Learn/HTML/Introduction_to_HTML/Creating_hyperlinks", "Learn/HTML/Introduction_to_HTML")}}

- -

В этом модуле

- - diff --git "a/files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/index.html" "b/files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/index.html" deleted file mode 100644 index 1ecf1eb84a..0000000000 --- "a/files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/index.html" +++ /dev/null @@ -1,67 +0,0 @@ ---- -title: Введение в HTML -slug: Learn/HTML/Введение_в_HTML -tags: - - HTML - - Введение - - Для чайников - - Заголовок - - Начинающим - - Новичкам - - Основы HTML - - Семантика - - Ссылки - - Структура - - Текст -translation_of: Learn/HTML/Introduction_to_HTML ---- -
{{LearnSidebar}}
- -

По сути, {{glossary("HTML")}} довольно простой язык, состоящий из элементов, которые могут быть применены к частям текста, чтобы придавать им различные значения (Это абзац? Это маркированный список? Это часть таблицы?), разделять документ на логические секции (есть ли у документа шапка? три столбца с контентом? меню навигации?) и добавлять контент на Вашу страницу, такой как фото и видео. Этот модуль расскажет Вам о первых двух возможностях HTML и научит фундаментальным концепциям и синтаксису, которые вам нужно знать, чтобы понять HTML.

- -

Необходимые условия

- -

Чтобы начать изучение этого модуля, вам не нужны никакие знания HTML, но вы должны иметь хотя бы базовые навыки обращения с компьютером и навыки пассивного использования Веба (т.е просто смотря на него, потребляя контент). У вас должна быть базовая рабочая среда, описанная в разделе Установка базового програмного обеспечения), а также понимание, как создавать и управлять файлами, что подробно описано в статье Работа с файлами — обе статьи являются частью нашего модуля Начало работы с сетью.

- -
-

Примечание: если вы работаете на компьютере/планшете/другом устройстве, с отсутствием возможности создания собственных файлов, вы можете испробовать примеры кода (большинство) в онлайн-редакторах кода, таких как JSBin или Thimble.

-
- -

Руководства

- -

Этот модуль содержит следующие статьи, которые помогут изучить всю основную теорию HTML и предоставят широкие возможности для проверки некоторых навыков.

- -
-
Начало работы с HTML
-
Охватывает базовые основы HTML, чтобы вы начали изучение - мы опишем элементы, атрибуты и все другие важные термины, о которых вы, возможно, уже слышали, а также где и как они располагаются в языке. Мы также покажем, структуру HTML элемента, как устроена типичная страница HTML, и объясним другие важные языковые особенности. По ходу мы будем играть с HTML так, чтобы вам было интересно!
-
Что такое заголовок? Метаданные в HTML
-
Заголовок HTML — это часть документа, которая не отображается в браузере при загрузке страницы. Он содержит информацию, такую как: страница {{htmlelement("title")}}, ссылки на {{glossary("CSS")}} (если вы хотите стилизовать свой HTML при помощи CSS), ссылки на пользовательские значки и метаданные (которые представляют собой данные о HTML, например, кто его написал или важные ключевые слова, которые описывают документ).
-
Основы редактирования текста в HTML
-
Основной задачей HTML является придание тексту значения (также известно, как семантика), чтобы браузер знал, как его правильно отображать. В этой статье расматривается то, как использовать HTML, чтобы разбить блок текста на структуру из заголовков и абзацев, добавить акцент/значение слов, создать списки и многое другое.
-
Создание гиперссылок
-
Гиперссылки очень важны — ведь именно они делают интернет интернетом. В этой статье описан синтаксис, необходимый для создания ссылок, а также описано их наилучшее применение на практике.
-
Углубленное форматирование текста
-
Существует множество других элементов HTML для редактирования текста, про которые мы вам не рассказали в статье Основы редактирования текста в HTML. Описанные здесь элементы менее известны, но о них также полезно знать. Здесь вы узнаете о разметке цитат, списках описания, компьютерном коде и другом сопутствующем тексте, нижнем и верхнем индексах, контактной информации и многом другом.
-
Структура документа и веб-сайта
-
Помимо определения отдельных частей страницы (таких как "абзац" или "изображение"), HTML также используется для определения отдельных зон веб-сайта (таких как "шапка", "меню навигации",  "столбец с основным содержимым".) В этой статье рассматривается, как планировать базовую структуру веб-сайта и писать HTML для представления этой структуры.
-
Отладка HTML
-
Писать на HTML хорошо, но что, если что-то идет не так, и вы не можете найти место ошибки в коде? В этой статье вы познакомитесь с некоторыми инструментами, которые могут Вам помочь.
-
- -

Оценка

- -

Следующие задания проверят ваше понимание основ HTML, описанных в приведенных выше руководствах.

- -
-
Разметка письма
-
Все мы рано или поздно учимся писать письма; также это полезеный тест, для проверки ваших навыков форматирования текста! Поэтому, в этом задании вам будет предоставлено письмо для разметки.
-
Структурируем страницу
-
Этот тест проверит вашу способность использовать HTML для структурирования простой страницы, которая содержит шапку ("хедер") , нижний колонтитул ("футер"), меню навигации, основное содержимое и боковую панель.
-
- -

Смотрите также

- -
-
Основы интернет-грамотности
-
Отличный фундаментальный курс Mozilla, который дает множество тестов, проверяющих знания, о которых мы говорили в модуле Введение в HTML. Учащиееся знакомятся с чтением, письмом и использованием сети в модуле из 6 частей. Откройте для себя основы Интернета через производство и сотрудничество.
-
diff --git "a/files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/marking_up_a_letter/index.html" "b/files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/marking_up_a_letter/index.html" deleted file mode 100644 index c9ede9d116..0000000000 --- "a/files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/marking_up_a_letter/index.html" +++ /dev/null @@ -1,101 +0,0 @@ ---- -title: Разметка письма -slug: Learn/HTML/Введение_в_HTML/Marking_up_a_letter -tags: - - HTML -translation_of: Learn/HTML/Introduction_to_HTML/Marking_up_a_letter ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/Debugging_HTML", "Learn/HTML/Introduction_to_HTML/Structuring_a_page_of_content", "Learn/HTML/Introduction_to_HTML")}}
- -

Мы все учимся писать письма рано или поздно; это также хороший способ испытать наши навыки форматирования! В этом задании у вас будет письмо для проверки ваших навыков форматирования текста HTML, использования гиперссылок и элемента <head>.

- - - - - - - - - - - - -
Знания: -

Перед выполнением этого задания вы должны пройти Начало работы с HTML, Что такое заголовок? Метаданные в HTML, Основы редактирования текста в HTML, Создание гиперссылок, и Углубленное форматирование текста.

-
Цель: -

Проверить базовые и продвинутые навыки HTML форматирования и работы с гиперссылками, и знания о содержимом HTML тега <head>.

-
- -

Отправная точка

- -

Для начала задания, вы должны скачать текст, который вам надо отформатировать, и CSS стиль, который вы должны подключить к вашему HTML. Создайте .html файл используюя текстовый редактор, которым вы пользуетесь (или воспользуйтесь онлайн редактороми, таким как JSBin или Thimble).

- -

Описание проекта

- -

В этом проекте, ваша задача - отформатировать письмо, которое должно быть размещено во внутренней сети университета. Это письмо - ответ исследователя будущему PhD студенту о его заявлении на работу в университете.

- -

Блочные элементы / структура:

- - - -

Строчные элементы:

- - - -

Заголовок документа:

- - - -

Советы и подсказки

- - - -

Пример

- -

Это скриншот размеченного письма:

- -

Example

- -

Оценка

- -

Если вам дали это задание на каком-то курсе, просто передайте свою страницу для проверки преподавателю. Если вы учитесь сами, обратитесь на форум, в тему этого задания, или по тегу #mdn в нашем IRC-канале (Mozilla IRC). Сделайте это задание сами — вам некого обманывать, кроме себя самого.

- -

{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/Debugging_HTML", "Learn/HTML/Introduction_to_HTML/Structuring_a_page_of_content", "Learn/HTML/Introduction_to_HTML")}}

- -

В этом модуле

- - diff --git "a/files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/structuring_a_page_of_content/index.html" "b/files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/structuring_a_page_of_content/index.html" deleted file mode 100644 index b5bb7fa235..0000000000 --- "a/files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/structuring_a_page_of_content/index.html" +++ /dev/null @@ -1,101 +0,0 @@ ---- -title: Структурируем страницу -slug: Learn/HTML/Введение_в_HTML/Structuring_a_page_of_content -tags: - - HTML -translation_of: Learn/HTML/Introduction_to_HTML/Structuring_a_page_of_content ---- -
{{LearnSidebar}}
- -
{{PreviousMenu("Learn/HTML/Introduction_to_HTML/Marking_up_a_letter", "Learn/HTML/Introduction_to_HTML")}}
- -

Разметить страницу так, чтобы к ней было просто применить CSS — первое, чему должен научиться будущий веб-разработчик. В этом задании вам придется подумать о том, как должна выглядеть страница, и подобрать подходящую семантическую разметку.

- - - - - - - - - - - - -
Что нужно знать:Вам пондобятся навыки из всего курса. Особое внимание уделите разделу Структура документа и веб-сайта.
Цель: -

Проверить знания структуры веб-страницы и ее перевода в разметку.

-
- -

Отправная точка

- -

Чтобы начать это, вы должны перейти и скачать архив содержаший все начальные активы. Архив содержит:

- - - -

Создайте пример на вашем локальном компьютере или, альтернативно, используйте сайт, например JSBin или Thimble для исследования.

- -

Краткое описание проекта

- -

Для этого проекта ваша задача - взять контент для домашней страницы веб-сайта наблюдения за птицами и добавить к нему структурные элементы, чтобы он мог использовать макет страницы. Он должен иметь:

- - - -

Вам необходимо добавить подходящую обертку для:

- - - -

Вы также должны:

- - - -

Советы и подсказки

- - - -

Пример

- -

Следующий скриншот показывает пример того, как может выглядеть домашняя страница после маркировки.

- -

The finished example for the assessment; a simple webpage about birdwatching, including a heading of "Birdwatching", bird photos, and a welcome message

- -

Оценивание

- -

Если вам дали это задание на каком-то курсе, просто передайте свою страницу для проверки преподавателю. Если вы учитесь сами, обратитесь на форум, задав тему обсуждения этого упражнения, или в IRC-канале #mdn в IRC Mozilla, или в IRC-канале #mdn в IRC Mozilla. Попробуйте выполнить задание сами, ведь Вам некого обманывать, кроме себя самого!

- -

{{PreviousMenu("Learn/HTML/Introduction_to_HTML/Marking_up_a_letter", "Learn/HTML/Introduction_to_HTML")}}

- -

В этом модуле

- - diff --git "a/files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/the_head_metadata_in_html/index.html" "b/files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/the_head_metadata_in_html/index.html" deleted file mode 100644 index dfb2840569..0000000000 --- "a/files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/the_head_metadata_in_html/index.html" +++ /dev/null @@ -1,300 +0,0 @@ ---- -title: Что внутри "head"? Метаданные в HTML -slug: Learn/HTML/Введение_в_HTML/The_head_metadata_in_HTML -tags: - - HTML - - Meta - - favicon - - head - - lang - - metadata - - Для начинающих - - Заголовок - - Руководство - - иконка - - метаданные - - язык -translation_of: Learn/HTML/Introduction_to_HTML/The_head_metadata_in_HTML ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/Getting_started", "Learn/HTML/Introduction_to_HTML/HTML_text_fundamentals", "Learn/HTML/Introduction_to_HTML")}}
- -

Элемент {{glossary("Head", "head")}} HTML-документа не отображается на странице в веб-браузере. Он содержит такую информацию, как:

- - - -

В этой статье мы рассмотрим всё вышеперечисленное и многое другое, чтобы дать вам хорошую основу для работы с разметкой.

- - - - - - - - - - - - -
Предварительные требования:Базовое знакомство с HTML , описанное в Начало работы с HTML.
Задача:Узнать о заголовке HTML, его значении, важнейших элементах, которые содержатся в нём, и о том, как он может повлиять на HTML-документ.
- -

Что такое <head>?

- -

Давайте снова посмотрим на HTML-документ из прошлой статьи:

- -
<!DOCTYPE html>
-<html>
-  <head>
-    <meta charset="utf-8">
-    <title>Моя тестовая страница</title>
-  </head>
-  <body>
-    <p>Это — моя страница</p>
-  </body>
-</html>
- -

Содержимое {{htmlelement("head")}}, в отличие от содержимого элемента {{htmlelement("body")}}, не отображается на странице. Задача <head> — хранить {{glossary("Metadata", "метаданные")}} документа. В приведенном выше примере <head> совсем небольшой:

- -
<head>
-  <meta charset="utf-8">
-  <title>Моя тестовая страница</title>
-</head>
- -

Однако на больших страницах блок <head> может быть довольно объемным. Попробуйте зайти на какие-нибудь из ваших любимых сайтов и посмотреть содержимое <head> с помощью инструментов разработчика. Наша цель сейчас — не в том, чтобы показать вам, как использовать всё, что только можно добавить в head, а дать представление и научить вас, как использовать основные элементы. Давайте начнем.

- -

Название страницы (title)

- -

Мы уже видели, как работает элемент {{htmlelement("title")}}: его используют для добавления заголовка (названия страницы) в документ. Элемент {{htmlelement("h1")}} тоже иногда назвают заголовком страницы. Но это разные вещи!

- - - -

Активное изучение: разбор простого примера

- -
    -
  1. Чтобы приступить к активному изучению,  скачайте страницу title-example.html из нашего GitHub-репозитория. Это можно сделать двумя способами: - -
      -
    1. Скопируйте и вставьте код страницы в новый текстовый файл в своём редакторе кода, затем сохраните его в любом удобном месте.
    2. -
    3. Нажмите на странице кнопку "Raw", нажмите Файл > Сохранить Как... в меню браузера и выберите папку для сохранения.
    4. -
    -
  2. -
  3. Откройте файл в браузере. Вы увидите что-то вроде этого: -

    A simple web page with the title set to <title> element, and the <h1> set to <h1> element.Теперь должно стать совершенно ясно, в чём разница между <h1> и <title>!

    -
  4. -
  5. Откройте код страницы в редакторе, измените содержимое элементов и обновите страницу в браузере. Развлекайтесь!
  6. -
- -

Содержимое элемента <title> используется и в других местах. Например, при добавлении страницы в избранное (Bookmarks > Bookmark This Page в Firefox), текст из <title> предлагается в качестве названия закладки.

- -

A webpage being bookmarked in firefox; the bookmark name has been automatically filled in with the contents of the <title> element

- -

Текст из <title> также появляется в результатах поиска, как мы скоро увидим.

- -

Метаданные: Элемент <meta>

- -

Метаданные — данные, которые описывают данные. У HTML есть «официальное» место для метаданных документа — элемент {{htmlelement("meta")}}. Конечно, другие вещи, о которых мы говорим в этой статье, тоже можно назвать метаданными. Существует множество разновидностей <meta>. Не станем пытаться охватить их все сразу — так недолго и запутаться, а рассмотрим несколько самых популярных, чтобы разобраться, что к чему.

- -

Указываем кодировку текста документа

- -

В заголовке примера выше есть следующая строка:

- -
<meta charset="utf-8">
- -

В этом элементе указана кодировка документа — набор символов, которые в нём можно использовать . utf-8 — универсальный набор символов, который включает почти все символы со всех языков человечества. Такая веб-страница сможет работать с любым языком. Установить эту кодировку на всех веб-страницов, которые вы создаёте — отличная идея! Страница в такой кодировке прекрасно отображает как английские, так и японские символы:

- -

a web page containing English and Japanese characters, with the character encoding set to universal, or utf-8. Both languages display fine,Если использовать, скажем, кодировку ISO-8859-1 (набор символов для латиницы), текст страницы испортится:

- -

a web page containing English and Japanese characters, with the character encoding set to latin. The Japanese characters don't display correctly

- -
-

Примечание: Некоторые браузеры (например, Chrome) автоматически исправляют неправильную кодировку, поэтому, в зависимости от используемого вами браузера, вы можете не увидеть эту проблему. Несмотря на это вам всё равно необходимо указывать кодировку UTF-8 для вашей страницы, чтобы избежать возможных проблем в других браузерах.

-
- -

Активное изучение: экспериментируем с символьными кодировками

- -

Чтобы проверить это, вернитесь к HTML из примера <title> (странице title-example.html), поменяйте meta charset на ISO-8859-1 и попробуйте написать что-нибудь на японском или русском. Вот текст из нашего примера (кстати, там написано «рис горячий»):

- -
<p>Пример на японском: ご飯が熱い。</p>
- -

Указываем автора и описание

- -

У элементов <meta> часто есть атрибуты name и content:

- - - -

Два полезных элемента метаданных — указание автора страницы и краткое описание её содержимого. Рассмотрим эти элементы на примере:

- -
<meta name="author" content="Крис Миллс">
-<meta name="description" content="Задача MDN — в том, чтобы обучить
-новичков всему тому, что нужно им для разработки веб-сайтов и приложений.">
- -

По указанному имени автора (author) можно найти человека, который написал страницу, и связаться с ним. Некоторые системы управления содержимым (CMS) автоматически обрабатывают эту информацию и делают её доступной для таких целей.

- -

Краткое описание (description) содержимого страницы учитывается поисковыми системами при совпадении ключевых слов. Такое называют поисковой оптимизацией, или {{glossary("SEO")}}.

- -

Активное изучение: как поисковые системы используют описание

- -

Описание из <meta name="description"> используется на страницах поисковой выдачи. Проведём небольшое исследование такого сценария.

- -
    -
  1. Перейдите на главную страницу Mozilla Developer Network.
  2. -
  3. Откройте исходный код страницы (кликните правой кнопкой мыши и выберите Просмотреть код в контекстном меню.)
  4. -
  5. Найдите тег meta с описанием. Он выглядит так: -
    <meta name="description" content="Веб-документация на MDN
    -предоставляет собой информацию об открытых веб-технологиях,
    -включая HTML, CSS и различные API для веб-сайтов и
    -прогрессивных веб-приложений. Также на сайте содержатся материалы
    -для разработчиков о таких продуктах Mozilla, как Инструменты разработчика Firefox.">
    -
  6. -
  7. Теперь найдите "Mozilla Developer Network" в своём поисковике (мы использовали Google). Обратите внимание, что описание и название из <meta> и <title> используется в результатах поиска, — мы не зря указали их!
  8. -
- -

Результат поиска в Google

- -
-

Примечание: Google также показывает важные страницы MDN под ссылкой на главную страницу. Такие ссылки называются sitelinks, и их можно настроить через Google Search Console, чтобы пользователи могли сразу перейти к ним со страницы поиска.

-
- -
-

Примечание: Многие типы <meta> больше не используются. Так, поисковые системы больше не используют данные из элемента <meta type="keywords" content="ваши, ключевые, слова, введите, здесь">, в котором указывали ключевые слова, по которым можно найти страницу: спамеры засовывали туда все слова, какие могли придумать, чтобы их сайты почаще появлялись в поиске.

-
- -

Другие виды метаданных

- -

В сети вы найдете также другие типы метаданных. Многие из них — это собственные форматы, созданные для предоставления определенным сайтам (например, социальных сетей) специальной информации, которую они могут использовать.

- -

Например, Протокол Open Graph создан Facebook чтобы предоставить сайтам дополнительные возможности использования метеданных. В исходном коде MDN Web Docs вы можете найти строки:

- -
<meta property="og:image" content="https://wiki.developer.mozilla.org/static/img/opengraph-logo.72382e605ce3.png">
-<meta property="og:description" content="Веб-документация на MDN предоставляет
-собой информацию об открытых веб-технологиях, включая HTML, CSS и различные API для веб-сайтов
-и прогрессивных веб-приложений. Также на сайте содержатся материалы для разработчиков о таких
-продуктах Mozilla, как Инструменты разработчика Firefox.">
-<meta property="og:title" content="MDN Web Docs">
- -

Один из результатов добавления этих метеданных в том, что когда вы добавите ссылку MDN Web Docs на facebook, она отобразится с изображением и описанием, улучшая опыт взаимодействия (User eXperience, UX).

- -

Open graph protocol data from the MDN homepage as displayed on facebook, showing an image, title, and description.У Twitter также есть собственный формат метаданных, с помощью которого  создается аналогичный эффект, при отображении URL сайта на twitter.com:

- -
<meta name="twitter:title" content="MDN Web Docs">
- -

Добавление иконок

- -

Чтобы добавить своему сайту узнаваемости, можно указать в метаданных разные иконки.

- -

Favicon, один из старожилов интернета, стал первой из таких иконок. Браузеры показывают её в заголовке вкладки и в списке избранных страниц.The Firefox bookmarks panel, showing a bookmarked example with a favicon displayed next to it.

- -

Чтобы добавить на страницу favicon:

- -
    -
  1. Сохраните изображение в формате .ico (многие браузеры поддерживают и в более привычных форматах, таких как .gif или .png) в папку со своим документом. Старые браузеры, например, Internet Explorer 6, поддерживают только формат .ico
  2. -
  3. Добавьте ссылку на иконку в <head> документа: -
    <link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
    -
  4. -
- -

Для разных устройств можно указывать разные иконки. Например, на главной странице MDN:

- -
<!-- Для iPad 3 с Retina-экраном высокого разрешения: -->
-<link rel="apple-touch-icon-precomposed" sizes="144x144" href="https://developer.cdn.mozilla.net/static/img/favicon144.a6e4162070f4.png">
-<!-- Для iPhone с Retina-экраном высокого разрешения: -->
-<link rel="apple-touch-icon-precomposed" sizes="114x114" href="https://developer.cdn.mozilla.net/static/img/favicon114.0e9fabd44f85.png">
-<!-- Для iPad первого и второго поколения: -->
-<link rel="apple-touch-icon-precomposed" sizes="72x72" href="https://developer.cdn.mozilla.net/static/img/favicon72.8ff9d87c82a0.png">
-<!-- Для iPhone, iPod Touch без Retina и устройств с Android 2.1+: -->
-<link rel="apple-touch-icon-precomposed" href="https://developer.cdn.mozilla.net/static/img/favicon57.a2490b9a2d76.png">
-<!-- Для других случаев - обычный favicon -->
-<link rel="shortcut icon" href="https://developer.cdn.mozilla.net/static/img/favicon32.e02854fdcf73.png">
- -

В комментариях указано, для чего используется каждая иконка — например, при добавлении страницы на домашний экран iPad будет использована иконка в высоком разрешении. 

- -

Не беспокойтесь о реализации всех этих типов значков — это довольно продвинутая функция, и мы не станем возвращаться к ней в курсе. Основная цель — показать вам, что это такое, если вы столкнетесь с ними при просмотре исходного кода других веб-сайтов.

- -

Подключение CSS и JavaScript

- -

Современные сайты используют {{glossary("CSS")}}, чтобы выглядеть привлекательнее, и добавляют интерактивные функции через {{glossary("JavaScript")}}: видеоплееры, карты, игры. Обычно связянные стили добавляют на страницу через элемент {{htmlelement("link")}}, а скрипты — через элемент {{htmlelement("script")}} .

- - - -

Активное изучение: добавляем на страницу CSS и JavaScript

- -
    -
  1. Для этого упражнения скачайте файлы meta-example.html, script.js и style.css и положите их в одну папку на своём компьютере. Проверьте, что они сохранились с правильными именами и расширениями.
  2. -
  3. Откройте HTML в браузере и текстовом редакторе.
  4. -
  5. Следуя изученному материалу, добавьте на страницу скрипт и стиль с помощью элементов {{htmlelement("link")}} и {{htmlelement("script")}}.
  6. -
- -

Если всё получилось, когда вы сохраните HTML и обновите страницу в браузере, вы увидите кое-что новенькое:

- -

Example showing a page with CSS and JavaScript applied to it. The CSS has made the page go green, whereas the JavaScript has added a dynamic list to the page.

- - - -
-

Примечание: Если вам никак не удаётся подключить CSS или JS, посмотрите на наш готовый пример — страницу css-and-js.html.

-
- -

Основной язык HTML страницы

- -

Наконец, стоит отметить, что вы можете (и действительно должны) установить язык для своей страницы. Это можно сделать, добавив атрибут lang в открывающий HTML-тег (как в примере meta-example.html: и как показано ниже):

- -
<html lang="en-US">
- -
<html lang="ru">
-
- -

Это полезно во многих случаях. Ваш HTML-документ будет более эффективно индексироваться поисковыми системами, если его язык установлен (что позволяет ему правильно отображаться в языковых результатах), и он полезен людям с нарушением зрения, которые используют программы, читающие страницы вслух (например, слово "шесть" пишется одинаково как на французском, так и на английском языках, но произносится по-разному.).

- -

Можно также указать язык для части документа. Например, мы могли бы установить язык для части страницы на японском:

- -
<p>Пример на японском: <span lang="jp">ご飯が熱い。</span>.</p>
- -

Коды языков определены в стандарте ISO 639-1. Подробнее о работе с языками можно узнать в Языковые тэги в HTML и XML.

- -

Заключение

- -

На этом заканчивается наш беглый обзор по HTML-блоку head  —  с его помощью вы можете делать гораздо больше, но исчерпывающий обзор будет скучным и запутанным на этом этапе, мы же сейчас хотели дать вам представление о самых распространённых вещах, которые вы можете там найти! В следующей статье мы рассмотрим основы разметки текста в HTML.

- -

{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/Getting_started", "Learn/HTML/Introduction_to_HTML/HTML_text_fundamentals", "Learn/HTML/Introduction_to_HTML")}}

- -

В этом модуле

- - diff --git "a/files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/\320\275\320\260\321\207\320\260\320\273\320\276_\321\200\320\260\320\261\320\276\321\202\321\213/index.html" "b/files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/\320\275\320\260\321\207\320\260\320\273\320\276_\321\200\320\260\320\261\320\276\321\202\321\213/index.html" deleted file mode 100644 index 48904b9e17..0000000000 --- "a/files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/\320\275\320\260\321\207\320\260\320\273\320\276_\321\200\320\260\320\261\320\276\321\202\321\213/index.html" +++ /dev/null @@ -1,772 +0,0 @@ ---- -title: Начало работы с HTML -slug: Learn/HTML/Введение_в_HTML/Начало_работы -tags: - - Guide - - HTML - - Аттрибуты - - Для начинающих - - Комментарии - - Пробелы - - Программирование - - Руководство - - Урок - - элементы -translation_of: Learn/HTML/Introduction_to_HTML/Getting_started ---- -
{{LearnSidebar}}
- -
{{NextMenu("Learn/HTML/Introduction_to_HTML/The_head_metadata_in_HTML", "Learn/HTML/Введение_в_HTML/Начало_работы")}}
- -

В этой статье мы охватим азы HTML, необходимые для начала работы. Дадим определение «элементам», «атрибутам», «тегам» и прочим важным понятиям, о которых вы, возможно, слышали, а также об их роли в языке. Мы также покажем, как устроены HTML-элементы, типичная HTML-страница, и объясним другие важные аспекты языка. По ходу дела, чтобы вы не заскучали, мы поиграем с настоящей HTML-страницей!

- - - - - - - - - - - - -
Необходимые знания:Умение работать с компьютером, наличие необходимого ПО, базовые знания о работе с файлами.
Цель:Познакомиться с языком HTML и научиться описывать некоторые его элементы.
- -

Что такое HTML?

- -

{{glossary("HTML")}} (HyperText Markup Language - язык гипертекстовой разметки) не является языком программирования; это язык разметки, используемый для определения структуры веб-страниц, посещаемых пользователями. Они могут иметь сложную или простую структуру, всё зависит от замысла и желания веб-разработчика. HTML состоит из ряда {{glossary("Element", "элементов")}}, которые вы используете для того, чтобы охватить, обернуть или разметить различные части содержимого, чтобы оно имело определенный вид или срабатывало определенным способом. Встроенные {{glossary("Tag", "тэги")}} могут преобразовать часть содержимого в гиперссылку, по которой можно перейти на другую веб-страницу, выделить курсивом слова и так далее. Например, рассмотрим следующую строку:

- -
Мой кот очень сердитый
- -

Если мы хотим, чтобы строка отобразилась в таком же виде, мы можем определить её, как "параграф", заключив её в теги элемента "параграф"  ({{htmlelement("p")}}), например:

- -
<p>Мой кот очень сердитый</p>
- -
-

Примечание: Метки в HTML нечувствительны к регистру, то есть они могут быть записаны в верхнем или нижнем регистре. Например, тег {{htmlelement("title")}} может быть записан как <title>, <TITLE>, <Title>, <TiTlE>, и т.д., и он будет работать нормально. Лучшей практикой, однако, является запись всех тегов в нижнем регистре для обеспечения согласованности, удобочитаемости и других причин.

-
- -

Структура HTML элементов

- -

Давайте рассмотрим элемент "параграф" чуть подробнее:

- -

- -

Основными частями элемента являются:

- -
    -
  1. Открывающий тег: Он состоит из названия (обозначения) элемента (в нашем случае, p), помещённого внутри угловых скобок. Данный тег служит признаком начала элемента, с этого момента тег начинает влиять на следующее после него содержимое.
  2. -
  3. Закрывающий тег: выглядит как и открывающий, но содержит слэш перед названием тега. Он служит признаком конца элемента. Пропуски закрывающих тегов — типичная ошибка новичков, которая может приводить к неопределённым результатам — в лучшем случае всё сработает правильно, в других страница может вовсе не прорисоваться или прорисоваться не как ожидалось.
  4. -
  5. Содержимое: Как видно, в нашем случае содержимым является простой текст.
  6. -
  7. Элемент: открывающий тег + закрывающий тег + содержимое = элемент.
  8. -
- -

Активное изучение: создание вашего первого HTML элемента

- -

Отредактируйте строку текста ниже в поле Ввод, обернув ее тегами <em> и </em> (вставьте <em> перед строкой, чтобы указать начало элемента, и </em> после нее, чтобы указать конец элемента) — эти действия должны выделить строку текста курсивом! Вы можете видеть изменения в реальном времени в поле Вывод.

- -

Если Вы ошиблись, то всегда можете начать снова, воспользовавшись кнопкой Сбросить. Если упражнение вызывает у Вас затруднения, то нажмите кнопку Показать решение, чтобы увидеть правильный ответ.

- - - -

{{ EmbedLiveSample('Playable_code', 700, 400, "", "", "hide-codepen-jsfiddle") }}

- -

Вложенные элементы

- - - -

Вы также можете вкладывать элементы внутрь других элементов — это называется вложенностью. Если мы хотим подчеркнуть, что наш кот очень сердитый, мы можем заключить слово "очень" в элемент {{htmlelement("strong")}} , который означает, что это слово крайне важно в данном контексте:

- -
<p>Мой кот <strong>очень</strong>  сердитый.</p>
- -

Вы должны удостовериться, что элементы вложены должным образом: в следующем примере мы открываем p элемент первым, затем элемент strong, затем мы закрываем элемент strong первым, затем p. Следующее писать неправильно:

- -
<p>Мой кот <strong>очень сердитый.</p></strong>
- -

Элементы должны открываться и закрываться правильно таким образом, чтобы явно находиться внутри или снаружи друг друга. Если они перекрываются так, как в примере выше, то ваш браузер попытается «додумать» за вас, что вы имели в виду, и вы получите непредсказуемый результат. Так что не делайте так!

- -

Блочные и строчные элементы

- - - -

Существует две важных категории элементов в HTML, которые вам стоит знать — элементы блочного уровня и строчные элементы.

- - - -

Посмотрите на следующий пример:

- -
<em>Первый</em><em>второй</em><em>третий</em>
-
-<p>четвертый</p><p>пятый</p><p>шестой</p>
-
- -

{{htmlelement("em")}} — это строчный элемент, так что, как вы здесь видите, первые три элемента находятся на одной строке друг с другом без пробелов между ними. С другой стороны, {{htmlelement("p")}} — это элемент блочного уровня, так что каждый элемент находится на новой строке, с пространством выше и ниже каждого (этот интервал определяется CSS-оформлением по умолчанию, которое браузеры применяют к абзацам).

- -

{{ EmbedLiveSample('Block_versus_inline_elements', 700, 200, "", "") }}

- -
-

Примечание: HTML5 переопределил категории элементов в HTML: смотрите Категории типов содержимого элементов. Хотя эти определения точнее и однозначнее, чем те, которые были раньше, их гораздо сложнее понять, чем «блочный» и «строчный», поэтому мы будем придерживаться их в этом разделе.

-
- -
-

Примечание: Не путайте термины «блочный» и «строчный», используемые в этом разделе, с одноименными типами отображения в CSS. Хотя по умолчанию они коррелируют, смена типа отображения в CSS не меняет категорию элемента и не влияет на то, во что его можно вкладывать и что можно вкладывать в него. Эта довольно частая путаница — одна из причин, почему HTML5 отказался от этих терминов.

-
- -
-

Примечание: Вам могут пригодиться справочники, включающие списки блочных и строчных элементов — смотри Элементы блочного уровня и Строчные элементы.

-
- -

Пустые элементы

- - - -

Не все элементы соответствуют вышеупомянутому шаблону: открывающий тег, контент, закрывающий тег. Некоторые элементы состоят из одного тега и обычно используются для вставки чего-либо в то место документа, где размещены. Например, элемент {{htmlelement("img")}} вставляет картинку на страницу в том самом месте, где он расположен:

- -
<img src="https://raw.githubusercontent.com/mdn/beginner-html-site/gh-pages/images/firefox-icon.png">
- -

Это выведет на вашу страницу следующее:

- -

{{ EmbedLiveSample('Empty_elements', 700, 300, "", "", "hide-codepen-jsfiddle") }}

- -
-

Примечание: Пустые элементы иногда называют void-элементами.

-
- -

Атрибуты

- -

У элементов также могут быть атрибуты, которые выглядят так:

- -

&amp;amp;lt;p class="editor-note">My cat is very grumpy&amp;amp;lt;/p>

- -

Атрибуты содержат дополнительную информацию об элементе, которая, по вашему мнению, не должна отображаться в содержимом элемента. В данном случае атрибут class позволяет вам дать элементу идентификационное имя, которое в дальнейшем может быть использовано для обращения к элементу с информацией о стиле и прочими вещами.

- -

Атрибут должен иметь:

- -
    -
  1. Пробел между атрибутом и именем элемента (или предыдущим атрибутом, если у элемента уже есть один или несколько атрибутов).
  2. -
  3. Имя атрибута и следующий за ним знак равенства.
  4. -
  5. Значение атрибута, заключенное в кавычки.
  6. -
- -

Активное изучение: Добавление атрибутов в элемент

- - - -

Возьмём для примера элемент {{htmlelement("a")}} — означает anchor (якорь) и делает текст внутри него гиперссылкой. Может иметь несколько атрибутов, вот несколько из них:

- - - -

Измените строку текста ниже в поле Ввод так, чтобы она вела на ваш любимый вебсайт. Сначала добавьте элемент <a>затем атрибут href и атрибут title. Наконец, укажите атрибут target чтобы открыть ссылку на новой вкладке. Вы можете наблюдать сделанные изменения в реальном времени в поле Вывод. Вы должны увидеть гиперссылку, при наведении курсора на которую появляется содержимое атрибута title, а при щелчке переходит по адресу в атрибуте href. Помните, что между именем элемента и каждым из атрибутов должен быть пробел.

- -

Если Вы ошиблись, то всегда можете начать снова, воспользовавшись кнопкой Сбросить. Если упражнение вызывает у Вас затруднения, то нажмите кнопку Показать решение, чтобы увидеть правильный ответ.

- - - -

{{ EmbedLiveSample('Playable_code2', 700, 400, "", "", "hide-codepen-jsfiddle") }}

- -

Булевые атрибуты

- - - -

Иногда вы будете видеть атрибуты, написанные без значения — это совершенно допустимо.  Такие атрибуты называются булевые, и они могут иметь только одно значение, которое в основном совпадает с его именем. В качестве примера возьмем атрибут {{htmlattrxref("disabled", "input")}}, который можно назначить для формирования элементов ввода, если вы хотите, чтобы они были отключены (неактивны), так что пользователь не может вводить какие-либо данные в них.

- -
<input type="text" disabled="disabled">
- -

Для краткости совершенно допустимо записывать их следующим образом (мы также для справки разместили не деактивированный элемент input, чтобы дать вам большее понимание происходящего):

- -
<input type="text" disabled>
-
-<input type="text">
-
- -

На выходе оба варианта будут выглядеть следующим образом:

- -

{{ EmbedLiveSample('Boolean_attributes', 700, 100, "", "", "hide-codepen-jsfiddle") }}

- -

Опускание кавычек вокруг значений атрибутов

- - - -

Осматриваясь во всемирной сети, вы будете встречать различные незнакомые способы написания разметки, включая написание значений атрибутов без кавычек. Это допустимо при определенных условиях, но разрушит вашу разметку при других. Например, возвращаясь к нашему упражнению с гиперссылкой, мы можем написать основной вариант только с атрибутом href так:

- -
<a href=https://www.mozilla.org/>любимый веб-сайт</a>
- -

Однако, как только мы добавим атрибут title в таком же стиле, мы поступим неверно:

- -
<a href=https://www.mozilla.org/ title=The Mozilla homepage>favorite website</a>
- -

В этом месте браузер неверно истолкует вашу разметку, думая, что атрибут title — это на самом деле три разных атрибута — атрибут title со значением "The" и два булевых атрибута: Mozilla и homepage. Это, очевидно, не то, что имелось в виду, и приведёт к ошибке или неожиданному поведению кода, как это показано в живом примере ниже. Попробуйте навести курсор на ссылку, чтобы увидеть, на что похож текст title!

- -

{{ EmbedLiveSample('Omitting_quotes_around_attribute_values', 700, 100, "", "", "hide-codepen-jsfiddle") }}

- -

Наш совет: всегда используйте кавычки в атрибутах — это позволит избежать подобных проблем, и, следовательно, код будет более читабельным.

- -

Одинарные или двойные кавычки?

- - - -

В этой статье вы заметите, что все атрибуты заключены в двойные кавычки. Однако, вы можете видеть одинарные кавычки в HTML документах других людей. Это исключительно дело вкуса, и вы можете свободно выбирать, какие из них предпочитаете. Обе следующие строки эквивалентны:

- -
<a href="http://www.example.com">Ссылка к моему примеру.</a>
-
-<a href='http://www.example.com'>Ссылка к моему примеру.</a>
- -

Однако вы должны убедиться, что не смешиваете их вместе. Следующее будет неверным!

- -
<a href="http://www.example.com'>Ссылка к моему примеру.</a>
- -

Если вы используете один тип кавычек в своем HTML, то вы можете поместить внутрь их кавычки другого типа, не вызывая никаких проблем:

- -
<a href="http://www.example.com" title="Isn't this fun?">A link to my example.</a>
- -

Если вы хотите вставить кавычки того же типа, то вы должны использовать объекты HTML. Например, это работать не будет:

- -
<a href='http://www.example.com' title='Isn't this fun?'>A link to my example.</a>
- -

Поэтому вам нужно сделать так:

- -
<a href='http://www.example.com' title='Isn&#39;t this fun?'>A link to my example.</a>
- -

Структура HTML документа

- -

Ниже дан пример оборачивания основных, самостоятельных HTML элементов, которые сами по себе не очень полезны. Давайте посмотрим, как самостоятельные элементы объединяются для формирования всей HTML страницы:

- -
<!DOCTYPE html>
-<html>
-  <head>
-    <meta charset="utf-8">
-    <title>Тестовая страница</title>
-  </head>
-  <body>
-    <p>Это — моя страница</p>
-  </body>
-</html>
- -

Вот что мы имеем:

- -
    -
  1. <!DOCTYPE html>: Объявление типа документа. Очень давно, ещё когда HTML был молод (1991/2), типы документов использовались в качестве ссылок на набор правил, которым HTML-страница должна была следовать, чтобы она считалась хорошей, что может означать автоматическую проверку ошибок и другие полезные вещи. Объявление типа документа выглядело примерно вот так: - -
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    -"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    - Однако в наши дни никто особо не думает о них, и типы документа стали историческим артефактом, которые должны быть включены везде, чтобы всё работало правильно. <!DOCTYPE html> — это самый короткий вид типа документа, который считается действующим. На самом деле это всё, что нужно вам знать о типах документов .
  2. -
  3. <html></html>: Элемент {{htmlelement("html")}} содержит в себе всё содержимое на всей странице, и иногда его называют "корневой элемент". 
  4. -
  5. <head></head>: Элемент {{htmlelement("head")}}. Данный элемент выступает в качестве контейнера для всего содержимого, которое вы хотите включить в HTML документ, но не хотите показывать посетителям вашей страницы. Он включает такие вещи, как ключевые слова и описание страницы, которые вы хотели бы показывать в поисковых запросах, CSS для стилизирования вашего контента, объявление поддерживаемого набора символов и многое другое. Вы узнаете больше об этом из следующей статьи данного руководства.
  6. -
  7. <meta charset="utf-8">: Этот элемент устанавливает в качестве символьной кодировки для вашего документа utf-8 , который включает большинство символов из всех известных человечеству языков. По существу, теперь страница сможет отобразить любой текстовый контент, который вы сможете в неё вложить. Нет причин не устанавливать эту кодировку, это также позволит избежать некоторых проблем позднее.
  8. -
  9. <title></title>: Элемент {{htmlelement("title")}}. Этот элемент устанавливает заголовок вашей страницы, который появляется во вкладке браузера, загружающей эту страницу, также это заглавие используется при описании страницы, когда вы сохраняете её в закладках или избранном.
  10. -
  11. <body></body>: Элемент {{htmlelement("body")}}. Он содержит весь контент, который вы хотите показывать посетителям вашей страницы, — текст, изображения, видео, игры, проигрываемые аудио дорожки или что-то ещё.
  12. -
- -

Активное изучение: Добавление элементов в ваш HTML-документ

- - - -

Если вы хотите поэкспериментировать с написанием HTML на своём компьютере, то можете:

- -
    -
  1. Скопировать пример HTML-страницы, расположенный выше.
  2. -
  3. Создать новый файл в текстовом редакторе.
  4. -
  5. Вставить код в ваш новый текстовый файл.
  6. -
  7. Сохранить файл как index.html.
  8. -
- -
-

Примечание: Вы также можете найти этот базовый пример HTML на  MDN Learning Area Github repo.

-
- -

Теперь можете открыть браузер и посмотреть, во что отрисовался код, а потом изменить его, обновить страницу и посмотреть, что получилось. Сначала страница выглядит так:

- -

Скриншот примера тестовой страницы
- Для этого упражнения вы можете редактировать код локально на своём компьютере, как предлагается выше, а можете работать в редакторе, расположенном ниже. В редакторе показано только содержимое элемента {{htmlelement("body")}}. Попробуйте сделать следующее:

- - - -

Если вы запутались, всегда можно запустить пример сначала кнопкой Сбросить. Сдаётесь — посмотрите ответ, нажав на Показать решение.

- - - -

{{ EmbedLiveSample('Playable_code3', 700, 600, "", "", "hide-codepen-jsfiddle") }}

- -

Пробелы в HTML

- - - -

Вы могли заметить, что в примерах кода из этой статьи много пробелов. Это вовсе не обязательно — следующие два примера эквивалентны:

- -
<p>Собаки глупы.</p>
-
-<p>Собаки
-         глупы.</p>
- -

Не важно, сколько пустого места вы используете в разметке (что может включать пробелы и сдвиги строк): браузер при анализе кода сократит всё пустое место до одного пробела. Зачем использовать много пробелов? Ответ: это доступность для понимания — гораздо легче разобраться, что происходит в вашем коде, если он удобно отформатирован, а не просто собран вместе в одном большом беспорядке. В нашем коде каждый вложенный элемент сдвинут на два пробела относительно элемента, в котором он находится. Вы можете использовать любое форматирование (в частности, количество пробелов для отступа), но лучше придерживаться одного стиля.

- -

Ссылки на сущности: Включение специальных символов в HTML

- - - -

В HTML символы <, >, ", ' и & являются специальными. Они являются частью самого синтаксиса HTML. Так как же включить в текст один из этих специальных символов? Например, если вы хотите использовать амперсанд или знак «меньше» и не интерпретировать его как код.

- -

Мы должны использовать ссылки-мнемоники  — специальные коды, которые отображают спецсимволы, и могут быть использованы в необходимых позициях. Каждая ссылка-мнемоник начинается с ампресанда (&) и завершается точкой с запятой (;).

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Буквенный символСимвольный эквивалент
<&lt;
>&gt;
"&quot;
'&apos;
&&amp;
- -

В  следующем примере вы видите два абзаца, которые рассказывают о веб-технологиях:

- -
<p>В HTML вы определяете параграф элементом <p>.</p>
-
-<p>В HTML вы определяете параграф элементом &lt;p&gt;.</p>
- -

В живом выводе ниже вы можете заметить, что первый абзац выводится неправильно, так как браузер считает, что второй элемент  <p> является началом нового абзаца! Второй абзац нашего кода выводится правильно, потому что мы заменили угловые скобки на ссылки-мнемоники.

- -

{{ EmbedLiveSample('Entity_references_Including_special_characters_in_HTML', 700, 200, "", "", "hide-codepen-jsfiddle") }}

- -
-

Примечание: Таблица всех доступных в  HTML символов-мнемоников — в Википедии: List of XML and HTML character entity references.

-
- -

HTML комментарии

- - - -

В HTML, как и в большинстве языков программирования, есть возможность писать комментарии в коде. Комментарии игнорируются обозревателем и не видны пользователю, их добавляют для того, чтобы пояснить, как работает написанный код, что делают отдельные его части и т. д. Такая практика полезна, если вы возвращаетесь к коду, который давно не видели или когда хотите передать его кому-то другому.

- -

Чтобы превратить часть содержимого HTML-файла в комментарий, нужно поместить её в специальные маркеры <!-- и -->, например:

- -
<p> Меня нет в комментариях( </p>
-
-<!-- <p>А теперь есть!</p> -->
- -

Как вы увидете ниже, первый параграф будет отображён на экране, а второй нет.

- -

{{ EmbedLiveSample('HTML_comments', 700, 100, "", "", "hide-codepen-jsfiddle") }}

- -

Подведение итогов

- -

Вы дошли до конца статьи — надемся, вам понравилось путешествие по основам HTML. На этом этапе вы уже должны немного разобраться, как выглядит язык, как он работает на базовом уровне и уметь описать несколько элементов и атрибутов. Сейчас идеальное время и место, чтобы продолжить изучать HTML. В последующих статьях мы рассмотрим некоторые из вещей, которые вы уже рассмотрели, но намного подробнее, а также представим некоторые новые функции языка. Оставайтесь с нами!

- -
-

Примечание: Сейчас, когда вы начинаете больше узнавать о HTML, вы также можете начать изучать основы каскадных таблиц стилей Cascading Style Sheets, или CSS. CSS — это язык, который используется для стилизации веб-страниц (например, изменение шрифта или цветов или изменение макета страницы). Как вы скоро поймете, HTML и CSS созданы друг для друга.

-
- -

Смотрите также

- - - -
{{NextMenu("Learn/HTML/Introduction_to_HTML/The_head_metadata_in_HTML", "Learn/HTML/Введение_в_HTML/Начало_работы")}}
- -
- -

В этом модуле

- - diff --git "a/files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\320\263\320\270\320\277\320\265\321\200\321\201\321\201\321\213\320\273\320\276\320\272/index.html" "b/files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\320\263\320\270\320\277\320\265\321\200\321\201\321\201\321\213\320\273\320\276\320\272/index.html" deleted file mode 100644 index fcee7272e4..0000000000 --- "a/files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\320\263\320\270\320\277\320\265\321\200\321\201\321\201\321\213\320\273\320\276\320\272/index.html" +++ /dev/null @@ -1,435 +0,0 @@ ---- -title: Создание гиперссылок -slug: Learn/HTML/Введение_в_HTML/Создание_гиперссылок -tags: - - Абсолютные - - Гиперссылки - - Единый указатель ресурса - - Заголовок - - Начинающий - - Обучение - - Относительные - - Руководство - - Ссылки - - Язык гипертекстовой разметки -translation_of: Learn/HTML/Introduction_to_HTML/Creating_hyperlinks ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/HTML_text_fundamentals", "Learn/HTML/Introduction_to_HTML/Advanced_text_formatting", "Learn/HTML/Introduction_to_HTML")}}
- -

Гиперссылки действительно важны — они делают Интернет Интернетом. В этой статье представлен синтаксис, необходимый для создания ссылки,  а также обсуждаются лучшие практики обращения со ссылками.

- - - - - - - - - - - - -
Предварительные требования:Базовое знакомство с HTML, описаное в статье Начало работы c HTML. Форматирование текста в HTML, описанное в статье Основы редактирования текста в HTML.
Задача:Научиться эффективно использовать гиперссылки и связывать несколько файлов вместе.
- -

Что такое гиперссылка?

- -

Гиперссылки — одно из самых интересных нововведений Интернета. Они были особенностью Сети с самого начала, но именно они превращают Интернет в Интернет. Они позволяют нам связывать наши документы с любым другим документом (или ресурсом), с которым мы хотим. С их помощью мы также можем связывать документы с их конкретными частями, и мы можем сделать приложения доступными на простом веб-адресе (сравните это с локальными приложениями, которые должны быть установлены, и другими такими же вещами). Почти любой веб-контент может быть преобразован в ссылку, так что когда вы кликаете по ней (или иным образом активируете), она заставляет веб-браузер перейти на другой веб-адрес ({{glossary("URL")}}.)

- -
-

Примечание: URL-адрес может указывать на файлы HTML, текстовые файлы, изображения, текстовые документы, видео и аудиофайлы и все остальное, что может жить в Интернете. Если веб-браузер не знает, как отображать или обрабатывать файл, он спросит вас, хотите ли вы открыть файл (в этом случае обязанность открытия или обработки файла передаётся в соответствующее локальное приложение на устройстве) или загрузить файл (в этом случае вы можете попытаться разобраться с ним позже).

-
- -

Например, домашняя страница BBC содержит большое количество ссылок, которые указывают не только на множество новостей, но и на различные области сайта (меню), страницы входа / регистрации (пользовательские инструменты) и многое другое.

- -

frontpage of bbc.co.uk, showing many news items, and navigation menu functionality

- -

Анатомия ссылки

- -

Простая ссылка создаётся путём обёртывания текста (или другого содержимого, смотрите  {{anch("Ссылки-блоки")}}), который вы хотите превратить в ссылку, в элемент {{htmlelement ("a")}}, и придания этому элементу атрибута {{htmlattrxref ("href", "a")}} (который также известен как гипертекстовая ссылка, или цель), который будет содержать веб-адрес, на который вы хотите указать ссылку.

- -
<p>Я создал ссылку на
-  <a href="https://www.mozilla.org/ru/">домашнюю страницу Mozilla</a>.
-</p>
- -

Это дало нам следующий результат:

- -

Я создал ссылку на домашнюю страницу Mozilla.

- -

Добавляем инфомацию через атрибут title

- -

Другим атрибутом, который вы можете добавить к своим ссылкам, является — title. Он предназначен для хранения полезной информации о ссылке. Например, какую информацию содержит страница или другие вещи, о которых вам нужно знать. Например:

- -
<p>Я создал ссылку на
-  <a href="https://www.mozilla.org/ru/"
-     title="Лучшее место для поиска дополнительной информации
-     о миссии Mozilla и о том, как внести свой вклад">домашнюю страницу Mozilla
-  </a>.
-</p>
- -

Вот что получилось (описание появится, если навести курсор на ссылку):

- -

Я создал ссылку на домашнюю страницу Mozilla.

- -
-

Примечание: Описание из атрибута title отображается только при наведении курсора, значит люди, полагающиеся на клавиатурные элементы управления для навигации по веб-страницам, будут испытывать трудности с доступом к информации, которую содержит title. Если информация заголовка действительно важна для удобства использования страницы, то вы должны представить ее таким образом, который будет доступен для всех пользователей, например, поместив её в обычный текст.

-
- -

Активное изучение: создаём собственную ссылку

- -

Время упражнения: мы хотели бы, чтобы вы создали любой HTML-документ в текстовом редакторе на своём компьютере (наш базовый пример подойдёт.)

- - - -

Ссылки-блоки

- -

Как упоминалось ранее, вы можете превратить любой элемент в ссылку, даже блочный элемент. Если у вас есть изображение, которые вы хотели бы превратить в ссылку, вы можете просто поместить изображение между тегами <a></a>.

- -
<a href="https://www.mozilla.org/ru/">
-  <img src="mozilla-image.png" alt="логотип mozilla со ссылкой на их домашнюю страницу">
-</a>
- -
-

Примечание: Вы узнаете гораздо больше об использовании изображений в Интернете в следующей статье.

-
- -

Краткое руководство по URL-адресам и путям

- -

Чтобы полностью понять адреса ссылок, вам нужно понять несколько вещей про URL-адреса и пути к файлам. Этот раздел даст вам информацию, необходимую для достижения этой цели.

- -

URL-адрес (Uniform Resource Locator, или единый указатель ресурса, но так его никто не называет) — это просто строка текста, которая определяет, где что-то находится в Интернете. Например, домашняя страница Mozilla находится по адресу https://www.mozilla.org/ru/.

- -

URL-адреса используют пути для поиска файлов. Пути указывают, где в файловой системе находится файл, который вас интересует. Давайте рассмотрим простой пример структуры каталогов (смотрите каталог creating-hyperlinks.)

- -

A simple directory structure. The parent directory is called creating-hyperlinks and contains two files called index.html and contacts.html, and two directories called projects and pdfs, which contain an index.html and a project-brief.pdf file, respectively

- -

Корень структуры — каталог  creating-hyperlinks. При работе на локальном веб-сайте у вас будет один каталог, в который входит весь сайт. В корне у нас есть два файла — index.html и contacts.html. На настоящем веб-сайте index.html был бы нашей домашней, или лендинг-страницей (веб-страницей, которая служит точкой входа для веб-сайта или определенного раздела веб-сайта).

- -

В корне есть ещё два каталога —  pdfs и projects. У каждого из них есть один файл внутри — project-brief.pdf и index.html, соответсвенно. Обратите внимание на то, что вы можете довольно успешно иметь два index.html файла в одном проекте, пока они находятся в разных местах файловой системы.  Многие веб-сайты так делают. Второй index.html, возможно, будет главной лендинг-страницей для связанной с проектом информации.

- - - -
-

Примечание: Вы можете объединить несколько экземпляров этих функций в сложные URL-адреса, если необходимо, например: 
- ../../../сложный/путь/к/моему/файлу.html.

-
- -

Фрагменты документа

- -

Можно ссылаться на определенную часть документа HTML (известную как фрагмент документа), а не только на верхнюю часть документа. Для этого вам сначала нужно назначить атрибут {{htmlattrxref("id")}} элементу, с которым вы хотите связаться. Обычно имеет смысл ссылаться на определённый заголовок, поэтому это выглядит примерно так:

- -
<h2 id="Почтовый_адрес">Почтовый адрес</h2>
- -

Затем, чтобы связаться с  этим конкретным  id, вы должны включить его в конец URL-адреса, которому предшествует знак решётки, например:

- -
<p>Хотите написать мне письмо? Используйте наш
-  <a href="contacts.html#Почтовый_адрес">почтовый адрес</a>.
-</p>
- -

Вы даже можете использовать ссылку на фрагмент документа отдельно для ссылки на другую часть того же документа:

- -
<p>
-  <a href="#Почтовый_адрес">Почтовый адрес кампании</a>
-  можно найти в нижней части этой страницы.
-</p>
- -

Абсолютные и относительные URL-адреса

- -

Два понятия, с которыми вы столкнетесь в Интернете, — это абсолютный URL и относительный URL:

- -
-
Абсолютный URL
-
Указывает на местоположение, определяемое его абсолютным местоположением в Интернете, включая {{glossary("protocol","протокол")}} и {{glossary("domain name","доменное имя")}}. Например, если страница index.html загружается в каталог, называемый projects, который находится внутри корня веб-сервера, а домен веб-сайта — http://www.example.com, страница будет доступна по адресу http://www.example.com/projects/index.html (или даже просто http://www.example.com/projects/), так как большинство веб-серверов просто ищет целевую страницу, такую ​​как index.html, для загрузки, если он не указан в URL-адресе.).
-
- -

Абсолютный URL всегда будет указывать на одно и то же местоположение, независимо от того, где он используется.

- -
-
Относительный URL
-
Указывает расположение относительно файла, с которого вы связываетесь, это больше похоже на случай, который мы рассматривали в предыдущей секции. Для примера, если мы хотим указать со страницы http://www.example.com/projects/index.html на PDF файл, находящийся в той же директории, наш URL может быть просто названием файла —  project-brief.pdf — никакой дополнительной информации не требуется. Если PDF расположен в поддериктории pdfs внутри каталога projects, относительная ссылка будет pdfs/project-brief.pdf (аналогичный абсолютный URL был бы http://www.example.com/projects/pdfs/project-brief.pdf.).
-
- -

Относительный URL будет указывать на различные места, в зависимости от того, где находится файл, в котором он используется, — например, если мы переместим наш файл index.html из каталога projects в корневой каталог веб-сервера (верхний уровень, не в директорию) , то относительный URL pdfs/project-brief.pdf будет вести на http://www.example.com/pdfs/project-brief.pdf, а не на http://www.example.com/projects/pdfs/project-brief.pdf.

- -

Советуем вам основательно разобраться в этой теме!

- -

Практика написания хороших ссылок

- -

При написании ссылок рекомендуется следовать некоторым правилам. Давайте рассмотрим их.

- - - -

Используйте четкие формулировки описания ссылок

- -

На вашей странице легко добавить ссылки. Но этого не совсем достаточно. Мы должны сделать наши ссылки доступными для всех читателей, независимо от их возможностей и инструментов просмотра страницы, которые они предпочитают. Например:

- - - -

Взгляните на этот пример:

- -

Хороший текст ссылки: Скачать Firefox

- -
<p><a href="https://firefox.com/">
-  Скачать Firefox
-</a></p>
- -

Плохой текст ссылки: Нажми сюда, чтобы скачать Firefox

- -
<p><a href="https://firefox.com/">
-  Нажми сюда
-</a>
-чтобы скачать Firefox</p>
-
- -

Советы:

- - - -

Используйте относительные ссылки, где это возможно

- -

Из прочитанного выше, вы можете подумать, что всё время использовать абсолютные ссылки — хорошая идея; в конце концов, они не ломаются, когда страница перемещается. Тем не менее, лучше использовать относительные ссылки везде, где это возможно, в пределах одного сайта  (при ссылке на другие сайты необходимо использовать абсолютную ссылку):

- - - -

Создавая ссылки на не HTML ресурсы — добавляйте описание

- -

Когда вы создаёте ссылку на файл, нажав на который можно загрузить документ PDF или Word или открыть просмотр видео, прослушивание аудио файла или перейти на страницу с другим, неожиданным для пользователя результатом (всплывающее окно или загрузка Flash-фильма), добавляйте четкую формулировку, чтобы уменьшить путаницу. Отсуствие описания может раздражать пользователя. Приведем пример:

- - - -

Посмотрите на примеры, чтобы увидеть, как добавить описание:

- -
<p><a href="http://www.example.com/large-report.pdf">
-  Скачать отчет о продажах (PDF, 10MB)
-</a></p>
-
-<p><a href="http://www.example.com/video-stream/">
-  Посмотреть видео (видео откроется в отдельном окне, HD качество)
-</a></p>
-
-<p><a href="http://www.example.com/car-game">
-  Играть в гонки (необходим Flash)
-</a></p>
- -

Используйте атрибут download, когда создаете ссылку

- -

Когда создаёте ссылку на файл, который должен быть загружен, а не открыт в браузере, можете использовать атрибут download, чтобы создать имя файла по умолчанию для сохранения . Приведем пример ссылки для загрузки браузера Firefox 39:

- -
<a href="https://download.mozilla.org/?product=firefox-39.0-SSL&os=win&lang=en-US"
-   download="firefox-39-installer.exe">
-  Скачать Firefox 39 для Windows
-</a>
- -

Активное изучение: создание меню навигации

- -

Для этого упражнения мы хотим, чтобы вы создали ссылки на страницы в меню навигации в многостраничном сайте. Это один из распространенных способов создания сайта: на каждой странице используется одна и та же структура страниц, включая одно и то же меню навигации, поэтому при нажатии ссылок создается впечатление, что вы остаетесь в одном месте: меню остается на месте, а контент меняется.

- -

Вам нужно скачать или создать следующие страницы в одном каталоге (Смотрите navigation-menu-start):

- - - -

Что делать:

- -
    -
  1. Добавьте неупорядоченный список в указанном месте в любом html-файле. Список должен состоять из имен страниц (index, projects и т.д.). Меню навигации обычно представляет собой список ссылок, поэтому создание неупорядоченного списка семантически верно.
  2. -
  3. Создайте ссылки каждому элементу списка, ведущие на эти страницы.
  4. -
  5. Скопируйте созданное меню в каждую страницу.
  6. -
  7. На каждой странице удалите только ссылку, которая указывает на эту же страницу (на странице index.html удалить ссылку index и так далее). Дело в том, что, находясь на странице index.html, нам незачем видеть ссылку в меню на эту же страницу. С одной стороны, нам незачем ещё раз переходить на эту же страницу, с другой, такой прием помогает визуально определить, смотря на меню, в какой части сайта мы находимся.
  8. -
- -

Когда закончите задание, посмотрите, как это должно выглядеть:

- -

An example of a simple HTML navigation menu, with home, pictures, projects, and social menu items

- -
-

Если не удается сделать, или вы неуверены, что сделали верно, посмотрите наш вариант navigation-menu-marked-up.

-
- -

Ссылки электронной почты

- -

Можно создавать ссылки или кнопки, которые при нажатии открывают новое исходящее сообщение электронной почты, а не ссылку на ресурс или страницу. Для этого используется элемент {{HTMLElement("a")}} и mailto: — адрес почты.

- -

Самыми простыми и часто используемыми формами mailto: являются  subject, cc, bcc и body; дальше прописываем адрес электронной почты. Например:

- -
<a href="mailto:nowhere@mozilla.org">Отправить письмо для nowhere</a>
-
- -

В результате полчим ссылку вида: Отправить письмо для nowhere.

- -

Сам адрес электронной почты не является обязательным для заполнения. Если оставить это поле пустым (в поле {{htmlattrxref("href", "a")}} оставить только "mailto:"), откроется новое исходящее сообщение почтовой программой, в поле получателя будет пусто. Это можно использовать для кнопки "Поделиться".

- -

Особенности и детали

- -

Помимо адреса электронной почты, вы можете предоставить другую информацию. Фактически, любые стандартные поля для отправки почты могут быть добавлены к указанному вами адресу mailto. Часто используемыми из них являются «subject», «cc» и «body» (которые не являются истинным полем заголовка, но позволяют указать дополнительную информацию для нового сообщения электронной почты). Каждое поле и его значение задаются в качестве условия запроса.

- -

Вот пример который включает cc(кому отправить копию сообщения, все получатели письма видят список тех кто это письмо получит), bcc(скрытый адрес получателя, никто из получателей не будет видеть полный список получателей письма), subject(тема письма) и body(текст сообщения):

- -
<a href="mailto:nowhere@mozilla.org?cc=name2@rapidtables.com&bcc=name3@rapidtables.com&amp;subject=The%20subject%20of%20the%20email &amp;body=The%20body%20of%20the%20email">
-  Send mail with cc, bcc, subject and body
-</a>
- -
-

Примечание: Значение каждого поля должно быть написано в URL-кодировке (то есть с непечатаемыми символами и пробелами percent-escaped). Обратите внимание на знак вопроса (?) для разделения основного адреса и дополнительных полей, амперсанд (&) для разделения каждого поля mailto: URL. Для этого используется стандартное описание URL запроса. Прочтите о методе GET, чтобы лучше понимать описание URL запроса.

-
- -

Вот несколько примеров использования mailto URLs:

- - - -

Заключение

- -

Этой информации достаточно для создания ссылок! Вы вернётесь к ссылкам позже, когда начнёте изучать стили. Дальше вы рассмотрите семантику текста и более сложные и необычные возможности, которые будут полезны при создании контента сайта. В следующей главе будет рассматриваться продвинутое форматирование текста.

- -

{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/HTML_text_fundamentals", "Learn/HTML/Introduction_to_HTML/Advanced_text_formatting", "Learn/HTML/Introduction_to_HTML")}}

- -

В этом модуле

- - - -
- - - - - -
diff --git "a/files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/\321\201\321\202\321\200\321\203\320\272\321\202\321\203\321\200\320\260_\320\264\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\260_\320\270_\320\262\320\265\320\261-\321\201\320\260\320\271\321\202\320\260/index.html" "b/files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/\321\201\321\202\321\200\321\203\320\272\321\202\321\203\321\200\320\260_\320\264\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\260_\320\270_\320\262\320\265\320\261-\321\201\320\260\320\271\321\202\320\260/index.html" deleted file mode 100644 index 13f4f458d1..0000000000 --- "a/files/ru/learn/html/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_html/\321\201\321\202\321\200\321\203\320\272\321\202\321\203\321\200\320\260_\320\264\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\260_\320\270_\320\262\320\265\320\261-\321\201\320\260\320\271\321\202\320\260/index.html" +++ /dev/null @@ -1,291 +0,0 @@ ---- -title: Структура документа и веб-сайта -slug: Learn/HTML/Введение_в_HTML/Структура_документа_и_веб-сайта -tags: - - Guide - - HTML - - Базовая разметка - - Гайд - - Для новичков - - С чего начать - - Структура сайта -translation_of: Learn/HTML/Introduction_to_HTML/Document_and_website_structure ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/Advanced_text_formatting", "Learn/HTML/Introduction_to_HTML/Debugging_HTML", "Learn/HTML/Introduction_to_HTML")}}
- -

В дополнение к определению отдельных частей вашей страницы (таких как «абзац» или «изображение»), {{glossary("HTML")}} также содержит ряд элементов блочного уровня, используемых для определения областей вашего веб-сайта (такие как «заголовок», «навигационное меню», «колонка основного содержимого»). В этой статье рассматривается, как планировать базовую структуру сайта и писать HTML для представления этой структуры.

- - - - - - - - - - - - -
Необходимые знания:Базовое знакомство с HTML, описано в разделе Начало работы с HTML. Форматирование текста в HTML, описано в разделе Основы текста в HTML. Как работают гиперссылки, описано в разделе Создание гиперссылок.
Задача:Изучить, как структурировать документ с помощью семантических тегов и как разработать структуру простого веб-сайта.
- -

Основные составляющие документа

- -

Веб-страницы могут и будут отличаться друг от друга, но все они, преимущественно, состоят из аналогичных стандартных компонентов, если только страница не отображает полноэкранное видео или игру, не является частью какого-либо художественного проекта или просто плохо структурирована:

- -
-
Заголовок (колонтитул)
-
Обычно это большая полоса вверху страницы, с крупным заголовком и / или логотипом. Здесь указывается общая информация о веб-сайте, не меняющаяся от страницы к странице.
-
Навигационное меню
-
Ссылки на основные разделы сайта; обычно в виде кнопок, ссылок или вкладок. Также как и заголовок, навигация остается неизменной на всех страницах сайта — наличие непоследовательной навигации на Вашем сайте запутает и разочарует пользователей. Многие веб-дизайнеры считают панель навигации частью заголовка, а не отдельным компонентом, но это не является обязательным требованием; на самом деле, некоторые также утверждают, что их разделение на отдельные компоненты улучшает доступность, поскольку раздельная структура будет понятнее для людей, пользующихся считывателями экрана.
-
Основное содержимое
-
Большая область в центре страницы, содержащая, в основном, уникальный контент данной веб-страницы, например видео, которое вы хотите посмотреть, или рассказ, который вы читаете, или карту, которую вы хотите просмотреть, или заголовки новостей и т. д. Это одна из частей сайта, которая определенно будет меняться от страницы к странице!
-
Боковая панель
-
Как правило, содержит некоторую второстепенную информацию, ссылки, цитаты, рекламу и т.д. Обычно она относится к содержимому в основном контенте (например, на странице со статьей, боковая панель может содержать биографию автора или ссылки на связанные статьи), но в некоторых случаях здесь размещают и другие элементы, например, вторичную навигационную систему.
-
Нижний колонтитул (футер)
-
Полоса в нижней части страницы, которая обычно содержит уведомления об авторских правах или контактную информацию. Это место для размещения общей информации (например, заголовка), но обычно эта информация не является критичной или вторична для самого веб-сайта. Нижний колонтитул также иногда используется для {{Glossary("SEO")}} целей, предоставляя ссылки для быстрого доступа к популярному контенту.
-
- -

"Типичный веб-сайт" может быть структурирован примерно так:

- -

- -

HTML для структурирования содержимого

- -

Пример, показанный сверху, не красив и примитивен, но идеально подходит для иллюстрирования типичного макета веб-сайта. У некоторых веб-сайтов больше колонок, некоторые — более сложные, но идею Вы поняли. С правильным CSS Вы могли бы использовать практически любые элементы для обёртывания различных разделов и стилизовать их так, как Вам хочется, но, как обсуждалось ранее, нам нужно уважать семантику и использовать правильный элемент для правильной работы

- -

Это потому, что визуальные эффекты — это ещё не самое главное. Мы используем цвет и размер шрифта для привлечения внимания посетителей к наиболее полезным частям содержимого, такого как навигационное меню или связанные ссылки, но что насчет людей со слабым зрением, к примеру, для которых концепция "розового" и "большого шрифта" не будет полезной?

- -
-

Заметка: Люди с дальтонизмом составляют около 8% мирового населения. Слепые и слабовидящие люди составляют примерно 4-5% населения мира (в 2012 году в мире было 285 миллионов таких людей, а общая численность населения составляла около 7 миллиардов).

-
- -

В своём HTML-коде Вы можете размечать разделы содержимого сайта на основе их функциональности — использовать элементы, которые представляют разделы контента, описанные выше, а вспомогательные технологии, такие как программы чтения с экрана, смогут распознавать эти элементы и помогать в таких задачах, как "найти основную навигацию" или "найти основное содержимое". Как мы упоминали ранее в ходе курса, существует ряд последствий неиспользования правильной структуры элементов и семантики для правильной работы.

- -

Для реализации такой семантической разметки HTML предоставляет выделенные теги, которые можно использовать для создания таких разделов, например:

- - - -

Активное обучение: исследование кода для нашего примера

- -

Наш пример, представленный выше, содержит следующий код (Вы также можете найти пример в нашем репозитории Github). Мы хотели бы, чтобы Вы взгянули на приведенный выше пример, а затем просмотрели код ниже, чтобы узнать, из каких частей он состоит.

- -
<!DOCTYPE html>
-<html>
-  <head>
-    <meta charset="utf-8">
-
-    <title>Заголовок моей страницы</title>
-    <link href="https://fonts.googleapis.com/css?family=Open+Sans+Condensed:300|Sonsie+One" rel="stylesheet" type="text/css">
-    <link rel="stylesheet" href="style.css">
-
-    <!-- следующие 3 строки нужны для корректного отображения семантических элементов HTML5 в старых версиях Internet Explorer-->
-    <!--[if lt IE 9]>
-      <script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.js"></script>
-    <![endif]-->
-  </head>
-
-  <body>
-    <!-- Вот наш главный заголовок, который используется на всех страницах нашего веб-сайта -->
-
-    <header>
-      <h1>Заголовок</h1>
-    </header>
-
-    <nav>
-      <ul>
-        <li><a href="#">Домашняя страница</a></li>
-        <li><a href="#">Наша команда</a></li>
-        <li><a href="#">Проекты</a></li>
-        <li><a href="#">Контакты</a></li>
-      </ul>
-
-       <!-- Форма поиска — это еще один распространенный нелинейный способ навигации по веб-сайту. -->
-
-       <form>
-         <input type="search" name="q" placeholder="Search query">
-         <input type="submit" value="Go!">
-       </form>
-     </nav>
-
-    <!-- Здесь основное содержимое нашей страницы -->
-    <main>
-
-      <!-- Она содержит статью -->
-      <article>
-        <h2>Заголовок статьи</h2>
-
-        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Donec a diam lectus. Set sit amet ipsum mauris. Maecenas congue ligula as quam viverra nec consectetur ant hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur.</p>
-
-        <h3>Подраздел</h3>
-
-        <p>Donec ut librero sed accu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor.</p>
-
-        <p>Pelientesque auctor nisi id magna consequat sagittis. Curabitur dapibus, enim sit amet elit pharetra tincidunt feugiat nist imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros.</p>
-
-        <h3>Ещё один подраздел</h3>
-
-        <p>Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum soclis natoque penatibus et manis dis parturient montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est.</p>
-
-        <p>Vivamus fermentum semper porta. Nunc diam velit, adipscing ut tristique vitae sagittis vel odio. Maecenas convallis ullamcorper ultricied. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, is fringille sem nunc vet mi.</p>
-      </article>
-
-      <!-- Дополнительный контент также может быть вложен в основной контент -->
-      <aside>
-        <h2>Связанные темы</h2>
-
-        <ul>
-          <li><a href="#">Мне нравится стоять рядом с берегом моря</a></li>
-          <li><a href="#">>Мне нравится стоять рядом с морем</a></li>
-          <li><a href="#">Даже на севере Англии</a></li>
-          <li><a href="#">Здесь не перестаёт дождь</a></li>
-          <li><a href="#">Лаааадно...</a></li>
-        </ul>
-      </aside>
-
-    </main>
-
-    <!-- И вот наш главный нижний колонтитул, который используется на всех страницах нашего веб-сайта -->
-
-    <footer>
-      <p>©Авторские права никому не принадлежат, 2050. Все права защищены.</p>
-    </footer>
-
-  </body>
-</html>
- -

Потратьте некоторое время, чтобы просмотреть код и понять его — комментарии внутри кода также помогут Вам в этом. Мы не просим Вас делать ничего больше в этом уроке, потому что ключ к пониманию макета документа заключается в написании осмысленной структуры HTML, а затем её развёртывании с помощью CSS. Мы подождем, пока вы не начнете изучать CSS-макет как часть темы CSS.

- -

Подробнее об элементах HTML макета

- -

Полезно понять общий смысл всех структурных элементов HTML — это то, над чем вы будете работать постепенно, когда начнёте получать больше опыта с веб-разработкой. Вы можете ознакомиться с деталями, прочитав статью HTML-элементы. Пока что это основные определения, которые вы должны попытаться понять:

- - - -

Несемантические обертки

- -

Иногда Вы будете сталкиваться с ситуацией, когда Вы не можете найти идеальный семантический элемент, чтобы сгруппировать некоторые элементы вместе или обернуть некоторый контент. Иногда Вам просто нужно будет сгруппировать несколько элементов вместе, чтобы применить к ним, как к единой сущности, {{glossary("CSS")}} или {{glossary("JavaScript")}}. Для таких случаев в HTML есть элементы {{HTMLElement("div")}} и {{HTMLElement("span")}}. Вам следует использовать их с подходящим значением атрибута {{htmlattrxref('class')}} или {{htmlattrxref('id')}}, чтобы можно было легко получить к ним доступ.

- -

{{HTMLElement("span")}} — это строчный несемантический элемент, который стоит использовать только если Вы не можете подобрать более подходящий семантический текстовый элемент для обёртывания контента или если не хотите добавлять какие-либо конкретные значения. Например:

- -
<p>Пьяный Король возвратился в свою комнату в 01:00
-и всё никак не мог войти в дверь: хмель мешал <span class="editor-note">[Примечание редактора: В этот момент
-свет на сцене должен быть приглушён]</span>.</p>
- -

В этом примере примечание редактора просто сообщает дополнительные пожелания режиссёру пьесы. В нем нет особого семантического значения. Для слабовидящих пользователей, возможно, примечание будет отделено от основного содержимого с помощью CSS.

- -

{{HTMLElement("div")}} — это блочный несемантический элемент, который следует использовать только если Вы не можете подобрать более подходящий семантический блочный элемент или если не хотите добавлять какие-либо конкретные значения. Например, представьте виджет корзины в интернет-магазине, который Вы можете открыть в любой момент нахождения на сайте:

- -
<div class="shopping-cart">
-  <h2>Корзина</h2>
-  <ul>
-    <li>
-      <p><a href=""><strong>Silver earrings</strong></a>: $99.95.</p>
-      <img src="../products/3333-0985/thumb.png" alt="Серебряные серьги">
-    </li>
-    <li>
-      ...
-    </li>
-  </ul>
-  <p>Итого: $237.89</p>
-</div>
- -

Ему не подходит <aside>, поскольку это не обязательно относится к основному содержимому страницы (Вы хотите, чтобы его можно было просматривать из любого места). Также не подходит и  <section>, т. к. это не часть основного содержимого страницы. Поэтому <div> подходит в этом случае. Мы включили заголовок в качестве указателя, чтобы помочь пользователям программ чтения с экрана в его поиске.

- -
-

Внимание: div настолько просто использовать, что легко переборщить. Поскольку они не несут никакого семантического значения, они просто загромождают Ваш HTML-код. Старайтесь использовать их только тогда, когда нет лучшего семантического решения, и постарайтесь свести их использование к минимуму, иначе Вам будет трудно обновлять и поддерживать Ваши документы.

-
- -

Перенос строки и горизонтальный разделитель

- -

Два элемента, которые Вы будете периодически использовать или захотите узнать о них: {{htmlelement("br")}} и {{htmlelement("hr")}}:

- -

<br> создает разрыв строки в абзаце, и это единственный способ изменить жёсткую структуру в ситуации, когда Вам нужна серия фиксированных коротких строк, например, в почтовом адресе или стихотворении. Пример:

- -
<p>Жила-была девчушка Нелл,<br>
-Любившая писать HTML:<br>
-Её семантика ужасна была — <br>
-Она и сама прочитать ничего не могла.</p>
- -

Без элемента <br> абзац  разместится в одну длинную линию (как было сказано ранее, HTML игнорирует переносы строк), а с ним в коде — разметка будет выглядеть следующим образом:

- -

Жила-была девчушка Нелл,
- Любившая писать HTML:
- Её семантика ужасна была —
- Она и сама прочитать ничего не могла.

- -

<hr> создает горизонтальный разделитель в документе, это означает тематическое изменение текста (например, изменение темы или сцены). Визуально он просто похож на горизонтальную линию. В качестве примера:

- -
<p>Рон был зажат в углу адскими тварями. Он боялся, но твёрдо решил защитить своих друзей, поднял свою волшебную палочку и приготовился к битве, надеясь, что справится со своим несчастьем.</p>
-<hr>
-<p>Тем временем Гарри сидел дома с раскрытым указом и размышлял о том, когда выйдут новые серии спин-оффов; в это время зачарованное письмо пархнуло в окно и приземлилось у него на коленях. Он прочитал его и подскочил на ноги; он подумал: "Думаю, самое время вернуться к работе".</p>
- -

Будет выглядеть примерно так:

- -

Рон был зажат в углу адскими тварями. Он боялся, но твёрдо решил защитить своих друзей, поднял свою волшебную палочку и приготовился к битве, надеясь, что справится со своим несчастьем.

- -
-

Тем временем Гарри сидел дома с раскрытым указом и размышлял о том, когда выйдут новые серии спин-оффов; в это время зачарованное письмо пархнуло в окно и приземлилось у него на коленях. Он прочитал его и подскочил на ноги; он подумал: "Думаю, самое время вернуться к работе".

- -

Планирование простого веб-сайта

- -

Когда вы уже спланировали содержание одной веб-страницы, следующий логический шаг — продумать содержание всего веб-сайта: какие страницы нужны, как они будут устроены и связаны друг с другом для лучшего восприятия пользователем. Это называется {{glossary("Information architecture")}}. В большом, сложном веб-сайте на планирование может уходить много времени, однако спроектировать простой веб-сайт из нескольких страниц может быть очень легко и весело!

- -
    -
  1. Имейте в виду, что у вас будет несколько элементов, общих для большинства (если не всех) страниц — например, меню навигации и содержимого нижнего колонтитула. Например, для сайта компании хорошая идея разместить контактные данные в нижнем колонтитуле на каждой странице. Составьте список элементов, общих для всех страниц. the common features of the travel site to go on every page: title and logo, contact, copyright, terms and conditions, language chooser, accessibility policy
  2. -
  3. Теперь набросайте структуру страниц (можно взять за образец наш простой дизайн, приведенный раннее). Что находится в этих блоках?A simple diagram of a sample site structure, with a header, main content area, two optional sidebars, and footer
  4. -
  5. Теперь составьте список остальной (уникальной для каждой страницы) информации, которую вы разместите на сайте.A long list of all the features that we could put on our travel site, from searching, to special offers and country-specific info
  6. -
  7. Сгруппируйте информацию по темам. Какие части можно разместить на одной странице? Это похоже на метод {{glossary("Card sorting")}}. The items that should appear on a holiday site sorted into 5 categories: Search, Specials, Country-specific info, Search results, and Buy things
  8. -
  9. Составьте карту сайта. Обведите каждую страницу рамкой, и продумайте перемещения пользователя между ними. Обычно в центре оказывается главная страница, с которой можно быстро перейти на все остальные. На небольшом сайте большинство страниц помещают в главную навигацию, но не обязательно класть туда все ссылки. Также можете пометить, как выглядят элементы страниц — ссылками, списками, карточками.
  10. -
- -

A map of the site showing the homepage, country page, search results, specials page, checkout, and buy page

- -

Самостоятельная работа: создайте свою собственную карту сайта

- -

Приментие наш метод к своему сайту. О чем он будет?

- -
-

Примечание: Сохраните свой код, он Вам ещё понадобится.

-
- -

Заключение

- -

Вы стали лучше понимаеть, как структурировать веб-страницу или сайт. В последней статье этого модуля мы узнаем, как отлаживать HTML.

- -

Дополнительные материалы

- - - -

{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/Advanced_text_formatting", "Learn/HTML/Introduction_to_HTML/Debugging_HTML", "Learn/HTML/Introduction_to_HTML")}}

- -

В этом модуле

- - diff --git "a/files/ru/learn/html/\321\200\320\265\321\206\320\265\320\277\321\202\321\213/index.html" "b/files/ru/learn/html/\321\200\320\265\321\206\320\265\320\277\321\202\321\213/index.html" deleted file mode 100644 index 1a780e676b..0000000000 --- "a/files/ru/learn/html/\321\200\320\265\321\206\320\265\320\277\321\202\321\213/index.html" +++ /dev/null @@ -1,153 +0,0 @@ ---- -title: Использование HTML для решения общих задач -slug: Learn/HTML/Рецепты -tags: - - CodingScripting - - HTML - - На русском - - Программирование -translation_of: Learn/HTML/Howto ---- -

Следующие ссылки указывают на решения общих повседневных проблем, которые вам нужно решить с помощью HTML.

- -
-
-

Основы структурирования

- -

Основное применение HTML - это структура документа. Если вы новичок в HTML, вы должны начать с этого.

- - - -

Основы организации гипертекста

- -

HTML специализируется на предоставлении семантической информации для документа, поэтому HTML отвечает на многие вопросы, которые могут у вас возникнуть о том, как лучше донести ваше сообщение в документе.

- - -
- -
-

Гиперссылки

- -

Одной из главных причин по которым навигация в HTML страницах столь проста являются гиперссылки, которые могут которые возможно использоваться различными способами:

- - - -

Изображения и мультимедиа

- - - -

Сценарии и стили

- -

HTML определяет лишь структуру документа. Для улучшения внешнего вида документа обычно используется CSS. Чтобы добавить странице интерактивности вы также можете написать сценарий на одном из скриптовых языков (например JavaScript).

- - - -

Встраиваемый контент

- - -
-
- -

Необычные или продвинутые проблемы

- -

Помимо основ, HTML очень богат и предлагает расширенные возможности для решения сложных проблем. Эти статьи помогут вам разобраться с менее распространенными случаями использования, с которыми вы можете столкнуться:

- -
-
-

Формы

- -

Форма это сложная HTML структура предназначенная для отправки данных с веб-страницы на веб-сервер. Мы призываем вас просмотреть наше полное посвященное руководство. Вот где вы должны начать:

- - - -

Таблицы

- -

Некоторая информация удобнее всего представима в виде таблиц состоящих из строк и столбцов. Это одна из самых сложных структур в HTML, управлять которой не так просто как кажется:

- - - -

Представление данных

- - - -

Интерактивность

- - -
- -
-

Продвинутая организация текста

- - - -

Продвинутые изображения и мультимедиа images & multimedia

- - - -

Локализация

- -

HTML не одноязычен. Он имеет поддержку средств локализации документов.

- - - -

Производительность

- - -
-
- -

     

diff --git a/files/ru/learn/javascript/asynchronous/timeouts_and_intervals/index.html b/files/ru/learn/javascript/asynchronous/timeouts_and_intervals/index.html new file mode 100644 index 0000000000..e3aa0c72b8 --- /dev/null +++ b/files/ru/learn/javascript/asynchronous/timeouts_and_intervals/index.html @@ -0,0 +1,638 @@ +--- +title: 'Объединенный асинхронный JavaScript: Таймайты и интервалы' +slug: Learn/JavaScript/Asynchronous/Таймауты_и_интервалы +translation_of: Learn/JavaScript/Asynchronous/Timeouts_and_intervals +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Introducing", "Learn/JavaScript/Asynchronous/Promises", "Learn/JavaScript/Asynchronous")}}
+ +

В этом руководстве рассматриваются традиционные методы, доступные в JavaScript для асинхронного выполнения кода по истечении заданного периода времени или через регулярный интервал (например, заданное количество раз в секунду), обсуждаются их полезные свойства и рассматриваются присущие им проблемы. .

+ + + + + + + + + + + + +
Необходимые условия:Базовая компьютерная грамотность, достаточное понимание основ JavaScript.
Цель:Понимание асинхронных циклов и интервалов, и то как их можно использовать.
+ +

Введение

+ +

В течение долгого времени веб-платформа предлагала программистам JavaScript ряд функций, которые позволяли им асинхронно выполнять код по истечении определенного временного интервала и повторно выполнять асинхронный блок кода, пока вы не скажете ему остановиться.

+ +

Эти функции:

+ +
+
setTimeout()
+
Выполняет указанный блок кода один раз по истечении указанного времени
+
setInterval()
+
Выполняет указанный блок кода несколько раз с определенным интервалом между каждым вызовом.
+
requestAnimationFrame()
+
Современная версия setInterval (). Выполняут указанный блок кода перед тем, как браузер в следующий раз перерисовывает отображение, позволяя запускать анимацию с подходящей частотой кадров независимо от среды, в которой она выполняется.
+
+ +

Асинхронный код, установленный этими функциями, выполняется в основном потоке (по истечении указанного им таймера).

+ +
+

Важно знать, что вы можете (и часто будете) запускать другой код до выполнения вызова setTimeout () или между итерациями setInterval (). В зависимости от того, насколько интенсивно используются эти операции для процессора, они могут еще больше задержать выполнение асинхронного кода, поскольку любой асинхронный код будет выполняться только после того, как станет доступен основной поток. (Другими словами, когда стек пуст.) Вы узнаете больше по этому вопросу по мере изучения этой статьи.

+
+ +

В любом случае эти функции используются для запуска постоянной анимации и другой фоновой обработки на веб-сайте или в приложении. В следующих разделах мы покажем вам, как их можно использовать.

+ +

setTimeout()

+ +

Как мы ранее отметили, setTimeout () выполняет определенный блок кода один раз по истечении заданного времени. Принимает следующие параметры:

+ + + +
+

NOTE:  Указанное время (или задержка) не является гарантированным временем выполнения, а скорее минимальным временем выполнения. Обратные вызовы, которые вы передаете этим функциям, не могут выполняться, пока стек в основном потоке не станет пустым.

+ +

Как следствие, такой код, как setTimeout (fn, 0), будет выполняться, как только стек будет пуст, а не сразу. Если вы выполните такой код, как setTimeout (fn, 0), но сразу после выполнения цикла, который насчитывает от 1 до 10 миллиардов, ваш обратный вызов будет выполнен через несколько секунд.

+
+ +

В следующем примере, браузер будет ожидать две секунды перед тем как  выполнит анонимную функцию, тогда отобразит сообщение (живой пример, и исходный код):

+ +
let myGreeting = setTimeout(function() {
+  alert('Hello, Mr. Universe!');
+}, 2000)
+ +

Указанные вами функции не обязательно должны быть анонимными. Вы можете дать своей функции имя и даже определить ее где-нибудь еще и передать ссылку на функцию в setTimeout (). Следующие две версии фрагмента кода эквивалентны первой:

+ +
// С именованной функцией
+let myGreeting = setTimeout(function sayHi() {
+  alert('Hello, Mr. Universe!');
+}, 2000)
+
+// С функцией определенной отдельно
+function sayHi() {
+  alert('Hello Mr. Universe!');
+}
+
+let myGreeting = setTimeout(sayHi, 2000);
+ +

Это может быть полезно, если у вас есть функция, которую нужно вызывать как по таймауту, так например и в ответ на событие. Но это также может  помочь поддерживать ваш код в чистоте, особенно если обратный вызов тайм-аута занимает больше, чем несколько строк кода.

+ +

setTimeout () возвращает значение идентификатора, которое можно использовать для ссылки на тайм-аут позже, например, когда вы хотите его остановить.

+ +

Передача параметров в функцию setTimeout ()

+ +

Любые параметры, которые вы хотите передать функции, выполняемой внутри setTimeout (), должны быть переданы ей как дополнительные параметры в конце списка.

+ +

Например, вы можете реорганизовать предыдущую функцию, чтобы она передавала привет любому имени, переданному ей:

+ +
function sayHi(who) {
+  alert(`Hello ${who}!`);
+}
+ +

Теперь вы можете передать имя в вызов setTimeout () в качестве третьего параметра:

+ +
let myGreeting = setTimeout(sayHi, 2000, 'Mr. Universe');
+ +

Очистка таймаутов

+ +

Наконец, если был создан тайм-аут, вы можете отменить его до истечения указанного времени, вызвав clearTimeout(), передав ему идентификатор вызова setTimeout() в качестве параметра. Итак, чтобы отменить указанный выше тайм-аут, вы должны сделать следующее:

+ +
clearTimeout(myGreeting);
+ +
+

Note: См.greeter-app.html для более полной демонстрации, которая позволяет вам указать имя для приветствия и отменить приветствие с помощью отдельной кнопки (см. исходный код).

+
+ +

setInterval()

+ +

setTimeout () отлично работает, когда вам нужно один раз запустить код по истечении заданного периода времени. Но что происходит, когда вам нужно запускать код снова и снова - например, в случае анимации?

+ +

Здесь пригодится setInterval() . Работает очень похоже на setTimeout (), за исключением того, что функция, которую вы передаете в качестве первого параметра, выполняется повторно не менее чем за количество миллисекунд, заданных вторым параметром. Вы также можете передать любые параметры, необходимые для выполняемой функции, в качестве последующих параметров вызова setInterval ().

+ +

Давайте посмотрим на пример. Следующая функция создает новый объект Date(), с помощью toLocaleTimeString() извлекает из него строку с временем и отображает ее в пользовательском интерфейсе. Затем он запускает функцию один раз в секунду с помощью setInterval(), создавая эффект цифровых часов, которые обновляются раз в секунду ( реальный пример, и исходный код):

+ +
function displayTime() {
+   let date = new Date();
+   let time = date.toLocaleTimeString();
+   document.getElementById('demo').textContent = time;
+}
+
+const createClock = setInterval(displayTime, 1000);
+ +

Как и setTimeout (), setInterval () возвращает определенное значение, которое вы можете использовать позже, когда вам нужно очистить интервал.

+ +

Очистка интервала

+ +

setInterval () выполняет задачу постоянно. setInterval () продолжает выполнять задачу вечно, если вы что-то с ней не сделаете. Возможно, вам понадобится способ остановить такие задачи, иначе вы можете получить ошибки, если браузер не сможет выполнить какие-либо другие версии задачи или если анимация, обрабатываемая задачей, завершилась. Вы можете сделать это так же, как останавливаете timeouts - передавая идентификатор, возвращаемый вызовом setInterval (), в функцию clearInterval ():

+ +
const myInterval = setInterval(myFunction, 2000);
+
+clearInterval(myInterval);
+ +

Активное обучение: Создание собственного секундомера!

+ +

Учитывая все вышесказанное, у нас есть для вас задача. Возьмите копию нашего примера setInterval-clock.html , и измените ее так, чтобы создать свой собственный простой секундомер.

+ +

Вам нужно отображать время, как и раньше, но в этом примере вам нужно:

+ + + +

Несколько подсказок для вас:

+ + + +
+

Note: Если вы застряли, вы можете увидеть нашу версию (см. также исходный код ).

+
+ +

Что нужно помнить о setTimeout () и setInterval ()

+ +

При работе с setTimeout () и setInterval () следует помнить о нескольких вещах. Давайте рассмотрим их.

+ +

Рекурсивые таймауты

+ +

Есть еще один способ использования setTimeout (): вы можете вызвать его рекурсивно для повторного запуска одного и того же кода вместо использования setInterval ().

+ +

В приведенном ниже примере используется рекурсивный setTimeout () для запуска переданной функции каждые 100 миллисекунд:

+ +
let i = 1;
+
+setTimeout(function run() {
+  console.log(i);
+  i++;
+  setTimeout(run, 100);
+}, 100);
+ +

Сравните приведенный выше пример со следующим - здесь используется setInterval () для достижения того же эффекта:

+ +
let i = 1;
+
+setInterval(function run() {
+  console.log(i);
+  i++
+}, 100);
+ +

Чем рекурсивный setTimeout () отличается от setInterval () ?

+ +

Разница между двумя версиями приведенного выше кода невелика.

+ + + +

Когда ваш код потенциально может занять больше времени, чем назначенный вами интервал времени, лучше использовать рекурсивный setTimeout () - это сохранит постоянный временной интервал между выполнениями независимо от того, сколько времени потребуется для выполнения кода, и вы избежите ошибок.

+ +

Немедленные таймауты

+ +

Использование 0 в качестве значения для setTimeout () позволяет планировать выполнение указанной функции обратного вызова как можно скорее, но только после того, как будет запущен основной поток кода.

+ +

Например, код приведенный ниже (рабочий код) выводит alert содержащий "Hello", затем alert содержащий "World" как только вы нажмете ОК в первом alert.

+ +
setTimeout(function() {
+  alert('World');
+}, 0);
+
+alert('Hello');
+ +

Это может быть полезно в тех случаях, когда вы хотите установить блок кода для запуска, как только весь основной поток завершит работу - поместите его в цикл событий async, чтобы он запускался сразу после этого.

+ +

Очистка с помощью clearTimeout() или clearInterval()

+ +

clearTimeout () и clearInterval () используют один и тот же список записей для очистки. Интересно, что это означает, что вы можете использовать любой метод для очистки setTimeout () или setInterval ().

+ +

Для согласованности следует использовать clearTimeout () для очистки записей setTimeout () и clearInterval () для очистки записей setInterval (). Это поможет избежать путаницы.

+ +

requestAnimationFrame()

+ +

requestAnimationFrame() это специализированная функция цикла, созданная для эффективного запуска анимации в браузере. По сути, это современная версия setInterval () - она выполняет указанный блок кода до того, как браузер перерисовывает изображение, позволяя запускать анимацию с подходящей частотой кадров независимо от среды, в которой она выполняется.

+ +

Он был создан в ответ на проблемы с setInterval (), который, например, не работает с частотой кадров, оптимизированной для устройства, иногда пропускает кадры, продолжает работать, даже если вкладка не является активной вкладкой или анимация прокручивается со страницы и т. д.(Читай об этом больше в CreativeJS.)

+ +
+

Note: Вы можете найти примеры использования requestAnimationFrame() в этом курсе — например в  Рисование графики, and Практика построения объектов.

+
+ +

Метод принимает в качестве аргумента обратный вызов, который должен быть вызван перед перерисовкой. Это общий шаблон, в котором он используется:

+ +
function draw() {
+   // Drawing code goes here
+   requestAnimationFrame(draw);
+}
+
+draw();
+ +

Идея состоит в том, чтобы определить функцию, в которой ваша анимация обновляется (например, ваши спрайты перемещаются, счет обновляется, данные обновляются или что-то еще). Затем вы вызываете его, чтобы начать процесс. В конце функционального блока вы вызываете requestAnimationFrame () со ссылкой на функцию, переданной в качестве параметра, и это дает браузеру указание вызвать функцию снова при следующей перерисовке дисплея. Затем он выполняется непрерывно, поскольку код рекурсивно вызывает requestAnimationFrame ().

+ +
+

Note: Если вы хотите выполнить простое постоянное анимирование DOM , CSS Анимация вероятно будет быстрее. Она высисляется непосредственно внутренним кодом браузера, а не JavaScript.

+ +

Однако, если вы делаете что-то более сложное, включающее объекты, которые не доступны напрямую в the DOM (такие как 2D Canvas API или WebGL ), requestAnimationFrame() предпочтительный вариант в большинстве случаев.

+
+ +

Как быстро работает ваша анимация?

+ +

Плавность анимации напрямую зависит от частоты кадров анимации и измеряется в кадрах в секунду (fps). Чем выше это число, тем плавнее будет выглядеть ваша анимация до точки.

+ +

Поскольку большинство экранов имеют частоту обновления 60 Гц, максимальная частота кадров, к которой вы можете стремиться, составляет 60 кадров в секунду (FPS) при работе с веб-браузерами. Однако большее количество кадров означает больше обработки, которая часто может вызывать заикание и пропуски, также известные как пропадание кадров или заедание.

+ +

Если у вас есть монитор с частотой обновления 60 Гц и вы хотите достичь 60 кадров в секунду, у вас есть около 16,7 миллисекунд (1000/60) для выполнения кода анимации для рендеринга каждого кадра. Это напоминание о том, что вам нужно помнить об объеме кода, который вы пытаетесь запустить во время каждого прохождения цикла анимации.

+ +

requestAnimationFrame () всегда пытается приблизиться к этому волшебному значению 60 FPS, насколько это возможно. Иногда это невозможно - если у вас действительно сложная анимация и вы запускаете ее на медленном компьютере, частота кадров будет меньше. Во всех случаях requestAnimationFrame () всегда будет делать все возможное с тем, что у него есть.

+ +

Чем отличается requestAnimationFrame() от setInterval() and setTimeout()?

+ +

Давайте поговорим еще немного о том, чем метод requestAnimationFrame () отличается от других методов, используемых ранее. Глядя на наш код сверху:

+ +
function draw() {
+   // Drawing code goes here
+   requestAnimationFrame(draw);
+}
+
+draw();
+ +

Такой же код с использованием setInterval():

+ +
function draw() {
+   // Drawing code goes here
+}
+
+setInterval(draw, 17);
+ +

Как мы уже говорили ранее, вы не указываете временной интервал для requestAnimationFrame (). Просто он работает максимально быстро и плавно в текущих условиях. Браузер также не тратит время на запуск, если по какой-то причине анимация выходит за пределы экрана и т. д.

+ +

setInterval (), с другой стороны, требует указания интервала. Мы пришли к нашему окончательному значению 17 по формуле 1000 миллисекунд / 60 Гц, а затем округлили его в большую сторону. Округление - хорошая идея; если вы округлите в меньшую сторону, браузер может попытаться запустить анимацию со скоростью, превышающей 60 кадров в секунду, и в любом случае это не повлияет на плавность анимации. Как мы уже говорили, стандартная частота обновления - 60 Гц.

+ +

В том числе временная метка

+ +

Фактическому обратному вызову, переданному в функцию requestAnimationFrame (), также может быть задан параметр: значение отметки времени, которое представляет время с момента начала работы requestAnimationFrame ().

+ +

Это полезно, поскольку позволяет запускать вещи в определенное время и в постоянном темпе, независимо от того, насколько быстрым или медленным может быть ваше устройство. Общий шаблон, который вы бы использовали, выглядит примерно так:

+ +
let startTime = null;
+
+function draw(timestamp) {
+    if (!startTime) {
+      startTime = timestamp;
+    }
+
+   currentTime = timestamp - startTime;
+
+   // Do something based on current time
+
+   requestAnimationFrame(draw);
+}
+
+draw();
+ +

Поддержка браузерами

+ +

requestAnimationFrame () поддерживается в более поздних версиях браузеров, чем setInterval () / setTimeout (). Интересно, что он доступен в Internet Explorer 10 и выше.

+ +

Итак, если вам не тербуется поддержка старых версий IE, нет особых причин не использовать requestAnimationFrame().

+ +

Простой пример

+ +

Хватит теории! Давайте выполним упражнение с использованием requestAnimationFrame() . Создадим простую анимацию "spinner animation"—вы могли ее видеть в приложениях когда происходят задержки при ответе с сервера и т.п..

+ +
+

Note: Для такой простой анимации, вам следовало бы использовать CSS . Однако такой вид анимации очень полезен для демонстрации requestAnimationFrame() , вы скорее всего будете использовать этот метод когда делаете что-то более сложное, например обновление отображения игры в каждом кадре.

+
+ +
    +
  1. +

    Возьмите базовый HTML шаблон (такой как этот).

    +
  2. +
  3. +

    Поместите пустой  {{htmlelement("div")}} елемент внутри элемента {{htmlelement("body")}}, затем добавьте внутрь символ ↻ . Этот символ будет действовать как spinner в нашем примере.

    +
  4. +
  5. +

    Применитеpply следующий CSS к HTML шаблону (любым предпочитаемым способом). Он установ красный фон на странице, высоту <body> равную 100% высоты {{htmlelement("html")}} , и центрирует <div> внутри <body>, по горизонтали и вертикали.

    + +
    html {
    +  background-color: white;
    +  height: 100%;
    +}
    +
    +body {
    +  height: inherit;
    +  background-color: red;
    +  margin: 0;
    +  display: flex;
    +  justify-content: center;
    +  align-items: center;
    +}
    +
    +div {
    +  display: inline-block;
    +  font-size: 10rem;
    +}
    +
  6. +
  7. +

    Разместите  {{htmlelement("script")}} элемент перед </body> .

    +
  8. +
  9. +

    Разместите следующий JavaScript код в  <script> . Здесь вы сохраняете ссылку на <div> внутри, устанавливаете дяпеременной rotateCount значение 0, устанавливаете неинициализированную переменную, которая позже будет использоваться для хранения ссылки на вызов requestAnimationFrame(), и устанавливаете для переменной startTime значение null, которая будет позже использоваться для хранения времени начала requestAnimationFrame().

    + +
    const spinner = document.querySelector('div');
    +let rotateCount = 0;
    +let startTime = null;
    +let rAF;
    +
    +
  10. +
  11. +

    Под предыдущим кодом вставьте функцию draw() соторая будет использоваться для хранения нашешо кода анимации, который включает параметр timestamp :

    + +
    function draw(timestamp) {
    +
    +}
    +
  12. +
  13. +

    Внутри draw () добавьте следующие строки. Они определят время начала, если оно еще не определено (это произойдет только на первой итерации цикла), и установят для параметра rotateCount значение для поворота счетчика (текущая временная метка, возьмите начальную временную метку, разделенную на три, чтобы замедлиться):

    + +
      if (!startTime) {
    +   startTime = timestamp;
    +  }
    +
    +  rotateCount = (timestamp - startTime) / 3;
    +
    +
  14. +
  15. +

    Под предыдущей строкой внутри draw () добавьте следующий блок - он проверяет, превышает ли значение rotateCount 359 (например, 360, полный круг). Если это так, он устанавливает значение по модулю 360 (то есть остаток, оставшийся после деления значения на 360), поэтому круговая анимация может продолжаться непрерывно с разумным низким значением. Обратите внимание, что это не является строго необходимым, но легче работать со значениями от 0 до 359 градусов, чем со значениями типа «128000 градусов».

    + +
    if (rotateCount > 359) {
    +  rotateCount %= 360;
    +}
    +
  16. +
  17. Затем, под предыдущим блоком, добавьте следующую строку, чтобы вращать spinner: +
    spinner.style.transform = `rotate(${rotateCount}deg)`;
    +
  18. +
  19. +

    В самом низу внутри функции draw () вставьте следующую строку. Это ключ ко всей операции - вы устанавливаете для переменной, определенной ранее, активный вызов requestAnimation (), который принимает функцию draw () в качестве своего параметра. Это запускает анимацию, постоянно выполняя функцию draw () со скоростью, близкой к 60 FPS.

    + +
    rAF = requestAnimationFrame(draw);
    +
  20. +
  21. +

    Ниже, вызовите функцию draw() для запуска анимации.

    + +
    draw();
    +
  22. +
+ +
+

Note: Вы можете посмотреть рабочий образец на GitHub. ( исходный код.)

+
+ +

Очbстка вызова  requestAnimationFrame() 

+ +

Очистить вызов requestAnimationFrame () можно, вызвав соответствующий метод cancelAnimationFrame (). (Обратите внимание, что имя функции начинается с «cancel», а не «clear», как у методов «set ...».)

+ +

Просто передайте ему значение, возвращаемое вызовом requestAnimationFrame () для отмены, которое вы сохранили в переменной rAF:

+ +
cancelAnimationFrame(rAF);
+ +

Активное обучение: запуск и остановка нашей анимации

+ +

В этом упражнении мы хотели бы, чтобы вы протестировали метод cancelAnimationFrame (), взяв наш предыдущий пример и обновив его, добавив прослушиватель событий для запуска и остановки счетчика при щелчке мышью в любом месте страницы.

+ +

Подсказки:

+ + + +
+

Note: Для начала попробуйте сами; если вы действительно застряли, посмотрите наш живой пример и исходный код.

+
+ +

Регулировка анимации requestAnimationFrame() 

+ +

Одним из ограничений requestAnimationFrame () является то, что вы не можете выбирать частоту кадров. В большинстве случаев это не проблема, так как обычно вы хотите, чтобы ваша анимация работала как можно плавнее. Но как насчет того, чтобы создать олдскульную 8-битную анимацию?

+ +

Это было проблемой, например в анимации ходьбы, вдохновленной островом обезьян, из статьи Drawing Graphics:

+ +

{{EmbedGHLiveSample("learning-area/javascript/apis/drawing-graphics/loops_animation/7_canvas_walking_animation.html", '100%', 260)}}

+ +

В этом примере вы должны анимировать как положение персонажа на экране, так и отображаемый спрайт. В анимации спрайта всего 6 кадров. Если бы вы показывали разные кадры спрайта для каждого кадра, отображаемого на экране, с помощью requestAnimationFrame (), Guybrush двигал бы конечностями слишком быстро, и анимация выглядела бы нелепо. Следовательно, в этом примере регулируется скорость, с которой спрайт циклически повторяет свои кадры, используя следующий код:

+ +
if (posX % 13 === 0) {
+  if (sprite === 5) {
+    sprite = 0;
+  } else {
+    sprite++;
+  }
+}
+ +

Таким образом, код циклически повторяет спрайт только один раз каждые 13 кадров анимации.

+ +

... Фактически, это примерно каждые 6,5 кадров, поскольку мы обновляем posX (положение персонажа на экране) на два кадра:

+ +
if (posX > width/2) {
+  newStartPos = -( (width/2) + 102 );
+  posX = Math.ceil(newStartPos / 13) * 13;
+  console.log(posX);
+} else {
+  posX += 2;
+}
+ +

Это код, который вычисляет, как обновлять позицию в каждом кадре анимации.

+ +

Метод, который вы используете для регулирования анимации, будет зависеть от вашего конкретного кода. Например, в предыдущем примере счетчика вы могли заставить его двигаться медленнее, увеличивая rotateCount только на единицу в каждом кадре вместо двух.

+ +

Активное обучение: игра на реакцию

+ +

В последнем разделе этой статьи вы создадите игру на реакцию для двух игроков. В игре будет два игрока, один из которых управляет игрой с помощью клавиши A, а другой - с помощью клавиши L.

+ +

При нажатии кнопки «Start» счетчик, подобный тому, что мы видели ранее, отображается в течение случайного промежутка времени от 5 до 10 секунд. По истечении этого времени появится сообщение «PLAYERS GO !!» - как только это произойдет, первый игрок, который нажмет свою кнопку управления, выиграет игру.

+ +

{{EmbedGHLiveSample("learning-area/javascript/asynchronous/loops-and-intervals/reaction-game.html", '100%', 500)}}

+ +

Давайте поработаем над этим:

+ +
    +
  1. +

    Прежде всего, скачайте стартовый файл. Он содержит законченную структуру HTML и стили CSS, что дает нам игровую доску, которая показывает информацию двух игроков (как показано выше), но с счетчиком и параграфом результатов, отображаемыми друг над другом. Вам нужно просто написать JavaScript код.

    +
  2. +
  3. +

    Внутри пустого элемента {{htmlelement("script")}} на вашей старнице, начните с добавления следующих строк кода, котороые определяют некотороые переменные и константы, которые вам понадобятся в дальнейшем:

    + +
    const spinner = document.querySelector('.spinner p');
    +const spinnerContainer = document.querySelector('.spinner');
    +let rotateCount = 0;
    +let startTime = null;
    +let rAF;
    +const btn = document.querySelector('button');
    +const result = document.querySelector('.result');
    + +

    В следующем порядке:

    + +
      +
    1. Ссылка на спиннер, чтобы вы могли его анимировать.
    2. +
    3. Ссылка на элемент {{htmlelement("div")}} содержащий спиннер, используемый для отображения и скрытия.
    4. +
    5. Счетчик поворотов. Он определяет, на сколько вы хотите показывать вращение спиннера на каждом кадре анимации.
    6. +
    7. Нулевое время начала. Это будет заполнено временем начала, когда счетчик начнет вращаться.
    8. +
    9. Неинициализировання переменная для последующего хранения вызова {{domxref("Window.requestAnimationFrame", "requestAnimationFrame()")}} который анимирует спиннер.
    10. +
    11. Ссылка на кнопку Start .
    12. +
    13. Ссылка на параграф результатов.
    14. +
    +
  4. +
  5. +

    Ниже добавьте следующую функцию. Она просто берет два числа и возвращает случайное число между ними. Это понадобится вам позже, чтобы сгенерировать случайный интервал ожидания.

    + +
    function random(min,max) {
    +  var num = Math.floor(Math.random()*(max-min)) + min;
    +  return num;
    +}
    +
  6. +
  7. +

    Затем добавьте функцию draw(), которая анимирует спиннер. Это очень похоже на версию из предыдущего примера простого счетчика:

    + +
    function draw(timestamp) {
    +  if(!startTime) {
    +   startTime = timestamp;
    +  }
    +
    +  rotateCount = (timestamp - startTime) / 3;
    +
    +  if(rotateCount > 359) {
    +    rotateCount %= 360;
    +  }
    +
    +  spinner.style.transform = 'rotate(' + rotateCount + 'deg)';
    +  rAF = requestAnimationFrame(draw);
    +}
    +
  8. +
  9. +

    Теперь пришло время настроить начальное состояние приложения при первой загрузке страницы. Добавьте следующие две строки, которые просто скрывают абзац результатов и контейнер счетчика с помощью display: none ;.

    + +
    result.style.display = 'none';
    +spinnerContainer.style.display = 'none';
    +
  10. +
  11. +

    Затем определите функцию reset (), которая возвращает приложение в исходное состояние, необходимое для повторного запуска игры после ее завершения. Добавьте в конец кода следующее:

    + +
    function reset() {
    +  btn.style.display = 'block';
    +  result.textContent = '';
    +  result.style.display = 'none';
    +}
    +
  12. +
  13. +

    Хорошо, хватит подготовки! Пришло время сделать игру доступной! Добавьте в свой код следующий блок. Функция start () вызывает draw (), чтобы запустить вращение спиннера и отобразить его в пользовательском интерфейсе, скрыть кнопку Start, чтобы вы не могли испортить игру, запустив ее несколько раз одновременно, и запускает вызов setTimeout (), который выполняется функция setEndgame () по прошествии случайного интервала от 5 до 10 секунд. Следующий блок также добавляет прослушиватель событий к вашей кнопке для запуска функции start () при ее нажатии.

    + +
    btn.addEventListener('click', start);
    +
    +function start() {
    +  draw();
    +  spinnerContainer.style.display = 'block';
    +  btn.style.display = 'none';
    +  setTimeout(setEndgame, random(5000,10000));
    +}
    + +
    +

    Note: Вы увидете, что этот пример вызывает setTimeout() без сохранения возвращаемого значения. (не  let myTimeout = setTimeout(functionName, interval).) 

    + +

    Это прекрасно работает, если вам не нужно очищать интервал / тайм-аут в любой момент. Если вы это сделаете, вам нужно будет сохранить возвращенный идентификатор!

    +
    + +

    Конечным результатом предыдущего кода является то, что при нажатии кнопки «Start» отображается спиннер, и игроки вынуждены ждать произвольное количество времени, прежде чем их попросят нажать их кнопку. Эта последняя часть обрабатывается функцией setEndgame (), которую вы определите позже.

    +
  14. +
  15. +

    Добавьте в свой код следующую функцию:

    + +
    function setEndgame() {
    +  cancelAnimationFrame(rAF);
    +  spinnerContainer.style.display = 'none';
    +  result.style.display = 'block';
    +  result.textContent = 'PLAYERS GO!!';
    +
    +  document.addEventListener('keydown', keyHandler);
    +
    +  function keyHandler(e) {
    +    let isOver = false;
    +    console.log(e.key);
    +
    +    if (e.key === "a") {
    +      result.textContent = 'Player 1 won!!';
    +      isOver = true;
    +    } else if (e.key === "l") {
    +      result.textContent = 'Player 2 won!!';
    +      isOver = true;
    +    }
    +
    +    if (isOver) {
    +      document.removeEventListener('keydown', keyHandler);
    +      setTimeout(reset, 5000);
    +    }
    +  };
    +}
    + +

    Выполните следующие инструкции:

    + +
      +
    1. Во-первых, отмените анимацию спиннера с помощью {{domxref("window.cancelAnimationFrame", "cancelAnimationFrame()")}} (всегда полезно очистить ненужные процессы), и скройте контейнер счетчика.
    2. +
    3. Затем, отобразите абзац с результатами и установите для его текстового содержимого значение "PLAYERS GO!!"  чтобы сообщить игрокам, что теперь они могут нажать свою кнопку, чтобы победить.
    4. +
    5. Прикрепите к документу прослушиватель событий keydown . При нажатии любой кнопки запускается функция keyHandler().
    6. +
    7. Внутри keyHandler(), код включает обьект события в качестве параметра (представленного e) — его свойство {{domxref("KeyboardEvent.key", "key")}} содержит только что нажатую клавишу, и вы можете использовать это для твета на определенные нажатия клавиш определенными действиями.
    8. +
    9. Установите для переменной isOver значение false, чтобы мы могли отслеживать, были ли нажаты правильные клавиши, чтобы игрок 1 или 2 выиграл. Мы не хотим, чтобы игра заканчивалась при нажатии неправильной клваиши.
    10. +
    11. Регистрация e.key в консоли, это полезный способ узнать значение различных клавиш, которые вы нажимаете.
    12. +
    13. Когда e.key принимает значение "a", отобразить сообщение о том, что Player 1 выиграл, а когда e.key это "l", отобразить сообщение о том, что Player 2 выиграл. (Note: Это будет работать только со строчными буквами a и l — если переданы прописные A или L , это считается другими клавишами!) Если была нажата одна из этих клавиш, установите для isOver значение true.
    14. +
    15. Только еслиf isOver равно true, удалите прослушиватель событий keydown с помощью {{domxref("EventTarget.removeEventListener", "removeEventListener()")}} чтобы после того, как произошло выигрышное нажатие, больше не было возможности ввода с клавиатуры, чтобы испортить финальный результат игры. Вы также используете setTimeout() для вызова reset() через 5 секунд — как обьяснялось ранее, эта функция сбрасывает игру обратно в исходное состояние, чтобы можно было начать новую игру.
    16. +
    +
  16. +
+ +

Вот и все - вы справились!

+ +
+

Note: Если вы где то застряли, взгляните на наша версия игры (см. также исходный код ).

+
+ +

Заключение

+ +

Вот и все — все основы асинхронных циклов и интервалов рассмотрены в статье. Вы найдете эти методы полезными во многих ситуациях, но постарайтесь не злоупотреблять ими! Поскольку они по-прежнему выполняются в основном потоке, тяжелые и интенсивные обратные вызовы (особенно те, которые управляют DOM) могут действительно замедлить страницу, если вы не будете осторожныl.

+ +

{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Introducing", "Learn/JavaScript/Asynchronous/Promises", "Learn/JavaScript/Asynchronous")}}

+ +

В этом модуле

+ + + +
+
+
diff --git "a/files/ru/learn/javascript/asynchronous/\321\202\320\260\320\271\320\274\320\260\321\203\321\202\321\213_\320\270_\320\270\320\275\321\202\320\265\321\200\320\262\320\260\320\273\321\213/index.html" "b/files/ru/learn/javascript/asynchronous/\321\202\320\260\320\271\320\274\320\260\321\203\321\202\321\213_\320\270_\320\270\320\275\321\202\320\265\321\200\320\262\320\260\320\273\321\213/index.html" deleted file mode 100644 index e3aa0c72b8..0000000000 --- "a/files/ru/learn/javascript/asynchronous/\321\202\320\260\320\271\320\274\320\260\321\203\321\202\321\213_\320\270_\320\270\320\275\321\202\320\265\321\200\320\262\320\260\320\273\321\213/index.html" +++ /dev/null @@ -1,638 +0,0 @@ ---- -title: 'Объединенный асинхронный JavaScript: Таймайты и интервалы' -slug: Learn/JavaScript/Asynchronous/Таймауты_и_интервалы -translation_of: Learn/JavaScript/Asynchronous/Timeouts_and_intervals ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Introducing", "Learn/JavaScript/Asynchronous/Promises", "Learn/JavaScript/Asynchronous")}}
- -

В этом руководстве рассматриваются традиционные методы, доступные в JavaScript для асинхронного выполнения кода по истечении заданного периода времени или через регулярный интервал (например, заданное количество раз в секунду), обсуждаются их полезные свойства и рассматриваются присущие им проблемы. .

- - - - - - - - - - - - -
Необходимые условия:Базовая компьютерная грамотность, достаточное понимание основ JavaScript.
Цель:Понимание асинхронных циклов и интервалов, и то как их можно использовать.
- -

Введение

- -

В течение долгого времени веб-платформа предлагала программистам JavaScript ряд функций, которые позволяли им асинхронно выполнять код по истечении определенного временного интервала и повторно выполнять асинхронный блок кода, пока вы не скажете ему остановиться.

- -

Эти функции:

- -
-
setTimeout()
-
Выполняет указанный блок кода один раз по истечении указанного времени
-
setInterval()
-
Выполняет указанный блок кода несколько раз с определенным интервалом между каждым вызовом.
-
requestAnimationFrame()
-
Современная версия setInterval (). Выполняут указанный блок кода перед тем, как браузер в следующий раз перерисовывает отображение, позволяя запускать анимацию с подходящей частотой кадров независимо от среды, в которой она выполняется.
-
- -

Асинхронный код, установленный этими функциями, выполняется в основном потоке (по истечении указанного им таймера).

- -
-

Важно знать, что вы можете (и часто будете) запускать другой код до выполнения вызова setTimeout () или между итерациями setInterval (). В зависимости от того, насколько интенсивно используются эти операции для процессора, они могут еще больше задержать выполнение асинхронного кода, поскольку любой асинхронный код будет выполняться только после того, как станет доступен основной поток. (Другими словами, когда стек пуст.) Вы узнаете больше по этому вопросу по мере изучения этой статьи.

-
- -

В любом случае эти функции используются для запуска постоянной анимации и другой фоновой обработки на веб-сайте или в приложении. В следующих разделах мы покажем вам, как их можно использовать.

- -

setTimeout()

- -

Как мы ранее отметили, setTimeout () выполняет определенный блок кода один раз по истечении заданного времени. Принимает следующие параметры:

- - - -
-

NOTE:  Указанное время (или задержка) не является гарантированным временем выполнения, а скорее минимальным временем выполнения. Обратные вызовы, которые вы передаете этим функциям, не могут выполняться, пока стек в основном потоке не станет пустым.

- -

Как следствие, такой код, как setTimeout (fn, 0), будет выполняться, как только стек будет пуст, а не сразу. Если вы выполните такой код, как setTimeout (fn, 0), но сразу после выполнения цикла, который насчитывает от 1 до 10 миллиардов, ваш обратный вызов будет выполнен через несколько секунд.

-
- -

В следующем примере, браузер будет ожидать две секунды перед тем как  выполнит анонимную функцию, тогда отобразит сообщение (живой пример, и исходный код):

- -
let myGreeting = setTimeout(function() {
-  alert('Hello, Mr. Universe!');
-}, 2000)
- -

Указанные вами функции не обязательно должны быть анонимными. Вы можете дать своей функции имя и даже определить ее где-нибудь еще и передать ссылку на функцию в setTimeout (). Следующие две версии фрагмента кода эквивалентны первой:

- -
// С именованной функцией
-let myGreeting = setTimeout(function sayHi() {
-  alert('Hello, Mr. Universe!');
-}, 2000)
-
-// С функцией определенной отдельно
-function sayHi() {
-  alert('Hello Mr. Universe!');
-}
-
-let myGreeting = setTimeout(sayHi, 2000);
- -

Это может быть полезно, если у вас есть функция, которую нужно вызывать как по таймауту, так например и в ответ на событие. Но это также может  помочь поддерживать ваш код в чистоте, особенно если обратный вызов тайм-аута занимает больше, чем несколько строк кода.

- -

setTimeout () возвращает значение идентификатора, которое можно использовать для ссылки на тайм-аут позже, например, когда вы хотите его остановить.

- -

Передача параметров в функцию setTimeout ()

- -

Любые параметры, которые вы хотите передать функции, выполняемой внутри setTimeout (), должны быть переданы ей как дополнительные параметры в конце списка.

- -

Например, вы можете реорганизовать предыдущую функцию, чтобы она передавала привет любому имени, переданному ей:

- -
function sayHi(who) {
-  alert(`Hello ${who}!`);
-}
- -

Теперь вы можете передать имя в вызов setTimeout () в качестве третьего параметра:

- -
let myGreeting = setTimeout(sayHi, 2000, 'Mr. Universe');
- -

Очистка таймаутов

- -

Наконец, если был создан тайм-аут, вы можете отменить его до истечения указанного времени, вызвав clearTimeout(), передав ему идентификатор вызова setTimeout() в качестве параметра. Итак, чтобы отменить указанный выше тайм-аут, вы должны сделать следующее:

- -
clearTimeout(myGreeting);
- -
-

Note: См.greeter-app.html для более полной демонстрации, которая позволяет вам указать имя для приветствия и отменить приветствие с помощью отдельной кнопки (см. исходный код).

-
- -

setInterval()

- -

setTimeout () отлично работает, когда вам нужно один раз запустить код по истечении заданного периода времени. Но что происходит, когда вам нужно запускать код снова и снова - например, в случае анимации?

- -

Здесь пригодится setInterval() . Работает очень похоже на setTimeout (), за исключением того, что функция, которую вы передаете в качестве первого параметра, выполняется повторно не менее чем за количество миллисекунд, заданных вторым параметром. Вы также можете передать любые параметры, необходимые для выполняемой функции, в качестве последующих параметров вызова setInterval ().

- -

Давайте посмотрим на пример. Следующая функция создает новый объект Date(), с помощью toLocaleTimeString() извлекает из него строку с временем и отображает ее в пользовательском интерфейсе. Затем он запускает функцию один раз в секунду с помощью setInterval(), создавая эффект цифровых часов, которые обновляются раз в секунду ( реальный пример, и исходный код):

- -
function displayTime() {
-   let date = new Date();
-   let time = date.toLocaleTimeString();
-   document.getElementById('demo').textContent = time;
-}
-
-const createClock = setInterval(displayTime, 1000);
- -

Как и setTimeout (), setInterval () возвращает определенное значение, которое вы можете использовать позже, когда вам нужно очистить интервал.

- -

Очистка интервала

- -

setInterval () выполняет задачу постоянно. setInterval () продолжает выполнять задачу вечно, если вы что-то с ней не сделаете. Возможно, вам понадобится способ остановить такие задачи, иначе вы можете получить ошибки, если браузер не сможет выполнить какие-либо другие версии задачи или если анимация, обрабатываемая задачей, завершилась. Вы можете сделать это так же, как останавливаете timeouts - передавая идентификатор, возвращаемый вызовом setInterval (), в функцию clearInterval ():

- -
const myInterval = setInterval(myFunction, 2000);
-
-clearInterval(myInterval);
- -

Активное обучение: Создание собственного секундомера!

- -

Учитывая все вышесказанное, у нас есть для вас задача. Возьмите копию нашего примера setInterval-clock.html , и измените ее так, чтобы создать свой собственный простой секундомер.

- -

Вам нужно отображать время, как и раньше, но в этом примере вам нужно:

- - - -

Несколько подсказок для вас:

- - - -
-

Note: Если вы застряли, вы можете увидеть нашу версию (см. также исходный код ).

-
- -

Что нужно помнить о setTimeout () и setInterval ()

- -

При работе с setTimeout () и setInterval () следует помнить о нескольких вещах. Давайте рассмотрим их.

- -

Рекурсивые таймауты

- -

Есть еще один способ использования setTimeout (): вы можете вызвать его рекурсивно для повторного запуска одного и того же кода вместо использования setInterval ().

- -

В приведенном ниже примере используется рекурсивный setTimeout () для запуска переданной функции каждые 100 миллисекунд:

- -
let i = 1;
-
-setTimeout(function run() {
-  console.log(i);
-  i++;
-  setTimeout(run, 100);
-}, 100);
- -

Сравните приведенный выше пример со следующим - здесь используется setInterval () для достижения того же эффекта:

- -
let i = 1;
-
-setInterval(function run() {
-  console.log(i);
-  i++
-}, 100);
- -

Чем рекурсивный setTimeout () отличается от setInterval () ?

- -

Разница между двумя версиями приведенного выше кода невелика.

- - - -

Когда ваш код потенциально может занять больше времени, чем назначенный вами интервал времени, лучше использовать рекурсивный setTimeout () - это сохранит постоянный временной интервал между выполнениями независимо от того, сколько времени потребуется для выполнения кода, и вы избежите ошибок.

- -

Немедленные таймауты

- -

Использование 0 в качестве значения для setTimeout () позволяет планировать выполнение указанной функции обратного вызова как можно скорее, но только после того, как будет запущен основной поток кода.

- -

Например, код приведенный ниже (рабочий код) выводит alert содержащий "Hello", затем alert содержащий "World" как только вы нажмете ОК в первом alert.

- -
setTimeout(function() {
-  alert('World');
-}, 0);
-
-alert('Hello');
- -

Это может быть полезно в тех случаях, когда вы хотите установить блок кода для запуска, как только весь основной поток завершит работу - поместите его в цикл событий async, чтобы он запускался сразу после этого.

- -

Очистка с помощью clearTimeout() или clearInterval()

- -

clearTimeout () и clearInterval () используют один и тот же список записей для очистки. Интересно, что это означает, что вы можете использовать любой метод для очистки setTimeout () или setInterval ().

- -

Для согласованности следует использовать clearTimeout () для очистки записей setTimeout () и clearInterval () для очистки записей setInterval (). Это поможет избежать путаницы.

- -

requestAnimationFrame()

- -

requestAnimationFrame() это специализированная функция цикла, созданная для эффективного запуска анимации в браузере. По сути, это современная версия setInterval () - она выполняет указанный блок кода до того, как браузер перерисовывает изображение, позволяя запускать анимацию с подходящей частотой кадров независимо от среды, в которой она выполняется.

- -

Он был создан в ответ на проблемы с setInterval (), который, например, не работает с частотой кадров, оптимизированной для устройства, иногда пропускает кадры, продолжает работать, даже если вкладка не является активной вкладкой или анимация прокручивается со страницы и т. д.(Читай об этом больше в CreativeJS.)

- -
-

Note: Вы можете найти примеры использования requestAnimationFrame() в этом курсе — например в  Рисование графики, and Практика построения объектов.

-
- -

Метод принимает в качестве аргумента обратный вызов, который должен быть вызван перед перерисовкой. Это общий шаблон, в котором он используется:

- -
function draw() {
-   // Drawing code goes here
-   requestAnimationFrame(draw);
-}
-
-draw();
- -

Идея состоит в том, чтобы определить функцию, в которой ваша анимация обновляется (например, ваши спрайты перемещаются, счет обновляется, данные обновляются или что-то еще). Затем вы вызываете его, чтобы начать процесс. В конце функционального блока вы вызываете requestAnimationFrame () со ссылкой на функцию, переданной в качестве параметра, и это дает браузеру указание вызвать функцию снова при следующей перерисовке дисплея. Затем он выполняется непрерывно, поскольку код рекурсивно вызывает requestAnimationFrame ().

- -
-

Note: Если вы хотите выполнить простое постоянное анимирование DOM , CSS Анимация вероятно будет быстрее. Она высисляется непосредственно внутренним кодом браузера, а не JavaScript.

- -

Однако, если вы делаете что-то более сложное, включающее объекты, которые не доступны напрямую в the DOM (такие как 2D Canvas API или WebGL ), requestAnimationFrame() предпочтительный вариант в большинстве случаев.

-
- -

Как быстро работает ваша анимация?

- -

Плавность анимации напрямую зависит от частоты кадров анимации и измеряется в кадрах в секунду (fps). Чем выше это число, тем плавнее будет выглядеть ваша анимация до точки.

- -

Поскольку большинство экранов имеют частоту обновления 60 Гц, максимальная частота кадров, к которой вы можете стремиться, составляет 60 кадров в секунду (FPS) при работе с веб-браузерами. Однако большее количество кадров означает больше обработки, которая часто может вызывать заикание и пропуски, также известные как пропадание кадров или заедание.

- -

Если у вас есть монитор с частотой обновления 60 Гц и вы хотите достичь 60 кадров в секунду, у вас есть около 16,7 миллисекунд (1000/60) для выполнения кода анимации для рендеринга каждого кадра. Это напоминание о том, что вам нужно помнить об объеме кода, который вы пытаетесь запустить во время каждого прохождения цикла анимации.

- -

requestAnimationFrame () всегда пытается приблизиться к этому волшебному значению 60 FPS, насколько это возможно. Иногда это невозможно - если у вас действительно сложная анимация и вы запускаете ее на медленном компьютере, частота кадров будет меньше. Во всех случаях requestAnimationFrame () всегда будет делать все возможное с тем, что у него есть.

- -

Чем отличается requestAnimationFrame() от setInterval() and setTimeout()?

- -

Давайте поговорим еще немного о том, чем метод requestAnimationFrame () отличается от других методов, используемых ранее. Глядя на наш код сверху:

- -
function draw() {
-   // Drawing code goes here
-   requestAnimationFrame(draw);
-}
-
-draw();
- -

Такой же код с использованием setInterval():

- -
function draw() {
-   // Drawing code goes here
-}
-
-setInterval(draw, 17);
- -

Как мы уже говорили ранее, вы не указываете временной интервал для requestAnimationFrame (). Просто он работает максимально быстро и плавно в текущих условиях. Браузер также не тратит время на запуск, если по какой-то причине анимация выходит за пределы экрана и т. д.

- -

setInterval (), с другой стороны, требует указания интервала. Мы пришли к нашему окончательному значению 17 по формуле 1000 миллисекунд / 60 Гц, а затем округлили его в большую сторону. Округление - хорошая идея; если вы округлите в меньшую сторону, браузер может попытаться запустить анимацию со скоростью, превышающей 60 кадров в секунду, и в любом случае это не повлияет на плавность анимации. Как мы уже говорили, стандартная частота обновления - 60 Гц.

- -

В том числе временная метка

- -

Фактическому обратному вызову, переданному в функцию requestAnimationFrame (), также может быть задан параметр: значение отметки времени, которое представляет время с момента начала работы requestAnimationFrame ().

- -

Это полезно, поскольку позволяет запускать вещи в определенное время и в постоянном темпе, независимо от того, насколько быстрым или медленным может быть ваше устройство. Общий шаблон, который вы бы использовали, выглядит примерно так:

- -
let startTime = null;
-
-function draw(timestamp) {
-    if (!startTime) {
-      startTime = timestamp;
-    }
-
-   currentTime = timestamp - startTime;
-
-   // Do something based on current time
-
-   requestAnimationFrame(draw);
-}
-
-draw();
- -

Поддержка браузерами

- -

requestAnimationFrame () поддерживается в более поздних версиях браузеров, чем setInterval () / setTimeout (). Интересно, что он доступен в Internet Explorer 10 и выше.

- -

Итак, если вам не тербуется поддержка старых версий IE, нет особых причин не использовать requestAnimationFrame().

- -

Простой пример

- -

Хватит теории! Давайте выполним упражнение с использованием requestAnimationFrame() . Создадим простую анимацию "spinner animation"—вы могли ее видеть в приложениях когда происходят задержки при ответе с сервера и т.п..

- -
-

Note: Для такой простой анимации, вам следовало бы использовать CSS . Однако такой вид анимации очень полезен для демонстрации requestAnimationFrame() , вы скорее всего будете использовать этот метод когда делаете что-то более сложное, например обновление отображения игры в каждом кадре.

-
- -
    -
  1. -

    Возьмите базовый HTML шаблон (такой как этот).

    -
  2. -
  3. -

    Поместите пустой  {{htmlelement("div")}} елемент внутри элемента {{htmlelement("body")}}, затем добавьте внутрь символ ↻ . Этот символ будет действовать как spinner в нашем примере.

    -
  4. -
  5. -

    Применитеpply следующий CSS к HTML шаблону (любым предпочитаемым способом). Он установ красный фон на странице, высоту <body> равную 100% высоты {{htmlelement("html")}} , и центрирует <div> внутри <body>, по горизонтали и вертикали.

    - -
    html {
    -  background-color: white;
    -  height: 100%;
    -}
    -
    -body {
    -  height: inherit;
    -  background-color: red;
    -  margin: 0;
    -  display: flex;
    -  justify-content: center;
    -  align-items: center;
    -}
    -
    -div {
    -  display: inline-block;
    -  font-size: 10rem;
    -}
    -
  6. -
  7. -

    Разместите  {{htmlelement("script")}} элемент перед </body> .

    -
  8. -
  9. -

    Разместите следующий JavaScript код в  <script> . Здесь вы сохраняете ссылку на <div> внутри, устанавливаете дяпеременной rotateCount значение 0, устанавливаете неинициализированную переменную, которая позже будет использоваться для хранения ссылки на вызов requestAnimationFrame(), и устанавливаете для переменной startTime значение null, которая будет позже использоваться для хранения времени начала requestAnimationFrame().

    - -
    const spinner = document.querySelector('div');
    -let rotateCount = 0;
    -let startTime = null;
    -let rAF;
    -
    -
  10. -
  11. -

    Под предыдущим кодом вставьте функцию draw() соторая будет использоваться для хранения нашешо кода анимации, который включает параметр timestamp :

    - -
    function draw(timestamp) {
    -
    -}
    -
  12. -
  13. -

    Внутри draw () добавьте следующие строки. Они определят время начала, если оно еще не определено (это произойдет только на первой итерации цикла), и установят для параметра rotateCount значение для поворота счетчика (текущая временная метка, возьмите начальную временную метку, разделенную на три, чтобы замедлиться):

    - -
      if (!startTime) {
    -   startTime = timestamp;
    -  }
    -
    -  rotateCount = (timestamp - startTime) / 3;
    -
    -
  14. -
  15. -

    Под предыдущей строкой внутри draw () добавьте следующий блок - он проверяет, превышает ли значение rotateCount 359 (например, 360, полный круг). Если это так, он устанавливает значение по модулю 360 (то есть остаток, оставшийся после деления значения на 360), поэтому круговая анимация может продолжаться непрерывно с разумным низким значением. Обратите внимание, что это не является строго необходимым, но легче работать со значениями от 0 до 359 градусов, чем со значениями типа «128000 градусов».

    - -
    if (rotateCount > 359) {
    -  rotateCount %= 360;
    -}
    -
  16. -
  17. Затем, под предыдущим блоком, добавьте следующую строку, чтобы вращать spinner: -
    spinner.style.transform = `rotate(${rotateCount}deg)`;
    -
  18. -
  19. -

    В самом низу внутри функции draw () вставьте следующую строку. Это ключ ко всей операции - вы устанавливаете для переменной, определенной ранее, активный вызов requestAnimation (), который принимает функцию draw () в качестве своего параметра. Это запускает анимацию, постоянно выполняя функцию draw () со скоростью, близкой к 60 FPS.

    - -
    rAF = requestAnimationFrame(draw);
    -
  20. -
  21. -

    Ниже, вызовите функцию draw() для запуска анимации.

    - -
    draw();
    -
  22. -
- -
-

Note: Вы можете посмотреть рабочий образец на GitHub. ( исходный код.)

-
- -

Очbстка вызова  requestAnimationFrame() 

- -

Очистить вызов requestAnimationFrame () можно, вызвав соответствующий метод cancelAnimationFrame (). (Обратите внимание, что имя функции начинается с «cancel», а не «clear», как у методов «set ...».)

- -

Просто передайте ему значение, возвращаемое вызовом requestAnimationFrame () для отмены, которое вы сохранили в переменной rAF:

- -
cancelAnimationFrame(rAF);
- -

Активное обучение: запуск и остановка нашей анимации

- -

В этом упражнении мы хотели бы, чтобы вы протестировали метод cancelAnimationFrame (), взяв наш предыдущий пример и обновив его, добавив прослушиватель событий для запуска и остановки счетчика при щелчке мышью в любом месте страницы.

- -

Подсказки:

- - - -
-

Note: Для начала попробуйте сами; если вы действительно застряли, посмотрите наш живой пример и исходный код.

-
- -

Регулировка анимации requestAnimationFrame() 

- -

Одним из ограничений requestAnimationFrame () является то, что вы не можете выбирать частоту кадров. В большинстве случаев это не проблема, так как обычно вы хотите, чтобы ваша анимация работала как можно плавнее. Но как насчет того, чтобы создать олдскульную 8-битную анимацию?

- -

Это было проблемой, например в анимации ходьбы, вдохновленной островом обезьян, из статьи Drawing Graphics:

- -

{{EmbedGHLiveSample("learning-area/javascript/apis/drawing-graphics/loops_animation/7_canvas_walking_animation.html", '100%', 260)}}

- -

В этом примере вы должны анимировать как положение персонажа на экране, так и отображаемый спрайт. В анимации спрайта всего 6 кадров. Если бы вы показывали разные кадры спрайта для каждого кадра, отображаемого на экране, с помощью requestAnimationFrame (), Guybrush двигал бы конечностями слишком быстро, и анимация выглядела бы нелепо. Следовательно, в этом примере регулируется скорость, с которой спрайт циклически повторяет свои кадры, используя следующий код:

- -
if (posX % 13 === 0) {
-  if (sprite === 5) {
-    sprite = 0;
-  } else {
-    sprite++;
-  }
-}
- -

Таким образом, код циклически повторяет спрайт только один раз каждые 13 кадров анимации.

- -

... Фактически, это примерно каждые 6,5 кадров, поскольку мы обновляем posX (положение персонажа на экране) на два кадра:

- -
if (posX > width/2) {
-  newStartPos = -( (width/2) + 102 );
-  posX = Math.ceil(newStartPos / 13) * 13;
-  console.log(posX);
-} else {
-  posX += 2;
-}
- -

Это код, который вычисляет, как обновлять позицию в каждом кадре анимации.

- -

Метод, который вы используете для регулирования анимации, будет зависеть от вашего конкретного кода. Например, в предыдущем примере счетчика вы могли заставить его двигаться медленнее, увеличивая rotateCount только на единицу в каждом кадре вместо двух.

- -

Активное обучение: игра на реакцию

- -

В последнем разделе этой статьи вы создадите игру на реакцию для двух игроков. В игре будет два игрока, один из которых управляет игрой с помощью клавиши A, а другой - с помощью клавиши L.

- -

При нажатии кнопки «Start» счетчик, подобный тому, что мы видели ранее, отображается в течение случайного промежутка времени от 5 до 10 секунд. По истечении этого времени появится сообщение «PLAYERS GO !!» - как только это произойдет, первый игрок, который нажмет свою кнопку управления, выиграет игру.

- -

{{EmbedGHLiveSample("learning-area/javascript/asynchronous/loops-and-intervals/reaction-game.html", '100%', 500)}}

- -

Давайте поработаем над этим:

- -
    -
  1. -

    Прежде всего, скачайте стартовый файл. Он содержит законченную структуру HTML и стили CSS, что дает нам игровую доску, которая показывает информацию двух игроков (как показано выше), но с счетчиком и параграфом результатов, отображаемыми друг над другом. Вам нужно просто написать JavaScript код.

    -
  2. -
  3. -

    Внутри пустого элемента {{htmlelement("script")}} на вашей старнице, начните с добавления следующих строк кода, котороые определяют некотороые переменные и константы, которые вам понадобятся в дальнейшем:

    - -
    const spinner = document.querySelector('.spinner p');
    -const spinnerContainer = document.querySelector('.spinner');
    -let rotateCount = 0;
    -let startTime = null;
    -let rAF;
    -const btn = document.querySelector('button');
    -const result = document.querySelector('.result');
    - -

    В следующем порядке:

    - -
      -
    1. Ссылка на спиннер, чтобы вы могли его анимировать.
    2. -
    3. Ссылка на элемент {{htmlelement("div")}} содержащий спиннер, используемый для отображения и скрытия.
    4. -
    5. Счетчик поворотов. Он определяет, на сколько вы хотите показывать вращение спиннера на каждом кадре анимации.
    6. -
    7. Нулевое время начала. Это будет заполнено временем начала, когда счетчик начнет вращаться.
    8. -
    9. Неинициализировання переменная для последующего хранения вызова {{domxref("Window.requestAnimationFrame", "requestAnimationFrame()")}} который анимирует спиннер.
    10. -
    11. Ссылка на кнопку Start .
    12. -
    13. Ссылка на параграф результатов.
    14. -
    -
  4. -
  5. -

    Ниже добавьте следующую функцию. Она просто берет два числа и возвращает случайное число между ними. Это понадобится вам позже, чтобы сгенерировать случайный интервал ожидания.

    - -
    function random(min,max) {
    -  var num = Math.floor(Math.random()*(max-min)) + min;
    -  return num;
    -}
    -
  6. -
  7. -

    Затем добавьте функцию draw(), которая анимирует спиннер. Это очень похоже на версию из предыдущего примера простого счетчика:

    - -
    function draw(timestamp) {
    -  if(!startTime) {
    -   startTime = timestamp;
    -  }
    -
    -  rotateCount = (timestamp - startTime) / 3;
    -
    -  if(rotateCount > 359) {
    -    rotateCount %= 360;
    -  }
    -
    -  spinner.style.transform = 'rotate(' + rotateCount + 'deg)';
    -  rAF = requestAnimationFrame(draw);
    -}
    -
  8. -
  9. -

    Теперь пришло время настроить начальное состояние приложения при первой загрузке страницы. Добавьте следующие две строки, которые просто скрывают абзац результатов и контейнер счетчика с помощью display: none ;.

    - -
    result.style.display = 'none';
    -spinnerContainer.style.display = 'none';
    -
  10. -
  11. -

    Затем определите функцию reset (), которая возвращает приложение в исходное состояние, необходимое для повторного запуска игры после ее завершения. Добавьте в конец кода следующее:

    - -
    function reset() {
    -  btn.style.display = 'block';
    -  result.textContent = '';
    -  result.style.display = 'none';
    -}
    -
  12. -
  13. -

    Хорошо, хватит подготовки! Пришло время сделать игру доступной! Добавьте в свой код следующий блок. Функция start () вызывает draw (), чтобы запустить вращение спиннера и отобразить его в пользовательском интерфейсе, скрыть кнопку Start, чтобы вы не могли испортить игру, запустив ее несколько раз одновременно, и запускает вызов setTimeout (), который выполняется функция setEndgame () по прошествии случайного интервала от 5 до 10 секунд. Следующий блок также добавляет прослушиватель событий к вашей кнопке для запуска функции start () при ее нажатии.

    - -
    btn.addEventListener('click', start);
    -
    -function start() {
    -  draw();
    -  spinnerContainer.style.display = 'block';
    -  btn.style.display = 'none';
    -  setTimeout(setEndgame, random(5000,10000));
    -}
    - -
    -

    Note: Вы увидете, что этот пример вызывает setTimeout() без сохранения возвращаемого значения. (не  let myTimeout = setTimeout(functionName, interval).) 

    - -

    Это прекрасно работает, если вам не нужно очищать интервал / тайм-аут в любой момент. Если вы это сделаете, вам нужно будет сохранить возвращенный идентификатор!

    -
    - -

    Конечным результатом предыдущего кода является то, что при нажатии кнопки «Start» отображается спиннер, и игроки вынуждены ждать произвольное количество времени, прежде чем их попросят нажать их кнопку. Эта последняя часть обрабатывается функцией setEndgame (), которую вы определите позже.

    -
  14. -
  15. -

    Добавьте в свой код следующую функцию:

    - -
    function setEndgame() {
    -  cancelAnimationFrame(rAF);
    -  spinnerContainer.style.display = 'none';
    -  result.style.display = 'block';
    -  result.textContent = 'PLAYERS GO!!';
    -
    -  document.addEventListener('keydown', keyHandler);
    -
    -  function keyHandler(e) {
    -    let isOver = false;
    -    console.log(e.key);
    -
    -    if (e.key === "a") {
    -      result.textContent = 'Player 1 won!!';
    -      isOver = true;
    -    } else if (e.key === "l") {
    -      result.textContent = 'Player 2 won!!';
    -      isOver = true;
    -    }
    -
    -    if (isOver) {
    -      document.removeEventListener('keydown', keyHandler);
    -      setTimeout(reset, 5000);
    -    }
    -  };
    -}
    - -

    Выполните следующие инструкции:

    - -
      -
    1. Во-первых, отмените анимацию спиннера с помощью {{domxref("window.cancelAnimationFrame", "cancelAnimationFrame()")}} (всегда полезно очистить ненужные процессы), и скройте контейнер счетчика.
    2. -
    3. Затем, отобразите абзац с результатами и установите для его текстового содержимого значение "PLAYERS GO!!"  чтобы сообщить игрокам, что теперь они могут нажать свою кнопку, чтобы победить.
    4. -
    5. Прикрепите к документу прослушиватель событий keydown . При нажатии любой кнопки запускается функция keyHandler().
    6. -
    7. Внутри keyHandler(), код включает обьект события в качестве параметра (представленного e) — его свойство {{domxref("KeyboardEvent.key", "key")}} содержит только что нажатую клавишу, и вы можете использовать это для твета на определенные нажатия клавиш определенными действиями.
    8. -
    9. Установите для переменной isOver значение false, чтобы мы могли отслеживать, были ли нажаты правильные клавиши, чтобы игрок 1 или 2 выиграл. Мы не хотим, чтобы игра заканчивалась при нажатии неправильной клваиши.
    10. -
    11. Регистрация e.key в консоли, это полезный способ узнать значение различных клавиш, которые вы нажимаете.
    12. -
    13. Когда e.key принимает значение "a", отобразить сообщение о том, что Player 1 выиграл, а когда e.key это "l", отобразить сообщение о том, что Player 2 выиграл. (Note: Это будет работать только со строчными буквами a и l — если переданы прописные A или L , это считается другими клавишами!) Если была нажата одна из этих клавиш, установите для isOver значение true.
    14. -
    15. Только еслиf isOver равно true, удалите прослушиватель событий keydown с помощью {{domxref("EventTarget.removeEventListener", "removeEventListener()")}} чтобы после того, как произошло выигрышное нажатие, больше не было возможности ввода с клавиатуры, чтобы испортить финальный результат игры. Вы также используете setTimeout() для вызова reset() через 5 секунд — как обьяснялось ранее, эта функция сбрасывает игру обратно в исходное состояние, чтобы можно было начать новую игру.
    16. -
    -
  16. -
- -

Вот и все - вы справились!

- -
-

Note: Если вы где то застряли, взгляните на наша версия игры (см. также исходный код ).

-
- -

Заключение

- -

Вот и все — все основы асинхронных циклов и интервалов рассмотрены в статье. Вы найдете эти методы полезными во многих ситуациях, но постарайтесь не злоупотреблять ими! Поскольку они по-прежнему выполняются в основном потоке, тяжелые и интенсивные обратные вызовы (особенно те, которые управляют DOM) могут действительно замедлить страницу, если вы не будете осторожныl.

- -

{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Introducing", "Learn/JavaScript/Asynchronous/Promises", "Learn/JavaScript/Asynchronous")}}

- -

В этом модуле

- - - -
-
-
diff --git a/files/ru/learn/javascript/building_blocks/events/index.html b/files/ru/learn/javascript/building_blocks/events/index.html new file mode 100644 index 0000000000..db13cec676 --- /dev/null +++ b/files/ru/learn/javascript/building_blocks/events/index.html @@ -0,0 +1,606 @@ +--- +title: Введение в события +slug: Learn/JavaScript/Building_blocks/События +tags: + - Изучение + - Обработчик событий + - Руководство + - события +translation_of: Learn/JavaScript/Building_blocks/Events +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Return_values","Learn/JavaScript/Building_blocks/Image_gallery", "Learn/JavaScript/Building_blocks")}}
+ +

События — это действия или случаи, возникающие в программируемой вами системе, о которых система сообщает вам для того, чтобы вы могли с ними взаимодействовать. Например, если пользователь нажимает кнопку на веб-странице, вы можете ответить на это действие, отобразив информационное окно. В этой статье мы обсудим некоторые важные концепции, связанные с событиями, и посмотрим, как они работают в браузерах. Эта статья не является исчерпывающим источником по этой теме — здесь только то, что вам нужно знать на этом этапе.

+ + + + + + + + + + + + +
Предпосылки:Базовая компьютерная грамотность, базовое понимание HTML и CSS, Первые шаги в JavaScript.
Задача:Понять фундаментальную теорию событий, как они работают в браузерах и как события могут различаться в разных средах программирования.
+ +

Серия удачных событий

+ +

При возникновении события система генерирует сигнал, а также предоставляет механизм, с помощью которого можно автоматически предпринимать какие-либо действия (например, выполнить определенный код), когда происходит событие. Например, в аэропорту, когда взлетно-посадочная полоса свободна для взлета самолета, сигнал передается пилоту, и в результате они приступают к взлету.

+ +

+ +

В Web события запускаются внутри окна браузера и, как правило, прикрепляются к конкретному элементу, который в нем находится. Это может быть один элемент, набор элементов, документ HTML, загруженный на текущей вкладке, или все окно браузера. Существует множество различных видов событий, которые могут произойти, например:

+ + + +

Подробнее о событиях можно посмотреть в Справочнике по событиям.

+ +

Каждое доступное событие имеет обработчик событий  блок кода (обычно это функция JavaScript, вводимая вами в качестве разработчика), который будет запускаться при срабатывании события. Когда такой блок кода определен на запуск в ответ на возникновение события, мы говорим, что мы регистрируем обработчик событий. Обратите внимание, что обработчики событий иногда называют прослушивателями событий (event listeners). Они в значительной степени взаимозаменяемы для наших целей, хотя, строго говоря, они работают вместе. Прослушиватель отслеживает событие, а обработчик — это код, который запускается в ответ на событие.

+ +
+

Примечание: Важно отметить, что веб-события не являются частью основного языка JavaScript. Они определены как часть JavaScript-API, встроенных в браузер.

+
+ +

Простой пример

+ +

Рассмотрим простой пример. Вы уже видели события и обработчики событий во многих примерах в этом курсе, но давайте повторим для закрепления информации. В этом примере у нас есть кнопка {{htmlelement ("button")}}, при нажатии которой цвет фона изменяется случайным образом:

+ +
<button>Change color</button>
+ + + +

JavaScript выглядит так:

+ +
const btn = document.querySelector('button');
+
+function random(number) {
+  return Math.floor(Math.random() * (number+1));
+}
+
+btn.onclick = function() {
+  const rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
+  document.body.style.backgroundColor = rndCol;
+}
+ +

В этом коде мы сохраняем ссылку на кнопку внутри переменной btn типа const, используя функцию {{domxref ("Document.querySelector()")}}. Мы также определяем функцию, которая возвращает случайное число. Третья часть кода — обработчик события. Переменная btn указывает на элемент <button> — для этого типа объекта существуют возникающие при определенном взаимодействии с ним события, а значит, возможно использование обработчиков событий. Мы отслеживаем момент возникновения события при щелчке мышью, связывая свойство обработчика события onclick с анонимной функцией, генерирующей случайный цвет RGB и устанавливающей его в качестве цвета фона элемента <body>.

+ +

Этот код теперь будет запускаться всякий раз, когда возникает событие при нажатии на элемент <button> — всякий раз, когда пользователь щелкает по нему.

+ +

Пример вывода выглядит следующим образом:

+ +

{{ EmbedLiveSample('Простой_пример', '100%', 200, "") }}

+ +

События не только для веб-страниц

+ +

События, как понятие, относятся не только к JavaScript — большинство языков программирования имеют модель событий, способ работы которой часто отличается от модели в JavaScript. Фактически, даже модель событий в JavaScript для веб-страниц отличается от модели событий для просто JavaScript, поскольку используются они в разных средах.

+ +

Например, Node.js — очень популярная среда исполнения JavaScript, которая позволяет разработчикам использовать JavaScript для создания сетевых и серверных приложений. Модель событий Node.js основана на том, что существуют прослушиватели, отслеживающие события, и эмиттеры (передатчики), которые периодически генерируют события. В общем-то, это похоже на модель событий в JavaScript для веб-страниц, но код совсем другой. В этой модели используется функция on() для регистрации прослушивателей событий, и функция once() для регистрации прослушивателя событий, который отключается после первого срабтывания. Хорошим примером использования являются протоколы событий HTTP connect event docs.

+ +

Вы также можете использовать JavaScript для создания кросс-браузерных расширений — улучшения функциональности браузера с помощью технологии WebExtensions. В отличии от модели веб-событий здесь свойства прослушивателей событий пишутся в так называемом регистре CamelCase (например, onMessage, а не onmessage) и должны сочетаться с функцией addListener. См. runtime.onMessage page для примера.

+ +

На данном этапе обучения вам не нужно особо разбираться в различных средах программирования, однако важно понимать, что принцип работы событий в них отличается.

+ +

Способы использования веб-событий

+ +

Существует множество различных способов добавления кода прослушивателя событий на веб-страницы так, чтобы он срабатывал при возникновении соответствующего события. В этом разделе мы рассмотрим различные механизмы и обсудим, какие из них следует использовать.

+ +

Свойства обработчика событий

+ +

В этом курсе вы уже сталкивались со свойствами, связываемыми с алгоритмом работы обработчика событий. Вернемся к приведенному выше примеру:

+ +
const btn = document.querySelector('button');
+
+btn.onclick = function() {
+  var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
+  document.body.style.backgroundColor = rndCol;
+}
+ +

В данной ситауции свойство onclick — это свойство обработчика события. В принципе это обычное свойство кнопки как элемента (наравне с btn.textContent или btn.style), но оно относится к особому типу. Если вы установите его равным какому-нибудь коду, этот код будет запущен при возникновении события (при нажатии на кнопку).

+ +

Для получения того же результата, Вы также можете присвоить свойству обработчика имя уже описанной функции (как мы видели в статье Создайте свою функцию):

+ +
const btn = document.querySelector('button');
+
+function bgChange() {
+  const rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
+  document.body.style.backgroundColor = rndCol;
+}
+
+btn.onclick = bgChange;
+ +

Давайте теперь поэкспериментируем с другими свойствами обработчика событий.

+ +

Создайте локальную копию файла random-color-eventhandlerproperty.html и откройте ее в своем браузере. Это всего лишь копия простого примера про случайные цвета, который мы уже разобрали в этой статье. Теперь попробуйте изменить btn.onclick на следующие значения и понаблюдайте за результатами:

+ + + +

Некоторые события очень общие и доступны практически в любом месте (например, обработчик onclick может быть зарегистрирован практически для любого элемента), тогда как некоторые из них более конкретны и полезны только в определенных ситуациях (например, имеет смысл использовать onplay только для определенных элементов, таких как {{htmlelement ("video")}}).

+ +

Встроенные обработчики событий - не используйте их

+ +

Самый ранний из введенных в сеть Web методов регистрации обработчиков событий базируется на HTML атрибутах (встроенные обработчики событий):

+ +
<button onclick="bgChange()">Press me</button>
+
+ +
function bgChange() {
+  const rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
+  document.body.style.backgroundColor = rndCol;
+}
+ +
+

Примечание: Вы можете найти полный исходник кода из этого примера на GitHub (также взгляните на его выполнение).

+
+ +

Значение атрибута —  это буквально код JavaScript, который вы хотите запустить при возникновении события. В приведенном выше примере вызывается функция, определенная внутри элемента {{htmlelement ("script")}} на той же странице, но вы также можете вставить JavaScript непосредственно внутри атрибута, например:

+ +
<button onclick="alert('Hello, this is my old-fashioned event handler!');">Press me</button>
+ +

Для многих свойств обработчика событий существуют эквиваленты в виде атрибутов HTML. Однако, не рекомендуется их использовать — это считается плохой практикой. Использование атрибутов для регистрации обработчика событий кажется простым и быстрым методом, но такое описание обработчиков также скоро становится неудобным и неэффективным.

+ +

Более того, не рекомендуется смешивать HTML и JavaScript файлы, так как в дальнейшем такой код становится сложнее с точки зрения обработки (парсинга). Лучше держать весь JavaScript в одном месте. Также, если он находится в отдельном файле, вы можете применить его к нескольким документам HTML.

+ +

Даже при работе только в одном файле использование встроенных обработчиков не является хорошей идеей. Ладно, если у Вас одна кнопка, но что, если у вас их 100? Вам нужно добавить в файл 100 атрибутов; обслуживание такого кода очень быстро превратится в кошмар. С помощью JavaScript вы можете легко добавить функцию обработчика событий ко всем кнопкам на странице независимо от того, сколько их было.

+ +

Например:

+ +
const buttons = document.querySelectorAll('button');
+
+for (var i = 0; i < buttons.length; i++) {
+  buttons[i].onclick = bgChange;
+}
+ +

Обратите внимание, что для перебора всех элементов, которые содержит объект NodeList, можно воспользоваться встроенным методом forEach():

+ +
buttons.forEach(function(button) {
+  button.onclick = bgChange;
+});
+ +
+

Примечание: Разделение логики Вашей программы и Вашего контента также делает Ваш сайт более дружественным к поисковым системам.

+
+ +

Функции addEventListener() и removeEventListener()

+ +

Новый тип механизма событий определен в спецификации Document Object Model (DOM) Level 2 Events, которая предоставляет браузеру новую функцию — addEventListener(). Работает она аналогично свойствам обработчика событий, но синтаксис совсем другой. Наш пример со случайным цветом мог бы выглядеть и так:

+ +
var btn = document.querySelector('button');
+
+function bgChange() {
+  var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
+  document.body.style.backgroundColor = rndCol;
+}
+
+btn.addEventListener('click', bgChange);
+ +
+

Примечание: Вы можете найти исходный код из этого примера на GitHub (также взгляните на его выполнение).

+
+ +

Внутри функции addEventListener() мы указываем два параметра — имя события, для которого мы хотим зарегистрировать этот обработчик, и код, содержащий функцию обработчика, которую мы хотим запустить в ответ. Обратите внимание, что будет целесообразно поместить весь код внутри функции addEventListener() в анонимную функцию, например:

+ +
btn.addEventListener('click', function() {
+  var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
+  document.body.style.backgroundColor = rndCol;
+});
+ +

Этот механизм имеет некоторые преимущества по сравнению с более старыми механизмами, рассмотренными ранее. Например, существует аналогичная функция removeEventListener(), которая удаляет ранее добавленный прослушиватель. Это приведет к удалению набора слушателей в первом блоке кода в этом разделе:

+ +
btn.removeEventListener('click', bgChange);
+ +

Это не важно для простых небольших программ, но для более крупных и более сложных программ он может повысить эффективность очистки старых неиспользуемых обработчиков событий. Кроме того, это позволяет вам иметь одну и ту же кнопку, выполняющую различные действия в разных обстоятельствах — все, что вам нужно сделать, это добавить/удалить обработчики событий, если это необходимо.

+ +

Также, вы можете зарегистрировать несколько обработчиков для одного и того же прослушивателя. Следующие два обработчика не будут применяться:

+ +
myElement.onclick = functionA;
+myElement.onclick = functionB;
+ +

Поскольку вторая строка будет перезаписывать значение onclick, установленное первой. Однако, если:

+ +
myElement.addEventListener('click', functionA);
+myElement.addEventListener('click', functionB);
+ +

Обе функции будут выполняться при щелчке элемента.

+ +

Кроме того, в этом механизме событий имеется ряд других мощных функций и опций. Эта тема выходит за рамки данной статьи, но если вы хотите изучить подробнее, переходите по ссылкам: Метод Event​Target​.add​Event​Listener() и Метод Event​Target​.remove​Event​Listener().

+ +

Какой механизм мне использовать?

+ +

Из трех механизмов определенно не нужно использовать атрибуты событий HTML. Как упоминалось выше, это устаревшая и плохая практика.

+ +

Остальные два являются относительно взаимозаменяемыми, по крайней мере для простых целей

+ + + +

Основные преимущества третьего механизма заключаются в том, что при необходимости можно удалить код обработчика событий, используя removeEventListener(), и так же можно добавить несколько элементов-слушателей того же типа к элементам. Например, вы можете вызвать addEventListener('click', function() {...}) для элемента несколько раз, с разными функциями, указанными во втором аргументе. Это невозможно при использовании свойств обработчика событий, поскольку любые последующие попытки установить свойство будут перезаписывать более ранние, например:

+ +
element.onclick = function1;
+element.onclick = function2;
+etc.
+ +
+

Примечание: Если вам требуется поддержка браузеров старше Internet Explorer 8 в вашем проекте, вы можете столкнуться с трудностями, так как такие старые браузеры используют старые модели событий из более новых браузеров. Но не бойтесь, большинство библиотек JavaScript (например, jQuery) имеют встроенные функции, которые абстрагируют различия между браузерами. Не беспокойтесь об этом слишком много на этапе вашего учебного путешествия.

+
+ +

Другие концепции событий

+ +

Рассмотрим некоторые современные концепции, имеющие отношение к событиям. На данный момент не обязательно понимать их полностью, но предстывление о них поможет лучше понять некоторые модели кода, с которыми вы, вероятно, столкнетесь.

+ +

   Объекты событий

+ +

Иногда внутри функции обработчика событий вы можете увидеть параметр, заданный с таким именем, как event, evt или просто e. Называется он объектом события и он автоматически передается обработчикам событий для предоставления дополнительных функций и информации. Например, давайте немного перепишем наш прмер со случайным цветом:

+ +
function bgChange(e) {
+  var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
+  e.target.style.backgroundColor = rndCol;
+  console.log(e);
+}
+
+btn.addEventListener('click', bgChange);
+ +
+

Примечание: Вы можете найти исходник кода для этого примера на GitHub (также взгляните на его выполнение).

+
+ +

Итак в коде выше мы включаем объект события e в функцию, а в функции — настройку стиля фона для e.target, который является кнопкой. Свойство объекта события target всегда является ссылкой на элемент, с которым только что произошло событие. Поэтому в этом примере мы устанавливаем случайный цвет фона на кнопке, а не на странице.

+ +
+

Примечание: Вместо e/evt/event можно использовать любое имя для объекта события, которое затем можно использовать для ссылки на него в функции обработчика событий. e/evt/event чаще всего используются разработчиками, потому что они короткие и легко запоминаются. И хорошо придерживаться стандарта.

+
+ +

e.target применяют, когда нужно установить один и тот же обработчик событий на несколько элементов и, когда на них происходит событие, применить определенное действие к ним ко всем. Например, у вас может быть набор из 16 плиток, которые исчезают при нажатии. Полезно всегда иметь возможность просто указать, чтобы объект исчез, как e.target, вместо того, чтобы выбирать его более сложным способом. В следующем примере (см. исходный код на  useful-eventtarget.html,а как он работает можно посмотреть здесь), мы создаем 16 элементов {{htmlelement ("div")}} с использованием JavaScript. Затем мы выберем все из них, используя {{domxref ("document.querySelectorAll()")}}, и с помощью цикла for выберем каждый из них, добавив обработчик onclick к каждому так, чтобы случайный цвет применялся к каждому клику:

+ +
var divs = document.querySelectorAll('div');
+
+for (var i = 0; i < divs.length; i++) {
+  divs[i].onclick = function(e) {
+    e.target.style.backgroundColor = bgChange();
+  }
+}
+ +

Результат выглядит следующим образом (попробуйте щелкнуть по нему):

+ + + +

{{ EmbedLiveSample('Hidden_example', '100%', 400) }}

+ +

Большинство обработчиков событий, с которыми вы столкнулись, имеют только стандартный набор свойств и функций (методов), доступных для объекта события (см. {{domxref("Event")}} для ссылки на полный список). Однако некоторые более продвинутые обработчики добавляют специальные свойства, содержащие дополнительные данные, которые им необходимо выполнять. Например, Media Recorder API имеет событие, доступное для данных, которое срабатывает, когда записано какое-либо аудио или видео и доступно для выполнения чего-либо (например, для сохранения или воспроизведения). Соответствующий объект события ondataavailable handler имеет свойство данных, содержащее записанные аудио- или видеоданные, чтобы вы могли получить к нему доступ и что-то сделать с ним.

+ +

    Предотвращение поведения по умолчанию

+ +

Иногда бывают ситуации, когда нужно остановить событие, выполняющее то, что оно делает по умолчанию. Наиболее распространенным примером является веб-форма, например, пользовательская форма регистрации. Когда вы вводите данные и нажимаете кнопку отправки, естественное поведение заключается в том, что данные должны быть отправлены на указанную страницу на сервере для обработки, а браузер перенаправлется на страницу с сообщением об успехе (или остаться на той же странице, если другое не указано).

+ +

Но если пользователь отправил данные не правильно, как разработчик, вы хотите остановить отправку на сервер и выдать сообщение об ошибке с информацией о том, что не так и что нужно сделать. Некоторые браузеры поддерживают функции автоматической проверки данных формы, но, поскольку многие этого не делают, вам не следует полагаться на них и выполнять свои собственные проверки валидации. Давайте посмотрим на простой пример.

+ +

Простая форма HTML, в которой требуется ввести ваше имя и фамилию:

+ +
<form>
+  <div>
+    <label for="fname">Имя: </label>
+    <input id="fname" type="text">
+  </div>
+  <div>
+    <label for="lname">Фамилия: </label>
+    <input id="lname" type="text">
+  </div>
+  <div>
+     <input id="submit" type="submit">
+  </div>
+</form>
+<p></p>
+ + + +

В JavaScript мы реализуем очень простую проверку внутри обработчика события onsubmit (событие "отправить" запускается в форме, когда оно отправлено), который проверяет, пусты ли текстовые поля. Если они пусты, мы вызываем функцию preventDefault() объекта события, которая останавливает отправку формы, а затем выводит сообщение об ошибке в абзаце ниже нашей формы, чтобы сообщить пользователю, что не так:

+ +
var form = document.querySelector('form');
+var fname = document.getElementById('fname');
+var lname = document.getElementById('lname');
+var submit = document.getElementById('submit');
+var para = document.querySelector('p');
+
+form.onsubmit = function(e) {
+  if (fname.value === '' || lname.value === '') {
+    e.preventDefault();
+    para.textContent = 'Оба поля должны быть заполнены!';
+  }
+}
+ +

Очевидно, что это довольно слабая проверка формы - это не помешает пользователю отправить форму с пробелами или цифрами, введенными в поля, но для примера подходит. Вывод выглядит следующим образом:

+ +

{{ EmbedLiveSample('Предотвращение_поведения_по_умолчанию', '100%', 140) }}

+ +
+

Примечание: чтобы увидеть исходный код, откройте preventdefault-validation.html (также запустите здесь).

+
+ +

Всплытие и перехват событий

+ +

Последним предметом для рассмотрения в этой теме является то, с чем вы не часто будете сталкиваться, но это может стать настоящей головной болью, если вы не поймете, как работает следующий механизм. Всплытие и перехват событий — два механизма, описывающих, что происходит, когда два обработчика одного и того же события активируются на одном элементе. Посмотрим на пример. Чтобы сделать это проще — откройте пример show-video-box.html в одной вкладке и исходный код в другой вкладке. Он также представлен ниже:

+ + + +

{{ EmbedLiveSample('Hidden_video_example', '100%', 500) }}

+ +

Это довольно простой пример, который показывает и скрывает {{htmlelement ("div")}} с элементом {{htmlelement ("video")}} внутри него:

+ +
<button>Display video</button>
+
+<div class="hidden">
+  <video>
+    <source src="rabbit320.mp4" type="video/mp4">
+    <source src="rabbit320.webm" type="video/webm">
+    <p>Your browser doesn't support HTML5 video. Here is a <a href="rabbit320.mp4">link to the video</a> instead.</p>
+  </video>
+</div>
+ +

При нажатии на кнопку {{htmlelement ("button")}}, изменяется атрибут класса элемента <div> с hidden на showing (CSS примера содержит эти два класса, которые размещают блок вне экрана и на экране соответственно):

+ +
div {
+        position: absolute;
+        top: 50%;
+        transform: translate(-50%,-50%);
+        ...
+      }
+.hidden {
+   left: -50%;
+  }
+.showing {
+   left: 50%;
+  }
+ +
var btn = document.querySelector('button');
+btn.onclick = function() {
+  videoBox.setAttribute('class', 'showing');
+}
+ +

Затем мы добавляем еще пару обработчиков событий onclick. Первый к <div>, а второй к <video>. Идея заключается в том, чтобы при щелчке по области <div> вне зоны видео поле снова скрылось, а при клике в области <video>  видео начало воспроизводиться.

+ +
var videoBox = document.querySelector('div');
+var video = document.querySelector('video');
+
+videoBox.onclick = function() {
+  videoBox.setAttribute('class', 'hidden');
+};
+
+video.onclick = function() {
+  video.play();
+};
+ +

Но есть проблема: когда вы нажимаете на видео, оно начинает воспроизводиться, но одновременно вызывает скрытие <div>. Это связано с тем, что видео находится внутри <div>, это часть его, поэтому нажатие на видео фактически запускает оба вышеуказанных обработчика событий.

+ +

Всплытие и перехват событий — концепция выполнения

+ +

Когда событие инициируется элементом, который имеет родительские элементы (например, {{htmlelement ("video")}} в нашем случае), современные браузеры выполняют две разные фазы —  фазу  захвата и фазу всплытия.

+ +

На стадии захвата происходит следующее:

+ + + +

На стадии всплытия происходит полная противоположность:

+ + + +

+ +

(Нажмите на изображение, чтобы увеличить диаграмму)

+ +

В современных браузерах по умолчанию все обработчики событий регистрируются в фазе всплытия. Итак, в нашем текущем примере, когда вы нажимаете видео, событие click вызывается из элемента <video> наружу, в элемент <html>. По пути:

+ + + +

Исправление проблемы с помощью stopPropagation()

+ +

Чтобы исправить это раздражающее поведение, стандартный объект события имеет функцию, называемую stopPropagation(), которая при вызове в обработчике событий объекта делает так, чтобы обработчик выполнялся, но событие не всплывало дальше по цепочке, поэтому не будут запускаться другие обработчики.

+ +

Поэтому мы можем исправить нашу текущую проблему, изменив вторую функцию-обработчик в предыдущем блоке кода:

+ +
video.onclick = function(e) {
+  e.stopPropagation();
+  video.play();
+};
+ +

Вы можете попробовать создать локальную копию show-video-box.html и попробовать его самостоятельно исправить или просмотреть исправленный результат в show-video-box-fixed.html (также см. исходный код здесь).

+ +
Примечание: Зачем беспокоиться как с захватом, так и с всплыванием? Что ж, в старые добрые времена, когда браузеры были менее совместимы, чем сейчас, Netscape использовал только захват событий, а Internet Explorer использовал только всплывающие события. Когда W3C решил попытаться стандартизировать поведение и достичь консенсуса, они в итоге получили эту систему, которая включала в себя и то, и другое, что реализовано в одном из современных браузеров.
+ +
+

Примечание: Как упоминалось выше, по умолчанию все обработчики событий регистрируются в фазе всплытия и это имеет смысл в большинстве случаев. Если вы действительно хотите зарегистрировать событие в фазе захвата, вы можете сделать это, зарегистрировав обработчик с помощью addEventListener() и установив для третьего дополнительного свойства значение true.

+
+ +

Делегирование события

+ +

Всплытие также позволяет нам использовать делегирование событий.  Если у какого-либо родительского элемента есть множество дочерних элементов, и вы хотите, чтобы определенный код выполнялся при щелчке (событии) на каждом из дочерних элементов, можно установить прослушиватель событий на родительском элементе и события, происходящие на дочерних элементах будут всплывать до их родителя. При этом не нужно устанавливать прослушивателя событий на каждом дочернем элементе.

+ +

Хорошим примером является серия элементов списка. Если вы хотите, чтобы каждый из них, например, отображал сообщение при нажатии, вы можете установить прослушиватель событий click для родительского элемента <ul> и он будет всплывать в элементах списка.

+ +

Эту концепцию объясняет в своем блоге Дэвид Уолш, где приводит несколько примеров. (см. How JavaScript Event Delegation Works.)

+ +

Вывод

+ +

Это все, что вам нужно знать о веб-событиях на этом этапе. Как уже упоминалось, события не являются частью основного JavaScript — они определены в веб-интерфейсах браузера (Web API).

+ +

Кроме того, важно понимать, что различные контексты, в которых используется JavaScript, обычно имеют разные модели событий — от веб-API до других областей, таких как браузерные WebExtensions и Node.js (серверный JavaScript). Может сейчас вы не особо в этом разбираетесь, но по мере изучения веб-разработки начнет приходить более ясное понимание тематики.

+ +

Если у вас возникли вопросы, попробуйте прочесть статью снова или обратитесь за помощью к нам.

+ +

См. также

+ + + +

{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Return_values","Learn/JavaScript/Building_blocks/Image_gallery", "Learn/JavaScript/Building_blocks")}}

+ +

В этом модуле

+ + + +
+
+ +
+
diff --git "a/files/ru/learn/javascript/building_blocks/\321\201\320\276\320\261\321\213\321\202\320\270\321\217/index.html" "b/files/ru/learn/javascript/building_blocks/\321\201\320\276\320\261\321\213\321\202\320\270\321\217/index.html" deleted file mode 100644 index db13cec676..0000000000 --- "a/files/ru/learn/javascript/building_blocks/\321\201\320\276\320\261\321\213\321\202\320\270\321\217/index.html" +++ /dev/null @@ -1,606 +0,0 @@ ---- -title: Введение в события -slug: Learn/JavaScript/Building_blocks/События -tags: - - Изучение - - Обработчик событий - - Руководство - - события -translation_of: Learn/JavaScript/Building_blocks/Events ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Return_values","Learn/JavaScript/Building_blocks/Image_gallery", "Learn/JavaScript/Building_blocks")}}
- -

События — это действия или случаи, возникающие в программируемой вами системе, о которых система сообщает вам для того, чтобы вы могли с ними взаимодействовать. Например, если пользователь нажимает кнопку на веб-странице, вы можете ответить на это действие, отобразив информационное окно. В этой статье мы обсудим некоторые важные концепции, связанные с событиями, и посмотрим, как они работают в браузерах. Эта статья не является исчерпывающим источником по этой теме — здесь только то, что вам нужно знать на этом этапе.

- - - - - - - - - - - - -
Предпосылки:Базовая компьютерная грамотность, базовое понимание HTML и CSS, Первые шаги в JavaScript.
Задача:Понять фундаментальную теорию событий, как они работают в браузерах и как события могут различаться в разных средах программирования.
- -

Серия удачных событий

- -

При возникновении события система генерирует сигнал, а также предоставляет механизм, с помощью которого можно автоматически предпринимать какие-либо действия (например, выполнить определенный код), когда происходит событие. Например, в аэропорту, когда взлетно-посадочная полоса свободна для взлета самолета, сигнал передается пилоту, и в результате они приступают к взлету.

- -

- -

В Web события запускаются внутри окна браузера и, как правило, прикрепляются к конкретному элементу, который в нем находится. Это может быть один элемент, набор элементов, документ HTML, загруженный на текущей вкладке, или все окно браузера. Существует множество различных видов событий, которые могут произойти, например:

- - - -

Подробнее о событиях можно посмотреть в Справочнике по событиям.

- -

Каждое доступное событие имеет обработчик событий  блок кода (обычно это функция JavaScript, вводимая вами в качестве разработчика), который будет запускаться при срабатывании события. Когда такой блок кода определен на запуск в ответ на возникновение события, мы говорим, что мы регистрируем обработчик событий. Обратите внимание, что обработчики событий иногда называют прослушивателями событий (event listeners). Они в значительной степени взаимозаменяемы для наших целей, хотя, строго говоря, они работают вместе. Прослушиватель отслеживает событие, а обработчик — это код, который запускается в ответ на событие.

- -
-

Примечание: Важно отметить, что веб-события не являются частью основного языка JavaScript. Они определены как часть JavaScript-API, встроенных в браузер.

-
- -

Простой пример

- -

Рассмотрим простой пример. Вы уже видели события и обработчики событий во многих примерах в этом курсе, но давайте повторим для закрепления информации. В этом примере у нас есть кнопка {{htmlelement ("button")}}, при нажатии которой цвет фона изменяется случайным образом:

- -
<button>Change color</button>
- - - -

JavaScript выглядит так:

- -
const btn = document.querySelector('button');
-
-function random(number) {
-  return Math.floor(Math.random() * (number+1));
-}
-
-btn.onclick = function() {
-  const rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
-  document.body.style.backgroundColor = rndCol;
-}
- -

В этом коде мы сохраняем ссылку на кнопку внутри переменной btn типа const, используя функцию {{domxref ("Document.querySelector()")}}. Мы также определяем функцию, которая возвращает случайное число. Третья часть кода — обработчик события. Переменная btn указывает на элемент <button> — для этого типа объекта существуют возникающие при определенном взаимодействии с ним события, а значит, возможно использование обработчиков событий. Мы отслеживаем момент возникновения события при щелчке мышью, связывая свойство обработчика события onclick с анонимной функцией, генерирующей случайный цвет RGB и устанавливающей его в качестве цвета фона элемента <body>.

- -

Этот код теперь будет запускаться всякий раз, когда возникает событие при нажатии на элемент <button> — всякий раз, когда пользователь щелкает по нему.

- -

Пример вывода выглядит следующим образом:

- -

{{ EmbedLiveSample('Простой_пример', '100%', 200, "") }}

- -

События не только для веб-страниц

- -

События, как понятие, относятся не только к JavaScript — большинство языков программирования имеют модель событий, способ работы которой часто отличается от модели в JavaScript. Фактически, даже модель событий в JavaScript для веб-страниц отличается от модели событий для просто JavaScript, поскольку используются они в разных средах.

- -

Например, Node.js — очень популярная среда исполнения JavaScript, которая позволяет разработчикам использовать JavaScript для создания сетевых и серверных приложений. Модель событий Node.js основана на том, что существуют прослушиватели, отслеживающие события, и эмиттеры (передатчики), которые периодически генерируют события. В общем-то, это похоже на модель событий в JavaScript для веб-страниц, но код совсем другой. В этой модели используется функция on() для регистрации прослушивателей событий, и функция once() для регистрации прослушивателя событий, который отключается после первого срабтывания. Хорошим примером использования являются протоколы событий HTTP connect event docs.

- -

Вы также можете использовать JavaScript для создания кросс-браузерных расширений — улучшения функциональности браузера с помощью технологии WebExtensions. В отличии от модели веб-событий здесь свойства прослушивателей событий пишутся в так называемом регистре CamelCase (например, onMessage, а не onmessage) и должны сочетаться с функцией addListener. См. runtime.onMessage page для примера.

- -

На данном этапе обучения вам не нужно особо разбираться в различных средах программирования, однако важно понимать, что принцип работы событий в них отличается.

- -

Способы использования веб-событий

- -

Существует множество различных способов добавления кода прослушивателя событий на веб-страницы так, чтобы он срабатывал при возникновении соответствующего события. В этом разделе мы рассмотрим различные механизмы и обсудим, какие из них следует использовать.

- -

Свойства обработчика событий

- -

В этом курсе вы уже сталкивались со свойствами, связываемыми с алгоритмом работы обработчика событий. Вернемся к приведенному выше примеру:

- -
const btn = document.querySelector('button');
-
-btn.onclick = function() {
-  var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
-  document.body.style.backgroundColor = rndCol;
-}
- -

В данной ситауции свойство onclick — это свойство обработчика события. В принципе это обычное свойство кнопки как элемента (наравне с btn.textContent или btn.style), но оно относится к особому типу. Если вы установите его равным какому-нибудь коду, этот код будет запущен при возникновении события (при нажатии на кнопку).

- -

Для получения того же результата, Вы также можете присвоить свойству обработчика имя уже описанной функции (как мы видели в статье Создайте свою функцию):

- -
const btn = document.querySelector('button');
-
-function bgChange() {
-  const rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
-  document.body.style.backgroundColor = rndCol;
-}
-
-btn.onclick = bgChange;
- -

Давайте теперь поэкспериментируем с другими свойствами обработчика событий.

- -

Создайте локальную копию файла random-color-eventhandlerproperty.html и откройте ее в своем браузере. Это всего лишь копия простого примера про случайные цвета, который мы уже разобрали в этой статье. Теперь попробуйте изменить btn.onclick на следующие значения и понаблюдайте за результатами:

- - - -

Некоторые события очень общие и доступны практически в любом месте (например, обработчик onclick может быть зарегистрирован практически для любого элемента), тогда как некоторые из них более конкретны и полезны только в определенных ситуациях (например, имеет смысл использовать onplay только для определенных элементов, таких как {{htmlelement ("video")}}).

- -

Встроенные обработчики событий - не используйте их

- -

Самый ранний из введенных в сеть Web методов регистрации обработчиков событий базируется на HTML атрибутах (встроенные обработчики событий):

- -
<button onclick="bgChange()">Press me</button>
-
- -
function bgChange() {
-  const rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
-  document.body.style.backgroundColor = rndCol;
-}
- -
-

Примечание: Вы можете найти полный исходник кода из этого примера на GitHub (также взгляните на его выполнение).

-
- -

Значение атрибута —  это буквально код JavaScript, который вы хотите запустить при возникновении события. В приведенном выше примере вызывается функция, определенная внутри элемента {{htmlelement ("script")}} на той же странице, но вы также можете вставить JavaScript непосредственно внутри атрибута, например:

- -
<button onclick="alert('Hello, this is my old-fashioned event handler!');">Press me</button>
- -

Для многих свойств обработчика событий существуют эквиваленты в виде атрибутов HTML. Однако, не рекомендуется их использовать — это считается плохой практикой. Использование атрибутов для регистрации обработчика событий кажется простым и быстрым методом, но такое описание обработчиков также скоро становится неудобным и неэффективным.

- -

Более того, не рекомендуется смешивать HTML и JavaScript файлы, так как в дальнейшем такой код становится сложнее с точки зрения обработки (парсинга). Лучше держать весь JavaScript в одном месте. Также, если он находится в отдельном файле, вы можете применить его к нескольким документам HTML.

- -

Даже при работе только в одном файле использование встроенных обработчиков не является хорошей идеей. Ладно, если у Вас одна кнопка, но что, если у вас их 100? Вам нужно добавить в файл 100 атрибутов; обслуживание такого кода очень быстро превратится в кошмар. С помощью JavaScript вы можете легко добавить функцию обработчика событий ко всем кнопкам на странице независимо от того, сколько их было.

- -

Например:

- -
const buttons = document.querySelectorAll('button');
-
-for (var i = 0; i < buttons.length; i++) {
-  buttons[i].onclick = bgChange;
-}
- -

Обратите внимание, что для перебора всех элементов, которые содержит объект NodeList, можно воспользоваться встроенным методом forEach():

- -
buttons.forEach(function(button) {
-  button.onclick = bgChange;
-});
- -
-

Примечание: Разделение логики Вашей программы и Вашего контента также делает Ваш сайт более дружественным к поисковым системам.

-
- -

Функции addEventListener() и removeEventListener()

- -

Новый тип механизма событий определен в спецификации Document Object Model (DOM) Level 2 Events, которая предоставляет браузеру новую функцию — addEventListener(). Работает она аналогично свойствам обработчика событий, но синтаксис совсем другой. Наш пример со случайным цветом мог бы выглядеть и так:

- -
var btn = document.querySelector('button');
-
-function bgChange() {
-  var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
-  document.body.style.backgroundColor = rndCol;
-}
-
-btn.addEventListener('click', bgChange);
- -
-

Примечание: Вы можете найти исходный код из этого примера на GitHub (также взгляните на его выполнение).

-
- -

Внутри функции addEventListener() мы указываем два параметра — имя события, для которого мы хотим зарегистрировать этот обработчик, и код, содержащий функцию обработчика, которую мы хотим запустить в ответ. Обратите внимание, что будет целесообразно поместить весь код внутри функции addEventListener() в анонимную функцию, например:

- -
btn.addEventListener('click', function() {
-  var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
-  document.body.style.backgroundColor = rndCol;
-});
- -

Этот механизм имеет некоторые преимущества по сравнению с более старыми механизмами, рассмотренными ранее. Например, существует аналогичная функция removeEventListener(), которая удаляет ранее добавленный прослушиватель. Это приведет к удалению набора слушателей в первом блоке кода в этом разделе:

- -
btn.removeEventListener('click', bgChange);
- -

Это не важно для простых небольших программ, но для более крупных и более сложных программ он может повысить эффективность очистки старых неиспользуемых обработчиков событий. Кроме того, это позволяет вам иметь одну и ту же кнопку, выполняющую различные действия в разных обстоятельствах — все, что вам нужно сделать, это добавить/удалить обработчики событий, если это необходимо.

- -

Также, вы можете зарегистрировать несколько обработчиков для одного и того же прослушивателя. Следующие два обработчика не будут применяться:

- -
myElement.onclick = functionA;
-myElement.onclick = functionB;
- -

Поскольку вторая строка будет перезаписывать значение onclick, установленное первой. Однако, если:

- -
myElement.addEventListener('click', functionA);
-myElement.addEventListener('click', functionB);
- -

Обе функции будут выполняться при щелчке элемента.

- -

Кроме того, в этом механизме событий имеется ряд других мощных функций и опций. Эта тема выходит за рамки данной статьи, но если вы хотите изучить подробнее, переходите по ссылкам: Метод Event​Target​.add​Event​Listener() и Метод Event​Target​.remove​Event​Listener().

- -

Какой механизм мне использовать?

- -

Из трех механизмов определенно не нужно использовать атрибуты событий HTML. Как упоминалось выше, это устаревшая и плохая практика.

- -

Остальные два являются относительно взаимозаменяемыми, по крайней мере для простых целей

- - - -

Основные преимущества третьего механизма заключаются в том, что при необходимости можно удалить код обработчика событий, используя removeEventListener(), и так же можно добавить несколько элементов-слушателей того же типа к элементам. Например, вы можете вызвать addEventListener('click', function() {...}) для элемента несколько раз, с разными функциями, указанными во втором аргументе. Это невозможно при использовании свойств обработчика событий, поскольку любые последующие попытки установить свойство будут перезаписывать более ранние, например:

- -
element.onclick = function1;
-element.onclick = function2;
-etc.
- -
-

Примечание: Если вам требуется поддержка браузеров старше Internet Explorer 8 в вашем проекте, вы можете столкнуться с трудностями, так как такие старые браузеры используют старые модели событий из более новых браузеров. Но не бойтесь, большинство библиотек JavaScript (например, jQuery) имеют встроенные функции, которые абстрагируют различия между браузерами. Не беспокойтесь об этом слишком много на этапе вашего учебного путешествия.

-
- -

Другие концепции событий

- -

Рассмотрим некоторые современные концепции, имеющие отношение к событиям. На данный момент не обязательно понимать их полностью, но предстывление о них поможет лучше понять некоторые модели кода, с которыми вы, вероятно, столкнетесь.

- -

   Объекты событий

- -

Иногда внутри функции обработчика событий вы можете увидеть параметр, заданный с таким именем, как event, evt или просто e. Называется он объектом события и он автоматически передается обработчикам событий для предоставления дополнительных функций и информации. Например, давайте немного перепишем наш прмер со случайным цветом:

- -
function bgChange(e) {
-  var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
-  e.target.style.backgroundColor = rndCol;
-  console.log(e);
-}
-
-btn.addEventListener('click', bgChange);
- -
-

Примечание: Вы можете найти исходник кода для этого примера на GitHub (также взгляните на его выполнение).

-
- -

Итак в коде выше мы включаем объект события e в функцию, а в функции — настройку стиля фона для e.target, который является кнопкой. Свойство объекта события target всегда является ссылкой на элемент, с которым только что произошло событие. Поэтому в этом примере мы устанавливаем случайный цвет фона на кнопке, а не на странице.

- -
-

Примечание: Вместо e/evt/event можно использовать любое имя для объекта события, которое затем можно использовать для ссылки на него в функции обработчика событий. e/evt/event чаще всего используются разработчиками, потому что они короткие и легко запоминаются. И хорошо придерживаться стандарта.

-
- -

e.target применяют, когда нужно установить один и тот же обработчик событий на несколько элементов и, когда на них происходит событие, применить определенное действие к ним ко всем. Например, у вас может быть набор из 16 плиток, которые исчезают при нажатии. Полезно всегда иметь возможность просто указать, чтобы объект исчез, как e.target, вместо того, чтобы выбирать его более сложным способом. В следующем примере (см. исходный код на  useful-eventtarget.html,а как он работает можно посмотреть здесь), мы создаем 16 элементов {{htmlelement ("div")}} с использованием JavaScript. Затем мы выберем все из них, используя {{domxref ("document.querySelectorAll()")}}, и с помощью цикла for выберем каждый из них, добавив обработчик onclick к каждому так, чтобы случайный цвет применялся к каждому клику:

- -
var divs = document.querySelectorAll('div');
-
-for (var i = 0; i < divs.length; i++) {
-  divs[i].onclick = function(e) {
-    e.target.style.backgroundColor = bgChange();
-  }
-}
- -

Результат выглядит следующим образом (попробуйте щелкнуть по нему):

- - - -

{{ EmbedLiveSample('Hidden_example', '100%', 400) }}

- -

Большинство обработчиков событий, с которыми вы столкнулись, имеют только стандартный набор свойств и функций (методов), доступных для объекта события (см. {{domxref("Event")}} для ссылки на полный список). Однако некоторые более продвинутые обработчики добавляют специальные свойства, содержащие дополнительные данные, которые им необходимо выполнять. Например, Media Recorder API имеет событие, доступное для данных, которое срабатывает, когда записано какое-либо аудио или видео и доступно для выполнения чего-либо (например, для сохранения или воспроизведения). Соответствующий объект события ondataavailable handler имеет свойство данных, содержащее записанные аудио- или видеоданные, чтобы вы могли получить к нему доступ и что-то сделать с ним.

- -

    Предотвращение поведения по умолчанию

- -

Иногда бывают ситуации, когда нужно остановить событие, выполняющее то, что оно делает по умолчанию. Наиболее распространенным примером является веб-форма, например, пользовательская форма регистрации. Когда вы вводите данные и нажимаете кнопку отправки, естественное поведение заключается в том, что данные должны быть отправлены на указанную страницу на сервере для обработки, а браузер перенаправлется на страницу с сообщением об успехе (или остаться на той же странице, если другое не указано).

- -

Но если пользователь отправил данные не правильно, как разработчик, вы хотите остановить отправку на сервер и выдать сообщение об ошибке с информацией о том, что не так и что нужно сделать. Некоторые браузеры поддерживают функции автоматической проверки данных формы, но, поскольку многие этого не делают, вам не следует полагаться на них и выполнять свои собственные проверки валидации. Давайте посмотрим на простой пример.

- -

Простая форма HTML, в которой требуется ввести ваше имя и фамилию:

- -
<form>
-  <div>
-    <label for="fname">Имя: </label>
-    <input id="fname" type="text">
-  </div>
-  <div>
-    <label for="lname">Фамилия: </label>
-    <input id="lname" type="text">
-  </div>
-  <div>
-     <input id="submit" type="submit">
-  </div>
-</form>
-<p></p>
- - - -

В JavaScript мы реализуем очень простую проверку внутри обработчика события onsubmit (событие "отправить" запускается в форме, когда оно отправлено), который проверяет, пусты ли текстовые поля. Если они пусты, мы вызываем функцию preventDefault() объекта события, которая останавливает отправку формы, а затем выводит сообщение об ошибке в абзаце ниже нашей формы, чтобы сообщить пользователю, что не так:

- -
var form = document.querySelector('form');
-var fname = document.getElementById('fname');
-var lname = document.getElementById('lname');
-var submit = document.getElementById('submit');
-var para = document.querySelector('p');
-
-form.onsubmit = function(e) {
-  if (fname.value === '' || lname.value === '') {
-    e.preventDefault();
-    para.textContent = 'Оба поля должны быть заполнены!';
-  }
-}
- -

Очевидно, что это довольно слабая проверка формы - это не помешает пользователю отправить форму с пробелами или цифрами, введенными в поля, но для примера подходит. Вывод выглядит следующим образом:

- -

{{ EmbedLiveSample('Предотвращение_поведения_по_умолчанию', '100%', 140) }}

- -
-

Примечание: чтобы увидеть исходный код, откройте preventdefault-validation.html (также запустите здесь).

-
- -

Всплытие и перехват событий

- -

Последним предметом для рассмотрения в этой теме является то, с чем вы не часто будете сталкиваться, но это может стать настоящей головной болью, если вы не поймете, как работает следующий механизм. Всплытие и перехват событий — два механизма, описывающих, что происходит, когда два обработчика одного и того же события активируются на одном элементе. Посмотрим на пример. Чтобы сделать это проще — откройте пример show-video-box.html в одной вкладке и исходный код в другой вкладке. Он также представлен ниже:

- - - -

{{ EmbedLiveSample('Hidden_video_example', '100%', 500) }}

- -

Это довольно простой пример, который показывает и скрывает {{htmlelement ("div")}} с элементом {{htmlelement ("video")}} внутри него:

- -
<button>Display video</button>
-
-<div class="hidden">
-  <video>
-    <source src="rabbit320.mp4" type="video/mp4">
-    <source src="rabbit320.webm" type="video/webm">
-    <p>Your browser doesn't support HTML5 video. Here is a <a href="rabbit320.mp4">link to the video</a> instead.</p>
-  </video>
-</div>
- -

При нажатии на кнопку {{htmlelement ("button")}}, изменяется атрибут класса элемента <div> с hidden на showing (CSS примера содержит эти два класса, которые размещают блок вне экрана и на экране соответственно):

- -
div {
-        position: absolute;
-        top: 50%;
-        transform: translate(-50%,-50%);
-        ...
-      }
-.hidden {
-   left: -50%;
-  }
-.showing {
-   left: 50%;
-  }
- -
var btn = document.querySelector('button');
-btn.onclick = function() {
-  videoBox.setAttribute('class', 'showing');
-}
- -

Затем мы добавляем еще пару обработчиков событий onclick. Первый к <div>, а второй к <video>. Идея заключается в том, чтобы при щелчке по области <div> вне зоны видео поле снова скрылось, а при клике в области <video>  видео начало воспроизводиться.

- -
var videoBox = document.querySelector('div');
-var video = document.querySelector('video');
-
-videoBox.onclick = function() {
-  videoBox.setAttribute('class', 'hidden');
-};
-
-video.onclick = function() {
-  video.play();
-};
- -

Но есть проблема: когда вы нажимаете на видео, оно начинает воспроизводиться, но одновременно вызывает скрытие <div>. Это связано с тем, что видео находится внутри <div>, это часть его, поэтому нажатие на видео фактически запускает оба вышеуказанных обработчика событий.

- -

Всплытие и перехват событий — концепция выполнения

- -

Когда событие инициируется элементом, который имеет родительские элементы (например, {{htmlelement ("video")}} в нашем случае), современные браузеры выполняют две разные фазы —  фазу  захвата и фазу всплытия.

- -

На стадии захвата происходит следующее:

- - - -

На стадии всплытия происходит полная противоположность:

- - - -

- -

(Нажмите на изображение, чтобы увеличить диаграмму)

- -

В современных браузерах по умолчанию все обработчики событий регистрируются в фазе всплытия. Итак, в нашем текущем примере, когда вы нажимаете видео, событие click вызывается из элемента <video> наружу, в элемент <html>. По пути:

- - - -

Исправление проблемы с помощью stopPropagation()

- -

Чтобы исправить это раздражающее поведение, стандартный объект события имеет функцию, называемую stopPropagation(), которая при вызове в обработчике событий объекта делает так, чтобы обработчик выполнялся, но событие не всплывало дальше по цепочке, поэтому не будут запускаться другие обработчики.

- -

Поэтому мы можем исправить нашу текущую проблему, изменив вторую функцию-обработчик в предыдущем блоке кода:

- -
video.onclick = function(e) {
-  e.stopPropagation();
-  video.play();
-};
- -

Вы можете попробовать создать локальную копию show-video-box.html и попробовать его самостоятельно исправить или просмотреть исправленный результат в show-video-box-fixed.html (также см. исходный код здесь).

- -
Примечание: Зачем беспокоиться как с захватом, так и с всплыванием? Что ж, в старые добрые времена, когда браузеры были менее совместимы, чем сейчас, Netscape использовал только захват событий, а Internet Explorer использовал только всплывающие события. Когда W3C решил попытаться стандартизировать поведение и достичь консенсуса, они в итоге получили эту систему, которая включала в себя и то, и другое, что реализовано в одном из современных браузеров.
- -
-

Примечание: Как упоминалось выше, по умолчанию все обработчики событий регистрируются в фазе всплытия и это имеет смысл в большинстве случаев. Если вы действительно хотите зарегистрировать событие в фазе захвата, вы можете сделать это, зарегистрировав обработчик с помощью addEventListener() и установив для третьего дополнительного свойства значение true.

-
- -

Делегирование события

- -

Всплытие также позволяет нам использовать делегирование событий.  Если у какого-либо родительского элемента есть множество дочерних элементов, и вы хотите, чтобы определенный код выполнялся при щелчке (событии) на каждом из дочерних элементов, можно установить прослушиватель событий на родительском элементе и события, происходящие на дочерних элементах будут всплывать до их родителя. При этом не нужно устанавливать прослушивателя событий на каждом дочернем элементе.

- -

Хорошим примером является серия элементов списка. Если вы хотите, чтобы каждый из них, например, отображал сообщение при нажатии, вы можете установить прослушиватель событий click для родительского элемента <ul> и он будет всплывать в элементах списка.

- -

Эту концепцию объясняет в своем блоге Дэвид Уолш, где приводит несколько примеров. (см. How JavaScript Event Delegation Works.)

- -

Вывод

- -

Это все, что вам нужно знать о веб-событиях на этом этапе. Как уже упоминалось, события не являются частью основного JavaScript — они определены в веб-интерфейсах браузера (Web API).

- -

Кроме того, важно понимать, что различные контексты, в которых используется JavaScript, обычно имеют разные модели событий — от веб-API до других областей, таких как браузерные WebExtensions и Node.js (серверный JavaScript). Может сейчас вы не особо в этом разбираетесь, но по мере изучения веб-разработки начнет приходить более ясное понимание тематики.

- -

Если у вас возникли вопросы, попробуйте прочесть статью снова или обратитесь за помощью к нам.

- -

См. также

- - - -

{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Return_values","Learn/JavaScript/Building_blocks/Image_gallery", "Learn/JavaScript/Building_blocks")}}

- -

В этом модуле

- - - -
-
- -
-
diff --git a/files/ru/learn/javascript/first_steps/a_first_splash/index.html b/files/ru/learn/javascript/first_steps/a_first_splash/index.html new file mode 100644 index 0000000000..b2a811b992 --- /dev/null +++ b/files/ru/learn/javascript/first_steps/a_first_splash/index.html @@ -0,0 +1,675 @@ +--- +title: Первое погружение в JavaScript +slug: Learn/JavaScript/Первые_шаги/A_first_splash +translation_of: Learn/JavaScript/First_steps/A_first_splash +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/What_is_JavaScript", "Learn/JavaScript/Первые_шаги/Что_пошло_не_так", "Learn/JavaScript/Первые_шаги")}}
+ +

Теперь, когда вы получили базовое представление о JavaScript — самое время познакомиться с ним на практике! В данной статье представлен ускоренный практический курс, демонстрирующий основные возможности JavaScript. В этом курсе, шаг за шагом, вы создадите простую игру «Угадай число».

+ + + + + + + + + + + + +
Необходимые навыки:Базовая компьютерная грамотность, знание основ HTML и CSS, понимание что такое и для чего нужен JavaScript.
Цели:Получение первого опыта в программировании на JavaScript.
+ +

Вам не придется сразу понимать весь код — мы только хотим познакомить вас с базовыми концепциями языка и дать представление о том, как работает JavaScript (и другие языки программирования). В дальнейших статьях вы изучите эти концепции более подробно!

+ +
+

Большинство языковых конструкций JavaScript, с которыми вы познакомитесь (функции, циклы и т.д.), имеют аналоги в других языках программирования — т.е. языки имеют разный синтаксис, но концепции в большинстве случаев те же самые.

+
+ +

Думай как программист

+ +

Одним из самых трудных и значимых моментов в обучении программированию является не изучение непосредственно синтаксиса языка, а понимание того как применять его для решения реальных задач. Вам нужно начать думать как программист, обычно это означает следующее:

+ + + +

Всё вместе это потребует тяжелой работы, знания языка, практики в написании кода - и немного творчества. Чем больше вы будете заняты решением практических задач, тем быстрее будете расти в программировании. Мы не обещаем, что вы сразу начнете "думать как программист", но предоставим для этого достаточно возможностей в этой статье.

+ +

Учитывая вышесказанное, на примере простой игры, давайте детально разберем каждый этап создания программы и познакомимся с некоторыми конструкциями языка.

+ +

Игра «Угадай число»

+ +

В этой статье мы покажем вам как создать простую игру, которую вы видите ниже:

+ + + +

{{ EmbedLiveSample('Top_hidden_code', '100%', 320) }}

+ +

Поиграйте в нее - познакомьтесь с игрой, прежде чем двигаться дальше.

+ +

Давайте представим, что ваш босс дал вам следующую информацию для создания этой игры:

+ +
+

Я хочу чтобы ты создал простую игру по принципу "Угадай число". Игра должна случайным образом генерировать число от 0 до 100, затем игрок должен отгадать это число за 10 попыток. После каждой попытки игроку сообщают угадал он число или не угадал и если он ошибся, то ему сообщается, что загаданное число больше или меньше того, которое он ввел. Так же необходимо показывать игроку числа из его предыдущих попыток. Игра будет окончена, если игрок угадал число верно или если у него кончатся все попытки. После окончания игры игроку будет дана возможность сыграть в игру еще раз.

+
+ +

Поглядев на это краткое изложение, первое, что мы можем сделать - это начать разбивать его на простые действия, максимально думая как программист:

+ +
    +
  1. Сгенерировать случайное число между 1 и 100.
  2. +
  3. Начать запись количества попыток игрока угадать число. Начать с 1.
  4. +
  5. Предоставить попытку угадать игроку загаданное число.
  6. +
  7. Как только попытка угадать была отправлена, сначала записать ее где-нибудь, чтобы пользователь мог увидеть свои предыдущие попытки
  8. +
  9. Далее, проверить было ли это число верным.
  10. +
  11. Если число верное: +
      +
    1. Показать поздравительное сообщение.
    2. +
    3. Оградить игрока от дальнейшей возможности ввода чисел (это испортит игру).
    4. +
    5. Предоставить возможность для перезапуска игры.
    6. +
    +
  12. +
  13. Если число не верное и есть попытки: +
      +
    1. Сказать игроку, что он не угадал.
    2. +
    3. Разрешить ему использовать еще попытку.
    4. +
    5. Повысить число попыток на 1.
    6. +
    +
  14. +
  15. Если число не верное и попыток нет: +
      +
    1. Сказать игроку, что игра окончена.
    2. +
    3. Оградить игрока от дальнейшей возможности ввода чисел (это испортит игру).
    4. +
    5. Предоставить возможность для перезапуска игры.
    6. +
    +
  16. +
  17. Во время перезапуска игры убедиться, что игровая логика и пользовательский интерфейс полностью сбросились на начальные значения и далее перейти обратно к пункту 1.
  18. +
+ +

Давайте теперь перейдем к рассмотрению того, как мы можем превратить эти шаги в код, создавая примеры и исследуя возможности JavaScript по ходу.

+ +

Подготовка

+ +

В начале этого урока, мы хотели бы, чтобы вы создали локальную копию файла  number-guessing-game-start.html  (см. здесь).  Откройте его как в текстовом редакторе, так и в веб-браузере. На данный момент вы увидите простой заголовок, абзац с инструкцией и форму для ввода предположения, но форма в настоящее время ничего не сделает.

+ +

Место, где мы будем добавлять весь наш код, находится внутри элемента {{htmlelement("script")}} в нижней части HTML:

+ +
<script>
+
+  // Your JavaScript goes here
+
+</script>
+
+ +

Добавление переменных для хранения данных

+ +

Давайте начнем. Прежде всего добавьте следующие строки внутри элемента  {{htmlelement("script")}} :

+ +
var randomNumber = Math.floor(Math.random() * 100) + 1;
+
+var guesses = document.querySelector('.guesses');
+var lastResult = document.querySelector('.lastResult');
+var lowOrHi = document.querySelector('.lowOrHi');
+
+var guessSubmit = document.querySelector('.guessSubmit');
+var guessField = document.querySelector('.guessField');
+
+var guessCount = 1;
+var resetButton;
+ +

В этом разделе кода устанавливаются переменные, необходимые для хранения данных, которые будет использоваться нашей программой. Переменные - это в основном контейнеры для значений (например, числа или строки текста). Вы создаете переменную с ключевым словом var, за которой следует имя для вашей переменной. Затем вы можете присвоить значение своей переменной знак равенства (=), за которым следует значение, которое вы хотите дать.

+ +

В нашем примере:

+ + + +
+

Заметка: В дальнейшем вы узнаете намного больше о переменных, в следующей статье.

+
+ +

Функции (Functions)

+ +

Затем добавьте следующие ниже предыдущего JavaScript:

+ +
function checkGuess() {
+  alert('I am a placeholder');
+}
+ +

Функции представляют собой многократно используемые блоки кода, написав один раз вы можете запускать их снова и снова, сохраняя нужный постоянно повторяющийся код. Это действительно полезно. Существует несколько способов определить функцию, но пока мы сосредоточимся на одном простом варианте. Здесь мы определили функцию используя ключевое слово function, за ним идет имя с двумя скобками после него. После этого мы добавляем две фигурные скобки ({ }). Внутри фигурных скобок содержится весь код, запускающийся всякий раз, когда вызываем функцию.

+ +

Код запускается вводом имени функции, за которым следуют две скобки.

+ +

Сейчас попробуйте сохранить код и обновить его в браузере.

+ +

Перейдите к консоли JavaScript в инструментах разработчика, и введите следующую строку:

+ +
checkGuess();
+ +

Вы должны увидеть предупреждение, в котором говорится "I am a placeholder"; в нашем коде мы определили функцию, которая создает предупреждение, когда ее вызывают.

+ +
+

Заметка: В дальнейшем вы намного больше узнаете о функциях.

+
+ +

Операторы (Operators)

+ +

Операторы JavaScript позволяют нам проводить проверки, математические рассчеты, объединять строки вместе и выполнять другие подобные действия.

+ +

Сохраните наш код и обновите страницу показанную в браузере. Откройте консоль JavaScript, если вы еще её не открыли, чтобы попробовать ввести текст из приведенных ниже примеров — введите каждую строчку из столбца "Пример", нажимая Enter после каждого из них, и посмотрите какие результаты они возвращают. Если у вас нет доступа к инструментам разработчика в браузере, вы всегда можете использовать простую встроенную консоль, показанную ниже:

+ + + +

{{ EmbedLiveSample('Hidden_code', '100%', 300) }}

+ +

Сначала давайте посмотрим на арифметические операторы, например:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ОператорИмяПример
+Сложение6 + 9
-Вычитание20 - 15
*Умножение3 * 7
/Деление10 / 5
+ +

Вы также можете использовать оператор + для сложения строк текста (в программировании это называется конкатенацией). Попробуйте ввести следующие строки:

+ +
var name = 'Bingo';
+name;
+var hello = ' says hello!';
+hello;
+var greeting = name + hello;
+greeting;
+ +

Также есть сокращенные операторы, называемые расширенными операторами присваивания. Например, если вы просто хотите добавить новую строку к существующей и вернуть результат, вы можете сделать так:

+ +
name += ' says hello!';
+ +

Это эквивалентно этому:

+ +
name = name + ' says hello!';
+ +

Когда мы запускаем проверку true/false (истина/ложь) (например, внутри условных выражений — смотри {{anch("Conditionals", "ниже")}}), мы используем операторы сравнения, например:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ОператорИмяПример
===Строгое равенство (это точно одно и то же?)5 === 2 + 4
!==Строгое неравенство (это не одно и то же?)'Chris' !== 'Ch' + 'ris'
<Меньше чем10 < 6
>Больше чем10 > 20
+ +

Условные выражения (Conditionals)

+ +

Вернемся к нашей функции checkGuess(), я думаю, можно с уверенностью сказать, что мы не хотим, чтобы она просто выводила сообщение заполнитель. Мы хотим, чтобы она проверяла сделал игрок правильный выбор или нет, и соответсвующе реагировала.

+ +

Теперь, заменим вашу текущую функциюcheckGuess() на эту версию:

+ +
function checkGuess() {
+  var userGuess = Number(guessField.value);
+  if (guessCount === 1) {
+    guesses.textContent = 'Previous guesses: ';
+  }
+  guesses.textContent += userGuess + ' ';
+
+  if (userGuess === randomNumber) {
+    lastResult.textContent = 'Congratulations! You got it right!';
+    lastResult.style.backgroundColor = 'green';
+    lowOrHi.textContent = '';
+    setGameOver();
+  } else if (guessCount === 10) {
+    lastResult.textContent = '!!!GAME OVER!!!';
+    setGameOver();
+  } else {
+    lastResult.textContent = 'Wrong!';
+    lastResult.style.backgroundColor = 'red';
+    if(userGuess < randomNumber) {
+      lowOrHi.textContent = 'Last guess was too low!';
+    } else if(userGuess > randomNumber) {
+      lowOrHi.textContent = 'Last guess was too high!';
+    }
+  }
+
+  guessCount++;
+  guessField.value = '';
+  guessField.focus();
+}
+ +

Как много кода — фу! Давайте отдельно рассмотрим каждый раздел и объясним, что он делает.

+ + + +

События (Events)

+ +

На данный момент у нас есть хорошо реализованная функция checkGuess(), но она ничего не сделает, потому что мы еще не вызвали ее. В идеале мы хотим вызывать её во время нажатия кнопки « Submit guess », и для этого нам нужно использовать событие. События - это действия, которые происходят в браузере, например, нажатие кнопки или загрузка страницы или воспроизведение видео, в ответ на которые мы можем запускать блоки кода. Конструкции, которые прослушивают событие, называются прослушивателями событий, а блоки кода, выполняемые в ответ на срабатывание событий, называются обработчиками событий.

+ +

Добавьте следующую строку ниже закрывающей фигурной скобки функции checkGuess():

+ +
guessSubmit.addEventListener('click', checkGuess);
+ +

Здесь мы добавляем прослушиватель событий к кнопке guessSubmit. Это метод, который принимает два входных значения (называемые аргументами) - тип события, которое мы выслушиваем (в данном случае click) в виде строки, и код, который мы хотим запустить при возникновении события (в данном случае функция checkGuess() - обратите внимание, что нам не нужно указывать круглые скобки при записи внутри {{domxref("EventTarget.addEventListener", "addEventListener()")}}).

+ +

Попробуйте сохранить и обновить код сейчас, и ваш пример должен теперь работать, но до определенного момента. Единственная проблема в том, что если вы угадаете правильный ответ или исчерпаете догадки, игра сломается, потому что мы еще не определили функцию setGameOver(), которая должна запускаться после завершения игры. Давайте добавим наш недостающий код и завершим пример функциональности.

+ +

Завершение игры

+ +

Давайте добавим функцию setGameOver() в конец нашего кода, а затем пройдем по ней. Добавьте это под нижней частью вашего JavaScript:

+ +
function setGameOver() {
+  guessField.disabled = true;
+  guessSubmit.disabled = true;
+  resetButton = document.createElement('button');
+  resetButton.textContent = 'Start new game';
+  document.body.appendChild(resetButton);
+  resetButton.addEventListener('click', resetGame);
+}
+ + + +

Теперь нам нужно также определить эту функцию! Добавьте следующий код, снова в нижнюю часть вашего JavaScript:

+ +
function resetGame() {
+  guessCount = 1;
+
+  var resetParas = document.querySelectorAll('.resultParas p');
+  for (var i = 0 ; i < resetParas.length ; i++) {
+    resetParas[i].textContent = '';
+  }
+
+  resetButton.parentNode.removeChild(resetButton);
+
+  guessField.disabled = false;
+  guessSubmit.disabled = false;
+  guessField.value = '';
+  guessField.focus();
+
+  lastResult.style.backgroundColor = 'white';
+
+  randomNumber = Math.floor(Math.random() * 100) + 1;
+}
+ +

Этот довольно длинный блок кода полностью сбрасывает все на то, как это было в начале игры, поэтому у игрока может быть еще один ход. Это:

+ + + +

С этого момента у вас есть полностью работающая (простая) игра - поздравляем!

+ +

Все, что нам осталось сделать в этой статье, - это поговорить о нескольких других важных функциях кода, которые вы уже видели, хотя вы, возможно, этого не осознали.

+ +

Циклы (Loops) 

+ +
+
+
Одна часть вышеприведенного кода, которую мы должны рассмотреть более подробно, - это цикл for. Циклы - очень важная концепция программирования, которая позволяет вам снова и снова запускать кусок кода, пока не будет выполнено определенное условие.
+ +
Для начала перейдите в панель инструментов разработчика JavaScript-консоли и введите следующее:
+
+
+ +
for (var i = 1 ; i < 21 ; i++) { console.log(i) }
+ +

Что случилось? Номера с 1 по 20 были напечатаны в консоли. Это из-за цикла. Цикл for принимает три входных значения (аргументы):
+ Начальное значение: в этом случае мы начинаем подсчет c 1, но это может быть любое число которое вам нравится. Вы можете заменить i любым другим именем, которое вам нравится, но я использую его как условность, потому что оно короткое и легко запоминается. Условие выхода: Здесь мы указали i <21 - цикл будет продолжаться до тех пор, пока i будет меньше 21. Когда i достигнет 21, цикл больше не будет работать. Инкремент: мы указали i ++, что означает «увеличить i на 1». Цикл будет выполняться один раз для каждого значения i, пока оно не достигнет значения 21 (как обсуждалось выше). В этом случае мы просто печатаем значение i в консоли на каждой итерации с помощью {{domxref ("Console.log", "console.log ()")}}.

+ +

Теперь давайте посмотрим на цикл в нашей игре угадывания чисел - в функции resetGame () можно найти следующее:

+ +
var resetParas = document.querySelectorAll('.resultParas p');
+for (var i = 0 ; i < resetParas.length ; i++) {
+  resetParas[i].textContent = '';
+}
+ +

Этот код создает переменную, содержащую список всех абзацев внутри <div class = "resultParas">, используя метод {{domxref ("Document.querySelectorAll", "querySelectorAll ()")}}, затем он проходит через каждый из них, удаляя текстовое содержимое каждого из них.

+ +

Немного об объектах (Objects)

+ +

Давайте добавим еще одно окончательное улучшение, прежде чем перейти к обсуждению. Добавьте следующую строку чуть ниже var resetButton; в верхней части вашего JavaScript, затем сохраните файл:

+ +
guessField.focus();
+ +

Эта строка использует метод {{domxref("HTMLElement.focus", "focus()")}}, чтобы автоматически помещать текстовый курсор в текстовое поле {{htmlelement("input")}}, как только загрузится страница. Пользователь сможет сразу набрать свою первую догадку, не нажимая поле формы. Это всего лишь небольшое дополнение, но оно улучшает удобство использования - дает пользователю хорошую визуальную подсказку относительно того, что они должны делать в игре.

+ +

Давайте проанализируем, что произошло. В JavaScript все элементы являются объектами. Объект - это набор связанных функций, хранящихся в одной группе. Вы можете создавать собственные объекты, но это требует мастерства, и мы не хотели бы раскрывать эту тему в рамках данного курса. Будет достаточно обсудить встроенные объекты вашего браузера, которые позволяют реализовывать множество полезных вещей.

+ +

В нашем примере мы сначала создали переменную guessField, которая запоминает значение из поля ввода в нашем HTML - следующая строка находится среди первых в нашем коде:

+ +
var guessField = document.querySelector('.guessField');
+ +

Чтобы получить это значение, мы использовали метод {{domxref("document.querySelector", "querySelector()")}} объекта {{domxref("document")}}. querySelector() "берет" одну часть информации -  CSS selector, который выбирает нужный элемент.

+ +

Поскольку guessField теперь содержит ссылку на элемент {{htmlelement("input")}}, теперь он будет иметь доступ к ряду свойств (в основном к переменным, хранящимся внутри объектов, некоторые значения которых нельзя изменять) и методы (в основном функции, хранящиеся внутри объектов). Одним из методов, доступных для ввода элементов, является focus (), поэтому мы можем теперь использовать эту строку для фокусировки ввода текста:

+ +
guessField.focus();
+ +

Для переменных, которые не содержат ссылок на элементы формы, не будет доступен focus(). Например, переменная guesses содержит ссылку на элемент {{htmlelement ("p")}}, а guessCount содержит число.

+ +

Поиграем с объектами браузера

+ +

Давайте немного поиграем с некоторыми объектами браузера.

+ +
    +
  1. Для начала запустите свою программу в браузере.
  2. +
  3. Далее, откройте инструменты разработчика в вашем браузере, и убедитесь, что вы перешли во вкладку с консолью JavaScript.
  4. +
  5. Введите guessField и консоль покажет, что переменная содержит элемент {{htmlelement("input")}}. Вы также можете заметить, что консоль автоматически заполняет имена объектов, которые существуют внутри исполняющей среды, включая ваши переменные!
  6. +
  7. Теперь введите следующее: +
    guessField.value = 'Hello';
    + Свойство value представляет текущее значение, введенное в текстовое поле. Заметьте, что, введя эту команду, мы изменили его!
  8. +
  9. Попробуйте ввести guesses и нажать return. Консоль покажет, что в переменной содержится элемент {{htmlelement("p")}}.
  10. +
  11. Теперь попробуйте ввести: +
    guesses.value
    + Браузер вернет вам undefined, потому что value не существует в параграфах.
  12. +
  13. Для изменения текста внутри параграфа, взамен используйте свойство {{domxref("Node.textContent", "textContent")}}. Попробуйте: +
    guesses.textContent = 'Where is my paragraph?';
    +
  14. +
  15. Теперь немного повеселимся. Попробуйте ввести следующие строки, одну за другой: +
    guesses.style.backgroundColor = 'yellow';
    +guesses.style.fontSize = '200%';
    +guesses.style.padding = '10px';
    +guesses.style.boxShadow = '3px 3px 6px black';
    + Каждый элемент на странице имеет свойство style, которое само по себе содержит объект, свойства которого содержат все встроенные стили CSS, применяемые к этому элементу. Это позволяет нам динамически задавать новые стили CSS для элементов с помощью JavaScript.
  16. +
+ +

Теперь можно отдохнуть...

+ +

Итак, на этом пример закончился - отлично, вы добрались до конца! Попробуйте свой финальный код или поиграйте с нашей готовой версией здесь. Если вы не можете запустить этот пример, сверьтесь с исходным кодом.

+ +

{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/What_is_JavaScript", "Learn/JavaScript/Первые_шаги/Что_пошло_не_так", "Learn/JavaScript/Первые_шаги")}}

diff --git a/files/ru/learn/javascript/first_steps/arrays/index.html b/files/ru/learn/javascript/first_steps/arrays/index.html new file mode 100644 index 0000000000..7f38ce4a50 --- /dev/null +++ b/files/ru/learn/javascript/first_steps/arrays/index.html @@ -0,0 +1,678 @@ +--- +title: Массивы +slug: Learn/JavaScript/Первые_шаги/Arrays +tags: + - JavaScript + - Pop + - Push + - shift + - unshift + - Для начинающих + - Массивы + - Статья +translation_of: Learn/JavaScript/First_steps/Arrays +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/Useful_string_methods", "Learn/JavaScript/Первые_шаги/Создатель_глуых_историй", "Learn/JavaScript/Первые_шаги")}}
+ +

В финальной статье этого раздела, мы познакомимся с массивами — лаконичным способом хранения списка элементов под одним именем. Мы поймем, чем они полезны, затем узнаем, как создать массив, получить, добавить и удалить элементы, хранящиеся в массиве.

+ + + + + + + + + + + + +
Необходимые навыки:Базовая компьютерная грамотность, базовое понимание HTML и CSS, понимание о том, что такое JavaScript.
Цель:Понять, что такое массивы и как использовать их в JavaScript.
+ +

Что такое массив?

+ +

Массивы обычно описываются как «объекты, подобные спискам»; они представляют собой в основном отдельные объекты, которые содержат несколько значений, хранящихся в списке. Объекты массива могут храниться в переменных и обрабатываться во многом так же, как и любой другой тип значения, причем разница заключается в том, что мы можем получить доступ к каждому значению внутри списка отдельно и делать супер полезные и эффективные вещи со списком, а также делать то же самое для каждого из значений. Представим, что у нас есть список продуктов и их цены, хранящиеся в массиве, и мы хотим их просмотреть и распечатать на счете-фактуре, общая сумма всех цен и распечатка общей цены внизу.

+ +

Если бы у нас не было массивов, мы должны были бы хранить каждый элемент в отдельной переменной, а затем вызывать код, выполняющий печать и добавляющий отдельно каждый элемент. Написание такого кода займет намного больше времени, сам код будет менее эффективным и подверженным  ошибкам. Если бы у нас было 10 элементов для добавления в счет-фактуру, это еще куда ни шло, но как насчет 100 предметов? Или 1000? Мы вернемся к этому примеру позже в статье.

+ +

Как и в предыдущих статьях, давайте узнаем о реальных основах массивов, введя некоторые примеры в консоль JavaScript. Мы предоставили один ниже (вы также можете open this console в отдельном окне, или использовать browser developer console, если вам угодно).

+ + + +

{{ EmbedLiveSample('Hidden_code', '100%', 300) }}

+ +

Создание массива

+ +

Массивы создаются из квадратных скобок , которые содержат список элементов, разделённых запятыми.

+ +
    +
  1. Допустим, мы бы хотели хранить список покупок в массиве — мы бы сделали что-то вроде этого. Введите следующие строчки в вашу консоль: +
    var shopping = ['bread', 'milk', 'cheese', 'hummus', 'noodles'];
    +shopping;
    +
  2. +
  3. В данном случае, каждый элемент в массиве — это строка , но имейте в виду, что вы можете хранить любой элемент в массиве — строку, число, объект, другую переменную, даже другой массив. Вы также можете перемешивать типы элементов — они не должны все быть числами, строками, и так далее. Попробуйте это: +
    var sequence = [1, 1, 2, 3, 5, 8, 13];
    +var random = ['tree', 795, [0, 1, 2]];
    +
  4. +
  5. Попробуйте сами создать несколько массивов, перед тем как двигаться дальше.
  6. +
+ +

Получение и изменение элементов массива

+ +

Вы можете после этого получать доступ к отдельным элементам в массиве, используя квадратные скобки, таким же способом каким вы получаете доступ к буквам в строке.

+ +
    +
  1. Введите следующее в вашу консоль: +
    shopping[0];
    +// возвращает "bread"
    +
  2. +
  3. Вы также можете изменять элемент в массиве, просто дав отдельному элементу массива новое значение. Попробуйте это: +
    shopping[0] = 'tahini';
    +shopping;
    +// shopping теперь возвратит [ "tahini", "milk", "cheese", "hummus", "noodles" ]
    + +
    Заметка: Мы уже упоминали это прежде, но просто как напоминание — компьютеры начинают считать с нуля!
    +
  4. +
  5. Заметьте, что массив внутри массива называется многомерным массивом. Вы можете получить доступ к элементу внутри массива, который сам находится внутри другого массива, объединив два набора квадратных скобок. Например, для доступа к одному из элементов внутри массива, который является третьим элементом внутри массива random (см. предыдущую секцию данной статьи), мы могли бы сделать что-то вроде этого: +
    random[2][2];
    +
  6. +
  7. Попробуйте внести некоторые дополнительные изменения в свои примеры массивов, прежде чем двигаться дальше.
  8. +
+ +

Нахождение длины массива

+ +

Вы можете найти длину массива (количество элементов в нём) точно таким же способом, как вы находите длину строки (в символах) — используя свойство {{jsxref("Array.prototype.length","length")}}. Попробуйте следующее:

+ +
sequence.length;
+// должно возвратить 7
+ +

Это свойство имеет и другие применения, но чаще всего используется, чтобы сказать, что цикл продолжается, пока он не зациклится на всех элементах массива. Так, например:

+ +
var sequence = [1, 1, 2, 3, 5, 8, 13];
+for (var i = 0; i < sequence.length; i++) {
+  console.log(sequence[i]);
+}
+ +

В будущих статьях вы узнаете о циклах, но вкратце этот код говорит:

+ +
    +
  1. Начать цикл с номера позиции 0 в массиве.
  2. +
  3. Остановить цикл на номере элемента, равном длине массива. Это будет работать для массива любой длины, но в этом случае он остановит цикл на элементе номер 7 (это хорошо, поскольку последний элемент, который мы хотим, чтобы цикл был закрыт, равен 6).
  4. +
  5. Для каждого элемента вернуть его значение в консоли браузера с помощью console.log().
  6. +
+ +

Некоторые полезные методы массивов

+ +

В этом разделе мы рассмотрим некоторые полезные методы, связанные с массивом, которые позволяют нам разбивать строки на элементы массива и наоборот, а также добавлять новые элементы в массивы.

+ +

Преобразование между строками и массивами

+ +

Часто у Вас могут быть некоторые необработанные данные, содержащиеся в большой длинной строке, и вы можете захотеть разделить полезные пункты до более удобной и полезной формы, а затем сделать что-то для них, например отобразить их в таблице данных. Для этого мы можем использовать метод {{jsxref ("String.prototype.split ()", "split ()")}}. В его простейшей форме он принимает единственный параметр, символ, который вы хотите отделить в строке, и возвращает подстроки между разделителем как элементы в массиве.

+ +
+

Заметка: Хорошо, технически это строковый метод, не метод массива, но мы поместили его в массивы, так как он хорошо подходит для них.

+
+ +
    +
  1. Поиграем с этим, посмотрим как это работает. Сначала, создадим строку в вашей консоли: +
    var myData = 'Manchester,London,Liverpool,Birmingham,Leeds,Carlisle';
    +
  2. +
  3. Теперь разделим ee посредством запятой: +
    var myArray = myData.split(',');
    +myArray;
    +
  4. +
  5. Наконец, попробуйте найти длину вашего нового массива и извлечь из него некоторые элементы: +
    myArray.length;
    +myArray[0]; // первый элемент в массиве
    +myArray[1]; // второй элемент в массиве
    +myArray[myArray.length-1]; // последний элемент в массиве
    +
  6. +
  7. Вы можете сделать обратное используя метод{{jsxref("Array.prototype.join()","join()")}} . Попробуйте следующее: +
    var myNewString = myArray.join(',');
    +myNewString;
    +
  8. +
  9.  Другой способ преобразования массива в строку - использовать метод {{jsxref("Array.prototype.toString()","toString()")}} . toString() ,возможно, проще,чем join() поскольку он не принимает параметр, но это ограничивает его. С join()вы можете указать разные разделители (попробуйте выполнить шаг 4 с другим символом, кроме запятой). +
    var dogNames = ["Rocket","Flash","Bella","Slugger"];
    +dogNames.toString(); //Rocket,Flash,Bella,Slugger
    +
  10. +
+ +

Добавление и удаление элементов массива

+ +

Мы еще не рассмотрели добавление и удаление элементов массива - давайте посмотрим на это сейчас. Мы будем использовать массив myArray , с которым мы столкнулись в предыдущем разделе. Если вы еще не прошли этот раздел, сначала создайте массив в консоли:

+ +
var myArray = ['Manchester', 'London', 'Liverpool', 'Birmingham', 'Leeds', 'Carlisle'];
+ +

Прежде всего, чтобы добавить или удалить элемент с конца массива, мы можем использовать {{jsxref("Array.prototype.push()","push()")}} и {{jsxref("Array.prototype.pop()","pop()")}} соответственно.

+ +
    +
  1. Давайте сначала используем метод push() — заметьте, что вам нужно указать один или более элементов, которые вы хотите добавить в конец своего массива. Попробуйте это: + +
    myArray.push('Cardiff');
    +myArray;
    +myArray.push('Bradford', 'Brighton');
    +myArray;
    +
    +
  2. +
  3. При завершении вызова метода возвращается новая длина массива. Если бы вы хотели сохранить новую длину массива в переменной, вы бы могли сделать что-то вроде этого: +
    var newLength = myArray.push('Bristol');
    +myArray;
    +newLength;
    +
  4. +
  5. Удаление последнего элемента массива можно совершить с помощью вызова метода pop(). Попробуйте это: +
    myArray.pop();
    +
  6. +
  7. Когда вызов метода завершается, возвращается удалённый элемент. Вы бы могли также сделать такое: +
    var removedItem = myArray.pop();
    +myArray;
    +removedItem;
    +
  8. +
+ +

{{jsxref("Array.prototype.unshift()","unshift()")}} и {{jsxref("Array.prototype.shift()","shift()")}} работают точно таким же способом, за исключением того что они работают в начале массива, а не в конце.

+ +
    +
  1. Сначала, попробуем метод unshift(): + +
    myArray.unshift('Edinburgh');
    +myArray;
    +
  2. +
  3. Теперь shift(); попробуйте эти! +
    var removedItem = myArray.shift();
    +myArray;
    +removedItem;
    +
  4. +
+ +

Практика: Печать продуктов!

+ +

Вернемся к описанному выше примеру - распечатываем названия продуктов и цен на счет-фактуру, затем суммируем цены и печатаем их внизу. В приведенном ниже редактируемом примере есть комментарии, содержащие числа - каждая из этих отметок является местом, где вы должны добавить что-то в код. Они заключаются в следующем:

+ +
    +
  1. Ниже комментария // number 1  имеется ряд строк, каждая из которых содержит название продукта и цену, разделенные двоеточием. Нужно превратить их в массив и сохранить его  под названием  products.
  2. +
  3. На строке с комментарием // number 2  начинается цикл for. В строке цикла имеется i <= 0, что является условием , которое заставляет цикл for выполняться только один раз, так как это значение i сообщает циклу: «останавливаться, когда i меньше или равен 0», при этом i начинается с 0. Нужно заменить i <= 0 условным тестом, который останавливает цикл, когда i перестает быть меньше длины массива products .
  4. +
  5. Под комментарием // number 3 мы хотим, чтобы вы написали строку кода, которая разбивает текущий элемент массива (name:price) на два отдельных элемента: один содержит только имя, а другой - содержащее только цену. Если не знаете, как это сделать, еще раз просмотрите статью Полезные строковые методы, а лучше, посмотрите раздел {{anch("Преобразование между строками и массивами")}} этой статьи.
  6. +
  7. В рамках приведенной выше строки нужно преобразовать цену из строки в число. Если не помните, как это сделать, ознакомьтесь со статьей строки в JavaScript.
  8. +
  9. В верхней части кода есть переменная с именем total , которая содержит значение 0. Внутри цикла (под комментарием // number 4) нужно добавить строку, которая добавляет текущую цену товара к этой сумме на каждой итерации цикла, так чтобы в конце кода была выведена корректная сумма в счет-фактуре. Для этого вам может понадобится оператор присваивания.
  10. +
  11. Под комментарием // number 5 нужно изменить строку так, чтобы переменная itemText была равна "current item name — $current item price",  например "Shoes — $23.99" для каждого случая, чтобы корректная информация для каждого элемента была напечатана в счете-фактуре. Здесь обычная конкатенация строк, которая должна быть вам знакома.
  12. +
+ + + +

{{ EmbedLiveSample('Playable_code', '100%', 730, "", "", "hide-codepen-jsfiddle") }}

+ +

Практика: Топ 5 поисовых запросов

+ +

Хорошим тоном, является использование методов массива, таких как {{jsxref ("Array.prototype.push ()", "push ()")}} и {{jsxref ("Array.prototype.pop ()", "pop ()") }} - это когда вы ведете запись активных элементов в веб-приложении. Например, в анимированной сцене может быть массив объектов, представляющих текущую отображаемую фоновую графику и вам может потребоваться только 50 одновременных отображений по причинам производительности или беспорядка. Когда новые объекты создаются и добавляются в массив, более старые могут быть удалены из массива для поддержания нужного числа.

+ +

В этом примере мы собираемся показать гораздо более простое использование - ниже мы даем вам поддельный поисковый сайт с полем поиска. Идея заключается в том, что когда в поле поиска вводятся запросы, в списке отображаются 5 предыдущих поисковых запросов. Когда число терминов превышает 5, последний член начинает удаляться каждый раз, когда новый член добавляется в начало, поэтому всегда отображаются 5 предыдущих терминов.

+ +
+

Примечание: В реальном приложении для поиска вы, вероятно, сможете щелкнуть предыдущие условия поиска, чтобы вернуться к предыдущим поисковым запросам и отобразите фактические результаты поиска! На данный момент мы просто сохраняем его.

+
+ +

Чтобы завершить приложение, вам необходимо:

+ +
    +
  1. Добавьте строку под комментарием // number 1, которая добавляет текущее значение, введенное в ввод поиска, к началу массива. Его можно получить с помощью searchInput.value.
  2. +
  3. Добавьте строку под комментарием // number 2, которая удаляет значение, находящееся в конце массива.
  4. +
+ + + +

{{ EmbedLiveSample('Playable_code_2', '100%', 700, "", "", "hide-codepen-jsfiddle") }}

+ +

Заключение

+ +

Прочитав эту статью, мы уверены, что вы согласитесь, что массивы кажутся довольно полезными; вы увидите, что они появляются повсюду в JavaScript, часто в сочетании с циклами, чтобы делать то же самое для каждого элемента массива. Мы научим вас всем полезным основам, которые нужно знать о циклах в следующем модуле, но пока вы должны себе похлопать и воспользоваться заслуженным перерывом; вы проработали все статьи в этом модуле!

+ +

Осталось только выполнить тестовую задачу, которая проверит ваше понимание статей, которые Вы прочли до этого момента. Удачи!

+ +

Посмотрите также

+ + + +

{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/Useful_string_methods", "Learn/JavaScript/Первые_шаги/Создатель_глуых_историй", "Learn/JavaScript/Первые_шаги")}}

+ +

В этом разделе

+ + diff --git a/files/ru/learn/javascript/first_steps/index.html b/files/ru/learn/javascript/first_steps/index.html new file mode 100644 index 0000000000..bd435e920f --- /dev/null +++ b/files/ru/learn/javascript/first_steps/index.html @@ -0,0 +1,56 @@ +--- +title: Первые шаги в JavaScript +slug: Learn/JavaScript/Первые_шаги +tags: + - JavaScript + - Массивы + - Новичкам +translation_of: Learn/JavaScript/First_steps +--- +
{{LearnSidebar}}
+ +

В нашем первом модуле, прежде чем перейти к практике написания кода на языке JavaScript, сначала мы дадим ответы на некоторые фундаментальные вопросы, а именно: "Что же такое JavaScript?", "Что он из себя представляет?" и "Что он может делать?". После этого мы внимательно рассмотрим некоторые из ключевых элементов, такие как переменные, строки, числа и массивы.

+ +

Предисловие

+ +

Вам не нужно иметь никаких предварительных знаний JavaScript чтобы приступить к этому модулю, но у вас должно быть некоторое представление о HTML и CSS. Рекомендуем ознакомиться со следующими материалами, прежде чем начинать знакомство с JavaScript:

+ + + +
+

Примечание:  Если Вы работаете на компьютере, планшете или другом устройстве, где нет возможности полноценно работать с файлами, можете использовать такие онлайн сервисы как  JSBin или Thimble, для запуска примеров кода. 

+
+ +

Руководства

+ +
+
Что такое JavaScript?
+
Добро пожаловать на курс начинающего JavaScript разработчика от MDN! В первой статье мы рассмотрим JavaScript в общем приближении и постараемся ответить на вопросы "Что такое JavaScript?" и "Для чего он предназначен?", и закрепим верное понимание его назначения. 
+
Первое погружение в JavaScript
+
Теперь, когда вы знаете кое-что о JavaScript, и что он может делать, мы предлагаем вам пройти интенсивный практический урок по базовой функциональности JavaScript. Здесь вы, шаг за шагом, создадите простую игру "Угадай число".
+
Что пошло не так? Устранение ошибок JavaScript
+
В процессе создания игры "Угадай число" из предыдущего урока, вы могли заметить что она не работала. Не стоит унывать - данная статья научит вас беречь собственные нервы, а так же, даст несколько советов о том как решать такие проблемы, искать и исправлять неполадки в JavaScript коде.
+
Хранение нужной вам информации - Переменные
+
После прочтения предыдущих статей вы должны знать что из себя представляет JavaScript, что он может, как взаимодействует с другими web технологиями, и каковы его основные особенности в общем приближении. В этой статье спустимся к самым основам языка и поработаем с Переменными.
+
Базовая математика в JavaScript — числа и операторы
+
Здесь мы обсуждаем математику в JavaScript - каким образом мы можем манипулировать числами и операторами для работы с ними.
+
Работа с текстом — строки в JavaScript
+
Теперь мы обратим своё внимание на строки - так называются кусочки текста в программировании. В этой статье мы рассмотрим то что действительно необходимо знать про строки в JavaScript: как создать строку, делать escape (экранирование) символов с помощью кавычек, и объединять их.
+
Полезные строковые методы
+
После того как мы рассмотрели основы работы со строками, давайте двинемся дальше и поговорим о том какие полезные операторы и методы существуют для строк, такие как вычисление длины, соединение и разделение строк, замена отдельных символов и многие другие. 
+
Массивы
+
В последней статье этого модуля мы рассмотрим массивы - изящный способ хранения различных наборов информации в имени всего одной переменной. Здесь мы поговорим о том почему это может быть полезным, рассмотрим как создать массив, получить, добавить или удалить элемент массива, и прочее.
+
+ +

Проверка полученных знаний

+ +

Предложенное тестовое задание проверит ваше понимание основ JavaScript, которые вы получили пройдя предложенные выше уроки. 

+ +
+
Генератор глупых историй
+
Вашим заданием будет применить на практике полученные знания и создать развлекательное приложение которое будет генерировать случайные нелепые истории.
+
diff --git a/files/ru/learn/javascript/first_steps/math/index.html b/files/ru/learn/javascript/first_steps/math/index.html new file mode 100644 index 0000000000..29ff9258bf --- /dev/null +++ b/files/ru/learn/javascript/first_steps/math/index.html @@ -0,0 +1,423 @@ +--- +title: Базовая математика в JavaScript — числа и операторы +slug: Learn/JavaScript/Первые_шаги/Math +tags: + - JavaScript + - Гайд + - Математика + - Начинающий + - Операторы + - Руководство + - Скриптинг + - Статья + - кодинг +translation_of: Learn/JavaScript/First_steps/Math +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/Variables", "Learn/JavaScript/Первые_шаги/Строки", "Learn/JavaScript/Первые_шаги")}}
+ +

В этой части курса мы обсуждаем математику в JavaScript — как мы можем использовать {{Glossary("Operator","operators")}} и другие функции, чтобы успешно манипулировать числами для выполнения наших задач.

+ + + + + + + + + + + + +
Необходимые условия:Базовая компьютерная грамотность, базовое понимание HTML и CSS, понимание того, что такое JavaScript.
Цель:Ознакомление с основами математики в JavaScript.
+ +

Все любят математику

+ +

Хорошо, может быть, не все. Некоторые из нас любят математику, некоторые из нас ненавидели математику с тех пор, как мы изучали таблицу умножения в школе, а некоторые из нас находятся где-то между ними. Но никто из нас не может отрицать, что математика является фундаментальной частью жизни, и мы не можем обойтись без нее. Это особенно актуально, когда мы учимся программировать на JavaScript (или на любом другом языке, если на то пошло) — большая часть того, что мы делаем, опирается на обработку числовых данных, вычисление новых значений и т.д. Так что не удивительно, что JavaScript имеет полнофункциональный набор математических функций.

+ +

В этой статье обсуждаются только основные разделы, которые вам нужно знать сейчас.

+ +

Типы чисел

+ +

В программировании даже скромная система десятичных чисел, которую мы все так хорошо знаем, сложнее, чем вы думаете. Мы используем разные термины для описания различных типов десятичных чисел. Например:

+ + + +

У нас даже есть разные типы числовых систем:

+ + + +

Прежде чем взорвется ваш мозг, остановитесь прямо здесь и сейчас! 

+ +

Во-первых, мы просто будем придерживаться десятичных чисел на протяжении всего курса; вы редко когда будете сталкиваться с необходимостью думать в других числовых системах, если вообще когда-либо с ней сталкнетесь.

+ +

Во-вторых, в отличие от некоторых других языков программирования, JavaScript имеет только один тип данных для чисел, как вы догадались это {{jsxref("Number")}}. Это означает, независимо от типа чисел, с которыми вы работаете в JavaScript, обрабатывать вы их будете точно так же.

+ +

Для меня всё — числа

+ +

Давайте быстро поиграем с некоторыми числами, чтобы снова познакомиться с основным синтаксисом, который нам нужен. Введите команды, перечисленные ниже, в вашу консоль (developer tools JavaScript console), или используйте простую встроенную консоль.

+ +
    +
  1. Прежде всего, давайте объявим пару переменных и инициализируем их целым числом и числом с плавающей точкой, соответственно, затем введите имена переменных обратно, чтобы проверить, что все в порядке: +
    var myInt = 5;
    +var myFloat = 6.667;
    +myInt;
    +myFloat;
    +
  2. +
  3. Числовые значения набираются без кавычек. Попробуйте объявить и инициализировать еще пару переменных, содержащих числа, прежде чем двигаться дальше.
  4. +
  5. Теперь давайте убедимся, что обе переменные содержат одинаковый тип данных. Для этого есть оператор {{jsxref("Operators/typeof", "typeof")}}, который позволяет проверить какой тип данных содержит в себе переменная. Введите две приведенные ниже строки: +
    typeof myInt;
    +typeof myFloat;
    + В обоих случаях вы должны получить "number" — это все упрощает, чем если бы разные числа имели разные типы данных, и нам приходилось иметь дело с ними по-разному.
  6. +
+ +

Арифметические операторы

+ +

Арифметические операторы — это основные операторы, которые мы используем для различных математических операций, например таких, как сложение или вычитание:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ОператорИмяФункцияПример
+СложениеОбъединение чисел в одно целое.6 + 9
-ВычитаниеВычитает правое число от левого.20 - 15
*УмножениеУмножает два числа вместе.3 * 7
/ДелениеДелит левое число на правое.10 / 5
%Модуль числа +

Возвращает значение остатка при делении первого числа на второе. Результат будет иметь тот же знак, что и первое число.

+
+

11 % 3 = 2 (поскольку число 3 вмещается три раза, остатком будет число 2)

+
**показатель степениВозводит базовое число в указанную степень, то есть количество базовых чисел, указанных экспонентой, умножается вместе. Впервые он был представлен в EcmaScript 2016.5 ** 5 (возвращает 3125, или как: 5*5*5*5*5)
+ +
+

Примечание: Иногда числа участвующие в математических операциях называют операндами ( {{Glossary("Operand", "operands")}} ).

+
+ +

Нам, вероятно, не нужно учить вас базовым математическим операциям, но мы хотели бы проверить ваше понимание синтаксиса. Попробуйте ввести приведенные ниже примеры в свою консоль (developer tools JavaScript console), или используйте встроенную консоль, с которой вы уже знакомы, чтобы ознакомиться с синтаксисом.

+ +
    +
  1. Для начала попробуйте ввести простые примеры, такие как: +
    10 + 7
    +9 * 8
    +60 % 3
    +
  2. +
  3. Вы также можете попробовать объявить переменные и присвоить им различные числа. Попробуйте вместо чисел использовать ранее объявленные переменные — переменные будут вести себя точно так же, как значения, которые они хранят. Например: +
    var num1 = 10;
    +var num2 = 50;
    +9 * num1;
    +num2 / num1;
    +
  4. +
  5. И напоследок, попробуйте ввести более сложные выражения, например: +
    5 + 10 * 3;
    +num2 % 9 * num1;
    +num2 + num1 / 8 + 2;
    +
  6. +
+ +

Некоторые примеры выше могут дать вам не тот результат, которого вы ожидали; приведенный ниже раздел может дать ответ на вопрос о том, почему.

+ +

Приоритет операторов

+ +

Давайте взглянем на последний пример сверху. Предположим, что num2 содержит значение 50 и num1 содержит значение 10 (как и было обозначено выше):

+ +
num2 + num1 / 8 + 2;
+ +

Будучи человеком, вы, вероятно, прочитаете это как "50 плюс 10 равно 60", затем "8 плюс 2 равно 10", и, наконец, "60 делить на 10 равно 6".

+ +

Но браузер видит это по-другому: "10 делить на 8 равно 1.25", затем "50 плюс 1.25 плюс 2 равно 53.25".

+ +

Это происходит из-за приоритета операторов - некоторые операторы будут применены перед другими в процесс вычисления суммы (в программировании ее называют выражением). Приоритет операторов в JavaScript ничем не отличается от приоритета арифметических операций, который вы изучали в школе - умножение и деление всегда выполняются первыми, затем сложение и вычитание (сумма всегда вычисляется слева направо).

+ +

Если вы хотите переопределить порядок выполнения операторов, вы можете окружить парными скобками часть выражения, которая должна быть выполнена первой. Для получения результата 6 вам следует сделать следующее:

+ +
(num2 + num1) / (8 + 2);
+ +

Результат этого выражения равен 6.

+ +
+

Заметка: полный список операторов JavaScript и приоритетов их выполнения можно найти по этой ссылке: Expressions and operators.

+
+ +

Операторы инкремента и декремента

+ +

Иногда вам захочется повторно добавить или вычесть единцу к/из значению числовой переменной. Это можно сделать с помощью оператора инкремента (++) и декремента (--). Мы использовали ++ в нашей игре "Угадай число" в статье первое погружение в JavaScript, где мы добавляли 1 к переменной guessCount, в которой хранилось значение количества попыток пользователя после каждого хода.

+ +
guessCount++;
+ +
+

Замечание: инкремент и декремент часто используются в циклах, о которых вы узнаете позже. Например, если вы захотите пройтись по списку цен и добавить к каждой налог с продаж, вам придется в цикле обойти каждую цену и провести необходимые вычисления для учета налога. Инкремент будет использован для перехода на новую ячейку списка при необходимости. У нас есть несложный пример реализации такого списка - попробуйте и взгляните на код чтобы посмотреть, сможете ли вы найти инкременты! Мы взглянем на циклы поближе позже по ходу курса.

+
+ +

Давайте попробуем сыграть с этим в вашей консоли. Для начала заметим, что вы не можете использовать инкремент/декремент непосредсвенно к числу, что может показаться странным. Дело в том, что мы присваиваем к переменной новое обновленное число, а не просто вычисляем значение. Следующий пример приведет к ошибке:

+ +
3++;
+ +

Таким образом, вы можете применить инкремент только к существующим переменным:

+ +
var num1 = 4;
+num1++;
+ +

Так, вторая странность! Если вы сделаете это, вы получите значение 4 - бразуер возвращает текущее число, после чего применяет к нему оператор инкремента. Вы можете удостовериться в том, что инкремент был применен, узнав значение переменной еще раз:

+ +
num1;
+ +

То же самое для --: попробуйте пример ниже

+ +
var num2 = 6;
+num2--;
+num2;
+ +
+

Замечание: вы можете заставить делать это в другом порядке - применить инкремент/декремент и только потом вернуть значение. Для этого необходимо записать оператор слева от переменной, а не справа. Попробуйте пример сверху еще раз, но в этот раз используйте ++num1 и --num2

+
+ +

Операторы присваивания

+ +

Операторы присваивания - операторы, которые присваивают значение переменным. Мы уже много раз использовали самый простой из них, =, он просто приравнивает значение переменной слева к значению справа:

+ +
var x = 3; // x содержит значение 3
+var y = 4; // y содержит значение 4
+x = y; // x теперь содержит значение y (x == 4)
+ +

Однако есть еще несколько сложных конструкций, которые позволяют делать ваш код более простым и аккуратным. Наиболее часто используемые перечислены ниже:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OperatorNamePurposeExampleShortcut for
+=Присваивание сложенияПрибавляет значение справа к переменной слева и возвращает новое значение переменнойx = 3;
+ x += 4;
x = 3;
+ x = x + 4;
-=Присваивание вычитанияВычитает значение справа из переменной слева и возвращает новое зачение переменнойx = 6;
+ x -= 3;
x = 6;
+ x = x - 3;
*= +

Присваивание умножения

+
Умножает переменную слева на значение справа и возвращает новое зачение переменнойx = 2;
+ x *= 3;
x = 2;
+ x = x * 3;
/=Присваивание деленияДелит переменную слева на значение справа и возвращает новое зачение переменнойx = 10;
+ x /= 5;
x = 10;
+ x = x / 5;
+ +

Попробуйте использовать такие конструкции, что понять, как они работают. Сможете ли вы определить значение до того, как напишите вторую строку?

+ +

Замьтете, что значение справа может быть как числом (константой), так и переменной, например:

+ +
var x = 3; // x содержит значение 3
+var y = 4; // y содержит значение 4
+x *= y; // x содержит значение 12
+ +
+

Заметка: есть еще другие операторы присваивания, в этой статье перечислены только самые базовые.

+
+ +

Активное обучение: меняем размеры коробки

+ +

В этом упражнении вы будете пользоваться числами и операторами для работы с размерами коробки. Коробка рисуется с помощью API браузера, которое назывется Canvas API. Вам не следует беспокоиться о том, как это работает - просто сосредоточьтесь на математике. Ширина и высота коробки (в пикселях) определяются переменными x и y, которые изначально равны 50.

+ +

{{EmbedGHLiveSample("learning-area/javascript/introduction-to-js-1/maths/editable_canvas.html", '100%', 520)}}

+ +

Открыть в новом окне

+ +

В коде сверху, который вы можете изменять, под комментарием есть две строчки, с помощью которых вы можете увеличивать/уменьшать размеры коробки. Мы хотим, чтобы вы выполнили несколько заданий:

+ + + +

Не расстраивайтесть, если вы не поняли код сверху. Нажмите кнопку Reset для запуска программы снова. Если вы смогли ответить верно на все вопросы, попробуйте поэкспериментировать с кодом еще (или, например, предложить друзьям несколько заданий).

+ +

Операторы сравнения

+ +

Иногда нам может понадобиться проверить какое-либо условие, а затем поступить в зависимости от результата - для этого мы используем операторы сравнения.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ОператорИмяНазначениеПример
===Строгое равенствоПроверяет левое и правое значения на идентичность5 === 2 + 4
!==Строгое неравенствоПроверяет левое и правое значения на неидентичность5 !== 2 + 3
<МеньшеПроверяет, меньше ли левое значение правого10 < 6
>БольшеПроверяет, больше ли левое значение правого10 > 20
<=Меньше или равноПроверят, меньше ли левое значение правому (или равно ему)3 <= 2
>=Больше или равноПроверят, больше ли левое значение левого (или равно ему)5 >= 4
+ +
+

Заметка: вы можете заметить, что некоторые люди используют == и != в их программах для сравнения на равенство и неравенство — это валидные JavaScript-операторы, но они отличаются от ===/!== — первая пара проверяет на равенство/неравенство значений, не рассматривая их типы. Вторая пара - строгая версия первой, которая проверяет типы операндов. При использовании строгой версии выявляется больше ошибок, поэтому мы рекомендуем использовать именно ее.

+
+ +

Если вы попробуете использовать эти операторы в консоли, вы увидите, что все они возвращают значения true/false — о типе данных boolean мы писали в прошлой статье. С их помощью мы можем принимать решения в нашей программе, например:

+ + + +

Мы взглянем на то, как реализовать такую логику после знакомства с условными выражениями в следующей статье. Сейчас мы рассмотрим небольшой пример:

+ +
<button>Запустить машину</button>
+<p>Машина остановлена</p>
+
+ +
var btn = document.querySelector('button');
+var txt = document.querySelector('p');
+
+btn.addEventListener('click', updateBtn);
+
+function updateBtn() {
+  if (btn.textContent === 'Start machine') {
+    btn.textContent = 'Stop machine';
+    txt.textContent = 'The machine has started!';
+  } else {
+    btn.textContent = 'Start machine';
+    txt.textContent = 'The machine id stopped.';
+  }
+}
+ +

{{EmbedGHLiveSample("learning-area/javascript/introduction-to-js-1/maths/conditional.html", '100%', 100)}}

+ +

Открыть в новом окне

+ +

Мы использовали оператор равенства внутри функции updateBtn(). В этом случае мы не проверяем пару математических выражений на равенcтво значений — мы просто смотрим, является ли текст на кнопке определенной строкой — что по сути является тем же самым. Если кнопка при нажатии содержит "Start machine", мы меняем содержимое метки на "Stop machine" и обновляем метку. Если же текст кнопки — "Stop machine", при нажатии мы возвращем все обратно. 

+ +
+

Заметка: Такой элемент управления, который переключается между двумя состояниями, обычно называется тумблером. Он переключается между одним состоянием и другим: свет включен, свет выключен и т. д.

+
+ +

Итого

+ +

В этой статье мы привели основную информацию, необходимую для работы с числами в JavaScript. Вы постоянно будете использовать числа в процессе обучения языку, поэтому желательно разобраться в этом сейчас. Если вам действительно не нравится математика, пусть вас утешит, что эта статья была сравнительно короткой.

+ +

В следующей статье мы изучим текст и то, как мы работаем с ним в JavaScript.

+ +
+

Примечание: если вам хочется узнать подробнее о том, как математика реализуется в JavaScript, вы можете посмотерть главный раздел JavaScript MDN. Статьи Числа и даты и Выражения и операторы - хороший вариант для начала.

+
+ +

{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/Variables", "Learn/JavaScript/Первые_шаги/Строки", "Learn/JavaScript/Первые_шаги")}}

diff --git a/files/ru/learn/javascript/first_steps/silly_story_generator/index.html b/files/ru/learn/javascript/first_steps/silly_story_generator/index.html new file mode 100644 index 0000000000..139e478847 --- /dev/null +++ b/files/ru/learn/javascript/first_steps/silly_story_generator/index.html @@ -0,0 +1,148 @@ +--- +title: Генератор глупых историй +slug: Learn/JavaScript/Первые_шаги/Создатель_глуых_историй +tags: + - JavaScript + - Задание + - Изучение + - Испытание + - Массивы + - НаписаниеКода + - НачальныйУровень + - Операторы + - Переменные + - Проверка + - Числа +translation_of: Learn/JavaScript/First_steps/Silly_story_generator +--- +
{{LearnSidebar}}
+ +
{{PreviousMenu("Learn/JavaScript/Первые_шаги/Arrays", "Learn/JavaScript/Первые_шаги")}}
+ +

В этом испытании вам будет нужно, используя знания, полученные в статьях этого модуля, применить их для создания забавного приложения, создающего случайные глупые истории. Удачно повеселиться!

+ + + + + + + + + + + + +
Требования:Перед началом выполнения этого испытания вам следует проработать все статьи в этом модуле.
Задача:Протестировать понимание основ языка JavaScript, таких как переменные, числа, операторы, строки и массивы.
+ +

Начальная точка

+ +

Для начала испытания вам следует:

+ + + +
+

Замечание:  Так же вы можете использовать такие сайты как  JSBin или Thimble для выполнения вашего испытания. Вы можете вставить HTML, CSS и JavaScript в один из этих онлайн редакторов. Если онлайн редактор, который вы используете, не имеет отдельного окна для JavaScript - не стесняйтесь вставить все скрипты в <script> элемент внутри  HTML страницы.

+
+ +

Краткое описание проекта

+ +

Вам предоставили некоторый необработанный HTML/CSS, несколько текстовых строк и функций JavaScript; вам необходимо написать необходимый JavaScript код, чтобы превратить это в рабочую программу, которая выполняет следующие действия:

+ + + +

Следующий скриншот показывает пример того, что должна выводить законченная программа:

+ +

+ +

Чтобы вы больше поняли идею опробуйте готовый пример (не заглядывая в исходный код!)

+ +

Шаги к цели

+ +

Следующие разделы описывают, что вам нужно будет сделать.

+ +

Начальная подготовка:

+ +
    +
  1. Создайте новый файл под названием main.js в той же папке, что и index.html.
  2. +
  3. Подключите данный JavaScript документ в ваш HTML файл с помощью {{htmlelement("script")}} элемента привязки main.js. Разместите его прямо перед закрывающимся </body> тегом.
  4. +
+ +

Задайте переменные и функции:

+ +
    +
  1. В исходном текстовом документе скопируйте весь код под заголовком "1. COMPLETE VARIABLE AND FUNCTION DEFINITIONS" и вставьте в начало файла main.js. Это даст вам три переменные, ссылающиеся на текстовое поле "Enter custom name" (customName),  кнопку "Generate random story" (randomize), и элемент снизу HTML страницы, куда будет помещена сама история {{htmlelement("p")}} (story), соответственно. Также у вас должна быть функцияrandomValueFromArray(), котрая принимает массив и случайным образом возвращает оттуда один из элементов.
  2. +
  3. Теперь взгляните на второй параграф исходного документа — "2. RAW TEXT STRINGS". Он содержит строки текста, которые будут использоваться как входные данные вашей программы. Вам следует поместить их внутрь переменных в файле main.js: +
      +
    1. Сохраните первую большую строку текста в переменную storyText.
    2. +
    3. Сохраните первый блок из трех строк как массив, назвав его insertX.
    4. +
    5. Сохраните второй блок из трех строк как массив, назвав его insertY.
    6. +
    7. Сохраните третий блок из трех строк как массив, назвав его insertZ.
    8. +
    +
  4. +
+ +

Создание обработчика событий и неполной функции:

+ +
    +
  1. Теперь возвращаемся к исходному текстовому файлу.
  2. +
  3. Скопируйте код под заголовком "3. EVENT LISTENER AND PARTIAL FUNCTION DEFINITION" и вставте его в конец файла main.js. Это: +
      +
    • Добавит обработчик события кликанья в переменную randomize,  Так что, когда кнопка будет нажата -  функция result() запустится.
    • +
    • Добавляет в код частично завершенную функцию result(). В течении оставшейся части испытания вам предстоит, заполняя строчки внутри этой функции, завершить ее и заставить работать должным образом.
    • +
    +
  4. +
+ +

Завершение функции result():

+ +
    +
  1. Создайте новую переменную newStory и установите ее значение равным storyText. Это необходимо, чтобы мы могли создавать новую случайную историю каждый раз, когда нажимается кнопка, и функция запускается. Если бы мы внесли изменения непосредственно в storyText, мы могли бы генерировать новую историю только один раз.
  2. +
  3. Создайте три новые переменные, называемые xItem, yItem и zItem, и сделайте их равными результату вызова randomValueFromArray() на трех ваших массивах (результат в каждом случае будет случайным элементом из каждого массива, на который он вызывается). Например, вы можете вызвать функцию и получить ее, чтобы вернуть одну случайную строку из insertX, записав randomValueFromArray (insertX).
  4. +
  5. Затем мы хотим заменить три заполнителя строки newStory - :insertx:, :inserty :  и :insertz: - со строками, хранящимися в xItem, yItem и zItem. Здесь вам поможет определенный строковый метод - в каждом случае сделать вызов метода равным newStory, при этом каждый раз, когда он вызывается, newStory делается равным самому себе, но с выполненными заменами. Поэтому каждый раз, когда нажимается кнопка, эти заполнители заменяются случайной строкой. Подсказка: рассматриваемый метод заменяет только первый экземпляр найденной подстроки, поэтому вам, возможно, придется сделать один из вызовов дважды.
  6. +
  7. Внутри первого блока if добавьте другой метод замены строки, чтобы заменить имя «Боб», найденное в строке newStory, с помощью переменной name. В этом блоке мы говорим: «Если значение введено в текстовый ввод customName, замените Боба в истории этим пользовательским именем».
  8. +
  9. Внутри второго блока if мы проверяем, была ли выбрана радиокнопка uk. Если это так, мы хотим преобразовать значения веса и температуры в историю из фунтов и Фаренгейта в метры и по Цельсию. Что вам нужно сделать, так это: +
      +
    1. Посмотрите формулу преобразования фунтов в стоуны и Фаренгейта в по Цельсию.
    2. +
    3. Внутри линии, которая определяет weight переменную, замените 300 на расчет, который преобразует 300 фунтов в стоуны. Добавьте 'stone' в конце результата общего вызова Math.round().
    4. +
    5. Внутри линии, определяющей temperature переменную, замените 94 на расчет, который преобразует 94 градуса по Фаренгейту в по Цельсию. Добавьте 'centigrade' в конце результата общего вызова Math.round().
    6. +
    7. Просто под двумя определениями переменных добавьте еще две строки замены строк, которые заменяют «94 farenheit» на содержимое переменной temperature и«300  pounds» на содержимое weight переменной.
    8. +
    +
  10. +
  11. Наконец, в предпоследней строке функции сделайте свойство textContent переменной story (которая ссылается на абзац) равным newStory.
  12. +
+ +

Советы и подсказки

+ + + +

Оценка и помощь

+ +

Если вы хотите, чтобы ваша работа была оценена, или застряли и хотите обратиться за помощью:

+ +
    +
  1. Разместите свою работу в онлайн-редакторе, таком как CodePen, jsFiddle или Glitch.
  2. +
  3. Напишите сообщение с просьбой об оценке и / или помощи на форуме MDN Discourse. Добавьте тег «learning» к своему сообщению, чтобы мы могли легче его найти. Ваш пост должен включать: +
      +
    • Описательное название, такое как «Требуется оценка для генератора глупых историй».
    • +
    • Подробная информация о том, что вы хотели бы, чтобы мы делали, например, что вы уже пробовали, если вы застряли и нуждаетесь в помощи.
    • +
    • Ссылка на пример, который вы хотите оценить или нуждаетесь в помощи, в онлайн-редакторе. Это хорошая практика - очень сложно помочь кому-то с проблемой кодирования, если вы не видите его код.
    • +
    • Ссылка на актуальную задачу или страницу оценки, чтобы мы могли найти вопрос, с которым вы хотите помочь.
    • +
    +
  4. +
+ +

{{PreviousMenu("Learn/JavaScript/Первые_шаги/Arrays", "Learn/JavaScript/Первые_шаги")}}

diff --git a/files/ru/learn/javascript/first_steps/strings/index.html b/files/ru/learn/javascript/first_steps/strings/index.html new file mode 100644 index 0000000000..583e29182e --- /dev/null +++ b/files/ru/learn/javascript/first_steps/strings/index.html @@ -0,0 +1,284 @@ +--- +title: Работа с текстом — строки в JavaScript +slug: Learn/JavaScript/Первые_шаги/Строки +translation_of: Learn/JavaScript/First_steps/Strings +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/Math", "Learn/JavaScript/Первые_шаги/Useful_string_methods", "Learn/JavaScript/Первые_шаги")}}
+ +

Теперь мы обратим внимание на строки — в программировании так называют части текста. В этой статье мы рассмотрим все распростанённые вещи, которые вы должны действительно знать о строках при изучении JavaScript, например, создание строк, экранирование кавычек в строках и объединение строк вместе.

+ + + + + + + + + + + + +
Необходимые навыки:Базовая компьютерная грамотность, базовое понимание HTML и CSS, понимание что такое JavaScript.
Цель:Знакомство с основами строк в JavaScript.
+ +

Сила слов

+ +

Слова очень важны для людей это основа нашего общения. Интернет представляет собой преимущественно текстовую среду, предназначенную для того что бы люди общались и делились информацией, поэтому нам полезно иметь контроль над словами, которые появляются в нем. {{glossary ("HTML")}} предоставляет визуальную и смысловую структуру для нашего текста, {{glossary ("CSS")}} позволяет нам стилизовать его, а JavaScript содержит ряд функций для управления строками, создания пользовательских приветственных сообщений, при необходимости отображая нужные текстовые метки, сортируя элементы в желаемом порядке и многое другое.

+ +

Практически во всех программах, которые мы показали вам на данный момент,  были задействованы некоторые манипуляции со строками.

+ +

Строки — основы

+ +

С первого взгляда строки обрабатываются аналогично числам, но если копнуть глубже, вы увидите некоторые заметные отличия. Давайте начнем с ввода некоторых основных строк в консоль, чтобы ознакомиться с ними. Мы предоставили одну ниже (вы также можете открыть эту консоль в отдельной вкладке или окне или использовать консоль разработчика браузера, если хотите).

+ + + +

{{ EmbedLiveSample('Hidden_code', '100%', 300) }}

+ +

Создание строки

+ +
    +
  1. Для начала введите следующие строки: +
    var string = 'The revolution will not be televised.';
    +string;
    +
  2. +
  3. Как и в случае с числами, мы объявляем переменную, инициализируя ее строковым значением, а затем возвращаем значение. Единственное различие здесь в том, что при написании строки вам нужно окружить значение кавычками. 
  4. +
  5. Если вы не сделаете этого или пропустите одну из кавычек, вы получите сообщение об ошибке. Попробуйте ввести следующие строки: +
    var badString = This is a test;
    +var badString = 'This is a test;
    +var badString = This is a test';
    + Эти строки не работают, потому что любая текстовая строка без кавычек считается именем переменной, именем свойства, зарезервированным словом или чем-то подобным. Если браузер не может найти его, возникает ошибка (например, «missing, before statement»). Если браузер может видеть, где начинается строка, но не может найти конец строки, как указано во 2-й строке, она жалуется на ошибку (с «unterminated string literal»). Если ваша программа выявляет такие ошибки, вернитесь назад и проверьте все свои строки, чтобы убедиться, что у вас нет пропущенных кавычек.
  6. +
  7. Следующий код будет выполнен только в том случае, если ранее была объявлена переменная string — убедитесь сами: +
    var badString = string;
    +badString;
    + В настоящее время строка badString имеет то же значение, что и строка string.
  8. +
+ +

Одиночные кавычки vs. Двойные кавычки

+ +
    +
  1. В JavaScript вы можете выбрать одинарные кавычки или двойные кавычки, чтобы обернуть ваши строки. Оба варианта будут работать нормально: +
    var sgl = 'Single quotes.';
    +var dbl = "Double quotes";
    +sgl;
    +dbl;
    +
  2. +
  3. Существует очень мало различий между одиночными и двойными кавычками, и решение какие из них использовать в коде остается на ваше усмотрение. Однако вы должны выбрать один вариант и придерживаться его, иначе ваш код может выдать ошибку, особенно если вы используете разные кавычки в одной строке! Ниже приведен пример: +
    var badQuotes = 'What on earth?";
    +
  4. +
  5. Браузер будет считать, что строка не была закрыта, потому что в строке может появиться другой тип цитаты, который вы не используете, чтобы хранить ваши строки в переменных. Из примера можно понять, о чем идет речь (в коде ошибок нет): +
    var sglDbl = 'Would you eat a "fish supper"?';
    +var dblSgl = "I'm feeling blue.";
    +sglDbl;
    +dblSgl;
    +
  6. +
  7. Однако вы не можете включить один и тот же знак кавычки внутри строки, если он используется для их хранения. Ниже приведена ошибка, браузер ошибочно определяет место, где строка кончается: +
    var bigmouth = 'I've got no right to take my place...';
    + Что приводит нас к следующей теме.
  8. +
+ +

Экранирование кавычек в строках

+ +

Чтобы исправить нашу предыдущую строку кода, нам нужно дать понять браузеру, что кавычка в середине строки не является меткой ее конца. Экранирование символов означает, что мы делаем что-то с ними, чтобы убедиться, что они распознаются как текст, а не часть кода. В JavaScript мы делаем это, помещая обратную косую черту непосредственно перед символом. Введите эти строки:

+ +
var bigmouth = 'I\'ve got no right to take my place...';
+bigmouth;
+ +

Так лучше. Таким же образом можно экранировать и другие символы, например "\. Кроме того существуют специальные коды. Для дополнительной информации см. Escape notation.

+ +

Конкатенация строк

+ +
    +
  1. Конкатенация — это новомодное программистское слово, которое означает «объединить». Объединение строк в JavaScript использует оператор плюс (+), тот же, который мы используем для сложения чисел, но в этом контексте он делает кое-что другое. Попробуем пример в нашей консоли.
  2. +
  3. +
    var one = 'Hello, ';
    +var two = 'how are you?';
    +var joined = one + two;
    +joined;
    + Результат этой программы - это переменная joined, содержащая значение "Hello, how are you?".
  4. +
  5. В последнем случае мы просто объединим две строки вместе, но на самом деле, вы можете объединить столько строк, сколько хотите, до тех пор, пока вы ставите + между ними. Попробуйте это: +
    var multiple = one + one + one + one + two;
    +multiple;
    +
  6. +
  7. Вы также можете использовать сочетание переменных и фактических строк. Попробуйте это: +
    var response = one + 'I am fine — ' + two;
    +response;
    +
  8. +
+ +
+

Примечание: Когда вы вводите фактическую строку в свой код, заключенную в одинарные или двойные кавычки, она называется строковым литералом.

+
+ +

Конкатенация строк в контексте

+ +

Давайте посмотрим на конкатенацию строк в действии — вот пример из предыдущего курса:

+ +
<button>Press me</button>
+ +
var button = document.querySelector('button');
+
+button.onclick = function() {
+  var name = prompt('What is your name?');
+  alert('Hello ' + name + ', nice to see you!');
+}
+ +

{{ EmbedLiveSample('Concatenation_in_context', '100%', 50) }}

+ +

Здесь мы используем функцию {{domxref ("Window.prompt ()", "Window.prompt ()")}} в строке 4, которая просит пользователя ответить на вопрос через всплывающее диалоговое окно, а затем сохраняет введенный текст внутри заданной переменной — в этом случае name. Затем мы используем функцию {{domxref ("Window.alert ()", "Window.alert ()")}} в строке 5 для отображения другого всплывающего окна, содержащего строку, которую мы собрали из двух строковых литералов и переменной name.

+ +

Числа vs. строки

+ +
    +
  1. Итак, что происходит, когда мы пытаемся добавить (или конкатенировать) строку и число? Попробуем это в нашей консоли: +
    'Front ' + 242;
    +
    + Вы можете ожидать, что это вызовет ошибку, но все работает отлично. Попытка представить строку как число на самом деле не имеет смысла, но число как строку — имеет, поэтому браузер довольно умно преобразует число в строку и объединяет две строки вместе.
  2. +
  3. Вы даже можете сделать это с двумя числами, вы можете заставить число стать строкой, обернув ее в кавычки. Попробуйте следующее (мы используем оператор typeof для того, чтобы установить является ли переменная числом или строкой): +
    var myDate = '19' + '67';
    +typeof myDate;
    +
  4. +
  5. Если у вас есть числовая переменная, которую вы хотите преобразовать в строчную без внесения каких-либо иных изменений или строковую переменную, которую вы хотите преобразовать в число, вы можете использовать следующие две конструкции: +
      +
    • Объект {{jsxref ("Number")}} преобразует всё переданное в него в число, если это возможно. Попробуйте следующее: +
      var myString = '123';
      +var myNum = Number(myString);
      +typeof myNum;
      +
    • +
    • С другой стороны, каждое число имеет метод, называемый toString(), который преобразует его в эквивалентную строку. Попробуй это: +
      var myNum = 123;
      +var myString = myNum.toString();
      +typeof myString;
      +
    • +
    + Эти конструкции могут быть действительно полезны в некоторых ситуациях. Например, если пользователь вводит число в текстовое поле формы, данные будут распознаны как строка. Однако, если вы хотите добавить это число к чему-то, вам понадобится его значение, поэтому вы можете передать его через Number(), чтобы справиться с этим. Именно это мы сделали в нашей Number Guessing Game,  в строке 61.
  6. +
+ +

Заключение

+ +

Итак, это основы строк, используемых в JavaScript. В следующей статье мы рассмотрим некоторые из встроенных методов, доступных для строк в JavaScript и то, как мы можем использовать их для управления нашими строками только в той форме, в которой мы хотим.

+ +
{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/Math", "Learn/JavaScript/Первые_шаги/Useful_string_methods", "Learn/JavaScript/Первые_шаги")}}
+ +

В этом модуле

+ + diff --git a/files/ru/learn/javascript/first_steps/useful_string_methods/index.html b/files/ru/learn/javascript/first_steps/useful_string_methods/index.html new file mode 100644 index 0000000000..1318ee39ac --- /dev/null +++ b/files/ru/learn/javascript/first_steps/useful_string_methods/index.html @@ -0,0 +1,723 @@ +--- +title: Полезные строковые методы +slug: Learn/JavaScript/Первые_шаги/Useful_string_methods +tags: + - Beginner + - CodingScripting + - JavaScript + - Learn + - length + - lower + - replace + - split + - upper + - Обучение + - Регистр +translation_of: Learn/JavaScript/First_steps/Useful_string_methods +--- +

{{LearnSidebar}}

+ +

{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/Строки", "Learn/JavaScript/Первые_шаги/Arrays", "Learn/JavaScript/Первые_шаги")}}

+ +

Мы рассмотрели базовые понятия, касающиеся строк. Давайте пойдем дальше и рассмотрим, какие полезные операции мы можем выполнять со строками, используя встроенные функции, такие как поиск длины текстовой строки, объединение и разделение строк, замена одного символа из строки другим и многое другое.

+ + + + + + + + + + + + +
Необходимые знания:Базовая компьютерная грамотность, базовое понимание HTML и CSS, понимание того, что такое JavaScript.
Задача:Понять, что строки являются объектами, и изучить, как использовать некоторые из основных методов, доступных для этих объектов для управления строками.
+ +

Строки как объекты

+ +

Почти всё в JavaScript является объектами. Когда вы создаете строку, например: 

+ +
let string = 'This is my string';
+ +

ваша переменная становится строковым объектом, и, как результат, ей доступно множество свойств и методов. Можете убедиться в этом, перейдя на страницу {{jsxref ("String")}} и просмотрев на ней список свойств и методов!

+ +

Только не волнуйтесь! Большинство из них вам не нужно знать сейчас на ранней стадии вашего обучения. Но некоторые из них вы, возможно, будете использовать довольно часто. Их мы и рассмотрим.

+ +

Приведем несколько примеров в новой консоли. Ниже вы можете открыть данную консоль в отдельной вкладке или окне, или, если вам так удобней, использовать браузер консоли разработчика.

+ + + +

{{ EmbedLiveSample('Hidden_code', '100%', 300, "", "", "hide-codepen-jsfiddle") }}

+ +

Поиск длины строки

+ +

Это легко — вы просто используете свойство {{jsxref ("String.prototype.length", "length")}}. Попробуйте ввести следующие строки:

+ +
let browserType = 'mozilla';
+browserType.length;
+ +

Результатом должно быть число 7, потому что слово «mozilla» состоит из 7 символов. Это свойство можно применить, например, если вы захотите найти длины серии имен, чтобы их можно было отображать по порядку длины или сообщить пользователю, что имя пользователя, которое он ввёл в поле формы, слишком длинное, если оно превышает определённую длину.

+ +

Получение определенного строкового символа

+ +

Вы можете вернуть любой символ внутри строки, используя обозначение в квадратных скобках. Это означает, что вы добавляете квадратные скобки ([ ]) в конце вашего имени переменной. В квадратных скобках вы указываете номер символа, который хотите вернуть. Например, чтобы получить первую букву, нужно написать:

+ +
browserType[0];
+ +

Компьютеры считают от 0, а не 1! Чтобы получить последний символ любой строки, мы могли бы использовать следующую строку, объединив эту технику с свойством length:

+ +
 browserType[browserType.length-1];
+ +

Длина слова «mozilla» равна 7, но, поскольку счет начинается с 0, позиция последнего символа равна 6, поэтому нам нужна length-1. Такой способ можно использовать, чтобы найти первую букву ряда строк и упорядочить их по алфавиту.

+ +

Поиск подстроки внутри строки и ее извлечение

+ +
    +
  1. Иногда вам может понадобиться выяснить, присутствует ли меньшая строка внутри большей (обычно мы говорим, что внутри строки есть подстрока). Это можно сделать с помощью метода {{jsxref ("String.prototype.indexOf ()", "indexOf ()")}}, который принимает одну {{glossary ("parameter")}} - подстроку, которую вы хотите найти. Введите: +
    browserType.indexOf('zilla');
    + Это дает нам результат 2, потому что подстрока «zilla» начинается в позиции 2 ("m" — 0, "o" — 1, "z" — 2) внутри «mozilla». Такой код можно использовать для фильтрации строк. Например, если есть список веб-адресов и вы хотите распечатать только те, которые содержат «mozilla».
  2. +
+ +
    +
  1. Это можно сделать по-другому, что, возможно, ещё более эффективно. Введите следующее: +
    browserType.indexOf('vanilla');
    + Это должно дать вам результат -1. Такое значение возвращается, когда подстрока, в данном случае «vanilla», не найдена в основной строке.
    +
    + Вы можете использовать это, чтобы найти все экземпляры строк, которые не содержат подстроку «mozilla» (для обратного эффекта, используйте оператор отрицания): +
    if(browserType.indexOf('mozilla') === -1) {
    +  // сделать что-то, если 'mozilla'
    +  // не является частью этой строки
    +}
    +
    +if(browserType.indexOf('mozilla') !== -1) {
    +  // сделать что-то, если 'mozilla'
    +  // является частью этой строки
    +}
    +
  2. +
  3. Когда вы знаете, где подстрока начинается внутри строки, и вы знаете, на каком символе вы хотите её завершить, можно использовать {{jsxref ("String.prototype.slice ()", "slice ()")}}  для извлечения. Попробуйте следующее: +
    browserType.slice(0,3);
    + Это возвращает «moz». Первым параметром является позиция символа, с которого начинается извлечение, а второй параметр — позиция последнего символа, перед которым нужно отсечь строку. Таким образом, срез происходит с первой позиции, вплоть до последней позиции, но не включая её (помним, что счет идёт с 0, а не с 1). Также можно сказать, что второй параметр равен длине возвращаемой строки.
  4. +
  5. Кроме того, если вы знаете, что хотите извлечь все остальные символы в строке после определённого символа, вам не нужно включать второй параметр. Достаточно включить только положение символа, с которого вы хотите начать извлечение оставшихся символов в строке. Введите: +
    browserType.slice(2);
    + Этот код возвращает «zilla» — это потому, что позиция символа 2 — это буква z, и поскольку вы не указали второй параметр, возвращаемая подстрока состояла из всех остальных символов в строке.
  6. +
+ +
+

Примечание: второй параметр slice() не обязателен: если вы его не включите в код, обрезание закончится на конце оригинальной строки. Есть и другие варианты; изучите страницу {{jsxref ("String.prototype.slice ()", "slice ()")}}, чтобы узнать, что ещё вы можете узнать.

+
+ +

Изменение регистра

+ +

Строковые методы {{jsxref ("String.prototype.toLowerCase ()", "toLowerCase ()")}} и {{jsxref ("String.prototype.toUpperCase ()", "toUpperCase ()")}} преобразовывают все символы в строке в нижний или верхний регистр соответственно. Этот способ можно применить, если вы хотите нормализовать все введенные пользователем данные перед их сохранением в базе данных.

+ +

Попробуем ввести следующие строки, чтобы узнать, что происходит:

+ +
var radData = 'My NaMe Is MuD';
+radData.toLowerCase();
+radData.toUpperCase();
+ +

Обновление частей строки

+ +

Вы можете заменить одну подстроку внутри строки на другую подстроку, используя метод {{jsxref ("String.prototype.replace ()", "replace ()")}}. Этот метод работает очень просто на базовом уровне, но у него есть некоторые продвинутые свойства, но мы пока не будем вдаваться в детали.

+ +

Он принимает два параметра — строку, которую вы хотите заменить, и строку, которую вы хотите вставить вместо заменяемой. Попробуйте этот пример:

+ +
browserType.replace('moz','van');
+ +

Обратите внимание, что для фактического получения обновленного значения, отраженного в переменной browserType в реальной программе, вам нужно будет установить значение переменной в результате операции; он не просто обновляет значение подстроки автоматически. Таким образом, вы должны были бы написать это: browserType = browserType.replace('moz','van');

+ +

Активные примеры обучения

+ +

В этом разделе мы дадим вам попробовать набить руку и вместе напишем код строковой манипуляции. В каждом упражнении ниже у нас есть массив строк и цикл, который обрабатывает каждое значение в массиве и отображает его в маркированном списке. Вам не нужно понимать массивы или циклы прямо сейчас — это будет объяснено в будущих статьях. Все, что вам нужно сделать в каждом случае, — написать код, который выводит строки в том формате, в котором мы предлагаем.

+ +

В каждом примере есть кнопка Сбросить, которую вы можете использовать для сброса кода, если вы допустили ошибку и не можете заставить его работать снова, а кнопку Показать решение вы можете нажать, чтобы увидеть потенциальный ответ, если вы действительно застрянете на решении.

+ +

Фильтрация приветственных сообщений

+ +

В первом упражнении мы начнем с простого: у нас есть множество сообщений поздравительных открыток, но мы хотим отсортировать их, чтобы перечислять только рождественские сообщения. Мы хотим, чтобы вы заполнили условный тест внутри структуры if( ... ), чтобы проверить каждую строку и отобразить её в списке, только если это рождественское сообщение.

+ +
    +
  1. Сначала подумайте о том, как вы можете проверить, является ли сообщение в каждом случае рождественским сообщением. Какая строка присутствует во всех этих сообщениях и какой метод вы можете использовать для проверки?
  2. +
  3. Затем вам нужно будет написать условный тест операнд1 оператор операнд2. Соответствует ли результат слева результату справа? Или в этом случае вызов метода слева возвращает результат справа?
  4. +
  5. Подсказка. В этом случае, вероятно, полезнее проверить, не является ли часть строки не равной (!==) определенному результату.
  6. +
+ + + +

{{ EmbedLiveSample('Playable_code', '100%', 590, "", "", "hide-codepen-jsfiddle") }}

+ +

Исправление регистра (размера букв в тексте—прим. пер.)

+ +

В этом упражнении у нас есть названия городов в Великобритании, но написанных разным регистром. Мы хотим, чтобы вы изменили их так, чтобы они были в нижнем регистре, за исключением первой буквы. Хороший способ сделать это:

+ +
    +
  1. Преобразуйте всю строку, содержащуюся в переменной input, в нижний регистр и сохраните ее в новой переменной.
  2. +
  3. Возьмите первую букву строки в этой новой переменной и сохраните ее в другой переменной.
  4. +
  5. Используя эту последнюю переменную в качестве подстроки, замените первую букву строчной строки первой буквой строчной строки, измененной на верхний регистр. Сохраните результат этой процедуры замены в другой новой переменной.
  6. +
  7. Измените значение переменной result на равную конечному результату (не input).
  8. +
+ +
+

Примечание: Подсказка — параметры строковых методов не обязательно должны быть строковыми литералами; они также могут быть переменными или даже переменными с вызываемым ими методом.

+
+ + + +

{{ EmbedLiveSample('Playable_code_2', '100%', 550, "", "", "hide-codepen-jsfiddle") }}

+ +

Создание новых строк из старых частей

+ +

В этом последнем упражнении массив содержит кучу строк, содержащих информацию о железнодорожных станциях на севере Англии. Строки представляют собой элементы данных, которые содержат трехбуквенный код станции, за которым следуют некоторые машиночитаемые данные, за которыми следует точка с запятой, а затем название станции, пригодное для чтения человеком. Например:

+ +
MAN675847583748sjt567654;Manchester Piccadilly
+ +

Мы хотим извлечь код станции и имя и поместить их в строку со следующей структурой:

+ +
MAN: Manchester Piccadilly
+ +

Мы бы рекоменовали реализовать это следующим образом:

+ +
    +
  1. Извлеките трехбуквенный код станции и сохраните его в новой переменной.
  2. +
  3. Найдите номер символьного номера точки с запятой.
  4. +
  5. Извлеките название для чтения человеком, используя номер индекса точки с запятой в качестве контрольной точки и сохраните его в новой переменной.
  6. +
  7. Объедините две новые переменные и строковый литерал, чтобы сделать финальную строку.
  8. +
  9. Измените значение переменной result равной конечной строке (не input). 
  10. +
+ + + +

{{ EmbedLiveSample('Playable_code_3', '100%', 585, "", "", "hide-codepen-jsfiddle") }}

+ +

Заключение

+ +

Нельзя не согласиться с тем, что способность обрабатывать слова и предложения в программировании очень важна — особенно в JavaScript, поскольку веб-сайты — все связаны с людьми. Эта статья дала вам основы, которые вам нужно знать о манипуляции строками на данный момент. Это пойдет вам на пользу, когда вы займётесь более сложными темами в будущем. Далее мы рассмотрим последний важный тип данных, на который нам нужно сосредоточиться в краткосрочной перспективе — массивы.

+ +

{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/Строки", "Learn/JavaScript/Первые_шаги/Arrays", "Learn/JavaScript/Первые_шаги")}}

+ +

В этом модуле

+ + diff --git a/files/ru/learn/javascript/first_steps/variables/index.html b/files/ru/learn/javascript/first_steps/variables/index.html new file mode 100644 index 0000000000..e1195effd5 --- /dev/null +++ b/files/ru/learn/javascript/first_steps/variables/index.html @@ -0,0 +1,372 @@ +--- +title: Переменные - место хранения необходимой информации +slug: Learn/JavaScript/Первые_шаги/Variables +translation_of: Learn/JavaScript/First_steps/Variables +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/Что_пошло_не_так", "Learn/JavaScript/Первые_шаги/Math", "Learn/JavaScript/Первые_шаги")}}
+ +

После прочтения последних двух статей вы знаете, что такое JavaScript, что он может сделать для вас, как использовать его вместе с другими веб-технологиями и какими он обладает функциями высокого уровня. В этой статье мы перейдем к реальным основам, рассмотрим, как работать с большинством базовых блоков JavaScript — Переменными.

+ + + + + + + + + + + + +
Необходимые навыки:Базовая компьютерная грамотность, базовое понимание HTML и CSS, понимание того, что такое JavaScript.
Цель:Ознакомиться с основами переменных в JavaScript.
+ +

Инструменты, которые вам нужны

+ +

В этой статье вам будет предложено ввести строки кода, чтобы проверить ваше понимание материала. Если вы используете браузер для настольных компьютеров, лучшим примером для ввода кода примера является консоль JavaScript вашего браузера (см. What are browser developer tools для получения дополнительной информации о том, как получить доступ к этому инструменту).

+ +

Также мы предоставили простую консоль JavaScript, встроенную ниже в странице, для ввода кода, если вы не используете браузер с консолью JavaScript или консоль на странице окажется для вас более комфортной.

+ +

Что такое переменные?

+ +

Переменные — это контейнер для таких значений, как числа, используемые в сложении, или строка, которую мы могли бы использовать как часть предложения. Но одна из особенностей переменных — их значение может меняться. Давайте взглянем на простой пример:

+ +
<button>Нажми на меня</button>
+ +
const button = document.querySelector('button');
+
+button.onclick = function() {
+  let name = prompt('Как Вас зовут?');
+  alert('Привет ' + name + ', рады видеть Вас!');
+}
+ +

{{ EmbedLiveSample('What_is_a_variable', '100%', 50, "", "", "hide-codepen-jsfiddle") }}

+ +

В примере, по нажатию кнопки выполнится несколько строк кода. Первая строка в функции покажет пользователю окно, где попросит ввести его имя и сохранит значение в переменной. Вторая строка отобразит приветствие с включенным введенным именем, взятым из значения переменной.

+ +

Чтобы лучше понять действие переменной здесь, давайте подумаем о том, как мы будем писать этот пример без использования переменной. Это будет выглядеть примерно так:

+ +
var name = prompt('Как вас зовут?');
+
+if (name === 'Адам') {
+  alert('Привет, Адам, рады тебя видеть!');
+} else if (name === 'Алан') {
+  alert('Привет, Алан, рады тебя видеть!');
+} else if (name === 'Бэлла') {
+  alert('Привет, Бэлла, рады тебя видеть!');
+} else if (name === 'Бьянка') {
+  alert('Привет, Бьянка, рады тебя видеть!');
+} else if (name === 'Крис') {
+  alert('Привет, Крис, рады тебя видеть!');
+}
+
+// ... и так далее ...
+ +

Вам сейчас не обязательно понимать синтаксис, который мы используем (пока!), но вы должны понять идею: если бы у нас не было доступных переменных, нам пришлось бы реализовать гигантский блок кода, который проверял, какое имя было введено, а затем отображал соответствующее сообщение для этого имени. Очевидно, что это неэффективно (код намного больше, даже для четырех вариантов), и он просто не сработает, так как вы не можете хранить все возможные варианты.

+ +

Переменные имеют смысл, и, когда вы узнаете больше о JavaScript, они начнут становиться второй натурой.

+ +

Еще одна особенность переменных заключается в том, что они могут содержать практически все, а не только строки и числа. Переменные могут также содержать сложные данные и даже целые функции. Об этом вы узнаете больше при дальнейшем изучении курса..

+ +

Заметьте: мы говорим, что переменные содержат значения. Это важное различие. Переменные не являются самими значениями; они представляют собой контейнеры для значений. Представьте, что они похожи на маленькие картонные коробки, в которых вы можете хранить вещи.

+ +

+ +

Объявление переменной

+ +

Чтобы использовать переменную, вы сначала должны ее создать, или, если быть точнее, объявить переменную. Чтобы сделать это, мы вводим ключевое слово var, за которым следует имя, которое вы хотите дать своей переменной:

+ +
var myName;
+var myAge;
+ +

Здесь мы создаем две переменные myName и myAge. Попробуйте ввести эти строки сейчас в консоли вашего веб-браузера или в консоли ниже (можно открыть эту консоль в отдельной вкладке или в новом окне). После этого попробуйте создать переменную (или две) с вашими именами.

+ + + +

{{ EmbedLiveSample('Hidden_code', '100%', 300) }}

+ +
+

Заметка: в JavaScript все инструкции кода должны заканчиваться точкой с запятой (;) - ваш код может работать правильно для отдельных строк, но, вероятно, не будет, когда вы пишете несколько строк кода вместе. Попытайтесь превратить написание точки с запятой в привычку.

+
+ +

Теперь проверим, существуют ли эти значения в среде выполненияв Для этого введем только имя переменной.

+ +
myName;
+myAge;
+ +

В настоящее время они не содержат значения, это пустые контейнеры. В этом случае, когда вы вводите имена переменных, вы должны получить значение  undefined . Если они не существуют, вы получите сообщение об ошибке - попробуйте сейчас ввести в консоли имя переменной ниже:

+ +
scoobyDoo;
+ +
+

Заметка: Не путайте переменную, которая существует, но не имеет значения, с переменной, которая вообще не существует - это разные вещи.

+
+ +

Присвоение значения переменной

+ +

Как только переменная объявлена, ей можно присвоить значение. Для этого пишется имя переменной, затем следует знак равенства (=), а за ним значение, которое вы хотите присвоить. Например:

+ +
myName = 'Chris';
+myAge = 37;
+ +

Попробуйте вернуться в консоль и ввести эти строки. Вы должны увидеть значение, которое вы назначили переменной, возвращаемой в консоли. Чтобы посмотреть значения переменных, нужно набрать их имя в консоли:

+ +
myName;
+myAge;
+ +

Вы можете объявить переменную и задать ей значение одновременно:

+ +
var myName = 'Chris';
+ +

Скорее всего, так вы будете писать большую часть времени, так как запись и выполнения кода с одно строки происходит быстрее, чем выполнение двух действий на двух отдельных строках.

+ +
+

Заметка: Если вы пишете многострочную программу JavaScript, которая объявляет и инициализирует (задает значение) переменную, вы можете объявить ее после ее инициализации, и она все равно будет работать. Это связано с тем, что объявления переменных обычно выполняются первыми, прежде чем остальная часть кода будет выполнена. Это называется hoisting - прочитайте var hoisting для более подробной информации по этому вопросу.

+
+ +

Обновление переменной

+ +

Когда переменной присваивается значение, вы можете изменить (обновить) это значение, просто указав другое значение. Попробуйте ввести следующие строки в консоль:

+ +
myName = 'Bob';
+myAge = 40;
+ +

Правила именования переменных

+ +

Вы можете назвать переменную как угодно, но есть ограничения. Как правило, вы должны придерживаться только латинских символов (0-9, a-z, A-Z) и символа подчеркивания.

+ + + +
+

Заметка: По ссылке можно найти довольно полный список зарезервированных ключевых слов: Lexical grammar — keywords.

+
+ +

Примеры хороших имен переменных:

+ +
age
+myAge
+init
+initialColor
+finalOutputValue
+audio1
+audio2
+
+ +

Примеры плохих имен переменных:

+ +
1
+a
+_12
+myage
+MYAGE
+var
+Document
+skjfndskjfnbdskjfb
+thisisareallylongstupidvariablenameman
+ +

Примеры имен переменных, которые вызовут ошибки:

+ +
var
+Document
+
+ +

Попытайтесь создать еще несколько переменных прямо сейчас, используя знания, изложенные выше.

+ +

Типы переменных

+ +

Есть несколько различных типов данных, которые мы можем хранить в переменных. В этом разделе мы кратко опишем их, а затем в будущих статьях вы узнаете о них более подробно.

+ +

Числа (Numbers)

+ +

Вы можете хранить числа в переменных (целые числа, такие как 30, или десятичные числа, такие как 2.456, также называемые числами с плавающей точкой или с плавающей запятой). Вам не нужно объявлять типы переменных в JavaScript, в отличие от некоторых других языков программирования Если давать переменной значение числа,кавычки не используются:

+ +
var myAge = 17;
+ +

Строки ('Strings')

+ +

Строки - это фрагменты текста. Когда вы даете переменной значение строки, вам нужно обернуть ее в одиночные или двойные кавычки, в противном случае JavaScript попытается проиндексировать ее как другое имя переменной.

+ +
var dolphinGoodbye = 'So long and thanks for all the fish';
+ +

Логические (Booleans)

+ +

Booleans - истинные / ложные значения - они могут иметь два значения: true или false. Они обычно используются для проверки состояния, после чего код запускается соответствующим образом. Вот простой пример:

+ +
var iAmAlive = true;
+ +

В действительности вы чаще будете использовать этот тип переменных так:

+ +
var test = 6 < 3;
+
+ +

Здесь используется оператор «меньше» (<), чтобы проверить, является ли 6 меньше 3. В данном примере, он вернет false, потому что 6 не меньше 3! В дальнейшем вы узнаете больше о таких операторах.

+ +

Массивы (Arrays)

+ +

Массив - это один объект, который содержит несколько значений, заключенных в квадратные скобки и разделенных запятыми. Попробуйте ввести следующие строки в консоль:

+ +
var myNameArray = ['Chris', 'Bob', 'Jim'];
+var myNumberArray = [10,15,40];
+ +

Как только эти массивы определены, можно получить доступ к каждому значению по их местоположению в массиве. Наберите следующие строки:

+ +
myNameArray[0]; // should return 'Chris'
+myNumberArray[2]; // should return 40
+ +

Квадратные скобки указывают значение индекса, соответствующее позиции возвращаемого значения. Возможно, вы заметили, что массивы в JavaScript индексируются с нулевой отметкой: первый элемент имеет индекс 0.

+ +

В следующей статье вы узнаете больше о массивах.

+ +

Объекты (Objects)

+ +

В программировании объект представляет собой структуру кода, который моделирует объект реальной жизни. У вас может быть простой объект, представляющий автостоянку, и содержит информацию о её ширине и длине; или вы можете иметь объект, который представляет человека, и содержит данные о его имени, росте, весе, на каком языке он говорит, как сказать ему привет и многое другое.

+ +

Попробуйте ввести следующую строку в консоль:

+ +
var dog = { name : 'Spot', breed : 'Dalmatian' };
+ +

Чтобы получить информацию, хранящуюся в объекте, вы можете использовать следующий синтаксис:

+ +
dog.name
+ +

Мы больше не будем рассматривать объекты в данном курсе - вы можете больше узнать о них в будущем модуле.

+ +

Свободная типизация

+ +

JavaScript - это «свободно типизируемый язык», что означает, что в отличие от некоторых других языков вам не нужно указывать, какой тип данных будет содержать переменная (например, числа, строки, массивы и т. д.).

+ +

Например, если вы объявите переменную и присвоите ей значение, заключенное в кавычки, браузер будет обрабатывать переменную как строку:

+ +
var myString = 'Привет';
+ +

Он все равно будет строкой, даже если он содержит числа, поэтому будьте осторожны:

+ +
var myNumber = '500'; // упс, это все еще строка (string)
+typeof(myNumber);
+myNumber = 500; // так-то лучше, теперь это число (number)
+typeof(myNumber);
+ +

Попробуйте ввести четыре строки выше в консоль одну за другой и посмотреть результаты. Вы заметите, что мы используем специальную функцию typeof()  - она возвращает тип данных переменной, которую вы передаете в нее. В первый раз, когда она вызывается, она должа возвращать строку, так как переменная myNumber содержит строку '500'. Посмотрите, что она вернет во второй раз, когда вы ее вызовите.

+ +

Подведение итогов

+ +

К настоящему времени вы должны знать достаточно о переменных JavaScript и о том, как их создавать. В следующей статье мы остановимся на числах более подробно, рассмотрев, как сделать базовую математику в JavaScript.

+ +

{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/Что_пошло_не_так", "Learn/JavaScript/Первые_шаги/Math", "Learn/JavaScript/Первые_шаги")}}

diff --git a/files/ru/learn/javascript/first_steps/what_is_javascript/index.html b/files/ru/learn/javascript/first_steps/what_is_javascript/index.html new file mode 100644 index 0000000000..f34dac6902 --- /dev/null +++ b/files/ru/learn/javascript/first_steps/what_is_javascript/index.html @@ -0,0 +1,339 @@ +--- +title: Что такое JavaScript? +slug: Learn/JavaScript/Первые_шаги/What_is_JavaScript +translation_of: Learn/JavaScript/First_steps/What_is_JavaScript +--- +
{{LearnSidebar}}
+ +
{{NextMenu("Learn/JavaScript/Первые_шаги/A_first_splash", "Learn/JavaScript/Первые_шаги")}}
+ +

Добро пожаловать на курс MDN JavaScript для начинающих! В первой статье курса мы дадим базовое определение JavaScript, ответим на вопросы «Что такое JavaScript?» и «Что он делает?», узнаем как работает JavaScript и как добавить его на веб-страницу.

+ + + + + + + + + + + + +
Необходимые навыки:Базовая компьютерная грамотность, знание основ HTML и CSS.
Цели:Знакомство с JavaScript и его возможностями, способами его подключения к веб-странице.
+ +

Определение высокого уровня

+ +

JavaScript это язык, который позволяет Вам применять сложные вещи на web странице — каждый раз, когда на web странице происходит что-то большее, чем просто её статичное отображение — отображение периодически обновляемого контента, или интерактивных карт, или анимация 2D/3D графики, или прокрутка видео в проигрывателе, и т.д. — можете быть уверены, что скорее всего, не обошлось без JavaScript. Это третий слой слоёного пирога стандартных web технологий, два из которых (HTML и CSS) мы детально раскрыли в других частях учебного пособия.

+ +

+ + + +

Три слоя прекрасно выстраиваются друг над другом. Возьмем простой текст для примера. Для придания структуры и смыслового назначения тексту, разметим его с помощью HTML:

+ +
<p>Player 1: Chris</p>
+ +

+ +

Затем мы добавим немного CSS, что бы это выглядело симпатичнее:

+ +
p {
+  font-family: 'helvetica neue', helvetica, sans-serif;
+  letter-spacing: 1px;
+  text-transform: uppercase;
+  text-align: center;
+  border: 2px solid rgba(0,0,200,0.6);
+  background: rgba(0,0,200,0.3);
+  color: rgba(0,0,200,0.6);
+  box-shadow: 1px 1px 2px rgba(0,0,200,0.4);
+  border-radius: 10px;
+  padding: 3px 10px;
+  display: inline-block;
+  cursor:pointer;
+}
+ +

+ +

И наконец, добавим немного JavaScript для придания динамического поведения:

+ +
const para = document.querySelector('p');
+
+para.addEventListener('click', updateName);
+
+function updateName() {
+  let name = prompt('Enter a new name');
+  para.textContent = 'Player 1: ' + name;
+}
+ +

{{ EmbedLiveSample('Определение_высокого_уровня', '100%', 80) }}

+ +

Попробуйте кликнуть по тексту чтобы увидеть, что произойдет (Вы так же можете найти это демо на GitHub — смотрите исходный код, или запустите вживую)!

+ +

JavaScript может делать намного больше — давайте выясним это более детально.

+ +

Так что же он действительно может делать?

+ +

Ядро языка JavaScript состоит из некоторого количества обычных возможностей, которые позволяют делать следующее:

+ + + +

Еще более увлекательным является функциональность, созданная поверх основного языка JavaScript. Так называемые интерфейсы прикладного программирования (API) предоставляют вам дополнительные сверхспособности для использования в вашем коде JavaScript.

+ +

API - это готовые наборы блоков кода, которые позволяют разработчику реализовывать программы, которые в противном случае было бы трудно или невозможно реализовать. Они делают то же самое для программирования, что готовые комплекты мебели делают для домашнего строительства - гораздо проще брать готовые панели и скручивать их вместе, чтобы сделать книжную полку, чем самому разрабатывать дизайн, ходить в поисках правильной древесины, вырезать все панели необходимого размера и формы, найти подходящие винты, а затем собрать их вместе, чтобы сделать книжную полку.

+ +

Они обычно делятся на две категории.

+ +

+ +

API-интерфейсы браузера встроены в ваш веб-браузер и могут отображать данные из окружающего компьютерного окружения или делать полезные сложные вещи. Например:    

+ + + +
+

Заметка: Большинство наших демо не будут корректно работать в старых браузерах — поэтому будет хорошей идеей,  для запуска вашего кода установить один из современных браузеров , таких как Firefox, Chrome, Edge или Opera . Также понадобится более подробно рассмотреть раздел по кроссбраузерному тестированию, когда вы приблизитесь к разработке производственного кода (т.е реального кода, который будут использовать клиенты).

+
+ +

По умолчанию сторонние API-интерфейсы  не встроены в браузер, и вам придётся захватывать их код и информацию из какого-либо места в Сети. Для примера: 

+ + + +
+

Заметка: Эти API-и являются продвинутыми, и мы не будем их рассматривать в нашем курсе, но ссылки, данные выше, предлагают полную документацию, если вы заинтересованы в более подробной информации.

+
+ +

Доступно еще больше! Но пока не заостряйте на этом внимание. Вы не сможете создать следующий Facebook, Google Maps или Instagram после 24 часов изучения JavaScript — сначала нужно изучить основы. И именно для этого вы здесь — давайте двигаться дальше!

+ +

Что JavaScript делает на вашей странице?

+ +

В этой главе мы рассмотрим код и увидим что же действительно происходит, когда на странице запускается JavaScript.

+ +

Давайте составим краткий бриф, что же происхоит когда мы загружаем страничку в браузере (первое упоминание в статье Как работает CSS). Когда вы загружаете страничку в браузере, вы запускаете ваш код (HTML, CSS и JavaScript) внутри исполняемой среды (внутри вкладки браузера). Это как будто фабрика берет сырьё (некий код) и выдает продукцию (веб-страничку).

+ +

+ +

Код JavaScript выполняется JavaScript-движком браузера, после того как код HTML и CSS был обработан и сформирован в веб-страницу. Это гарантирует, что структура и стиль страницы уже сформированы к моменту запуска JavaScript.

+ +

Это хорошо, так как часто использование JavaScript заключается в динамическом изменении HTML и CSS в целях обновления пользовательского интерфейса посредством Document Object Model API (как упоминалось выше). Если бы запуск JavaScript осуществлялся прежде загрузки HTML и CSS, то это привело бы к возникновению ошибок.  

+ +

Безопасность браузера

+ +

Каждая вкладка браузера представляет собой отдельную коробку для запуска кода (в техническом языке, эти коробки называются "средами исполнения") — это значит, что в большинстве случаев код на каждой вкладке запускается полностью отдельно, а код одной вкладки не может напрямую влиять на код другой вкладки или на другом веб-сайте. Это хорошая мера безопасности — если бы это было иначе, пираты могли написать код, который крал информацию с других сайтов или делал другие плохие вещи.

+ +
+

Заметка: Есть способы отправлять код и данные между разными веб-сайтами/вкладками безопасным способом, но это продвинутые методы, которые мы не будем рассматривать в рамках этого курса.

+
+ +

Последовательность выполнения JavaScript

+ +

Обычно, когда браузер сталкивается с блоком JavaScript, он запускает его по порядку, сверху вниз. Это значит, что вам нужно осторожно выбирать порядок. Например, вернемся к блоку JavaScript, который мы видели в первом примере:

+ +
const para = document.querySelector('p');
+
+para.addEventListener('click', updateName);
+
+function updateName() {
+  let name = prompt('Enter a new name');
+  para.textContent = 'Player 1: ' + name;
+}
+ +

Здесь мы выбираем абзац текста (строка 1), а затем добавляем к нему обнаружение событий (строка 3), чтобы при нажатии на этот абзац выполнялся блок кода updateName() (строки 5–8). Блок кода updateName() (эти типы многократно используемых блоков кода называются "функции") запрашивает у пользователя новое имя, а затем вставляет это имя в абзац для обновления отображения.

+ +

Если вы поменяете порядок первых двух строк кода, он перестанет работать — вместо этого вы получите ошибку возвращаемую в консоль браузераTypeError: para is undefined. Это значит, что объект para еще не существует и вы не можете добавить к нему обнаружение событий.

+ +
+

Заметка: Это очень частая ошибка — вы должны быть осторожны, чтобы объекты, на которые ссылается ваш код, существовали до того, как вы попытаетесь что-то с ними сделать.

+
+ +

Интерпретируемый против компилируемого кода

+ +

В контексте программирования, вы можете услышать термины интерпретация и компиляция. JavaScript является интерпретируемым языком — код запускается сверху вниз и результат запуска немедленно возвращается. Вам не нужно преобразовывать код в другую форму, перед запуском в браузере.

+ +

С другой стороны, компилируемые языки преобразуются (компилируются) в другую форму, прежде чем они будут запущены компьютером. Например, C / C ++ компилируются в язык ассемблера, который затем запускается компьютером.

+ +

Оба подхода имеют разные преимущества, которые на данном этапе мы обсуждать не будем.

+ +

Серверный против клиентского кода

+ +

Вы так же можете услышать термины серверный и клиентский код, особенно в контексте веб-разработки. Клиентский код — это код, который запускается на компьютере пользователя. При просмотре веб-страницы, клиентский код загружается, а затем запускается и отображается браузером. В этом модуле JavaScript мы явно говорим о клиентском JavaScript.

+ +

С другой стороны, серверный код запускается на сервере, затем его результаты загружаются и отображаются в браузере. Примеры популярных серверных веб-языков включают PHP, Python, Ruby и ASP.NET. И JavaScript! JavaScript так же может использоваться, как серверный язык, например в популярной среде Node.js — вы можете больше узнать о серверном JavaScript в нашем разделе Dynamic Websites – Server-side programming.

+ +

Слово динамический используется для описания и клиентского JavaScript, и серверного языка — это относится к возможности обновления отображения веб-страницы/приложения, чтобы показывать разные вещи в разных обстоятельствах, генерируя новый контент по мере необходимости. Серверный код динамически генерирует новый контент на сервере, например достает данные из базы данных, тогда как клиентский JavaScript динамически генерирует новое содержание внутри браузера на клиенте, например создает новую HTML таблицу, вставляя в нее данные полученные с сервера, затем отображает таблицу на веб-странице, которую видит пользователь. В этих двух контекстах значение немного отличается, но связано, и обычно оба подхода (серверный и клиентский) работают вместе.

+ +

Веб-страница без динамического обновления контента называется статической — она просто показывает один и тотже контент все время.

+ +

Как добавить JavaScript на вашу страницу?

+ +

JavaScript применяется к вашей HTML странице точно так же, как CSS. И если CSS использует элементы {{htmlelement("link")}} для внешних стилей и {{htmlelement("style")}} для встроеных в HTML, то для JavaScript нужен только один друг в HTML мире — элемент {{htmlelement("script")}}. Давайте узнаем, как это работает.

+ +

Внутренний JavaScript

+ +
    +
  1. Сначала, сделайте локальную копию нашего файла-примера apply-javascript.html. Сохраните его в удобное для вас место.
  2. +
  3. Откройте этот файл в вашем браузере и в вашем текстовом редакторе. Вы увидите, что HTML создает простую веб-страницу с активной кнопкой.
  4. +
  5. Затем, перейдите в текстовый редактор и добавьте следующие строки перед закрывающим тегом </head>: +
    <script>
    +
    +  // здесь будет JavaScript
    +
    +</script>
    +
  6. +
  7. Теперь добавим JavaScript внутрь элемента {{htmlelement("script")}}, чтобы сделать страницу более интересной — добавьте следующий код ниже строки "// здесь будет JavaScript": +
    document.addEventListener("DOMContentLoaded", function() {
    +  function createParagraph() {
    +    let para = document.createElement('p');
    +    para.textContent = 'You clicked the button!';
    +    document.body.appendChild(para);
    +  }
    +
    +  const buttons = document.querySelectorAll('button');
    +
    +  for(let i = 0; i < buttons.length ; i++) {
    +    buttons[i].addEventListener('click', createParagraph);
    +  }
    +});
    +
  8. +
  9. Сохраните файл и обновите страницу в браузере — теперь вы должны увидеть, что при нажатии на кнопку создается новый абзац и помещается ниже.
  10. +
+ +
+

Заметка: Если ваш пример не работает, пройдите еще раз все шаги и проверьте, сделали ли вы все правильно. Сохранили ли вы вашу локальную копию начального кода, как .html файл? Добавили ли ваш {{htmlelement("script")}} элемент после тэга </body>? Ввели ли вы JavaScript именно так, как показано? JavaScript регистрозависимый, и очень привередливый. Поэтому вам нужно вводить синтаксис именно так, как показано, в противном случае оно может не работать.

+
+ +
+

Заметка: Вы можете увидеть эту версию на GitHub-е как apply-javascript-internal.html (посмотреть вживую).

+
+ +

Внешний JavaScript

+ +

Это отлично работает, но что если мы хотим поместить наш JavaScript в отдельный файл? Давайте сейчас разберемся с этим.

+ +
    +
  1. Сначала, создайте новый файл в той же папке, что и ваш файл-пример HTML. Назовите его script.js — убедитесь, что у имени файла расширение .js, так как оно распознается, как JavaScript.
  2. +
  3. Замените ваше текущий элемент {{htmlelement("script")}} на следующий: +
    <script src="script.js" defer></script>
    +
  4. +
  5. Внутри script.js добавьте следующий скрипт: +
    function createParagraph() {
    +  let para = document.createElement('p');
    +  para.textContent = 'You clicked the button!';
    +  document.body.appendChild(para);
    +}
    +
    +const buttons = document.querySelectorAll('button');
    +
    +for(let i = 0; i < buttons.length ; i++) {
    +  buttons[i].addEventListener('click', createParagraph);
    +}
    +
  6. +
  7. Сохраните и обновите страницу в браузере, и вы увидите то же самое! Все работает точно так же, но теперь у нас есть JavaScript во внешнем файле. Это, как правило, хорошо с точки зрения организации кода и его повторного использования в нескольких HTML файлах. Кроме того, HTML легче читать без огромных кусков кода, который скапливается в нем.
  8. +
+ +
+

Заметка: Вы можете увидеть эту версию на GitHub-е как apply-javascript-external.html и script.js (посмотреть вживую).

+
+ +

Инлайновые JavaScript обработчики

+ +

Обратите внимание, что иногда можно столкнуться с частями JavaScript кода, который живет внутри HTML. Это может выглядеть примерно так:

+ +
+
function createParagraph() {
+  var para = document.createElement('p');
+  para.textContent = 'You clicked the button!';
+  document.body.appendChild(para);
+}
+ +
<button onclick="createParagraph()">Click me!</button>
+
+ +

Вы можете попробовать эту версию в нашей демонстрации ниже:

+ +

{{ EmbedLiveSample('Inline_JavaScript_handlers', '100%', 150) }}

+ +

Эта демонстрация имеет те же функциональные возможности, что и в предыдущих двух разделах, за исключением того, что элемент {{htmlelement("button")}} содержит встроенный обработчик onclick, который запускает функцию при нажатии кнопки.

+ +

Но пожалуйста, не делайте этого. Это плохая практика — загрязнять ваш HTML кодом JavaScript, и она не эффективна — вам нужно будет добавить атрибут onclick="createParagraph()" к каждой кнопке, к которой вы хотите подключить JavaScript.

+ +

Использование чистой JavaScript конструкции, позволит вам выбрать все кнопки, используя одну команду. Код, который можно использовали для этой цели, выглядит следующим образом:

+ +
const buttons = document.querySelectorAll('button');
+
+for(let i = 0; i < buttons.length ; i++) {
+  buttons[i].addEventListener('click', createParagraph);
+}
+ +

Это может выглядеть немного длиннее, чем атрибут onclick, но это будет работать для всех кнопок, независимо от того, сколько их на странице, и сколько их удалят или добавят. JavaScript менять не нужно.

+ +
+

Заметка: Попробуйте отредактировать вашу версию apply-javascript.html и добавить еще несколько кнопок в файл. После перезагрузки вы должны увидеть, что все кнопки создают параграф, если кликнуть на них. Классно, да?

+
+ +

Стратегии загрузки скриптов

+ +

Существует ряд проблем, связанных с загрузкой скриптов в нужное время. Всё не так просто, как кажется! Распространённой проблемой является то, что весь HTML-код на странице загружается в том порядке, в котором отображается. Если вы используете JavaScript для манипуляции элементами на странице (или, точнее, в DOM – Объектной Модели Документа), ваш код не будет работать, если JavaScript-код загрузится и распознается раньше HTML-кода, с которым вы пытаетесь взаимодействовать.

+ +

Комментарии

+ +

Так же, как и в HTML и CSS, возможно писать комментарии в вашем JavaScript коде, что будет проигнорировано браузером, и существует только для того, чтобы давать подсказки вашим друзьям-разработчикам о том, как работает код (и лично вам, если вы вернетесь к коду спустя 6 месяцев и не сможете вспомнить, что вы делали). Комментарии очень полезны, и вы должны часто их использовать, особенно для больших приложений. Вот два типа комментариев:

+ + + +

Так, например, мы можем описать наш последний демо-пример JavaScript подобными комментариями:

+ +
// Функция: создает новый параграф и добавляет его вниз тела HTML.
+
+function createParagraph() {
+  var para = document.createElement('p');
+  para.textContent = 'You clicked the button!';
+  document.body.appendChild(para);
+}
+
+/*
+  1. Получаем ссылки на все кнопки на странице в виде массива.
+  2. Перебераем все кнопки и добавляем к ним отслеживатель события нажатия.
+
+  При нажатии любой кнопки, будет выполняться функция createParagraph().
+*/
+
+var buttons = document.querySelectorAll('button');
+
+for (var i = 0; i < buttons.length ; i++) {
+  buttons[i].addEventListener('click', createParagraph);
+}
+ +

Выводы

+ +

Поздравляем, вы сделали ваш первый шаг в мир JavaScript. Мы начали всего-лишь с теории, чтобы вы привыкли к тому, что вы будете использовать JavaScript, и что именно вы можете делать с его помощью. На этом пути вы увидели несколько примеров кода и выучили, как JavaScript вписывается в остальной код на вашем сайте среди всего прочего.

+ +

JavaScript может показаться немного пугающим в данным момент, но не переживайте - в этом курсе мы проведем вас сквозь него простыми шагами, которые имеют смысл, забегая наперед. В следующей главе мы погрузимся непосредственно в практику, подталкивая вас погрузиться в код и сделать ваши собственные примеры JavaScript.

+ +

{{NextMenu("Learn/JavaScript/Первые_шаги/A_first_splash", "Learn/JavaScript/Первые_шаги")}}

diff --git a/files/ru/learn/javascript/first_steps/what_went_wrong/index.html b/files/ru/learn/javascript/first_steps/what_went_wrong/index.html new file mode 100644 index 0000000000..dbb0a4577a --- /dev/null +++ b/files/ru/learn/javascript/first_steps/what_went_wrong/index.html @@ -0,0 +1,249 @@ +--- +title: Что пошло не так? Устранение ошибок JavaScript +slug: Learn/JavaScript/Первые_шаги/Что_пошло_не_так +translation_of: Learn/JavaScript/First_steps/What_went_wrong +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/A_first_splash", "Learn/JavaScript/Первые_шаги/Variables", "Learn/JavaScript/Первые_шаги")}}
+ +

Когда вы создали игру «Угадай номер» в предыдущей статье, вы, возможно, обнаружили, что она не работает. Не бойтесь — эта статья призвана избавить вас от разрыва волос над такими проблемами, предоставив вам несколько простых советов о том, как найти и исправить ошибки в программах JavaScript.

+ + + + + + + + + + + + +
+

Нужно:

+
базовая компьютерная грамотность, базовое понимание HTML и CSS, понимание того, что такое JavaScript.
Цельполучить способность и уверенность в том, чтобы приступить к исправлению простых проблем в вашем собственном коде.
+ +

Типы ошибок

+ +

Когда вы делаете что-то не так в коде, есть два основных типа ошибок, с которыми вы столкнетесь:

+ + + +

Ладно, все не так просто — есть и другие отличия, которые вы поймете, пока будете изучать язык JavaScript глубже. Однако вышеуказанной классификации достаточно на раннем этапе вашей карьеры. Мы рассмотрим оба эти типа в дальнейшем.

+ +

Ошибочный пример

+ +

Чтобы начать работу, давайте вернемся к нашей игре с угадыванием чисел — за исключением того, что мы будем изучать версию с некоторыми преднамеренными ошибками. Перейдите в Github и сделайте себе локальную копию number-game-errors.html (см. здесь как это работает).

+ +
    +
  1. Чтобы начать работу, откройте локальную копию внутри вашего любимого текстового редактора и вашего браузера.
  2. +
  3. Попробуйте сыграть в игру — вы заметите, что когда вы нажимаете кнопку «Submit guess», она не работает!
  4. +
+ +
+

Примечание: Возможно, у вас может быть собственная версия игрового примера, которая не работает, которую вы можете исправить! Мы по-прежнему хотели бы, чтобы вы работали над статьей с нашей версией, чтобы вы могли изучать методы, которые мы здесь преподаем. Затем вы можете вернуться и попытаться исправить ваш пример.

+
+ +

На этом этапе давайте рассмотрим консоль разработчика, чтобы увидеть, можем ли мы видеть какие-либо синтаксические ошибки, а затем попытаемся их исправить. Вы узнаете, как это сделать, ниже.

+ +

Исправление синтаксических ошибок

+ +

Раньше в курсе мы заставили вас набрать некоторые простые команды JavaScript в консоль разработчика JavaScript (если вы не можете вспомнить, как открыть это в своем браузере, следуйте предыдущей ссылке, чтобы узнать, как это сделать). Что еще более полезно, так это то, что консоль предоставляет вам сообщения об ошибках всякий раз, когда существует синтаксическая ошибка внутри JavaScript, которая подается в механизм JavaScript браузера. Теперь пойдем на охоту.

+ +
    +
  1. Перейдите на вкладку, в которой у вас есть number-game-errors.html, и откройте консоль JavaScript. Вы должны увидеть сообщение об ошибке в следующих строках:
  2. +
  3. Это довольно простая ошибка для отслеживания, и браузер дает вам несколько полезных бит информации, которые помогут вам (скриншот выше от Firefox, но другие браузеры предоставляют аналогичную информацию). Слева направо, у нас есть: +
      +
    • Красный «x» означает, что это ошибка.
    • +
    • Сообщение об ошибке, указывающее, что пошло не так: «TypeError: guessSubmit.addeventListener не является функцией»
    • +
    • Ссылка «Узнать больше», которая ссылается на страницу MDN, которая объясняет, что эта ошибка означает в огромных количествах деталей.
    • +
    • Имя файла JavaScript, который ссылается на вкладку «Отладчик» консоли разработчика. Если вы перейдете по этой ссылке, вы увидите точную строку, где подсвечивается ошибка.
    • +
    • Номер строки, в которой находится ошибка, и номер символа в этой строке, где первая ошибка. В этом случае у нас есть строка 86, символ номер 3.
    • +
    +
  4. +
  5. Если мы посмотрим на строку 86 в нашем редакторе кода, мы найдем эту строку: +
    guessSubmit.addeventListener('click', checkGuess);
    +
  6. +
  7. В сообщении об ошибке говорится, что «guessSubmit.addeventListener не является функцией», поэтому мы, вероятно, где-то ошиблись. Если вы не уверены в правильности написания синтаксиса, часто бывает полезно найти функцию на MDN. Лучший способ сделать это в настоящее время — поиск «mdn имя-функции» в вашей любимой поисковой системе. Вот ссылка, которая поможет сократить вам некоторое время в данном случае: addEventListener().
  8. +
  9. Итак, глядя на эту страницу, кажется, что ошибка в том, что мы неправильно назвали имя функции! Помните, что JavaScript чувствителен к регистру, поэтому любые незначительные отличия в орфографии или регистре текста могут вызвать ошибку. Изменение этого параметра в addEventListener должно быть исправлено. Сделайте это сейчас.
  10. +
+ +
+

Примечание: См. наш TypeError: «x» не является справочной страницей функций для получения дополнительной информации об этой ошибке.

+
+ +

Синтаксические ошибки: второй раунд

+ +
+

Примечание: console.log() это часто используемая функция отладки, которая выводит значение в консоль. Поэтому она будет выводить значение lowOrHi в консоли, как только мы попытаемся установить его в строке 48.

+
+ +
    +
  1. Сохраните и обновите страницу, и вы увидите, что ошибка исчезла.
  2. +
  3. Теперь, если вы попробуете ввести значение и нажать кнопку "Submit guess", вы увидите ... другую ошибку! 
  4. +
  5. На этот раз сообщается об ошибке: "TypeError: lowOrHi is null", в строке 78. +
    Примечание: Null — это специальное значение, которое означает "ничего" или "не значение". Поэтому lowOrHi был объявлен и инициализирован без значения — у него нет типа или значения.
    + +
    Примечание: Эта ошибка не появилась, как только страница была загружена, потому что эта ошибка произошла внутри функции (внутри checkGuess() { ... } block). Об этом вы узнаете более подробно в нашей более поздней статье о функциях, код внутри функций выполняется в отдельной области для кода внешних функций. В этом случае код не был запущен, и ошибка не была брошена до тех пор, пока функция checkGuess() не была запущена строкой 86.
    +
  6. +
  7. Посмотрите на строку 78, и вы увидите следующий код: +
    lowOrHi.textContent = «Последнее предположение было слишком высоко!»;
    +
  8. +
  9. Эта строка пытается установить свойство textContent переменной lowOrHi как текстовую строку, но это не работает, поскольку lowOrHi не содержит того, что должна. Давайте посмотрим, почему так происходит — попробуйте найти другие экземпляры lowOrHi в коде. Самый ранний экземпляр, который вы найдете в JavaScript, находится в строке 48: +
    var lowOrHi = document.querySelector('lowOrHi');
    +
  10. +
  11. На этом этапе мы пытаемся заставить переменную содержать ссылку на элемент документа HTML. Давайте проверим, является ли значение  null после выполнения этой строки. Добавьте следующий код в строку 49: +
    console.log(lowOrHi);
    +
    +
  12. +
  13. Сохраните и обновите, и вы должны увидеть результат работы console.log() в консоли браузера. Разумеется, значение lowOrHi на данный момент равно null, поэтому определенно существует проблема в строке 48.
  14. +
  15. Давайте подумаем о том, что может быть проблемой. Строка 48 использует метод document.querySelector() для получения ссылки на элемент, выбирая его с помощью селектора CSS. Посмотрев далее наш файл, мы можем найти обсуждаемый элемент <p>: +
    <p class="lowOrHi"></p>
    +
    +
  16. +
  17. Поэтому нам нужен селектор классов, который начинается с точки (.), но селектор, передаваемый в метод querySelector() в строке 48, не имеет точки. Возможно, это и есть проблема! Попробуйте изменить lowOrHi на .lowOrHi в строке 48.
  18. +
  19. Повторите попытку сохранения и обновления, и ваш вызов console.log() должен вернуть элемент <p>, который мы хотим. Уф! Еще одна ошибка исправлена! Вы можете удалить строку с  console.log() сейчас, или оставить для дальнейшего применения — выбирайте сами.
  20. +
+ +
+

Примечание: Загляните на справочную страницу TypeError: "x" is (not) "y", чтобы узнать больше об этой ошибке.

+
+ +

Синтаксические ошибки: третий раунд

+ +
    +
  1. Теперь, если вы снова попробуете сыграть в игру, вы должны добиться большего успеха — игра должна играть абсолютно нормально, пока вы не закончите игру, либо угадав нужное число, либо потеряв жизни.
  2. +
  3. На данном этапе игра снова слетает, и выводится такая же ошибка, как и в начале — "TypeError: resetButton.addeventListener is not a function"! Однако, теперь она происходит из-за строки 94.
  4. +
  5. Посмотрев на строку 94, легко видеть, что здесь сделана такая же ошибка. Нам просто нужно изменить addeventListener на addEventListener.
  6. +
+ +

Логическая ошибка

+ +

На этом этапе игра должна проходить отлично, однако, поиграв несколько раз, вы, несомненно заметите, что случайное число, которое вы должны угадать, всегда 0 или 1. Определенно не совсем так, как мы хотим, чтобы игра была разыграна!

+ +

Безусловно, где-то в игре есть логическая ошибка — игра не возвращает ошибку, она просто работает неправильно.

+ +
    +
  1. Найдем переменную randomNumber , и строку где в первый раз устанавливали случайное число. Пример, в котором мы храним случайное число, которое должны угадать, на строке 44: + +
    var randomNumber = Math.floor(Math.random()) + 1;
    +
    + И на строке 113, где мы генерируем случайное число, каждый раз после окончания игры: + +
    randomNumber = Math.floor(Math.random()) + 1;
    +
    +
  2. +
  3. Чтобы проверить, действительно ли проблема в этом, давайте обратимся к нашему другу console.log() снова — вставьте ее ниже строк с ошибками: +
    console.log(randomNumber);
    +
    +
  4. +
  5. Сохраните и обновите, а дальше попробуйте пару раз сыграть — в консоли вы увидите что randomNumber равна 1 в каждой точке, где вы ее записали после строк с ошибками.
  6. +
+ +

Работаем через логику

+ +

Чтобы исправить это, давайте рассмотрим как работает строка. Первое, мы вызываем Math.random(), котрый генерирует случайное десятичное число, между 0 и 1, например 0.5675493843.

+ +
Math.random()
+ +

Дальше, мы передаем результат вызова Math.random() через Math.floor(), который округляет число вниз, до ближайшего целого числа. Затем мы добавляем 1 к данному результату:

+ +
Math.floor(Math.random()) + 1;
+ +

Округление случайного десятичного числа к меньшему, всегда будет возвращать 0, так что добавление к нему единицы будет возвращать всегда 1.  Нам нужно умножить случайное число на 100, прежде чем мы округлим его к меньшему. Следующая строка вернет нам случайное число между 0 и 99:

+ +
Math.floor(Math.random() * 100);
+ +

поэтому нам нужно добавить 1, чтоб нам возвращалось случайное число между 1 и 100:

+ +
Math.floor(Math.random() * 100) + 1;
+ +

А теперь, исправьте обе строки с ошибками, затем сохраните и обновите, игра должна работать так, как мы и планировали!

+ +

Другие распространенные ошибки

+ +

Существуют и другие распространенные ошибки, которые вы обнаружите в своем коде. В этом разделе показано большинство из них.

+ +

SyntaxError: отсутствует ; перед постановкой

+ +

Эта ошибка обычно означает что вы упустили точку с запятой в конце одной из ваших строк кода, но иногда ошибка может быть более загадочной. Например, если мы изменим эту строку внутри функции checkGuess() :

+ +
var userGuess = Number(guessField.value);
+ +

на эту

+ +
var userGuess === Number(guessField.value);
+ +

Это вызовет данную ошибку, потому что браузер подумает, что вы пытались сделать что-то другое. Вы должны быть уверены, что вы не перепутали оператор присваивания (=), который присваивает значение переменной — с оператором сравнения (===), который строго сравнивает операнды, и возвращает true/false .

+ +
+

Примечание: Загляните на справочную страницу Синтаксическая ошибка: пропущен символ ; до объявления инструкции для получения дополнительной информации об этой ошибке.

+
+ +

В программе всегда говорится, что вы выиграли, независимо от того, что вы ввели

+ +

Причиной этому является все то же перепутывание оператора присваивания (=) со строгим сравнением (===). Например, если мы изменим внутри checkGuess() эту строку кода:

+ +
if (userGuess === randomNumber) {
+ +

на эту

+ +
if (userGuess = randomNumber) {
+ +

мы всегда будем получать true, заставляя программу сообщать, что игра была выиграна. Будьте осторожны!

+ +

SyntaxError: отсутствует ) после списка аргументов

+ +

Эта ошибка проста — обычно она означает, что вы пропустили закрывающую скобку с конца вызова функции / метода.

+ +
+

Примечание: Загляните на справочную страницу  SyntaxError: missing ) after argument list для получения дополнительной информации об этой ошибке.

+
+ +

SyntaxError: missing : after property id

+ +

Эта ошибка обычно связана с неправильно сформированным объектом JavaScript, но в этом случае нам удалось получить ее, изменив

+ +
function checkGuess() {
+ +

на

+ +
function checkGuess( {
+
+ +

Это заставило браузер думать, что мы пытаемся передать содержимое функции в функцию в качестве аргумента. Будьте осторожны с этими скобками!

+ +

SyntaxError: missing } after function body

+ +

Это легко — обычно это означает, что вы пропустили одну из ваших фигурных скобок из функции или условной структуры. Мы получили эту ошибку, удалив одну из закрывающих фигурных скобок возле нижней части функции  checkGuess().

+ +

SyntaxError: expected expression, got 'string' or SyntaxError: unterminated string literal

+ +

Эти ошибки обычно означает, что вы пропустили открывающую или закрывающую кавычку для строковых значений. В первой ошибки выше,  строка  будет заменена на неожиданный персонаж (ей) , что браузер нашел вместо кавычек в начале строки. Вторая ошибка означает , что строка не закончилась кавычки.

+ +

При всех этих ошибках действуйте так, как в наших  примерах, которые мы рассмотрели в пошаговом руководстве. Когда возникает ошибка, посмотрите полученный номер строки, перейдите к этой строке и посмотрите, можете ли вы определить, что случилось. Имейте в виду, что ошибка не обязательно будет на этой строке, а также, что ошибка может быть вызвана не такой же проблемой, которую мы привели выше!

+ +
+

Примечание : Смотрите наш SyntaxError: Неожиданный токен и SyntaxError: незавершенная строка эталонных страниц для получения более подробной информации об этих ошибках.

+
+ +

Резюме

+ +

Итак, мы научились основам  выяснения ошибок в простых программах JavaScript. Не всегда так просто разобраться, что не так в вашем коде, но, по крайней мере, это сэкономит вам несколько часов сна и позволит вам продвигаться немного быстрее, когда что-либо заработает не так, как ожидалось, в вашем учебном путешествии.

+ +

Смотрите также

+ +
+
    +
  • Есть много других типов ошибок, которые не перечислены здесь; мы составляем ссылку , которая объясняет , что они означают подробно - см. ссылку ошибки JavaScript .
  • +
  • Если вы столкнетесь с любыми ошибками в коде, которые вы не знаете , как исправить после прочтения этой статьи, вы можете получить помощь! Спросите на нить обучения Область дискурсе , или в #mdn IRC канал на Mozilla IRC. Расскажите нам, какая у вас ошибка, и мы постараемся вам помочь. Приложите пример своего кода для большей ясности проблемы.
  • +
+
+ +

{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/A_first_splash", "Learn/JavaScript/Первые_шаги/Variables", "Learn/JavaScript/Первые_шаги")}}

diff --git a/files/ru/learn/javascript/objects/adding_bouncing_balls_features/index.html b/files/ru/learn/javascript/objects/adding_bouncing_balls_features/index.html new file mode 100644 index 0000000000..fe97392371 --- /dev/null +++ b/files/ru/learn/javascript/objects/adding_bouncing_balls_features/index.html @@ -0,0 +1,212 @@ +--- +title: Добавление функций в нашу демонстрацию отбойных шаров +slug: Learn/JavaScript/Объекты/Adding_bouncing_balls_features +translation_of: Learn/JavaScript/Objects/Adding_bouncing_balls_features +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Objects/Object_building_practice", "", "Learn/JavaScript/Objects")}}
+ +

В этом упражнении мы будем использовать проект прыгающих шаров из предыдущей статьи и добавим в него новые интересные возможности.

+ + + + + + + + + + + + +
Требования:Перед тем как приступить к этому упражнению нужно выполнить задания из всех статей текущего модуля.
Цель:Проверить насколько хорошо вы понимаете объекты и связанные с ними конструкции в языке Javascript. 
+ +

Начало

+ +

Для начала скопируйте файлы index-finished.html, style.css и main-finished.js из предыдущей статьи в новую директорию на вашем компьютере.

+ +

Для выполнения упражнения вы можете использовать сайт JSBin или Thimble. Вы можете вставлять HTML, CSS и JavaScript код в один из этих онлайн-редакторов. Если ваш онлайн-редактор не поддерживает раздельные панели для редактирования JavaScript/CSS кода, то вы можете встроить код в HTML с помощью тегов <script>/<style>.

+ +
+

Примечание. Если у вас что-то не получается — попросите о помощи. Более подробная информация находится в секции {{anch("Assessment or further help")}} в конце этой страницы.

+
+ +

Краткое описание проекта

+ +

Наша веселая демонстрация шаров - это весело, но теперь мы хотим сделать ее немного более интерактивной, добавив контролируемый пользователем злой круг, который будет есть шары, если он их поймает. Мы также хотим проверить ваши навыки создания объектов, создав общий объект Shape(), который могут наследовать наши шары и злой круг. Наконец, мы хотим добавить счетчик очков, чтобы отслеживать количество оставшихся шаров для захвата.

+ +

Следующий скриншот дает вам представление о том, как должна выглядеть готовая программа:

+ +

+ + + +

Чтобы дать вам больше идеи, посмотрите на законченный пример (не заглядывая в исходный код!)

+ +

Шаги по завершению

+ +

В следующих разделах описывается, что вам нужно делать.

+ +

Создание наших новых объектов

+ +

Прежде всего, измените существующий конструктор Ball() так, чтобы он стал конструктором Shape() и добавил новый конструктор Ball():

+ +
    +
  1. Конструктор Shape() должен определять свойства x, y, velX и velY,  так же, как и конструктор Ball(), но не свойства color и size.
  2. +
  3. Он также должен определить новое свойствоexists, которое используется для отслеживания наличия шаров в программе (не было съедено злым кругом). Это должно быть логическое (true / false).
  4. +
  5. Конструктор Ball() должен наследовать свойства x, y, velX, velY и exists из конструктора Shape().
  6. +
  7. Он также должен определить свойство color и size, как это сделал оригинальный конструктор Ball().
  8. +
  9. Не забудьте установить prototype и constructor конструктора Ball() соответствующим образом.
  10. +
+ +

Определения меток шара draw(), update() и collisionDetect() должны быть такими же, как и раньше.

+ +

Вам также нужно добавить новый параметр в новый вызов конструктора new Ball() ( ... ) - параметр exists должен быть 5-м параметром и ему должно быть присвоено значение true.

+ +

На этом этапе попробуйте перезагрузить код - он должен работать так же, как и раньше, с нашими перепроектированными объектами.

+ +

Определение EvilCircle()

+ +

Теперь пришло время встретить плохого парня - EvilCircle()! Наша игра будет включать только один злой круг, но мы все еще будем определять его с помощью конструктора, который наследует от Shape(), чтобы дать вам некоторую практику. Возможно, вам захочется добавить еще один круг в приложение, которое может контролироваться другим игроком или иметь несколько злобных окружений, управляемых компьютером. Вы, вероятно, не собираетесь захватить мир одним злым кругом, но он будет делать для этой оценки.

+ +

Конструктор EvilCircle() должен наследовать x, y, velX, velY и exists из Shape(), но velX и velY должны всегда равняться 20.

+ +

Вы должны сделать что-то вроде Shape.call(this, x, y, 20, 20, exists);

+ +

Он также должен определить свои собственные свойства следующим образом:

+ + + +

Опять же, не забудьте определить свои унаследованные свойства как параметры в конструкторе и правильно установить свойства prototype и constructor.

+ +

Defining EvilCircle()'s methods

+ +

EvilCircle() должен иметь четыре метода, как описано ниже.

+ +

draw()

+ +

Этот метод имеет ту же цель, что и метод draw() метода Ball(): он рисует экземпляр объекта на холсте. Он будет работать очень схожим образом, поэтому вы можете начать с копирования определения Ball.prototype.draw. Затем вы должны внести следующие изменения:

+ + + +

checkBounds()

+ +

Этот метод будет делать то же самое, что и первая часть функции  Ball()'s update(), чтобы посмотреть, не исчезнет ли злой круг от края экрана и не прекратит это делать. Опять же, вы можете просто скопировать определение Ball.prototype.update, но есть несколько изменений, которые вы должны сделать:

+ + + +

setControls()

+ +

Этот метод добавит прослушиватель событий onkeydown к объекту window, чтобы при нажатии определенных клавиш клавиатуры мы могли перемещать злой круг вокруг. Следующий код должен быть помещен внутри определения метода:

+ +
var _this = this;
+window.onkeydown = function(e) {
+    if (e.keyCode === 65) {
+      _this.x -= _this.velX;
+    } else if (e.keyCode === 68) {
+      _this.x += _this.velX;
+    } else if (e.keyCode === 87) {
+      _this.y -= _this.velY;
+    } else if (e.keyCode === 83) {
+      _this.y += _this.velY;
+    }
+  }
+ +

Поэтому, когда нажата клавиша, проконсультируется о свойствах keyCode объекта события, чтобы увидеть, какая клавиша нажата. Если это один из четырех, представленных указанными ключевыми кодами, тогда злой круг будет перемещаться влево / вправо / вверх / вниз.

+ + + +

collisionDetect()

+ +

Этот метод будет действовать очень похоже на метод collisionDetect() в Ball(), поэтому вы можете использовать его в качестве основы для этого нового метода. Но есть несколько отличий:

+ + + +

Приведение злого круга в программу

+ +

Теперь мы определили злой круг, нам нужно на самом деле заставить его появиться на нашей сцене. Для этого вам нужно внести некоторые изменения в функцию loop().

+ + + +

Реализация счетчика баллов

+ +

Чтобы выполнить счетчик счетчиков, выполните следующие действия:

+ +
    +
  1. В своем HTML-файле добавьте элемент {{HTMLElement ("p")}} непосредственно под элементом {{HTMLElement ("h1")}}, содержащим текст «Ball count:».
  2. +
  3. В вашем файле CSS добавьте следующее правило внизу: +
    p {
    +  position: absolute;
    +  margin: 0;
    +  top: 35px;
    +  right: 5px;
    +  color: #aaa;
    +}
    +
  4. +
  5. В своем JavaScript сделайте следующие обновления: +
      +
    • Создайте переменную, которая хранит ссылку на абзац.
    • +
    • Держите подсчет количества шаров на экране в некотором роде.
    • +
    • Увеличьте количество и покажите обновленное количество шаров каждый раз, когда шар добавляется в сцену.
    • +
    • Уменьшите счет и покажите обновленное количество мячей каждый раз, когда злой круг ест шарик (его не существует).
    • +
    +
  6. +
+ +

Советы и подсказки

+ + + +

Assessment

+ +

Если вы проводите эту оценку в рамках организованного курса, вы должны уметь отдать свою работу своему учителю / наставнику для маркировки. Если вы самообучаетесь, то вы можете получить руководство по маркировке довольно легко, задав тему обсуждения для этого упражнения или в IRC-канале #mdn в Mozilla IRC. Сначала попробуйте упражнение - ничего не выиграть от обмана!

+ +

{{PreviousMenuNext("Learn/JavaScript/Objects/Object_building_practice", "", "Learn/JavaScript/Objects")}}

+ + + +

In this module

+ + + + + +
+ + +
+ +
+
diff --git a/files/ru/learn/javascript/objects/basics/index.html b/files/ru/learn/javascript/objects/basics/index.html new file mode 100644 index 0000000000..a4e7cc0071 --- /dev/null +++ b/files/ru/learn/javascript/objects/basics/index.html @@ -0,0 +1,257 @@ +--- +title: Основы объектов в JavaScript +slug: Learn/JavaScript/Объекты/Основы +tags: + - JavaScript + - ООП +translation_of: Learn/JavaScript/Objects/Basics +--- +
{{LearnSidebar}}
+ +
{{NextMenu("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects")}}
+ +

В этой статье мы рассмотрим объекты в JavaScript. Мы будем разбирать основы синтаксиса объектов JavaScript и заново изучим некоторый функционал JavaScript, который мы уже исследовали ранее на курсе, подтвердив тот факт, что большая часть функционала, с которым мы уже столкнулись, в действительности является объектами.

+ + + + + + + + + + + + +
Необходимые знания:Элементарная компьютерная грамотность, базовое понимание HTML и CSS, знакомство с основами JavaScript (см. Первые шаги и Структурные элементы).
Цель:Понимать основу теории перед началом объектно-ориентированного программирования, как это связано с JavaScript ("большинство сущностей являются объектами"), и как начать работу с объектами JavaScript.
+ +

Основы объектов

+ +

Объект — это совокупность связанных данных и/или функциональных возможностей. Обычно состоят из нескольких переменных и функций, которые называются свойства и методы, если они находятся внутри объектов. Разберём пример, чтобы показать, как они выглядят.

+ +

Чтобы начать, скопируйте себе oojs.html файл. В нём содержится очень мало: {{HTMLElement("script")}} элемент для написания в нём исходного кода. Мы будем использовать это как основу для изучения основ синтаксиса объектов. Во время работы с этим примером у вас должна быть открытая консоль JavaScript инструментов разработчика, готовая к вводу некоторых команд.

+ +

Как и во многих случаях в JavaScript, создание объекта часто начинается с определения и инициализации переменной. Попробуйте ввести следующий код JavaScript в ваш файл, а затем сохраните файл и обновите страницу браузера:

+ +
const person = {};
+ +

Если Вы введёте person в текстовое JS консоль и нажмёте клавишу Enter, должен получиться следующий результат:

+ +
Object { }
+ +

Поздравляем, Вы только что создали Ваш первый объект. Но это пустой объект, поэтому мы не можем с ним ничего сделать. Давайте обновим наш объект, чтобы он выглядел так:

+ +
const person = {
+  name: ['Bob', 'Smith'],
+  age: 32,
+  gender: 'male',
+  interests: ['music', 'skiing'],
+  bio: function() {
+    alert(this.name[0] + ' ' + this.name[1] + ' is ' + this.age + ' years old. He likes ' + this.interests[0] + ' and ' + this.interests[1] + '.');
+  },
+  greeting: function() {
+    alert('Hi! I\'m ' + this.name[0] + '.');
+  }
+};
+
+ +

После сохранения и обновления, попробуйте ввести что-нибудь следующее в консоль JavaScript браузера:

+ +
person.name
+person.name[0]
+person.age
+person.interests[1]
+person.bio()
+person.greeting()
+ +

Теперь внутри объекта есть некоторые данные и функционал, и теперь можно получить доступ к ним с помощью некоторого лёгкого и простого синтаксиса!

+ +
+

Примечание: Если у вас возникли проблемы с применением файла в работе, попробуйте сравнить ваш код с нашей версией — см. oojs-finished.html (также see it running live). Одна из распространенных ошибок, когда Вы начинаете с объектами ставить запятую в конце последнего члена — это приводит к ошибке.

+
+ +

Итак что здесь происходит? Объект состоит из нескольких элементов, каждый из которых имеет своё название (пример name и age выше), и значение (пример ['Bob', 'Smith'] и 32). Каждая пара название/значение должны быть разделены запятой, а название и значение в каждом случае разделяются двоеточием. Синтаксис всегда следует этому образцу:

+ +
const objectName = {
+  member1Name: member1Value,
+  member2Name: member2Value,
+  member3Name: member3Value
+};
+ +

Значение члена объекта может быть чем угодно — в нашем объекте person есть строка, число, два массива, и две функции. Первые четыре элемента это элементы данных, относящиеся к свойствам объекта. Последние два элемента являются функциями, которые позволяют объекту что-то сделать с элементами данных, и называются методами объекта.

+ +

Такие объекты называются литералами объекта (object literal) — мы буквально вписали все содержимое объекта для его создания. Этот способ сильно отличается от объектов реализованных классами, которые мы рассмотрим позже.

+ +

Очень часто для создания объекта используется литерал объекта когда вам нужно каким-то образом перенести ряд структурированных, связанных элементов данных, например, отправляя запрос на сервер, для размещения их в базе данных. Отправка одного объекта намного эффективнее, чем отправка нескольких элементов по отдельности, и с ним легче работать чем с массивом, если требуется идентифицировать отдельные элементы по имени. 

+ +

Точечная запись (Dot notation)

+ +

Выше Вы получили доступ к свойствам и методам используя точечную запись (dot notation). Имя объекта (person) действует как пространство имен (namespace) — оно должно быть введено первым, для того чтобы получить доступ ко всему что заключено (encapsulated) внутри объекта. Далее Вы пишете точку, затем элемент, к которому хотите получить доступ — это может быть имя простого свойства, элемент массива, или вызов одного из методов объекта, например:

+ +
person.age
+person.interests[1]
+person.bio()
+ +

Внутренние пространства имен (Sub-namespaces)

+ +

Можно даже сделать значением элемента объекта другой объект. Например, попробуйте изменить значение свойства name с такого

+ +
name: ['Bob', 'Smith'],
+ +

на такое

+ +
name : {
+  first: 'Bob',
+  last: 'Smith'
+},
+ +

Здесь мы фактически создаем внутреннее пространство имен (sub-namespace). Это звучит сложно, но на самом деле это не так — для доступа к этим элементам Вам нужно сделать один дополнительный шаг с еще одной точкой. Попробуйте в консоли браузера следующее: 

+ +
person.name.first
+person.name.last
+ +

Важно: На этом этапе вам также нужно будет пересмотреть код метода и изменить все экземпляры с

+ +
name[0]
+name[1]
+ +

на

+ +
name.first
+name.last
+ +

Иначе ваши методы больше не будут работать.

+ +

Скобочная запись (Bracket notation)

+ +

Существует другой способ получить свойства объекта — использовать скобочную запись (bracket notation). Вместо написания этого кода:

+ +
person.age
+person.name.first
+ +

Вы можете использовать следующий

+ +
person['age']
+person['name']['first']
+ +

Это выглядит очень похоже на то, как Вы получаете элементы массива, и в принципе это так и есть — вместо использования числовых индексов для выбора элемента, Вы ассоциируете имя свойства для каждого значения. Ничего удивительного, что эти объекты иногда называют ассоциативными массивами — они сопоставляют строки со значениями так же, как массивы сопоставляют числовые индексы со значениями.

+ +

Запись элементов в объект

+ +

До сих пор мы рассмастривали только возврат (или получение) элементов объекта — Вы так же можете установить (обновить) значение элемента объекта просто объявив элемент, который Вы хотите установить (используя точечную или скобочную запись), например:

+ +
person.age = 45;
+person['name']['last'] = 'Cratchit';
+ +

Попробуйте ввести эти строки, а затем снова верните элементы, чтобы увидеть, как они изменились

+ +
person.age
+person['name']['last']
+ +

Вы можете не просто обновлять и устанавливать значения свойств и методов объекта, а так же устанавливать совершенно новые элементы. Попробуйте их в консоли JS:

+ +
person['eyes'] = 'hazel';
+person.farewell = function() { alert("Bye everybody!"); }
+ +

Теперь Вы можете проверить ваши новые элементы:

+ +
person['eyes']
+person.farewell()
+ +

Одним из полезных аспектов скобочной записи является то, что с ее помощью можно динамически задавать не только значения элементов, но и их имена. Предположим, что мы хотим, чтобы пользователи могли хранить пользовательские типы данных, введя имя и значение элемента в два следующих поля? Мы могли бы получить эти значения следующим образом:

+ +
let myDataName = nameInput.value;
+let myDataValue = nameValue.value;
+ +

Затем мы можем добавить имя и значение этого нового элемента в объект person таким образом:

+ +
person[myDataName] = myDataValue;
+ +

Чтобы проверить это, попробуйте добавить следующие строки в свой код, после закрывающей скобки объекта person :

+ +
let myDataName = 'height';
+let myDataValue = '1.75m';
+person[myDataName] = myDataValue;
+ +

Теперь попробуйте сохранить и обновить, затем введите следующее в консоль браузера:

+ +
person.height
+ +

Добавление свойства объекта с использованием вышеописанного метода невозможно с использованием точечной записи, которая может принимать только литеральное имя элемента, а не значение переменной указывающее на имя.

+ +

Что такое "this"?

+ +

Возможно, вы заметили что-то странное в наших методах. Посмотрите на этот пример:

+ +
greeting: function() {
+  alert('Hi! I\'m ' + this.name.first + '.');
+}
+ +

Вы, вероятно, задаетесь вопросом, что такое "this"? Ключевое слово this, ссылается на текущий объект, внутри которого пишется код — поэтому в нашем случае this равен объекту person. Но почему просто не написать person? Как Вы увидите в статье Object-oriented JavaScript for beginners (Объектно-ориентированный JavaScript для начинающих), когда мы начинаем создавать конструкторы и т.д., this очень полезен — он всегда будет гарантировать, что используется верное значение, когда контекст элемента изменяется (например, два разных экземпляра объекта person могут иметь разные имена, но захотят использовать свое собственное имя при приветствии.

+ +

Давайте проиллюстритуем, что мы имеем в виду, с упрощенной парой объектов person :

+ +
const person1 = {
+  name: 'Chris',
+  greeting: function() {
+    alert('Hi! I\'m ' + this.name + '.');
+  }
+}
+
+const person2 = {
+  name: 'Brian',
+  greeting: function() {
+    alert('Hi! I\'m ' + this.name + '.');
+  }
+}
+ +

В этом случае, person1.greeting() выведет "Hi! I'm Chris.". person2.greeting(), с другой стороны, выведет "Hi! I'm Brian.", хотя код метода одинаковый в обоих случаях. Как мы сказали ранее, this равен объекту, внутри которого находится код — это не очень полезно, когда Вы пишите литералы объектов вручную, но оно действительно помогает, когда Вы генерируете объекты динамически (например используя конструкторы). Это станет понятнее чуть позже.

+ +

Все это время вы использовали объекты

+ +

Пока Вы проходили эти примеры, Вы вероятно заметили, что точечная запись, которую Вы использовали, выглядит очень знакомо. Это потому, что Вы использовали ее на протяжении всего курса! Каждый раз, когда мы работаем над примером, использующим встроенный API браузера или объект JavaScript, мы использовали объекты, потому что такие функции построены с использованием тех же структур объектов, которые мы здесь рассматривали, хотя и более сложные, чем наши собственные пользовательские примеры. 

+ +

Поэтому, когда Вы использовали строковые методы, такие как:

+ +
myString.split(',');
+ +

Вы использовали метод доступный в экземпляре класса String. Каждый раз создавая строку в вашем коде, эта строка автоматически создается как экземпляр String, и поэтому имеет несколько общих методов/свойств, доступных на нем.

+ +

Когда Вы обращались к объектной модели документа (DOM), используя следующие строки:

+ +
const myDiv = document.createElement('div');
+const myVideo = document.querySelector('video');
+ +

Вы использовали методы доступные в экземпляре класса Document. Для каждой загруженной веб-страницы создается экземпляр Document, называемый document, который представляет всю структуру страницы, ее содержимое и другие функции, такие как URL-адрес. Опять же, это означает, что он имеет несколько общих методов/свойств, доступных на нем.

+ +

То же самое относится и к любому другому встроенному объекту/API, который вы использовали — Array, Math, и т. д.

+ +

Обратите внимание, что встроенные объекты/API не всегда создают экземпляры объектов автоматически. Как пример, Notifications API — который позволяет новым браузерам запускать системные уведомления, требует, чтобы Вы создавали новый экземпляр объекта с помощью конструктора для каждого уведомления, которое Вы хотите запустить. Попробуйте ввести следующее в консоль JavaScript:

+ +
const myNotification = new Notification('Hello!');
+ +

Опять же, мы рассмотрим конструкторы в следующей статье.

+ +
+

Примечание: Полезно подумать о том, как объекты взаимодействуют посредством передачи сообщений - когда объекту требуется другой объект для выполнения какого-либо действия, он часто отправляет сообщение другому объекту через один из его методов и ждет ответа, который мы знаем как возвращаемое (return) значение.

+
+ +

Резюме

+ +

Поздравляем, Вы достигли конца нашей первой статьи о объектах JS, теперь у вас должно быть хорошее представление о том, как работать с объектами в JavaScript - в том числе создавать свои собственные простые объекты. Вы также должны понимать, что объекты очень полезны в качестве структур для хранения связанных данных и функциональности - если бы мы пытались отслеживать все свойства и методы в нашем объекте person как отдельные переменные и функции, это было неэффективно, и мы бы рисковали столкнуться с другими переменными и функциями с такими же именами. Объекты позволяют нам безопасно хранить информацию в своем собственном блоке, вне опасности.

+ +

В следующей статье мы начнем рассматривать теорию объектно-ориентированного программирования (OOП) и как эти техники могут быть использованны в JavaScript 

+ +

{{NextMenu("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects")}}

+ +

В этом модуле

+ + diff --git a/files/ru/learn/javascript/objects/index.html b/files/ru/learn/javascript/objects/index.html new file mode 100644 index 0000000000..9acc354feb --- /dev/null +++ b/files/ru/learn/javascript/objects/index.html @@ -0,0 +1,47 @@ +--- +title: Введение в объекты JavaScript +slug: Learn/JavaScript/Объекты +tags: + - JavaScript + - Начинающим + - Объекты + - Руководства +translation_of: Learn/JavaScript/Objects +--- +
{{LearnSidebar}}
+ +

В JavaScript большинство сущностей являются объектами, начиная с самого основного функционала JavaScript, такого как строки (strings) и массивы (array), и заканчивая встроенными в браузер API. Вы можете даже создавать свои собственные объекты, чтобы инкапсулировать связанные между собой функции и переменные в эффективные пакеты и действовать как удобные хранилища данных. Понимание объектно-ориентированной природы JavaScript очень важно, если Вы хотите продолжить дальнейшее более углубленное изучение языка. Поэтому мы предоставляем Вам данный модуль, чтобы помочь Вам разобраться в этом. Здесь мы детально обучим Вас теории и синтаксису объектов, а затем рассмотрим, как создавать свои собственные объекты. 

+ +

Необходимые знания

+ +

Перед тем, как начать изучение данного модуля, Вы должны иметь некоторое представление о HTML и CSS. Мы советуем Вам поработать над разделами Введение в HTML и Введение в CSS перед изучением этого модуля JavaScript.

+ +

Также Вам необходимо знать основы JavaScript перед подробным изучением объектов JavaScript. Предварительно поработайте с разделами Первые шаги в JavaScript и Структурные элементы в JavaScript перед началом изучения данного модуля.

+ +
+

Примечание: Если Вы работаете за компьютером/планшетом/другим устройством, на котором у Вас нет возможности создавать собственные файлы, постарайтесь поработать с примерами кода на платформах онлайн-программирования, таких, как JSBin or Thimble.

+
+ +

Руководства

+ +
+
Основы объектов
+
В первой статье мы рассмотрим объекты в JavaScript. Мы будем разбирать основы синтаксиса объектов JavaScript и заново изучим некоторый функционал JavaScript, который мы уже исследовали ранее на курсе, подтвердив тот факт, что большая часть функционала, с которым мы уже столкнулись, в действительности является объектами.
+
Объектно-ориентированный JavaScript для начинающих
+
Закончив с основами, мы сфокусируемся на объектно-ориентированном JavaScript (OOJS) —  эта статья представляет основы теории объектно-ориентированного программирования (ООП). Затем мы изучим, как JavaScript эмулирует классы объектов через конструктор функций, и как создавать экземпляры объектов.
+
Прототипы объектов
+
Прототипы - это механизм, благодаря которому объекты в JavaScript наследуют функционал друг друга, но при этом они работают иначе по сравнению с механизмами наследования в классических объектно-ориентированных языках. В этой статье мы изучим эти отличия, объясним, как работает цепочка прототипов, и рассмотрим, как свойство прототипа может быть использовано для добавления методов к существующим конструкторам.
+
Наследование в JavaScript
+
После знакомства с самыми жуткими подробностями OOJS, эта статья покажет, как создавать "дочерные" классы объектов (конструкторы), которые наследуют функционал от своих "родительских" классов. В дополнении, мы дадим Вам пару советов о том, где и когда можно использовать OOJS.
+
Работа с JSON-данными
+
Представление объектов в JavaScript (JavaScript Object Notation) (JSON) - это стандартный формат для представления структурированных данных в виде объектов JavaScript, который обычно используется для представления и передачи данных на веб-сайтах (т.е. передача некоторых данных от сервера к клиенту - таким образом они могут быть отображены на веб-странице). Вы довольно часто будете с этим сталкиваться, поэтому в данной статье мы предоставим вам все, что необходимо для работы с JSON с помощью JavaScript, в том числе доступ к элементам данных в объекте JSON и написания собственного JSON-кода.
+
Практика построения объектов
+
В предыдущих статьях мы рассматривали самые основные моменты в теории и синтаксисе объектов в JavaScript, дав Вам твердую основу для начала. В этой статье мы погрузимся в практические занятия, получим больше практической работы в построении собственных объектов в JavaScript, чтобы сделать кое-что веселое и красочное - несколько цветных прыгающих шариков.
+
+ +

Задания

+ +
+
Добавление функционала к демо с прыгающими шариками
+
В этом задании, мы ожидаем, что Вы, используя демо с прыгающими шариками из предыдущей статьи как отправную точку, добавите немного нового и интересного функционала в него.
+
diff --git a/files/ru/learn/javascript/objects/inheritance/index.html b/files/ru/learn/javascript/objects/inheritance/index.html new file mode 100644 index 0000000000..c1565cd72f --- /dev/null +++ b/files/ru/learn/javascript/objects/inheritance/index.html @@ -0,0 +1,266 @@ +--- +title: Наследование в JavaScript +slug: Learn/JavaScript/Объекты/Inheritance +tags: + - JavaScript + - Наследование + - ООП +translation_of: Learn/JavaScript/Objects/Inheritance +--- +

+ +

+ + + +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects")}}
+ +

Теперь, когда объясняется большая часть подробностей OOJS, эта статья показывает, как создавать «дочерние» классы объектов (конструкторы), которые наследуют признаки из своих «родительских» классов. Кроме того, мы дадим некоторые советы о том, когда и где вы можете использовать OOJS , и посмотрим, как классы рассматриваются в современном синтаксисе ECMAScript.

+ + + + + + + + + + + + +
Необходимые знания: +

Базовая компьютерная грамотность, понимание основ HTML и CSS, знакомство с основами JavaScript (см. Первые шаги и Структурные элементы) and основы Объектно-ориентированного JS (см. Введение в объекты).

+
Цель:Понять, как можно реализовать наследование в JavaScript.
+ +

Прототипное наследование

+ +

До сих пор мы видели некоторое наследование в действии - мы видели, как работают прототипы и как элементы наследуются, поднимаясь по цепочке. Но в основном это связано с встроенными функциями браузера. Как создать объект в JavaScript, который наследует от другого объекта?

+ +

Давайте рассмотрим, как это сделать на конкретном примере.

+ +

Начало работы

+ +

Прежде всего сделайте себе локальную копию нашего файла oojs-class-inheritance-start.html (он также работает в режиме реального времени). В файле вы найдете тот же пример конструктора Person(), который мы использовали на протяжении всего модуля, с небольшим отличием - мы определили внутри конструктора только лишь свойства:

+ +
function Person(first, last, age, gender, interests) {
+  this.name = {
+    first,
+    last
+  };
+  this.age = age;
+  this.gender = gender;
+  this.interests = interests;
+};
+ +

Все методы определены в прототипе конструктора. Например:

+ +
Person.prototype.greeting = function() {
+  alert('Hi! I\'m ' + this.name.first + '.');
+};
+ +
+

Примечание. В исходном коде вы также увидите определенные методы bio() и farewell(). Позже вы увидите, как они могут быть унаследованы другими конструкторами.

+
+ +

Скажем так, мы хотели создать класс Teacher, подобный тому, который мы описали в нашем первоначальном объектно-ориентированном определении, которое наследует всех членов от Person, но также включает в себя:

+ +
    +
  1. Новое свойство, subject - оно будет содержать предмет, который преподает учитель.
  2. +
  3. Обновленный метод greeting(), который звучит немного более формально, чем стандартный метод greeting()— более подходит для учителя, обращающегося к некоторым ученикам в школе.
  4. +
+ +

Определение функции-конструктора Teacher()

+ +

Первое, что нам нужно сделать, это создать конструктор Teacher() - добавьте ниже следующий код:

+ +
function Teacher(first, last, age, gender, interests, subject) {
+  Person.call(this, first, last, age, gender, interests);
+
+  this.subject = subject;
+}
+ +

Это похоже на конструктор Person во многих отношениях, но здесь есть что-то странное, что мы не видели раньше - функцию call(). Эта функция в основном позволяет вам вызывать функцию, определенную где-то в другом месте, но в текущем контексте. Первый параметр указывает значение this, которое вы хотите использовать при выполнении функции, а остальные параметры - те, которые должны быть переданы функции при ее вызове.

+ +

Мы хотим, чтобы конструктор Teacher() принимал те же параметры, что и конструктор Person(), от которго он наследуется, поэтому мы указываем их как параметры в вызове call().

+ +

Последняя строка внутри конструктора просто определяет новое свойство subject, которое будут иметь учителя, и которого нет у Person().

+ +

В качестве примечания мы могли бы просто сделать это:

+ +
function Teacher(first, last, age, gender, interests, subject) {
+  this.name = {
+    first,
+    last
+  };
+  this.age = age;
+  this.gender = gender;
+  this.interests = interests;
+  this.subject = subject;
+}
+ +

Но это просто переопределяет свойства заново, а не наследует их от Person(), так что теряется смысл того, что мы пытаемся сделать. Он также занимает больше строк кода.

+ +

Наследование от конструктора без параметров

+ +

Обратите внимание, что если конструктор, от которого вы наследуете, не принимает значения своего свойства из параметров, вам не нужно указывать их в качестве дополнительных аргументов в call(). Так, например, если у вас было что-то действительно простое:

+ +
function Brick() {
+  this.width = 10;
+  this.height = 20;
+}
+ +

Вы можете наследовать свойства width и height, выполнив это (как и другие шаги, описанные ниже, конечно):

+ +
function BlueGlassBrick() {
+  Brick.call(this);
+
+  this.opacity = 0.5;
+  this.color = 'blue';
+}
+ +

Обратите внимание, что мы указали только this внутри call() - никаких других параметров не требуется, поскольку мы не наследуем никаких свойств родителя, которые задаются через параметры.

+ +

Установка Teacher()'s prototype и конструктор ссылок

+ +

Пока все хорошо, но у нас есть проблема. Мы определили новый конструктор и у него есть свойство prototype, которое по умолчанию просто содержит ссылку на саму конструкторскую функцию. Он не содержит методов свойства prototype конструктора Person. Чтобы увидеть это, введите Object.getOwnPropertyNames(Teacher.prototype) в поле ввода текста или в вашу консоль JavaScript. Затем введите его снова, заменив Teacher на Person. Новый конструктор не наследует эти методы. Чтобы увидеть это, сравните выводы в консоль Person.prototype.greeting и Teacher.prototype.greeting. Нам нужно заставить Teacher() наследовать методы, определенные на прототипе Person(). Итак, как мы это делаем?

+ +
    +
  1. Добавьте следующую строку ниже своего предыдущего добавления: +
    Teacher.prototype = Object.create(Person.prototype);
    + Здесь наш друг create() снова приходит на помощь. В этом случае мы используем его для создания нового объекта и делаем его значением Teacher.prototype. Новый объект имеет свой прототип Person.prototype и, следовательно, наследует, если и когда это необходимо, все доступные методы Person.prototype.
  2. +
  3. Нам нужно сделать еще одну вещь, прежде чем двигаться дальше. После добавления последней строки, Teacher.prototype.constructor стало равным Person(), потому что мы просто устанавливаем Teacher.prototype для ссылки на объект, который наследует его свойства от Person.prototype! Попробуйте сохранить код, загрузите страницу в браузере и введите Teacher.prototype.constructor в консоль для проверки.
  4. +
  5. Это может стать проблемой, поэтому нам нужно сделать это правильно. Вы можете сделать это, вернувшись к исходному коду и добавив следующие строки внизу: +
    Object.defineProperty(Teacher.prototype, 'constructor', {
    +    value: Teacher,
    +    enumerable: false, // false, чтобы данное свойство не появлялось в цикле for in
    +    writable: true });
    +
  6. +
  7. Теперь, если вы сохраните и обновите, введите Teacher.prototype.constructor, чтобы вернуть Teacher(), плюс мы теперь наследуем Person()!
  8. +
+ +

Предоставление Teacher() новой функции greeting()

+ +

Чтобы завершить наш код, нам нужно определить новую функцию greeting() в конструкторе Teacher().

+ +

Самый простой способ сделать это - определить его на прототипе Teacher() - добавить в нижнюю часть кода следующее:

+ +
Teacher.prototype.greeting = function() {
+  var prefix;
+
+  if (this.gender === 'male' || this.gender === 'Male' || this.gender === 'm' || this.gender === 'M') {
+    prefix = 'Mr.';
+  } else if (this.gender === 'female' || this.gender === 'Female' || this.gender === 'f' || this.gender === 'F') {
+    prefix = 'Mrs.';
+  } else {
+    prefix = 'Mx.';
+  }
+
+  alert('Hello. My name is ' + prefix + ' ' + this.name.last + ', and I teach ' + this.subject + '.');
+};
+ +

Это выводит на экран приветствие учителя, в котором используется соответствующий префикс имени для своего пола, разработанный с использованием условного оператора.

+ +

Попробуйте пример

+ +

Теперь, когда вы ввели весь код, попробуйте создать экземпляр объекта из Teacher(), поставив ниже вашего JavaScript кода (или что-то похожее по вашему выбору):

+ +
var teacher1 = new Teacher('Dave', 'Griffiths', 31, 'male', ['football', 'cookery'], 'mathematics');
+ +

Теперь сохраните, обновите, и попробуйте получить доступ к свойствам и методам вашего нового объекта teacher1, например:

+ +
teacher1.name.first;
+teacher1.interests[0];
+teacher1.bio();
+teacher1.subject;
+teacher1.greeting();
+teacher1.farewell();
+ +

Все должно работать нормально. Запросы в строках 1, 2, 3 и 6 унаследованны от общего конструктора Person() (класса). Запрос в строке 4 обращается к subject, доступному только для более специализированного конструктора (класса) Teacher(). Запрос в строке 5 получил бы доступ к методу greeting(), унаследованному от Person(), но Teacher() имеет свой собственный метод greeting() с тем же именем, поэтому запрос обращается к этому методу.

+ +
+

Примечание. Если вам не удается заставить это работать, сравните свой код с нашей готовой версией (см. также рабочее демо).

+
+ +

Методика, которую мы здесь рассмотрили, - это не единственный способ создания наследующих классов в JavaScript, но он работает нормально и это дает вам представление о том, как реализовать наследование в JavaScript.

+ +

Вам также может быть интересно узнать некоторые из новых функций {{glossary("ECMAScript")}}, которые позволяют нам делать наследование более чисто в JavaScript (см. Classes). Мы не рассматривали их здесь, поскольку они пока не поддерживаются очень широко в браузерах. Все остальные конструкторы кода, которые мы обсуждали в этом наборе статей, поддерживаются еще в IE9 или ранее и есть способы добиться более ранней поддержки, чем это.

+ +

Обычный способ - использовать библиотеку JavaScript - большинство популярных опций имеют простой набор функций, доступных для выполнения наследования более легко и быстро. CoffeeScript , например, предоставляет класс, расширяет и т.д.

+ +

Дальнейшее упражнение

+ +

В нашем руководстве по Объектно-ориентированному JavaScript для начинающих мы также включили класс Student как концепцию, которая наследует все особенности Person, а также имеет другой метод greeting() от Person, который гораздо более неформален, чем приветствие Teacher. Посмотрите, как выглядит приветствие ученика в этом разделе, и попробуйте реализовать собственный конструктор Student(), который наследует все функции Person() и реализует другую функцию greeting().

+ +
+

Примечание. Если вам не удается заставить это работать, сравните свой код с нашей готовой версией (см. также рабочее демо).

+
+ +

Object member summary

+ +

Подводя итог, вы в основном получили три типа свойств / методов, о которых нужно беспокоиться:

+ +
    +
  1. Те, которые определены внутри функции-конструктора, которые присваиваются экземплярам объекта. Их довольно легко заметить - в вашем собственном коде они представляют собой элементы, определенные внутри конструктора, используя строки this.x = x; в встроенном коде браузера они являются членами, доступными только для экземпляров объектов (обычно создаются путем вызова конструктора с использованием ключевого слова new, например var myInstance = new myConstructor ().
  2. +
  3. Те, которые определяются непосредственно самим конструктором, которые доступны только для конструктора. Они обычно доступны только для встроенных объектов браузера и распознаются путем непосредственной привязки к конструктору, а не к экземпляру. Например, Object.keys().
  4. +
  5. Те, которые определены в прототипе конструктора, которые наследуются всеми экземплярами и наследуют классы объектов. К ним относятся любой член, определенный в свойстве прототипа конструктора, например. myConstructor.prototype.x().
  6. +
+ +

Если вы не уверены, что это такое, не беспокойтесь об этом, пока вы еще учитесь и знание придет с практикой.

+ +

Когда вы используете наследование в JavaScript?

+ +

В частности, после этой последней статьи вы можете подумать: «У-у-у, это сложно». Ну, ты прав. Прототипы и наследование представляют собой некоторые из самых сложных аспектов JavaScript, но многие возможности и гибкость JavaScript вытекают из его структуры объектов и наследования и стоит понять, как это работает.

+ +

В некотором смысле вы используете наследование все время. Всякий раз, когда вы используете различные функции веб-API или методы/свойства, определенные во встроенном объекте браузера, который вы вызываете в своих строках, массивах и т.д., вы неявно используете наследование.

+ +

Что касается использования наследования в вашем собственном коде, вы, вероятно, не будете часто его использовать, особенно для начала и в небольших проектах. Это пустая трата времени на использование объектов и наследование только ради этого, когда они вам не нужны. Но по мере того, как ваши базы кода становятся больше, вы с большей вероятностью найдете необходимость в этом. Если вы начинаете создавать несколько объектов с подобными функциями, то создание универсального типа объекта, содержащего все общие функции и наследование этих функций в более специализированных типах объектов, может быть удобным и полезным.

+ +
+

Примечание. Из-за того, как работает JavaScript, с цепочкой прототипов и т.д., совместное использование функций между объектами часто называется делегированием. Специализированные объекты делегируют функциональность универсальному типу объекта.

+
+ +

При использовании наследования вам рекомендуется не иметь слишком много уровней наследования и тщательно отслеживать, где вы определяете свои методы и свойства. Можно начать писать код, который временно изменяет прототипы встроенных объектов браузера, но вы не должны этого делать, если у вас нет действительно веской причины. Слишком много наследования могут привести к бесконечной путанице и бесконечной боли при попытке отладки такого кода.

+ +

В конечном счете, объекты - это еще одна форма повторного использования кода, например функций или циклов, со своими конкретными ролями и преимуществами. Если вы обнаруживаете, что создаете кучу связанных переменных и функций и хотите отслеживать их все вместе и аккуратно их упаковывать, объект является хорошей идеей. Объекты также очень полезны, когда вы хотите передать коллекцию данных из одного места в другое. Обе эти вещи могут быть достигнуты без использования конструкторов или наследования. Если вам нужен только один экземпляр объекта, вам лучше всего использовать литерал объекта и вам, разумеется, не нужно наследование.

+ +

Резюме

+ +

В этой статье мы рассмотрели оставшуюся часть основной теории и синтаксиса OOJS, которые, как мы думаем, вам следует знать сейчас. На этом этапе вы должны понимать основы JavaScript, ООП, прототипы и прототипное наследование, как создавать классы (конструкторы) и экземпляры объектов, добавлять функции в классы и создавать подклассы, которые наследуются от других классов.

+ +

В следующей статье мы рассмотрим, как работать с JavaScript Object Notation (JSON), общим форматом обмена данными, написанным с использованием объектов JavaScript.

+ +

See also

+ + + +

{{PreviousMenuNext("Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects")}}

+ +

В этом модуле

+ + diff --git a/files/ru/learn/javascript/objects/json/index.html b/files/ru/learn/javascript/objects/json/index.html new file mode 100644 index 0000000000..371f254ec6 --- /dev/null +++ b/files/ru/learn/javascript/objects/json/index.html @@ -0,0 +1,353 @@ +--- +title: Работа с JSON +slug: Learn/JavaScript/Объекты/JSON +tags: + - Beginner + - JSON + - JavaScript +translation_of: Learn/JavaScript/Objects/JSON +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects/Object_building_practice", "Learn/JavaScript/Objects")}}
+ +

Обозначение объектов JavaScript (JSON - JavaScript Object Notation) - стандартный текстовый формат для представления структурированных данных на основе синтаксиса объекта JavaScript. Он обычно используется для передачи данных в веб-приложениях (например, отправка некоторых данных с сервера клиенту,таким образом чтобы это могло отображаться на веб-странице или наоборот). Вы будете сталкиваться с этим довольно часто, поэтому в этой статье мы даем вам все, что вам нужно для работы с JSON используя JavaScript, включая парсинг JSON, чтобы вы могли получить доступ к данным внутри него при создании JSON.

+ + + + + + + + + + + + +
Необходимые знания:Базовая компьютерная грамотность, базовые знания HTML и CSS, знакомство с основами JavaScript (см. First steps и Building blocks) и основами OOJS  (see Introduction to objects).
Цель:Понять, как работать с данными, хранящимися в JSON, и создавать свои собственные объекты JSON.
+ +

Нет, действительно, что такое JSON?

+ +

{{glossary("JSON")}} - текстовый формат данных, следующий за синтаксисом объекта JavaScript, который был популяризирован Дугласом Крокфордом. Несмотря на то, что он очень похож на буквенный синтаксис объекта JavaScript, его можно использовать независимо от JavaScript, и многие среды программирования имеют возможность читать (анализировать) и генерировать JSON.

+ +

JSON существует как строка,что необходимо при передаче данных по сети. Он должен быть преобразован в собственный объект JavaScript, если вы хотите получить доступ к данным. Это не большая проблема. JavaScript предоставляет глобальный объект JSON, который имеет методы для преобразования между ними.

+ +
+

Примечание: Преобразование строки в родной объект называется десериализацией (преобразование из последовательной формы в параллельную), в то время как преобразовании родного объекта в строку, таким образом ,чтобы он мог быть передан через сеть, называется сериализацией(преобразование в последовательную форму).

+
+ +

Объект JSON может быть сохранен в собственном файле, который в основном представляет собой текстовый файл с расширением .json и {{glossary("MIME type")}} application/json.

+ +

Структура JSON

+ +

Как описано выше, JSON представляет собой строку, формат которой очень похож на буквенный формат объекта JavaScript. Вы можете включать одни и те же базовые типы данных внутри JSON, так же как и  в стандартном объекте JavaScript - строки, числа, массивы, булевы и другие объектные литералы. Это позволяет построить иерархию данных, к примеру, так:

+ +
{
+  "squadName": "Super hero squad",
+  "homeTown": "Metro City",
+  "formed": 2016,
+  "secretBase": "Super tower",
+  "active": true,
+  "members": [
+    {
+      "name": "Molecule Man",
+      "age": 29,
+      "secretIdentity": "Dan Jukes",
+      "powers": [
+        "Radiation resistance",
+        "Turning tiny",
+        "Radiation blast"
+      ]
+    },
+    {
+      "name": "Madame Uppercut",
+      "age": 39,
+      "secretIdentity": "Jane Wilson",
+      "powers": [
+        "Million tonne punch",
+        "Damage resistance",
+        "Superhuman reflexes"
+      ]
+    },
+    {
+      "name": "Eternal Flame",
+      "age": 1000000,
+      "secretIdentity": "Unknown",
+      "powers": [
+        "Immortality",
+        "Heat Immunity",
+        "Inferno",
+        "Teleportation",
+        "Interdimensional travel"
+      ]
+    }
+  ]
+}
+ +

Если бы мы загрузили этот объект в программу JavaScript, создали переменную с названием superHeroes, мы могли бы затем получить доступ к данным внутри нее, используя те же самые точечную и скобочную нотации, которые мы рассмотрели в статье JavaScript object basics. Например:

+ +
superHeroes.homeTown
+superHeroes['active']
+ +

Чтобы получить доступ к последующим данным  по иерархии, вам просто нужно объединить требуемые имена свойств и индексы массивов. Например, чтобы получить доступ к третьей сверхспособности второго героя, указанного в списке участников, вы должны сделать следующее:

+ +
superHeroes['members'][1]['powers'][2]
+ +
    +
  1. Сначала у нас есть имя переменной - superHeroes.
  2. +
  3. Внутри мы хотим получить доступ к свойству members, поэтому мы используем ['members'].
  4. +
  5. members содержат массив, заполненный объектами. Мы хотим получить доступ ко второму объекту внутри массива, поэтому мы используем [1].
  6. +
  7. Внутри этого объекта мы хотим получить доступ к свойству powers, поэтому мы используем ['powers'].
  8. +
  9. Внутри свойства powers находится массив, содержащий сверхспособности выбранного героя. Нам нужен третий, поэтому мы используем [2].
  10. +
+ +
+

Примечание. Мы сделали JSON, видимый выше, доступным внутри переменной в нашем примере JSONTest.html (см. исходный код). Попробуйте загрузить это, а затем получить доступ к данным внутри переменной через консоль JavaScript вашего браузера.

+
+ +

Массивы как JSON

+ +

Выше мы упоминали ,что JSON текст выглядит практически так же как и JavaScript объект,и это почти правильно.Причина,по которой мы говорим почти правильно заключается в том ,что массив также валиден JSON  например:

+ +
[
+  {
+    "name": "Molecule Man",
+    "age": 29,
+    "secretIdentity": "Dan Jukes",
+    "powers": [
+      "Radiation resistance",
+      "Turning tiny",
+      "Radiation blast"
+    ]
+  },
+  {
+    "name": "Madame Uppercut",
+    "age": 39,
+    "secretIdentity": "Jane Wilson",
+    "powers": [
+      "Million tonne punch",
+      "Damage resistance",
+      "Superhuman reflexes"
+    ]
+  }
+]
+ +

Вышесказанное вполне справедливо для JSON. Вам просто нужно получить доступ к элементам массива (в его анализируемой версии), начиная с индекса массива, например [0]["powers"][0].

+ +

Другие примечания

+ + + +

Активное обучение: Работа с примером JSON

+ +

Итак, давайте рассмотрим пример, чтобы показать то, как мы можем использовать некоторые данные JSON на веб-сайте.

+ +

Начало работы

+ +

Для начала создайте локальные копии наших файлов heroes.html и style.css. Последний содержит простой CSS для стилизации нашей страницы, в то время как первый содержит очень простой HTML-код сущности:

+ +
<header>
+</header>
+
+<section>
+</section>
+ +

Плюс {{HTMLElement("script")}}, чтобы содержать код JavaScript, который мы будем писать в этом упражнении. На данный момент он содержит только две строки, которые захватывают ссылки на элементы {{HTMLElement("header")}} и {{HTMLElement("section")}} и сохраняют их в переменных:

+ +
var header = document.querySelector('header');
+var section = document.querySelector('section');
+ +

Мы предоставили данные JSON на нашем GitHub, на https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json.

+ +

Мы собираемся загрузить его на нашу страницу и использовать некоторые изящные манипуляции DOM, чтобы отобразить их, например:

+ +

+ +

Получение JSON

+ +

Чтобы получить JSON, мы будем использовать API, называемый {{domxref("XMLHttpRequest")}} (часто называемый XHR). Это очень полезный объект JavaScript, который позволяет нам делать сетевые запросы для извлечения ресурсов с сервера через JavaScript (например, изображения, текст, JSON, даже фрагменты HTML), что означает, что мы можем обновлять небольшие разделы контента без необходимости перезагрузки всей страницы. Это привело к более отзывчивым веб-страницам и звучит захватывающе, но, к сожалению, выходит за рамки этой статьи, чтобы изучить это гораздо более подробно.

+ +
    +
  1. Начнем с того, что мы собираемся сохранить URL-адрес JSON, который мы хотим получить в переменной. Добавьте нижеследующий код JavaScript: +
    var requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';
    +
  2. +
  3. Чтобы создать запрос, нам нужно создать новый экземпляр объекта запроса из конструктора XMLHttpRequest, используя ключевое слово new. Добавьте следующую ниже свою последнюю строку: +
    var request = new XMLHttpRequest();
    +
  4. +
  5. Теперь нам нужно открыть новый запрос, используя метод open(). Добавьте следующую строку: +
    request.open('GET', requestURL);
    + +

    Это занимает не менее двух параметров - есть другие доступные параметры. Нам нужно только два обязательных для этого простого примера:

    + +
      +
    • Метод HTTP, который следует использовать при выполнении сетевого запроса. В этом случае GET самый подходящий, так как мы просто извлекаем некоторые простые данные.
    • +
    • URL-адрес для запроса - это URL-адрес файла JSON, который мы сохранили ранее.
    • +
    +
  6. +
  7. Затем добавьте следующие две строки: здесь мы устанавливаем responseType в JSON, так что XHR знает, что сервер будет возвращать JSON и, что это должно быть преобразовано за кулисами в объект JavaScript. Затем мы отправляем запрос методом send(): +
    request.responseType = 'json';
    +request.send();
    +
  8. +
  9. Последний бит этого раздела предполагает ожидание ответа на возврат с сервера, а затем работы с ним. Добавьте следующий код ниже вашего предыдущего кода: +
    request.onload = function() {
    +  var superHeroes = request.response;
    +  populateHeader(superHeroes);
    +  showHeroes(superHeroes);
    +}
    +
  10. +
+ +

Здесь мы сохраняем ответ на наш запрос (доступный в свойстве response) в переменной superHeroes; эта переменная теперь будет содержать объект JavaScript, основанный на JSON! Затем мы передаем этот объект двум вызовам функций - первый из них заполнит <header> правильными данными, а второй создаст информационную карту для каждого героя в команде и вставляет ее в <section>.

+ +

Мы свернули код в обработчик событий, который запускается, когда событие загрузки запускается в объекте запроса (см. onload) - это связано с тем, что событие загрузки запускается, когда ответ успешно возвращается; поступая  таким образом,это гарантия того, что request.response определенно будет доступен, когда мы начнем работу с ним.

+ +

Заполнение заголовка

+ +

Теперь мы извлекли данные JSON и превратили его в объект JavaScript, давайте воспользуемся им, написав две функции, на которые мы ссылались выше. Прежде всего, добавьте следующее определение функции ниже предыдущего кода:

+ +
function populateHeader(jsonObj) {
+  var myH1 = document.createElement('h1');
+  myH1.textContent = jsonObj['squadName'];
+  header.appendChild(myH1);
+
+  var myPara = document.createElement('p');
+  myPara.textContent = 'Hometown: ' + jsonObj['homeTown'] + ' // Formed: ' + jsonObj['formed'];
+  header.appendChild(myPara);
+}
+ +

Мы назвали параметр jsonObj, чтобы напомнить себе, что этот объект JavaScript возник из JSON. Здесь мы сначала создаем элемент {{HTMLElement("h1")}} с createElement(), устанавливаем его textContent равным свойству squadName объекта, а затем добавляем его в заголовок с помощью appendChild(). Затем мы выполняем очень похожую операцию с абзацем: создаем его, устанавливаем его текстовое содержимое и добавляем его в заголовок. Единственное различие заключается в том, что его текст задан, как конкатенированная строка, содержащая как homeTown, так и formed свойства объекта.

+ +

Создание информационных карт героя

+ +

Затем добавьте следующую функцию внизу кода, которая создает и отображает карты супергероев:

+ +
function showHeroes(jsonObj) {
+  var heroes = jsonObj['members'];
+
+  for (var i = 0; i < heroes.length; i++) {
+    var myArticle = document.createElement('article');
+    var myH2 = document.createElement('h2');
+    var myPara1 = document.createElement('p');
+    var myPara2 = document.createElement('p');
+    var myPara3 = document.createElement('p');
+    var myList = document.createElement('ul');
+
+    myH2.textContent = heroes[i].name;
+    myPara1.textContent = 'Secret identity: ' + heroes[i].secretIdentity;
+    myPara2.textContent = 'Age: ' + heroes[i].age;
+    myPara3.textContent = 'Superpowers:';
+
+    var superPowers = heroes[i].powers;
+    for (var j = 0; j < superPowers.length; j++) {
+      var listItem = document.createElement('li');
+      listItem.textContent = superPowers[j];
+      myList.appendChild(listItem);
+    }
+
+    myArticle.appendChild(myH2);
+    myArticle.appendChild(myPara1);
+    myArticle.appendChild(myPara2);
+    myArticle.appendChild(myPara3);
+    myArticle.appendChild(myList);
+
+    section.appendChild(myArticle);
+  }
+}
+ +

Для начала сохраним свойство members объекта JavaScript в новой переменной. Этот массив содержит несколько объектов, которые содержат информацию для каждого героя.

+ +

Затем мы используем for loop для циклического прохождения каждого объекта в массиве. Для каждого из них мы:

+ +
    +
  1. Создаем несколько новых элементов: <article>, <h2>, три <p> и <ul>.
  2. +
  3. Установливаем <h2>, чтобы содержать name текущего героя.
  4. +
  5. Заполняем три абзаца своей secretIdentity, age и строкой, в которой говорится: «Суперспособности:», чтобы ввести информацию в список.
  6. +
  7. Сохраняем свойство powers в другой новой переменной под названием superPowers - где содержится массив, в котором перечислены сверхспособности текущего героя.
  8. +
  9. Используем другой цикл for, чтобы прокрутить сверхспособности текущего героя , для каждого из них мы создаем элемент <li>, помещаем в него сверхспособности, а затем помещаем listItem внутри элемента <ul> (myList) с помощью appendChild().
  10. +
  11. Последнее, что мы делаем, это добавляем <h2>, <p> и <ul> внутри <article> (myArticle), а затем добавляем <article> в <section>. Важное значение имеет порядок, в котором добавляются элементы, так как это порядок, который они будут отображать внутри HTML.
  12. +
+ +
+

Примечание. Если вам не удается заставить этот пример работать, попробуйте обратиться к нашему исходному коду heroes-finished.html (см. также он работает в режиме live).

+
+ +
+

Примечание. Если у вас возникли проблемы после нотации точек / скобок, которые мы используем для доступа к объекту JavaScript, в этом поможет открытие файла superheroes.json на другой вкладке или в текстовом редакторе ,и обращаться к нему каждый раз, когда вам нужен JavaScript. Вы также можете обратиться к нашей статье JavaScript objectbasics чтобы получить дополнительную информацию о нотации точек и скобок.

+
+ +

Преобразование между объектами и текстом

+ +

Вышеприведенный пример был прост с точки зрения доступа к объекту JavaScript, потому что мы задали XHR-запрос для прямого преобразования ответа JSON в объект JavaScript, используя:

+ +
request.responseType = 'json';
+ +

Но иногда нам не так везет - иногда мы получаем сырую строку JSON и нам нужно  преобразовать ее в объект самостоятельно. И когда мы хотим отправить объект JavaScript по сети, нам нужно  преобразовать его в JSON (строку) перед отправкой. К счастью, эти две проблемы настолько распространены в веб-разработке, что встроенный объект JSON доступен в браузерах, которые содержат следующие два метода:

+ + + +

Вы можете увидеть первый метод в действии в нашем примере heroes-finished-json-parse.html (см. исходный код) - это то же самое, что и в примере, который мы создали ранее, за исключением того, что мы установили XHR для возврата сырого JSON текста, затем используется parse(), чтобы преобразовать его в фактический объект JavaScript. Ключевой фрагмент кода находится здесь:

+ +
request.open('GET', requestURL);
+request.responseType = 'text'; // now we're getting a string!
+request.send();
+
+request.onload = function() {
+  var superHeroesText = request.response; // get the string from the response
+  var superHeroes = JSON.parse(superHeroesText); // convert it to an object
+  populateHeader(superHeroes);
+  showHeroes(superHeroes);
+}
+ +

Как вы могли догадаться, stringify() работает обратным образом. Попробуйте ввести следующие строки в консоль JavaScript браузера один за другим, чтобы увидеть его в действии:

+ +
var myJSON = { "name": "Chris", "age": "38" };
+myJSON
+var myString = JSON.stringify(myJSON);
+myString
+ +

Здесь мы создаем объект JavaScript, затем проверяем, что он содержит, а затем преобразуем его в строку JSON, используя stringify() , сохраняя возвращаемое значение в новой переменной, а затем снова проверяем его.

+ +

Резюме

+ +

В этой статье мы предоставили вам простое руководство по использованию JSON в ваших программах, в том числе о том, как создавать и анализировать JSON, и как получить доступ к данным, заблокированным внутри него. В следующей статье мы рассмотрим объектно-ориентированный JavaScript.

+ +

Смотрите также

+ + + +

{{PreviousMenuNext("Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects/Object_building_practice", "Learn/JavaScript/Objects")}}

+ +

В этом модуле

+ + + +
+ + +
+ +
+
diff --git a/files/ru/learn/javascript/objects/object-oriented_js/index.html b/files/ru/learn/javascript/objects/object-oriented_js/index.html new file mode 100644 index 0000000000..0299268a90 --- /dev/null +++ b/files/ru/learn/javascript/objects/object-oriented_js/index.html @@ -0,0 +1,286 @@ +--- +title: Объектно-ориентированный JavaScript для начинающих +slug: Learn/JavaScript/Объекты/Object-oriented_JS +tags: + - Constructor + - Create + - JavaScript + - OOJS + - Object + - Новичку + - ООП + - экземпляр +translation_of: Learn/JavaScript/Objects/Object-oriented_JS +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Objects/Basics", "Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects")}}
+ +

Разобравшись с основами, сосредоточимся на объектно-ориентированном JavaScript (OOJS) — данная статья дает базовое представление о теории объектно-ориентированного программирования (ООП), далее рассмотрено как JavaScript эмулирует классы объектов с помощью функции-конструктора и как создаются экземпляры объектов.

+ + + + + + + + + + + + +
Необходимые знания: +

Базовая компьютерная грамотность, базовое понимание HTML и CSS, знакомство с основами JavaScript (см. Первые шаги и Cтруктурные элементы JavaScript) и основы OOJS (см. Введение в объекты).

+
Цель:Понять основную теорию объектно-ориентированного программирования, как это относится к JavaScript («все является объектом») и как создавать конструкторы и экземпляры объектов.
+ +

Объектно-ориентированное программирование: основы

+ +

Начнём с упрощённого высокоуровневого представления о том, что такое объектно-ориентированное программирование (ООП). Мы говорим упрощённого, потому что ООП может быстро стать очень сложным, и если сейчас дать полный курс, вероятно, можно запутать больше, чем помочь. Основная идея ООП заключается в том, что мы используем объекты для отображения моделей из реального мира в наших программах и/или упрощения доступа к функциям, которые в противном случае было бы трудно или невозможно использовать.

+ +

Объекты могут содержать данные и код, представляющие информацию о том, что вы пытаетесь смоделировать, а также о том, какие у этих объектов должны быть функциональные возможности или поведение. Данные объекта (а часто так же и функции) могут быть точно сохранены (официальный термин "инкапсулированы") внутри пакета объекта, упрощая структуру и доступ к ним. Пакету объекта может быть присвоено определенное имя, на которое можно сослаться и которое иногда называют пространством имен. Объекты также широко используются в качестве хранилищ данных, которые могут быть легко отправлены по сети.

+ +

Определение шаблона объекта

+ +

Рассмотрим простую программу, которая отображает информацию об учениках и учителях в школе. Здесь мы рассмотрим теорию ООП в целом, а не в контексте какого-либо конкретного языка программирования.

+ +

Вернёмся к объекту Person из нашей статьи Основы объектов, который определяет общие сведения и функциональные возможности человека. Есть много вещей, которые вы можете узнать о человеке (его адрес, рост, размер обуви, профиль ДНК, номер паспорта, значимые черты личности ...), но в данном случае нас интересует только имя, возраст, пол и интересы, а также мы хотим иметь возможность написать краткую информацию о нём, основываясь на этих данных, и сделать так, чтобы он поздоровался. Это известно как абстракция — создание простой модели более сложной сущности, которая представляет её наиболее важные аспекты таким образом, чтобы с ней было удобно работать для выполнения целей нашей программы.

+ +

+ +

В некоторых языках ООП, это общее определение типа объекта называется class (JavaScript использует другой механизм и терминологию, как вы увидите ниже) — это на самом деле не объект, а шаблон, который определяет, какие характеристики должен иметь объект.

+ +

Создание реальных объектов

+ +

Из нашего класса мы можем создать экземпляры объектов — объекты, содержащие данные и функциональные возможности, определённые в классе. Из нашего класса Person мы теперь можем создавать модели реальных людей:

+ +

+ +

Когда экземпляр объекта создается из класса, для его создания выполняется функция-конструктор класса. Этот процесс создания экземпляра объекта из класса называется создание экземпляра (instantiation) — из класса создается экземпляр объекта.

+ +

Специализированные классы

+ +

В нашем случае нам не нужны все люди — нам требуются учителя и ученики, которые являются более конкретными типами людей. В ООП мы можем создавать новые классы на основе других классов — эти новые дочерние классы могут быть созданы для наследования данных и характеристик родительского класса, так чтобы можно было использовать функциональные возможности, общие для всех типов объекта, вместо того чтобы дублировать их. Когда функциональность различается между классами, можно по мере необходимости определять специализированные функции непосредственно на них.

+ +

+ +

Это действительно полезно — преподаватели и студенты имеют много общих характеристик, таких как имя, пол и возраст, и удобно определить их только один раз. Вы можете также задать одну и ту же характеристику отдельно в разных классах, поскольку каждое определение этой характеристики будет находиться в отдельном пространстве имен. Например, приветствие студента может быть в форме "Yo, I'm [firstName]" (например Yo, I'm Sam), в то время как учитель может использовать что-то более формальное, такое как "Hello, my name is [Prefix] [lastName], and I teach [Subject]." (например Hello, My name is Mr Griffiths, and I teach Chemistry).

+ +
+

Примечание: Если вам интересно, существует специальный термин Polymorphism (Полиморфизм) - это забавное слово, обозначающее реализацию той же функциональности для нескольких типов объекта. 

+
+ +

Теперь вы можете создавать экземпляры объекта из дочерних классов. Например:

+ +

+ +

Далее мы рассмотрим, как ООП теорию можно применить на практике в JavaScript.

+ +

Конструкторы и экземпляры объектов

+ +

JavaScript использует специальные функции, называемые функциями конструктора (constructor functions) для определения объектов и их свойств. Они полезны, потому что вы часто будете сталкиваться с ситуациями, в которых не известно, сколько объектов вы будете создавать; конструкторы позволяют создать столько объектов, сколько нужно эффективным способом, прикреплением данных и функций для объектов по мере необходимости.

+ +

Рассмотрим создание классов через конструкторы и создание экземпляров объектов из них в JavaScript. Прежде всего, мы хотели бы, чтобы вы создали новую локальную копию файла oojs.html, который мы видели в нашей первой статье «Объекты».

+ +

Простой пример

+ +
    +
  1. Давайте рассмотрим как можно определить человека с нормальной функцией. Добавьте эту функцию в элемент script: + +
    function createNewPerson(name) {
    +  const obj = {};
    +  obj.name = name;
    +  obj.greeting = function() {
    +    alert('Hi! I\'m ' + this.name + '.');
    +  };
    +  return obj;
    +}
    +
  2. +
  3. Теперь вы можете создать нового человека, вызвав эту функцию - попробуйте следующие строки в консоли JavaScript браузера: +
    const salva = createNewPerson('Salva');
    +salva.name;
    +salva.greeting();
    + Это работает достаточно хорошо, но код излишне многословен; если мы знаем, что хотим создать объект, зачем нам явно создавать новый пустой объект и возвращать его? К счастью, JavaScript предоставляет нам удобный способ в виде функций-конструкторов - давайте сделаем это сейчас!
  4. +
  5. Замените предыдущую функцию следующей: +
    function Person(name) {
    +  this.name = name;
    +  this.greeting = function() {
    +    alert('Hi! I\'m ' + this.name + '.');
    +  };
    +}
    +
  6. +
+ +

Функция-конструктор - это JavaScript версия класса. Вы заметите, что в нем есть все признаки, которые вы ожидаете от функции, хотя он ничего не возвращает и явно не создает объект - он в основном просто определяет свойства и методы. Вы также увидите, что ключевое слово this также используется здесь, - это в основном говорит о том, что всякий раз, когда создается один из этих экземпляров объектов, свойство имени объекта будет равно значению name, переданному вызову конструктора, и метод greeting() будет использовать значение имени, переданное также вызову конструктора.

+ +
+

Примечание: Имя функции конструктора обычно начинается с заглавной буквы - это соглашение используется для упрощения распознавания функций конструктора в коде.

+
+ +

Итак, как мы вызываем конструктор для создания некоторых объектов?

+ +
    +
  1. Добавьте следующие строки под предыдущим добавлением кода: +
    let person1 = new Person('Bob');
    +let person2 = new Person('Sarah');
    +
  2. +
  3. Сохраните код и перезагрузите его в браузере и попробуйте ввести следующие строки в консоль JS: +
    person1.name
    +person1.greeting()
    +person2.name
    +person2.greeting()
    +
  4. +
+ +

Круто! Теперь, как вы видите, у нас есть два новых объекта на странице, каждый из которых хранится в отдельном пространстве имен - при доступе к их свойствам и методам вы должны начинать вызовы с person1 или person2; функциональность, содержащаяся внутри, аккуратно упакована, поэтому она не будет конфликтовать с другими функциями. Тем не менее, у них есть одно и то же свойство name и greeting(). Обратите внимание, что они используют свое собственное значение name, которое было присвоено им, когда они были созданы; это одна из причин, почему очень важно использовать this, таким образом они будут использовать свои собственные значения, а не какие-либо другие.

+ +

Давайте снова посмотрим на вызовы конструктора:

+ +
let person1 = new Person('Bob');
+let person2 = new Person('Sarah');
+ +

В каждом случае ключевое слово new используется, чтобы сообщить браузеру, что мы хотим создать экземпляр нового объекта, за которым следует имя функции с ее необходимыми параметрами, содержащимися в круглых скобках, и результат сохраняется в переменной - очень похоже на то, как вызывается стандартная функция. Каждый экземпляр создается в соответствии с этим определением:

+ +
function Person(name) {
+  this.name = name;
+  this.greeting = function() {
+    alert('Hi! I\'m ' + this.name + '.');
+  };
+}
+ +

После создания новых объектов переменные person1 и person2 содержат следующие объекты:

+ +
{
+  name: 'Bob',
+  greeting: function() {
+    alert('Hi! I\'m ' + this.name + '.');
+  }
+}
+
+{
+  name: 'Sarah',
+  greeting: function() {
+    alert('Hi! I\'m ' + this.name + '.');
+  }
+}
+ +

Обратите внимание, что когда мы вызываем нашу функцию-конструктор, мы определяем greeting() каждый раз, что не является идеальным. Чтобы этого избежать, вместо этого мы можем определить функции на прототипе, о которых мы поговорим позже.

+ +

Создавая наш готовый конструктор

+ +

Пример, рассмотренный выше, был лишь наглядным примером, чтобы вы поняли суть. Теперь, давайте создадим нашу конечную функцию-конструктор Person().

+ +
    +
  1. Замените весь предыдущий код новой функцией конструктора - это, в принципе, тот же самое что и в наглядном примере, но несколько сложнее: +
    function Person(first, last, age, gender, interests) {
    +  this.name = {
    +    first : first,
    +    last: last
    +  };
    +  this.age = age;
    +  this.gender = gender;
    +  this.interests = interests;
    +  this.bio = function() {
    +    alert(this.name.first + ' ' + this.name.last + ' is ' + this.age + ' years old. He likes ' + this.interests[0] + ' and ' + this.interests[1] + '.');
    +  };
    +  this.greeting = function() {
    +    alert('Hi! I\'m ' + this.name.first + '.');
    +  };
    +};
    +
  2. +
  3. Теперь добавьте следующую строку ниже, чтобы создать экземпляр объекта из него: +
    let person1 = new Person('Bob', 'Smith', 32, 'male', ['music', 'skiing']);
    +
  4. +
+ +

Как вы могли заметить, вы можете получить доступ к свойствам и методам, как это было ранее, - попробуйте использовать их в консоли JS:

+ +
person1['age']
+person1.interests[1]
+person1.bio()
+// etc.
+ +
Примечание: Если у Вас возникли проблемы с работой кода, попробуйте сравнить его с нашей версией - см. oojs-class-finished.html (также смотрите, как он работает в прямом эфире).
+ +

Дальнейшие упражнения

+ +

Для начала, попробуйте добавить еще пару собственных строк создания объекта и попробуйте получить и установить элементы полученных экземпляров объектов.

+ +

Кроме того, есть несколько проблем с нашим методом bio() - вывод всегда включает местоимение «He» ("Он" в пер. с англ.), даже если ваш человек является женщиной или какой-либо другой предпочтительной гендерной классификацией. И bio будет включать только два интереса, даже если в массиве interests указано больше. Можете ли Вы решить, как исправить это в определении класса (конструкторе)? Вы можете поместить любой код, который вам нравится внутри конструктора (вам, вероятно, понадобятся несколько условий и цикл). Подумайте о том, как предложения должны быть структурированы по-разному в зависимости от пола и в зависимости от того, имеет ли число перечисленных интересов 1, 2 или более 2.

+ +
+

Примечание: Если у Вас возникли трудности с решением задачи, мы предоставили ответ в нашем репозитории GitHub (см. это в действии) — но сначала попробуйте написать сами!

+
+ +

Другие способы создания экземпляров объектов

+ +

До сих пор мы видели два разных способа создания экземпляра объекта - объявление объектного литерала и использование функции конструктора (см. выше).

+ +

Это имеет смысл, но есть и другие способы - мы бы хотели ознакомить Вас с ними на случай, если Вы встретите их в своих путешествиях по Сети.

+ +

Конструктор Object ()

+ +

Прежде всего, вы можете использовать конструктор Object() для создания нового объекта. Да, даже общие объекты имеют конструктор, который генерирует пустой объект.

+ +
    +
  1. Попробуйте ввести это в консоль JavaScript вашего браузера: +
    let person1 = new Object();
    +
  2. +
  3. Это сохраняет ссылку на пустой объект в переменную person1. Затем вы можете добавить свойства и методы к этому объекту с использованием точечной или скобочной нотации по желанию; попробуйте эти примеры в консоли: +
    person1.name = 'Chris';
    +person1['age'] = 38;
    +person1.greeting = function() {
    +  alert('Hi! I\'m ' + this.name + '.');
    +};
    +
  4. +
  5. Вы также можете передать литерал объекта конструктору Object() в качестве параметра, чтобы заполнить его свойствами / методами. Попробуйте это в консоли JS: +
    let person1 = new Object({
    +  name: 'Chris',
    +  age: 38,
    +  greeting: function() {
    +    alert('Hi! I\'m ' + this.name + '.');
    +  }
    +});
    +
  6. +
+ +

Использование метода create()

+ +

Конструкторы могут помочь вам определить порядок кода - вы можете создать конструктор в одном месте, а затем создавать экземпляры по мере необходимости, и их происхождение будет понятным.

+ +

Однако некоторые люди предпочитают создавать экземпляры объектов без предварительного создания конструкторов, особенно если они создают только несколько экземпляров объекта. JavaScript имеет встроенный метод create(), который позволяет вам это делать. С его помощью вы можете создать новый объект на основе любого существующего объекта.

+ +
    +
  1. Закончив упражнение из предыдущего раздела, загруженное в браузер, попробуйте это в консоли JavaScript: +
    let person2 = Object.create(person1);
    +
  2. +
  3. Теперь попробуйте: +
    person2.name
    +person2.greeting()
    +
  4. +
+ +

Вы увидите, что person2 был создан на основе person1 - он имеет те же свойства и метод, доступные для него.

+ +

Одно ограничение метода create() заключается в том, что IE8 не поддерживает его. Поэтому конструкторы могут быть более эффективными, если вы хотите поддерживать старые браузеры.

+ +

Подробнее мы рассмотрим особенности метода create() немного позже.

+ +

Сводка

+ +

В этой статье представлен упрощенный взгляд на объектно-ориентированную теорию — это еще не вся история, но она дает представление о том, с чем мы имеем дело. Кроме того, мы начали рассматривать различные способы создания экземпляров объектов.

+ +

В следующей статье мы рассмотрим прототипы объектов JavaScript.

+ +

{{PreviousMenuNext("Learn/JavaScript/Objects/Basics", "Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects")}}

+ +

В этом модуле

+ + diff --git a/files/ru/learn/javascript/objects/object_building_practice/index.html b/files/ru/learn/javascript/objects/object_building_practice/index.html new file mode 100644 index 0000000000..b06b769ca4 --- /dev/null +++ b/files/ru/learn/javascript/objects/object_building_practice/index.html @@ -0,0 +1,302 @@ +--- +title: Практика построения объектов +slug: Learn/JavaScript/Объекты/Object_building_practice +tags: + - Guide + - JavaScript +translation_of: Learn/JavaScript/Objects/Object_building_practice +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects/Adding_bouncing_balls_features", "Learn/JavaScript/Objects")}}
+ +

В предыдущих статьях мы рассмотрели всю существенную теорию объектов JavaScript и детали синтаксиса, давая вам прочную основу для начала. В этой статье мы погружаемся в практическое упражнение, давая вам больше практики в создании пользовательских объектов JavaScript, с веселым и красочным результатом.

+ + + + + + + + + + + + +
Необходимые знания:Базовая компьютерная грамотность, базовые знания HTML и CSS, знакомство с основами JavaScript (see First steps and Building blocks) и основами OOJS (см. Introduction to objects).
Цель:Получение некоторой практики в использовании объектов и объектно-ориентированных методов в реальном мире.
+ +

Давайте подбросим несколько мячей

+ +

В этой статье мы напишем классическую демонстрацию «прыгающих шаров», чтобы показать вам, насколько полезными могут быть объекты в JavaScript. Наши маленькие шары будут подпрыгивать на экране и менять цвет, когда они касаются друг друга. Готовый пример будет выглядеть примерно так:

+ +

+ +
    +
+ +

В этом примере будет использоваться Canvas API для рисования шаров на экране и API requestAnimationFrame для анимации всего экрана - вам не нужно иметь никаких предыдущих знаний об этих API, и мы надеемся, что к тому моменту, когда вы закончите эту статью, вам будет интересно изучить их больше. По пути мы воспользуемся некоторыми изящными объектами и покажем вам пару хороших приемов, таких как отскоки шаров от стен и проверка того, попали ли они друг в друга (иначе известный как обнаружение столкновения).

+ +

Начало работы

+ +

Для начала создайте локальные копии наших файловindex.html, style.css и main.js. Они содержат следующее:

+ +
    +
  1. Очень простой HTML-документ, содержащий элемент {{HTMLElement("h1")}}, элемент {{HTMLElement("canvas")}} для рисования наших шаров и элементы для применения нашего CSS и JavaScript в нашем HTML.
  2. +
  3. Некоторые очень простые стили, которые в основном служат для стилизации и позиционирования <h1>, и избавляются от любых полос прокрутки или отступы по краю страницы (так что это выглядит красиво и аккуратно).
  4. +
  5. Некоторые JavaScript, которые служат для настройки элемента <canvas> и предоставляют общую функцию, которую мы собираемся использовать.
  6. +
+ +

Первая часть скрипта выглядит так:

+ +
var canvas = document.querySelector('canvas');
+
+var ctx = canvas.getContext('2d');
+
+var width = canvas.width = window.innerWidth;
+var height = canvas.height = window.innerHeight;
+ +

Этот скрипт получает ссылку на элемент <canvas>, а затем вызывает метод getContext(), чтобы дать нам контекст, по которому мы можем начать рисовать. Результирующая переменная (ctx) - это объект, который непосредственно представляет область рисования холста и позволяет рисовать на ней 2D-фигуры.

+ +

Затем мы устанавливаем переменные, называемые width и height, а также ширину и высоту элемента canvas (представленные свойствами canvas.width и canvas.height), чтобы равняться ширине и высоте окна просмотра браузера (область, на которой отображается веб-страница - это можно получить из свойств {{domxref("Window.innerWidth")}} и {{domxref("Window.innerHeight")}}).

+ +

Вы увидите здесь, что мы объединяем несколько назначений вместе, чтобы все переменные были установлены быстрее - это совершенно нормально.

+ +

Последний бит исходного скрипта выглядит следующим образом:

+ +
function random(min, max) {
+  var num = Math.floor(Math.random() * (max - min + 1)) + min;
+  return num;
+}
+ +

Эта функция принимает два числа в качестве аргументов и возвращает случайное число в диапазоне между ними.

+ +

Моделирование мяча в нашей программе

+ +

В нашей программе будет много шаров, подпрыгивающих вокруг экрана. Поскольку эти шары будут вести себя одинаково, имеет смысл представлять их в виде объекта. Начнем с добавления следующего конструктора в конец нашего кода.

+ +
function Ball(x, y, velX, velY, color, size) {
+  this.x = x;
+  this.y = y;
+  this.velX = velX;
+  this.velY = velY;
+  this.color = color;
+  this.size = size;
+}
+ +

Здесь мы включаем некоторые параметры, которые определяют свойства, которым должен соответствовать каждый шар в нашей программе:

+ + + +

Этим мы сортируем свойства, но что насчет методов? Мы хотим заставить эти шары на самом деле сделать что-то в нашей программе.

+ +

Рисование шара

+ +

Сначала добавьте следующий метод draw() к Ball()'s prototype:

+ +
Ball.prototype.draw = function() {
+  ctx.beginPath();
+  ctx.fillStyle = this.color;
+  ctx.arc(this.x, this.y, this.size, 0, 2 * Math.PI);
+  ctx.fill();
+}
+ +

Используя эту функцию, мы можем сказать нашему шару нарисовать себя на экране, вызвав ряд членов контекста двумерного холста, который мы определили ранее (ctx). Контекст похож на бумагу, и теперь мы хотим, чтобы наше перо рисовало что-то на нем:

+ + + +

Теперь вы можете начать тестирование своего объекта..

+ +
    +
  1. Сохраните код и загрузите HTML-файл в браузер.
  2. +
  3. Откройте консоль JavaScript браузера, а затем обновите страницу, чтобы размер холста изменился в соответствии с новой шириной и высотой окна просмотра браузера после открытия консоли.
  4. +
  5. Чтобы создать новый экземпляр шара, введите следующее: +
    var testBall = new Ball(50, 100, 4, 4, 'blue', 10);
    +
  6. +
  7. Попробуйте вызвать его свойства и методы: +
    testBall.x
    +testBall.size
    +testBall.color
    +testBall.draw()
    +
  8. +
  9. После введения последней строки, вы должны увидеть, как мяч нарисовался где-то на вашем холсте.
  10. +
+ +

Обновление данных мяча

+ +

Мы можем нарисовать мяч в нужном положении, но чтобы начать движение мяча, нам нужна функция обновления. Добавьте следующий код внизу вашего файла JavaScript, чтобы добавить метод update() к Ball()'s prototype:

+ +
Ball.prototype.update = function() {
+  if ((this.x + this.size) >= width) {
+    this.velX = -(this.velX);
+  }
+
+  if ((this.x - this.size) <= 0) {
+    this.velX = -(this.velX);
+  }
+
+  if ((this.y + this.size) >= height) {
+    this.velY = -(this.velY);
+  }
+
+  if ((this.y - this.size) <= 0) {
+    this.velY = -(this.velY);
+  }
+
+  this.x += this.velX;
+  this.y += this.velY;
+}
+ +

Первые четыре части функции проверяют, достиг ли шар края холста. Если это так, мы изменяем полярность соответствующей скорости, чтобы заставить шар двигаться в противоположном направлении. Так, например, если мяч двигался вверх (положительный velY), то вертикальная скорость изменяется так, что он начинает двигаться вниз (отрицательная величина velY).

+ +

В этих четырех случаях мы:

+ + + +

В каждом случае мы включаем size шарика в расчет, потому что координаты x/y находятся в центре шара, но мы хотим, чтобы край шара отскакивал от периметра - мы не хотим, чтобы мяч на половину заходил за границу экрана прежде чем он начнет возвращаться назад.

+ +

Последние две строки добавляют значение velX к координате x, а значение velY - координате y - шар фактически перемещается при каждом вызове этого метода.

+ +

На сейчас этого достаточно, давайте продолжим анимацию!

+ +

Анимация мяча

+ +

Теперь давайте приступать к веселью! Сейчас мы начнем добавлять шары к холсту и анимировать их.

+ +
    +
  1. Во-первых, нам нужно где-то хранить все наши шары. Следующий массив выполнит это задание - добавьте его внизу кода: +
    var balls = [];
    + +

    Все программы, которые оживляют вещи, обычно включают цикл анимации, который служит для обновления информации в программе, а затем визуализации результирующего представления для каждого кадра анимации; это основа для большинства игр и других подобных программ.

    +
  2. +
  3. Добавьте ниже эту часть кода: +
    function loop() {
    +  ctx.fillStyle = 'rgba(0, 0, 0, 0.25)';
    +  ctx.fillRect(0, 0, width, height);
    +
    +  while (balls.length < 25) {
    +    var ball = new Ball(
    +      random(0,width),
    +      random(0,height),
    +      random(-7,7),
    +      random(-7,7),
    +      'rgb(' + random(0,255) + ',' + random(0,255) + ',' + random(0,255) +')',
    +      random(10,20)
    +    );
    +    balls.push(ball);
    +  }
    +
    +  for (var i = 0; i < balls.length; i++) {
    +    balls[i].draw();
    +    balls[i].update();
    +  }
    +
    +  requestAnimationFrame(loop);
    +}
    + +

    Наша функция loop() выполняет следующие действия:

    + +
      +
    • Устанавливает цвет заливки на полупрозрачный черный, затем рисует прямоугольник цвета по всей ширине и высоте холста, используя fillRect() (четыре параметра обеспечивают начальную координату, а ширину и высоту для рисованного прямоугольника ). Это позволяет скрыть рисунок предыдущего кадра до того, как будет нарисован следующий. Если вы этого не сделаете, вы увидите, как длинные змеи пробираются вокруг холста, а не шары! Цвет заливки устанавливается на полупрозрачный, rgba(0,0,0,0,25), чтобы позволить нескольким кадрам слегка просвечивать, создавая маленькие тропы за шариками по мере их перемещения. Если вы изменили 0.25 на 1, вы больше не увидите их. Попробуйте изменить это число, чтобы увидеть эффект, который он имеет.
    • +
    • Создает новый экземпляр нашего Ball(), используя случайные значения, сгенерированные с помощью нашей функции random(), затем push() на конец нашего массива шаров, но только в том случае, когда количество шаров в массиве меньше 25. Итак когда у нас есть 25 мячей на экране, больше не появляется шаров. Вы можете попробовать изменить число в balls.length < 25, чтобы получить больше или меньше шаров на экране. В зависимости от того, сколько вычислительной мощности имеет ваш компьютер / браузер, если указать несколько тысячь шаров, это может довольно существенно повлиять на производительность анимации. 
    • +
    • перебирает все шары в массиве balls и запускает каждую функцию draw() и update() для рисования каждого из них на экране, а затем выполняет необходимые обновления по положению и скорости во времени для следующего кадра.
    • +
    • Выполняет функцию снова с помощью метода requestAnimationFrame() - когда этот метод постоянно запускается и передается одно и то же имя функции, он будет запускать эту функцию определенное количество раз в секунду для создания плавной анимации. Обычно это делается рекурсивно - это означает, что функция вызывает себя каждый раз, когда она запускается, поэтому она будет работать снова и снова.
    • +
    +
  4. +
  5. И последнее, но не менее важное: добавьте следующую строку в конец вашего кода - нам нужно вызвать функцию один раз, чтобы начать анимацию. +
    loop();
    +
  6. +
+ +

Вот и все для основы - попробуйте сохранить и освежить, чтобы проверить свои прыгающие шары!

+ +

Добавление обнаружения столкновений

+ +

Теперь немного поиграем, давайте добавим в нашу программу обнаружение конфликтов, поэтому наши мячи узнают, когда они ударят по другому шару.

+ +
    +
  1. Прежде всего, добавьте следующее определение метода ниже, где вы определили метод update() (т.е. блок Ball.prototype.update). + +
    Ball.prototype.collisionDetect = function() {
    +  for (var j = 0; j < balls.length; j++) {
    +    if (!(this === balls[j])) {
    +      var dx = this.x - balls[j].x;
    +      var dy = this.y - balls[j].y;
    +      var distance = Math.sqrt(dx * dx + dy * dy);
    +
    +      if (distance < this.size + balls[j].size) {
    +        balls[j].color = this.color = 'rgb(' + random(0, 255) + ',' + random(0, 255) + ',' + random(0, 255) +')';
    +      }
    +    }
    +  }
    +}
    + +

    Этот метод немного сложный, поэтому не беспокойтесь, если вы не понимаете, как именно это работает. Ниже приводится объяснение:

    + +
      +
    • Для каждого шара нам нужно проверить каждый другой шар, чтобы увидеть, столкнулся ли он с текущим мячом. Чтобы сделать это, мы открываем еще один цикл for  через все шары в массиве balls[].
    • +
    • Сразу же в нашем цикле for мы используем оператор if, чтобы проверить, проходит ли текущий шарик, тот же самый шар, что и тот, который мы сейчас проверяем. Мы не хотим проверять, что мяч столкнулся с самим собой! Для этого мы проверяем, является ли текущий мяч (т.е. мяч, метод которого вызван методом collisionDetect) такой же, как шар петли (т.е. шар, на который ссылается текущая итерация цикла for в collisionDetect метод). Затем мы используем ! чтобы отменить проверку, чтобы код внутри оператора if выполнялся только в том случае, если они не совпадают.
    • +
    • Затем мы используем общий алгоритм для проверки столкновения двух окружностей. Мы в основном проверяем, перекрывается ли какая-либо из областей круга. Это объясняется далее 2D collision detection.
    • +
    • Если обнаружено столкновение, выполняется код внутри внутреннего оператора if. В этом случае мы просто устанавливаем свойство color обоих кругов на новый случайный цвет. Мы могли бы сделать что-то гораздо более сложное, например, заставить шары отскакивать друг от друга реалистично, но это было бы гораздо сложнее реализовать. Для такого моделирования физики разработчики склонны использовать игры или библиотеку физики, такие как PhysicsJS, matter.js, Phaser и т.д.
    • +
    +
  2. +
  3. Вы также должны вызвать этот метод в каждом кадре анимации. Добавьте следующий код после строки balls[i].update(); +
    balls[i].collisionDetect();
    +
  4. +
  5. Сохраните и обновите демо снова, и вы увидите, как ваши мячи меняют цвет, когда они сталкиваются!
  6. +
+ +
+

Примечание. Если вам не удается заставить этот пример работать, попробуйте сравнить код JavaScript с нашей готовой версией (также смотрите, как он работает в прямом эфире).

+
+ +

Резюме

+ +

Мы надеемся, что вам понравилось писать собственный пример случайных прыгающих шаров в реальном мире, используя различные объектные и объектно-ориентированные методы из всего модуля! Это должно было дать вам некоторую полезную практику использования объектов и хорошего контекста реального мира.

+ +

Вот и все для предметных статей - все, что осталось сейчас, - это проверить свои навыки в оценке объекта.

+ +

Смотрите также

+ + + +

{{PreviousMenuNext("Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects/Adding_bouncing_balls_features", "Learn/JavaScript/Objects")}}

+ +

В этом модуле

+ + diff --git a/files/ru/learn/javascript/objects/object_prototypes/index.html b/files/ru/learn/javascript/objects/object_prototypes/index.html new file mode 100644 index 0000000000..0a76580d9c --- /dev/null +++ b/files/ru/learn/javascript/objects/object_prototypes/index.html @@ -0,0 +1,285 @@ +--- +title: Прототипы объектов +slug: Learn/JavaScript/Объекты/Object_prototypes +tags: + - JavaScript + - create() + - Конструктор + - Начинающий + - ООП + - Обучение + - Обьект + - Статья + - прототип +translation_of: Learn/JavaScript/Objects/Object_prototypes +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects")}}
+ +
Прототипы - это механизм, с помощью которого объекты JavaScript наследуют свойства друг от друга. В этой статье мы объясним, как работают цепочки прототипов, и рассмотрим, как свойство prototype можно использовать для добавления методов к существующим конструкторам.
+ +
+ + + + + + + + + + + + +
Необходимые знания: +

Базовая компьютерная грамотность, базовое понимание HTML и CSS, знакомство с основами JavaScript (см. Первые шаги и Строительные блоки) и основы OOJS (см. Введение в объекты).

+
Цель: +

Понять прототипы объектов JavaScript, как работают прототипные цепочки и как добавить новые методы в prototype свойство.

+
+ +

Язык основанный на прототипах?

+ +

JavaScript часто описывают как язык прототипного наследования — каждый объект, имеет объект-прототип, который выступает как шаблон, от которого объект наследует методы и свойства. Объект-прототип так же может иметь свой прототип и наследовать его свойства и методы и так далее. Это часто называется цепочкой прототипов и объясняет почему одним объектам доступны свойства и методы которые определены в других объектах.

+ +

Точнее, свойства и методы определяются в свойстве prototype функции-конструктора объектов, а не в самих объектах.

+ +

В JavaScript создается связь между экземпляром объекта и его прототипом (свойство __proto__, которое является производным от свойства prototype конструктора), а свойства и методы обнаруживаются при переходе по цепочке прототипов.

+ +
+

Примечание: Важно понимать, что существует различие между прототипом объекта (который доступен через Object.getPrototypeOf(obj) или через устаревшее свойство __proto__) и свойством prototype в функциях-конструкторах. Первое свойство является свойством каждого экземпляра, а второе - свойством конструктора. То есть Object.getPrototypeOf(new Foobar()) относится к тому же объекту, что и Foobar.prototype.

+
+ +

Давайте посмотрим на пример, чтобы стало понятнее.

+ +

Понимание прототипа объектов

+ +

Вернемся к примеру, когда мы закончили писать наш конструктор Person()- загрузите пример в свой браузер. Если у вас еще нет работы от последней статьи, используйте наш пример oojs-class-further-exercises.html (см. Также исходный код).

+ +

В этом примере мы определили конструкторную функцию, например:

+ +
function Person(first, last, age, gender, interests) {
+
+  // Определения методов и свойств
+  this.name = {
+    'first': first,
+    'last' : last
+  };
+  this.age = age;
+  this.gender = gender;
+  //...см. Введение в объекты для полного определения
+}
+ +

Затем мы создаём экземпляр объекта следующим образом:

+ +
var person1 = new Person('Bob', 'Smith', 32, 'male', ['music', 'skiing']);
+ +

Если вы наберете «person1.» в вашей консоли JavaScript, вы должны увидеть, что браузер пытается автоматически заполнить это с именами участников, доступных на этом объекте:

+ +

+ +

В этом списке вы увидите элементы, определенные в конструкторе person 1 — Person() — name, age, gender, interests, bio, и greeting. Однако вы также увидите некоторые другие элементы — watch, valueOfи т. д. — они определены в объекте прототипа Person (), который является Object.

+ +

+ +

Итак, что произойдет, если вы вызываете метод в person1, который фактически определен в Object? Например:

+ +
person1.valueOf()
+ +

Этот метод — Object.valueOf()наследуется person1, потому что его конструктором является Person(), а прототипом Person() является Object(). valueOf() возвращает значение вызываемого объекта — попробуйте и убедитесь! В этом случае происходит следующее:

+ + + +
+

Примечание: Мы хотим повторить, что методы и свойства не копируются из одного объекта в другой в цепочке прототипов - к ним обращаются, поднимаясь по цепочке, как описано выше.

+
+ +
+

Примечание: Официально нет способа получить доступ к объекту прототипа объекта напрямую - «ссылки» между элементами в цепочке определены во внутреннем свойстве, называемом [[prototype]] в спецификации для языка JavaScript ( см. {{glossary("ECMAScript")}}). Однако у большинства современных браузеров есть свойство, доступное для них под названием __proto__ (это 2 подчеркивания с обеих сторон), который содержит объект-прототип объекта-конструктора. Например, попробуйте person1.__proto__ и person1.__proto__.__proto__, чтобы увидеть, как выглядит цепочка в коде!

+ +

С ECMAScript 2015 вы можете косвенно обращаться к объекту прототипа объекта Object.getPrototypeOf (obj).

+
+ +

Свойство prototype: Где определены унаследованные экземпляры

+ +

Итак, где определены наследуемые свойства и методы? Если вы посмотрите на страницу со ссылкой Object, вы увидите в левой части большое количество свойств и методов - это намного больше, чем количество унаследованных членов, доступных для объекта person1. Некоторые из них унаследованы, а некоторые нет - почему это?

+ +

Как упоминалось выше, наследованные свойства это те, что определены в свойстве prototype (вы можете называть это подпространством имен), то есть те, которые начинаются с Object.prototype., а не те, которые начинаются с простого Object. Значение свойства prototype - это объект, который в основном представляет собой контейнер для хранения свойств и методов, которые мы хотим наследовать объектами, расположенными дальше по цепочке прототипов.

+ +

Таким образом Object.prototype.watch(), Object.prototype.valueOf() и т. д. доступны для любых типов объектов, которые наследуются от Object.prototype, включая новые экземпляры объектов, созданные из конструктора Person() .

+ +

Object.is(), Object.keys() и другие члены, не определенные в контейнере prototype, не наследуются экземплярами объектов или типами объектов, которые наследуются от Object.prototype. Это методы / свойства, доступные только в конструкторе Object().

+ +
+

Примечание: Это кажется странным - как у вас есть метод, определенный для конструктора, который сам по себе является функцией? Ну, функция также является типом объекта - см. Ссылку на конструктор Function(), если вы нам не верите.

+
+ +
    +
  1. Вы можете проверить существующие свойства прототипа для себя - вернитесь к нашему предыдущему примеру и попробуйте ввести следующее в консоль JavaScript: +
    Person.prototype
    +
  2. +
  3. Результат покажет вам не много, ведь мы ничего не определили в прототипе нашего конструктора! По умолчанию prototype конструктора всегда пуст. Теперь попробуйте следующее: +
    Object.prototype
    +
  4. +
+ +

Вы увидите большое количество методов, определенных для свойства prototype Object'а , которые затем доступны для объектов, которые наследуются от Object, как показано выше.

+ +

Вы увидите другие примеры наследования цепочек прототипов по всему JavaScript - попробуйте найти методы и свойства, определенные на прототипе глобальных объектов String, Date, Number и Array, например. Все они имеют несколько элементов, определенных на их прототипе, поэтому, например, когда вы создаете строку, вот так:

+ +
var myString = 'This is my string.';
+ +

В myString сразу есть множество полезных методов, таких как split(), indexOf(), replace() и т. д.

+ +
+

Важно: Свойство prototype является одной из наиболее противоречивых названий частей JavaScript - вы можете подумать, что this указывает на объект прототипа текущего объекта, но это не так (это внутренний объект, к которому можно получить доступ __proto__, помните ?). prototype вместо этого - свойство, содержащее объект, на котором вы определяете членов, которые вы хотите наследовать.

+
+ +

Снова create()

+ +

Ранее мы показали, как метод Object.create() может использоваться для создания нового экземпляра объекта.

+ +
    +
  1. Например, попробуйте это в консоли JavaScript предыдущего примера: +
    var person2 = Object.create(person1);
    +
  2. +
  3. На самом деле create()создает новый объект из указанного объекта-прототипа. Здесь person2 создается с помощью person1 в качестве объекта-прототипа. Это можно проверить, введя в консоли следующее: +
    person2.__proto__
    +
  4. +
+ +

Это вернет объект person1.

+ +

Свойство constructor

+ +

Каждая функция-конструктор имеет свойство prototype, значением которого является объект, содержащий свойство constructor. Это свойство constructor указывает на исходную функцию-конструктор. Как вы увидите в следующем разделе, свойства, определенные в свойстве Person.prototype (или в общем случае в качестве свойства прототипа функции конструктора, который является объектом, как указано в предыдущем разделе) становятся доступными для всех объектов экземпляра, созданных с помощью конструктор Person(). Следовательно, свойство конструктора также доступно для объектов person1 и person2.

+ +
    +
  1. Например, попробуйте эти команды в консоли: +
    person1.constructor
    +person2.constructor
    + +

    Они должны возвращать конструктор Person(), поскольку он содержит исходное определение этих экземпляров.

    + +

    Хитрый трюк заключается в том, что вы можете поместить круглые скобки в конец свойства constructor (содержащие любые требуемые параметры) для создания другого экземпляра объекта из этого конструктора. Конструктор - это функция в конце концов, поэтому ее можно вызвать с помощью круглых скобок; вам просто нужно включить ключевое слово new, чтобы указать, что вы хотите использовать эту функцию в качестве конструктора.

    +
  2. +
  3. Попробуйте это в консоли: +
    var person3 = new person1.constructor('Karen', 'Stephenson', 26, 'female', ['playing drums', 'mountain climbing']);
    +
  4. +
  5. Теперь попробуйте получить доступ к функциям вашего нового объекта, например: +
    person3.name.first
    +person3.age
    +person3.bio()
    +
  6. +
+ +

Это хорошо работает. Вам не нужно будет использовать его часто, но это может быть действительно полезно, если вы хотите создать новый экземпляр и не имеете ссылки на исходный конструктор, который легко доступен по какой-либо причине.

+ +

Свойство constructor имеет другие применения. Например, если у вас есть экземпляр объекта и вы хотите вернуть имя конструктора этого экземпляра, вы можете использовать следующее:

+ +
instanceName.constructor.name
+ +

Например, попробуйте это:

+ +
person1.constructor.name
+
+ +
+

Примечание: Значение constructor.name может измениться (из-за прототипического наследования, привязки, препроцессоров, транспилеров и т. д.), Поэтому для более сложных примеров вы захотите использовать оператор instanceof.

+
+ +
    +
+ +

Изменение прототипов

+ +

Давайте рассмотрим пример изменения свойства prototype функции-конструктора — методы, добавленные в прототип, затем доступны для всех экземпляров объектов, созданных из конструктора.

+ +
    +
  1. Вернитесь к нашему примеру oojs-class-further-exercises.html и создайте локальную копию исходного кода. Ниже существующего JavaScript добавьте следующий код, который добавляет новый метод в свойство prototype конструктора: + +
    Person.prototype.farewell = function() {
    +  alert(this.name.first + ' has left the building. Bye for now!');
    +};
    +
  2. +
  3. Сохраните код и загрузите страницу в браузере и попробуйте ввести следующее в текстовый ввод: +
    person1.farewell();
    +
  4. +
+ +

Должно появиться всплывающее окно, с именем пользователя, определенным в конструкторе. Это действительно полезно, но ещё более полезно то, что вся цепочка наследования обновляется динамически, автоматически делая этот новый метод доступным для всех экземпляров объектов, полученных из конструктора.

+ +

Подумайте об этом на мгновение. В нашем коде мы определяем конструктор, затем мы создаем экземпляр объекта из конструктора, затем добавляем новый метод к прототипу конструктора:

+ +
function Person(first, last, age, gender, interests) {
+
+  // определения свойств и методов
+
+}
+
+var person1 = new Person('Tammi', 'Smith', 32, 'neutral', ['music', 'skiing', 'kickboxing']);
+
+Person.prototype.farewell = function() {
+  alert(this.name.first + ' has left the building. Bye for now!');
+};
+ +

Но метод farewell() по-прежнему доступен в экземпляре объекта person1 - его элементы были автоматически обновлены, чтобы включить недавно определенный метод farewell().

+ +
+

Примечание: Если у вас возникли проблемы с получением этого примера для работы, посмотрите на наш пример oojs-class-prototype.html (см. также это running live).

+
+ +

Вы редко увидите свойства, определенные в свойстве prototype, потому что они не очень гибки при таком определении. Например, вы можете добавить свойство следующим образом:

+ +
Person.prototype.fullName = 'Bob Smith';
+ +

Это не очень гибко, так как человека нельзя назвать так. Было бы намного лучше сделать это, создав fullName из name.first и name.last:

+ +
Person.prototype.fullName = this.name.first + ' ' + this.name.last;
+ +

Однако это не работает, поскольку в этом случае this будет ссылаться на глобальную область, а не на область функции. Вызов этого свойства вернет undefined undefined. Это отлично работало с методом, который мы определили ранее в прототипе, потому что он находится внутри области функций, которая будет успешно перенесена в область экземпляра объекта. Таким образом, вы можете определить постоянные свойства прототипа (т. е. те, которые никогда не нуждаются в изменении), но обычно лучше определять свойства внутри конструктора.

+ +

Фактически, довольно распространенный шаблон для большего количества определений объектов - это определение свойств внутри конструктора и методов в прототипе. Это упрощает чтение кода, поскольку конструктор содержит только определения свойств, а методы разделены на отдельные блоки. Например:

+ +
// Определение конструктора и его свойств
+
+function Test(a, b, c, d) {
+  // определение свойств...
+}
+
+// Определение первого метода
+
+Test.prototype.x = function() { ... };
+
+// Определение второго метода
+
+Test.prototype.y = function() { ... };
+
+//...и так далее
+ +

Этот образец можно увидеть в действии в примере приложения плана школы Петра Залевы.

+ +

Резюме

+ +

В этой статье рассмотрены прототипы объектов JavaScript (в том числе и то, как прототип цепочки объектов позволяет объектам наследовать функции друг от друга), свойство прототипа и как его можно использовать для добавления методов к конструкторам и другие связанные с этой статьёй темы.

+ +

В следующей статье мы рассмотрим то, как вы можете реализовать наследование функциональности между двумя собственными настраиваемыми объектами.

+ +

{{PreviousMenuNext("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects")}}

+ + + +

В этом модуле

+ + diff --git "a/files/ru/learn/javascript/\320\276\320\261\321\212\320\265\320\272\321\202\321\213/adding_bouncing_balls_features/index.html" "b/files/ru/learn/javascript/\320\276\320\261\321\212\320\265\320\272\321\202\321\213/adding_bouncing_balls_features/index.html" deleted file mode 100644 index fe97392371..0000000000 --- "a/files/ru/learn/javascript/\320\276\320\261\321\212\320\265\320\272\321\202\321\213/adding_bouncing_balls_features/index.html" +++ /dev/null @@ -1,212 +0,0 @@ ---- -title: Добавление функций в нашу демонстрацию отбойных шаров -slug: Learn/JavaScript/Объекты/Adding_bouncing_balls_features -translation_of: Learn/JavaScript/Objects/Adding_bouncing_balls_features ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/JavaScript/Objects/Object_building_practice", "", "Learn/JavaScript/Objects")}}
- -

В этом упражнении мы будем использовать проект прыгающих шаров из предыдущей статьи и добавим в него новые интересные возможности.

- - - - - - - - - - - - -
Требования:Перед тем как приступить к этому упражнению нужно выполнить задания из всех статей текущего модуля.
Цель:Проверить насколько хорошо вы понимаете объекты и связанные с ними конструкции в языке Javascript. 
- -

Начало

- -

Для начала скопируйте файлы index-finished.html, style.css и main-finished.js из предыдущей статьи в новую директорию на вашем компьютере.

- -

Для выполнения упражнения вы можете использовать сайт JSBin или Thimble. Вы можете вставлять HTML, CSS и JavaScript код в один из этих онлайн-редакторов. Если ваш онлайн-редактор не поддерживает раздельные панели для редактирования JavaScript/CSS кода, то вы можете встроить код в HTML с помощью тегов <script>/<style>.

- -
-

Примечание. Если у вас что-то не получается — попросите о помощи. Более подробная информация находится в секции {{anch("Assessment or further help")}} в конце этой страницы.

-
- -

Краткое описание проекта

- -

Наша веселая демонстрация шаров - это весело, но теперь мы хотим сделать ее немного более интерактивной, добавив контролируемый пользователем злой круг, который будет есть шары, если он их поймает. Мы также хотим проверить ваши навыки создания объектов, создав общий объект Shape(), который могут наследовать наши шары и злой круг. Наконец, мы хотим добавить счетчик очков, чтобы отслеживать количество оставшихся шаров для захвата.

- -

Следующий скриншот дает вам представление о том, как должна выглядеть готовая программа:

- -

- - - -

Чтобы дать вам больше идеи, посмотрите на законченный пример (не заглядывая в исходный код!)

- -

Шаги по завершению

- -

В следующих разделах описывается, что вам нужно делать.

- -

Создание наших новых объектов

- -

Прежде всего, измените существующий конструктор Ball() так, чтобы он стал конструктором Shape() и добавил новый конструктор Ball():

- -
    -
  1. Конструктор Shape() должен определять свойства x, y, velX и velY,  так же, как и конструктор Ball(), но не свойства color и size.
  2. -
  3. Он также должен определить новое свойствоexists, которое используется для отслеживания наличия шаров в программе (не было съедено злым кругом). Это должно быть логическое (true / false).
  4. -
  5. Конструктор Ball() должен наследовать свойства x, y, velX, velY и exists из конструктора Shape().
  6. -
  7. Он также должен определить свойство color и size, как это сделал оригинальный конструктор Ball().
  8. -
  9. Не забудьте установить prototype и constructor конструктора Ball() соответствующим образом.
  10. -
- -

Определения меток шара draw(), update() и collisionDetect() должны быть такими же, как и раньше.

- -

Вам также нужно добавить новый параметр в новый вызов конструктора new Ball() ( ... ) - параметр exists должен быть 5-м параметром и ему должно быть присвоено значение true.

- -

На этом этапе попробуйте перезагрузить код - он должен работать так же, как и раньше, с нашими перепроектированными объектами.

- -

Определение EvilCircle()

- -

Теперь пришло время встретить плохого парня - EvilCircle()! Наша игра будет включать только один злой круг, но мы все еще будем определять его с помощью конструктора, который наследует от Shape(), чтобы дать вам некоторую практику. Возможно, вам захочется добавить еще один круг в приложение, которое может контролироваться другим игроком или иметь несколько злобных окружений, управляемых компьютером. Вы, вероятно, не собираетесь захватить мир одним злым кругом, но он будет делать для этой оценки.

- -

Конструктор EvilCircle() должен наследовать x, y, velX, velY и exists из Shape(), но velX и velY должны всегда равняться 20.

- -

Вы должны сделать что-то вроде Shape.call(this, x, y, 20, 20, exists);

- -

Он также должен определить свои собственные свойства следующим образом:

- - - -

Опять же, не забудьте определить свои унаследованные свойства как параметры в конструкторе и правильно установить свойства prototype и constructor.

- -

Defining EvilCircle()'s methods

- -

EvilCircle() должен иметь четыре метода, как описано ниже.

- -

draw()

- -

Этот метод имеет ту же цель, что и метод draw() метода Ball(): он рисует экземпляр объекта на холсте. Он будет работать очень схожим образом, поэтому вы можете начать с копирования определения Ball.prototype.draw. Затем вы должны внести следующие изменения:

- - - -

checkBounds()

- -

Этот метод будет делать то же самое, что и первая часть функции  Ball()'s update(), чтобы посмотреть, не исчезнет ли злой круг от края экрана и не прекратит это делать. Опять же, вы можете просто скопировать определение Ball.prototype.update, но есть несколько изменений, которые вы должны сделать:

- - - -

setControls()

- -

Этот метод добавит прослушиватель событий onkeydown к объекту window, чтобы при нажатии определенных клавиш клавиатуры мы могли перемещать злой круг вокруг. Следующий код должен быть помещен внутри определения метода:

- -
var _this = this;
-window.onkeydown = function(e) {
-    if (e.keyCode === 65) {
-      _this.x -= _this.velX;
-    } else if (e.keyCode === 68) {
-      _this.x += _this.velX;
-    } else if (e.keyCode === 87) {
-      _this.y -= _this.velY;
-    } else if (e.keyCode === 83) {
-      _this.y += _this.velY;
-    }
-  }
- -

Поэтому, когда нажата клавиша, проконсультируется о свойствах keyCode объекта события, чтобы увидеть, какая клавиша нажата. Если это один из четырех, представленных указанными ключевыми кодами, тогда злой круг будет перемещаться влево / вправо / вверх / вниз.

- - - -

collisionDetect()

- -

Этот метод будет действовать очень похоже на метод collisionDetect() в Ball(), поэтому вы можете использовать его в качестве основы для этого нового метода. Но есть несколько отличий:

- - - -

Приведение злого круга в программу

- -

Теперь мы определили злой круг, нам нужно на самом деле заставить его появиться на нашей сцене. Для этого вам нужно внести некоторые изменения в функцию loop().

- - - -

Реализация счетчика баллов

- -

Чтобы выполнить счетчик счетчиков, выполните следующие действия:

- -
    -
  1. В своем HTML-файле добавьте элемент {{HTMLElement ("p")}} непосредственно под элементом {{HTMLElement ("h1")}}, содержащим текст «Ball count:».
  2. -
  3. В вашем файле CSS добавьте следующее правило внизу: -
    p {
    -  position: absolute;
    -  margin: 0;
    -  top: 35px;
    -  right: 5px;
    -  color: #aaa;
    -}
    -
  4. -
  5. В своем JavaScript сделайте следующие обновления: -
      -
    • Создайте переменную, которая хранит ссылку на абзац.
    • -
    • Держите подсчет количества шаров на экране в некотором роде.
    • -
    • Увеличьте количество и покажите обновленное количество шаров каждый раз, когда шар добавляется в сцену.
    • -
    • Уменьшите счет и покажите обновленное количество мячей каждый раз, когда злой круг ест шарик (его не существует).
    • -
    -
  6. -
- -

Советы и подсказки

- - - -

Assessment

- -

Если вы проводите эту оценку в рамках организованного курса, вы должны уметь отдать свою работу своему учителю / наставнику для маркировки. Если вы самообучаетесь, то вы можете получить руководство по маркировке довольно легко, задав тему обсуждения для этого упражнения или в IRC-канале #mdn в Mozilla IRC. Сначала попробуйте упражнение - ничего не выиграть от обмана!

- -

{{PreviousMenuNext("Learn/JavaScript/Objects/Object_building_practice", "", "Learn/JavaScript/Objects")}}

- - - -

In this module

- - - - - -
- - -
- -
-
diff --git "a/files/ru/learn/javascript/\320\276\320\261\321\212\320\265\320\272\321\202\321\213/index.html" "b/files/ru/learn/javascript/\320\276\320\261\321\212\320\265\320\272\321\202\321\213/index.html" deleted file mode 100644 index 9acc354feb..0000000000 --- "a/files/ru/learn/javascript/\320\276\320\261\321\212\320\265\320\272\321\202\321\213/index.html" +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: Введение в объекты JavaScript -slug: Learn/JavaScript/Объекты -tags: - - JavaScript - - Начинающим - - Объекты - - Руководства -translation_of: Learn/JavaScript/Objects ---- -
{{LearnSidebar}}
- -

В JavaScript большинство сущностей являются объектами, начиная с самого основного функционала JavaScript, такого как строки (strings) и массивы (array), и заканчивая встроенными в браузер API. Вы можете даже создавать свои собственные объекты, чтобы инкапсулировать связанные между собой функции и переменные в эффективные пакеты и действовать как удобные хранилища данных. Понимание объектно-ориентированной природы JavaScript очень важно, если Вы хотите продолжить дальнейшее более углубленное изучение языка. Поэтому мы предоставляем Вам данный модуль, чтобы помочь Вам разобраться в этом. Здесь мы детально обучим Вас теории и синтаксису объектов, а затем рассмотрим, как создавать свои собственные объекты. 

- -

Необходимые знания

- -

Перед тем, как начать изучение данного модуля, Вы должны иметь некоторое представление о HTML и CSS. Мы советуем Вам поработать над разделами Введение в HTML и Введение в CSS перед изучением этого модуля JavaScript.

- -

Также Вам необходимо знать основы JavaScript перед подробным изучением объектов JavaScript. Предварительно поработайте с разделами Первые шаги в JavaScript и Структурные элементы в JavaScript перед началом изучения данного модуля.

- -
-

Примечание: Если Вы работаете за компьютером/планшетом/другим устройством, на котором у Вас нет возможности создавать собственные файлы, постарайтесь поработать с примерами кода на платформах онлайн-программирования, таких, как JSBin or Thimble.

-
- -

Руководства

- -
-
Основы объектов
-
В первой статье мы рассмотрим объекты в JavaScript. Мы будем разбирать основы синтаксиса объектов JavaScript и заново изучим некоторый функционал JavaScript, который мы уже исследовали ранее на курсе, подтвердив тот факт, что большая часть функционала, с которым мы уже столкнулись, в действительности является объектами.
-
Объектно-ориентированный JavaScript для начинающих
-
Закончив с основами, мы сфокусируемся на объектно-ориентированном JavaScript (OOJS) —  эта статья представляет основы теории объектно-ориентированного программирования (ООП). Затем мы изучим, как JavaScript эмулирует классы объектов через конструктор функций, и как создавать экземпляры объектов.
-
Прототипы объектов
-
Прототипы - это механизм, благодаря которому объекты в JavaScript наследуют функционал друг друга, но при этом они работают иначе по сравнению с механизмами наследования в классических объектно-ориентированных языках. В этой статье мы изучим эти отличия, объясним, как работает цепочка прототипов, и рассмотрим, как свойство прототипа может быть использовано для добавления методов к существующим конструкторам.
-
Наследование в JavaScript
-
После знакомства с самыми жуткими подробностями OOJS, эта статья покажет, как создавать "дочерные" классы объектов (конструкторы), которые наследуют функционал от своих "родительских" классов. В дополнении, мы дадим Вам пару советов о том, где и когда можно использовать OOJS.
-
Работа с JSON-данными
-
Представление объектов в JavaScript (JavaScript Object Notation) (JSON) - это стандартный формат для представления структурированных данных в виде объектов JavaScript, который обычно используется для представления и передачи данных на веб-сайтах (т.е. передача некоторых данных от сервера к клиенту - таким образом они могут быть отображены на веб-странице). Вы довольно часто будете с этим сталкиваться, поэтому в данной статье мы предоставим вам все, что необходимо для работы с JSON с помощью JavaScript, в том числе доступ к элементам данных в объекте JSON и написания собственного JSON-кода.
-
Практика построения объектов
-
В предыдущих статьях мы рассматривали самые основные моменты в теории и синтаксисе объектов в JavaScript, дав Вам твердую основу для начала. В этой статье мы погрузимся в практические занятия, получим больше практической работы в построении собственных объектов в JavaScript, чтобы сделать кое-что веселое и красочное - несколько цветных прыгающих шариков.
-
- -

Задания

- -
-
Добавление функционала к демо с прыгающими шариками
-
В этом задании, мы ожидаем, что Вы, используя демо с прыгающими шариками из предыдущей статьи как отправную точку, добавите немного нового и интересного функционала в него.
-
diff --git "a/files/ru/learn/javascript/\320\276\320\261\321\212\320\265\320\272\321\202\321\213/inheritance/index.html" "b/files/ru/learn/javascript/\320\276\320\261\321\212\320\265\320\272\321\202\321\213/inheritance/index.html" deleted file mode 100644 index c1565cd72f..0000000000 --- "a/files/ru/learn/javascript/\320\276\320\261\321\212\320\265\320\272\321\202\321\213/inheritance/index.html" +++ /dev/null @@ -1,266 +0,0 @@ ---- -title: Наследование в JavaScript -slug: Learn/JavaScript/Объекты/Inheritance -tags: - - JavaScript - - Наследование - - ООП -translation_of: Learn/JavaScript/Objects/Inheritance ---- -

- -

- - - -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects")}}
- -

Теперь, когда объясняется большая часть подробностей OOJS, эта статья показывает, как создавать «дочерние» классы объектов (конструкторы), которые наследуют признаки из своих «родительских» классов. Кроме того, мы дадим некоторые советы о том, когда и где вы можете использовать OOJS , и посмотрим, как классы рассматриваются в современном синтаксисе ECMAScript.

- - - - - - - - - - - - -
Необходимые знания: -

Базовая компьютерная грамотность, понимание основ HTML и CSS, знакомство с основами JavaScript (см. Первые шаги и Структурные элементы) and основы Объектно-ориентированного JS (см. Введение в объекты).

-
Цель:Понять, как можно реализовать наследование в JavaScript.
- -

Прототипное наследование

- -

До сих пор мы видели некоторое наследование в действии - мы видели, как работают прототипы и как элементы наследуются, поднимаясь по цепочке. Но в основном это связано с встроенными функциями браузера. Как создать объект в JavaScript, который наследует от другого объекта?

- -

Давайте рассмотрим, как это сделать на конкретном примере.

- -

Начало работы

- -

Прежде всего сделайте себе локальную копию нашего файла oojs-class-inheritance-start.html (он также работает в режиме реального времени). В файле вы найдете тот же пример конструктора Person(), который мы использовали на протяжении всего модуля, с небольшим отличием - мы определили внутри конструктора только лишь свойства:

- -
function Person(first, last, age, gender, interests) {
-  this.name = {
-    first,
-    last
-  };
-  this.age = age;
-  this.gender = gender;
-  this.interests = interests;
-};
- -

Все методы определены в прототипе конструктора. Например:

- -
Person.prototype.greeting = function() {
-  alert('Hi! I\'m ' + this.name.first + '.');
-};
- -
-

Примечание. В исходном коде вы также увидите определенные методы bio() и farewell(). Позже вы увидите, как они могут быть унаследованы другими конструкторами.

-
- -

Скажем так, мы хотели создать класс Teacher, подобный тому, который мы описали в нашем первоначальном объектно-ориентированном определении, которое наследует всех членов от Person, но также включает в себя:

- -
    -
  1. Новое свойство, subject - оно будет содержать предмет, который преподает учитель.
  2. -
  3. Обновленный метод greeting(), который звучит немного более формально, чем стандартный метод greeting()— более подходит для учителя, обращающегося к некоторым ученикам в школе.
  4. -
- -

Определение функции-конструктора Teacher()

- -

Первое, что нам нужно сделать, это создать конструктор Teacher() - добавьте ниже следующий код:

- -
function Teacher(first, last, age, gender, interests, subject) {
-  Person.call(this, first, last, age, gender, interests);
-
-  this.subject = subject;
-}
- -

Это похоже на конструктор Person во многих отношениях, но здесь есть что-то странное, что мы не видели раньше - функцию call(). Эта функция в основном позволяет вам вызывать функцию, определенную где-то в другом месте, но в текущем контексте. Первый параметр указывает значение this, которое вы хотите использовать при выполнении функции, а остальные параметры - те, которые должны быть переданы функции при ее вызове.

- -

Мы хотим, чтобы конструктор Teacher() принимал те же параметры, что и конструктор Person(), от которго он наследуется, поэтому мы указываем их как параметры в вызове call().

- -

Последняя строка внутри конструктора просто определяет новое свойство subject, которое будут иметь учителя, и которого нет у Person().

- -

В качестве примечания мы могли бы просто сделать это:

- -
function Teacher(first, last, age, gender, interests, subject) {
-  this.name = {
-    first,
-    last
-  };
-  this.age = age;
-  this.gender = gender;
-  this.interests = interests;
-  this.subject = subject;
-}
- -

Но это просто переопределяет свойства заново, а не наследует их от Person(), так что теряется смысл того, что мы пытаемся сделать. Он также занимает больше строк кода.

- -

Наследование от конструктора без параметров

- -

Обратите внимание, что если конструктор, от которого вы наследуете, не принимает значения своего свойства из параметров, вам не нужно указывать их в качестве дополнительных аргументов в call(). Так, например, если у вас было что-то действительно простое:

- -
function Brick() {
-  this.width = 10;
-  this.height = 20;
-}
- -

Вы можете наследовать свойства width и height, выполнив это (как и другие шаги, описанные ниже, конечно):

- -
function BlueGlassBrick() {
-  Brick.call(this);
-
-  this.opacity = 0.5;
-  this.color = 'blue';
-}
- -

Обратите внимание, что мы указали только this внутри call() - никаких других параметров не требуется, поскольку мы не наследуем никаких свойств родителя, которые задаются через параметры.

- -

Установка Teacher()'s prototype и конструктор ссылок

- -

Пока все хорошо, но у нас есть проблема. Мы определили новый конструктор и у него есть свойство prototype, которое по умолчанию просто содержит ссылку на саму конструкторскую функцию. Он не содержит методов свойства prototype конструктора Person. Чтобы увидеть это, введите Object.getOwnPropertyNames(Teacher.prototype) в поле ввода текста или в вашу консоль JavaScript. Затем введите его снова, заменив Teacher на Person. Новый конструктор не наследует эти методы. Чтобы увидеть это, сравните выводы в консоль Person.prototype.greeting и Teacher.prototype.greeting. Нам нужно заставить Teacher() наследовать методы, определенные на прототипе Person(). Итак, как мы это делаем?

- -
    -
  1. Добавьте следующую строку ниже своего предыдущего добавления: -
    Teacher.prototype = Object.create(Person.prototype);
    - Здесь наш друг create() снова приходит на помощь. В этом случае мы используем его для создания нового объекта и делаем его значением Teacher.prototype. Новый объект имеет свой прототип Person.prototype и, следовательно, наследует, если и когда это необходимо, все доступные методы Person.prototype.
  2. -
  3. Нам нужно сделать еще одну вещь, прежде чем двигаться дальше. После добавления последней строки, Teacher.prototype.constructor стало равным Person(), потому что мы просто устанавливаем Teacher.prototype для ссылки на объект, который наследует его свойства от Person.prototype! Попробуйте сохранить код, загрузите страницу в браузере и введите Teacher.prototype.constructor в консоль для проверки.
  4. -
  5. Это может стать проблемой, поэтому нам нужно сделать это правильно. Вы можете сделать это, вернувшись к исходному коду и добавив следующие строки внизу: -
    Object.defineProperty(Teacher.prototype, 'constructor', {
    -    value: Teacher,
    -    enumerable: false, // false, чтобы данное свойство не появлялось в цикле for in
    -    writable: true });
    -
  6. -
  7. Теперь, если вы сохраните и обновите, введите Teacher.prototype.constructor, чтобы вернуть Teacher(), плюс мы теперь наследуем Person()!
  8. -
- -

Предоставление Teacher() новой функции greeting()

- -

Чтобы завершить наш код, нам нужно определить новую функцию greeting() в конструкторе Teacher().

- -

Самый простой способ сделать это - определить его на прототипе Teacher() - добавить в нижнюю часть кода следующее:

- -
Teacher.prototype.greeting = function() {
-  var prefix;
-
-  if (this.gender === 'male' || this.gender === 'Male' || this.gender === 'm' || this.gender === 'M') {
-    prefix = 'Mr.';
-  } else if (this.gender === 'female' || this.gender === 'Female' || this.gender === 'f' || this.gender === 'F') {
-    prefix = 'Mrs.';
-  } else {
-    prefix = 'Mx.';
-  }
-
-  alert('Hello. My name is ' + prefix + ' ' + this.name.last + ', and I teach ' + this.subject + '.');
-};
- -

Это выводит на экран приветствие учителя, в котором используется соответствующий префикс имени для своего пола, разработанный с использованием условного оператора.

- -

Попробуйте пример

- -

Теперь, когда вы ввели весь код, попробуйте создать экземпляр объекта из Teacher(), поставив ниже вашего JavaScript кода (или что-то похожее по вашему выбору):

- -
var teacher1 = new Teacher('Dave', 'Griffiths', 31, 'male', ['football', 'cookery'], 'mathematics');
- -

Теперь сохраните, обновите, и попробуйте получить доступ к свойствам и методам вашего нового объекта teacher1, например:

- -
teacher1.name.first;
-teacher1.interests[0];
-teacher1.bio();
-teacher1.subject;
-teacher1.greeting();
-teacher1.farewell();
- -

Все должно работать нормально. Запросы в строках 1, 2, 3 и 6 унаследованны от общего конструктора Person() (класса). Запрос в строке 4 обращается к subject, доступному только для более специализированного конструктора (класса) Teacher(). Запрос в строке 5 получил бы доступ к методу greeting(), унаследованному от Person(), но Teacher() имеет свой собственный метод greeting() с тем же именем, поэтому запрос обращается к этому методу.

- -
-

Примечание. Если вам не удается заставить это работать, сравните свой код с нашей готовой версией (см. также рабочее демо).

-
- -

Методика, которую мы здесь рассмотрили, - это не единственный способ создания наследующих классов в JavaScript, но он работает нормально и это дает вам представление о том, как реализовать наследование в JavaScript.

- -

Вам также может быть интересно узнать некоторые из новых функций {{glossary("ECMAScript")}}, которые позволяют нам делать наследование более чисто в JavaScript (см. Classes). Мы не рассматривали их здесь, поскольку они пока не поддерживаются очень широко в браузерах. Все остальные конструкторы кода, которые мы обсуждали в этом наборе статей, поддерживаются еще в IE9 или ранее и есть способы добиться более ранней поддержки, чем это.

- -

Обычный способ - использовать библиотеку JavaScript - большинство популярных опций имеют простой набор функций, доступных для выполнения наследования более легко и быстро. CoffeeScript , например, предоставляет класс, расширяет и т.д.

- -

Дальнейшее упражнение

- -

В нашем руководстве по Объектно-ориентированному JavaScript для начинающих мы также включили класс Student как концепцию, которая наследует все особенности Person, а также имеет другой метод greeting() от Person, который гораздо более неформален, чем приветствие Teacher. Посмотрите, как выглядит приветствие ученика в этом разделе, и попробуйте реализовать собственный конструктор Student(), который наследует все функции Person() и реализует другую функцию greeting().

- -
-

Примечание. Если вам не удается заставить это работать, сравните свой код с нашей готовой версией (см. также рабочее демо).

-
- -

Object member summary

- -

Подводя итог, вы в основном получили три типа свойств / методов, о которых нужно беспокоиться:

- -
    -
  1. Те, которые определены внутри функции-конструктора, которые присваиваются экземплярам объекта. Их довольно легко заметить - в вашем собственном коде они представляют собой элементы, определенные внутри конструктора, используя строки this.x = x; в встроенном коде браузера они являются членами, доступными только для экземпляров объектов (обычно создаются путем вызова конструктора с использованием ключевого слова new, например var myInstance = new myConstructor ().
  2. -
  3. Те, которые определяются непосредственно самим конструктором, которые доступны только для конструктора. Они обычно доступны только для встроенных объектов браузера и распознаются путем непосредственной привязки к конструктору, а не к экземпляру. Например, Object.keys().
  4. -
  5. Те, которые определены в прототипе конструктора, которые наследуются всеми экземплярами и наследуют классы объектов. К ним относятся любой член, определенный в свойстве прототипа конструктора, например. myConstructor.prototype.x().
  6. -
- -

Если вы не уверены, что это такое, не беспокойтесь об этом, пока вы еще учитесь и знание придет с практикой.

- -

Когда вы используете наследование в JavaScript?

- -

В частности, после этой последней статьи вы можете подумать: «У-у-у, это сложно». Ну, ты прав. Прототипы и наследование представляют собой некоторые из самых сложных аспектов JavaScript, но многие возможности и гибкость JavaScript вытекают из его структуры объектов и наследования и стоит понять, как это работает.

- -

В некотором смысле вы используете наследование все время. Всякий раз, когда вы используете различные функции веб-API или методы/свойства, определенные во встроенном объекте браузера, который вы вызываете в своих строках, массивах и т.д., вы неявно используете наследование.

- -

Что касается использования наследования в вашем собственном коде, вы, вероятно, не будете часто его использовать, особенно для начала и в небольших проектах. Это пустая трата времени на использование объектов и наследование только ради этого, когда они вам не нужны. Но по мере того, как ваши базы кода становятся больше, вы с большей вероятностью найдете необходимость в этом. Если вы начинаете создавать несколько объектов с подобными функциями, то создание универсального типа объекта, содержащего все общие функции и наследование этих функций в более специализированных типах объектов, может быть удобным и полезным.

- -
-

Примечание. Из-за того, как работает JavaScript, с цепочкой прототипов и т.д., совместное использование функций между объектами часто называется делегированием. Специализированные объекты делегируют функциональность универсальному типу объекта.

-
- -

При использовании наследования вам рекомендуется не иметь слишком много уровней наследования и тщательно отслеживать, где вы определяете свои методы и свойства. Можно начать писать код, который временно изменяет прототипы встроенных объектов браузера, но вы не должны этого делать, если у вас нет действительно веской причины. Слишком много наследования могут привести к бесконечной путанице и бесконечной боли при попытке отладки такого кода.

- -

В конечном счете, объекты - это еще одна форма повторного использования кода, например функций или циклов, со своими конкретными ролями и преимуществами. Если вы обнаруживаете, что создаете кучу связанных переменных и функций и хотите отслеживать их все вместе и аккуратно их упаковывать, объект является хорошей идеей. Объекты также очень полезны, когда вы хотите передать коллекцию данных из одного места в другое. Обе эти вещи могут быть достигнуты без использования конструкторов или наследования. Если вам нужен только один экземпляр объекта, вам лучше всего использовать литерал объекта и вам, разумеется, не нужно наследование.

- -

Резюме

- -

В этой статье мы рассмотрели оставшуюся часть основной теории и синтаксиса OOJS, которые, как мы думаем, вам следует знать сейчас. На этом этапе вы должны понимать основы JavaScript, ООП, прототипы и прототипное наследование, как создавать классы (конструкторы) и экземпляры объектов, добавлять функции в классы и создавать подклассы, которые наследуются от других классов.

- -

В следующей статье мы рассмотрим, как работать с JavaScript Object Notation (JSON), общим форматом обмена данными, написанным с использованием объектов JavaScript.

- -

See also

- - - -

{{PreviousMenuNext("Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects")}}

- -

В этом модуле

- - diff --git "a/files/ru/learn/javascript/\320\276\320\261\321\212\320\265\320\272\321\202\321\213/json/index.html" "b/files/ru/learn/javascript/\320\276\320\261\321\212\320\265\320\272\321\202\321\213/json/index.html" deleted file mode 100644 index 371f254ec6..0000000000 --- "a/files/ru/learn/javascript/\320\276\320\261\321\212\320\265\320\272\321\202\321\213/json/index.html" +++ /dev/null @@ -1,353 +0,0 @@ ---- -title: Работа с JSON -slug: Learn/JavaScript/Объекты/JSON -tags: - - Beginner - - JSON - - JavaScript -translation_of: Learn/JavaScript/Objects/JSON ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects/Object_building_practice", "Learn/JavaScript/Objects")}}
- -

Обозначение объектов JavaScript (JSON - JavaScript Object Notation) - стандартный текстовый формат для представления структурированных данных на основе синтаксиса объекта JavaScript. Он обычно используется для передачи данных в веб-приложениях (например, отправка некоторых данных с сервера клиенту,таким образом чтобы это могло отображаться на веб-странице или наоборот). Вы будете сталкиваться с этим довольно часто, поэтому в этой статье мы даем вам все, что вам нужно для работы с JSON используя JavaScript, включая парсинг JSON, чтобы вы могли получить доступ к данным внутри него при создании JSON.

- - - - - - - - - - - - -
Необходимые знания:Базовая компьютерная грамотность, базовые знания HTML и CSS, знакомство с основами JavaScript (см. First steps и Building blocks) и основами OOJS  (see Introduction to objects).
Цель:Понять, как работать с данными, хранящимися в JSON, и создавать свои собственные объекты JSON.
- -

Нет, действительно, что такое JSON?

- -

{{glossary("JSON")}} - текстовый формат данных, следующий за синтаксисом объекта JavaScript, который был популяризирован Дугласом Крокфордом. Несмотря на то, что он очень похож на буквенный синтаксис объекта JavaScript, его можно использовать независимо от JavaScript, и многие среды программирования имеют возможность читать (анализировать) и генерировать JSON.

- -

JSON существует как строка,что необходимо при передаче данных по сети. Он должен быть преобразован в собственный объект JavaScript, если вы хотите получить доступ к данным. Это не большая проблема. JavaScript предоставляет глобальный объект JSON, который имеет методы для преобразования между ними.

- -
-

Примечание: Преобразование строки в родной объект называется десериализацией (преобразование из последовательной формы в параллельную), в то время как преобразовании родного объекта в строку, таким образом ,чтобы он мог быть передан через сеть, называется сериализацией(преобразование в последовательную форму).

-
- -

Объект JSON может быть сохранен в собственном файле, который в основном представляет собой текстовый файл с расширением .json и {{glossary("MIME type")}} application/json.

- -

Структура JSON

- -

Как описано выше, JSON представляет собой строку, формат которой очень похож на буквенный формат объекта JavaScript. Вы можете включать одни и те же базовые типы данных внутри JSON, так же как и  в стандартном объекте JavaScript - строки, числа, массивы, булевы и другие объектные литералы. Это позволяет построить иерархию данных, к примеру, так:

- -
{
-  "squadName": "Super hero squad",
-  "homeTown": "Metro City",
-  "formed": 2016,
-  "secretBase": "Super tower",
-  "active": true,
-  "members": [
-    {
-      "name": "Molecule Man",
-      "age": 29,
-      "secretIdentity": "Dan Jukes",
-      "powers": [
-        "Radiation resistance",
-        "Turning tiny",
-        "Radiation blast"
-      ]
-    },
-    {
-      "name": "Madame Uppercut",
-      "age": 39,
-      "secretIdentity": "Jane Wilson",
-      "powers": [
-        "Million tonne punch",
-        "Damage resistance",
-        "Superhuman reflexes"
-      ]
-    },
-    {
-      "name": "Eternal Flame",
-      "age": 1000000,
-      "secretIdentity": "Unknown",
-      "powers": [
-        "Immortality",
-        "Heat Immunity",
-        "Inferno",
-        "Teleportation",
-        "Interdimensional travel"
-      ]
-    }
-  ]
-}
- -

Если бы мы загрузили этот объект в программу JavaScript, создали переменную с названием superHeroes, мы могли бы затем получить доступ к данным внутри нее, используя те же самые точечную и скобочную нотации, которые мы рассмотрели в статье JavaScript object basics. Например:

- -
superHeroes.homeTown
-superHeroes['active']
- -

Чтобы получить доступ к последующим данным  по иерархии, вам просто нужно объединить требуемые имена свойств и индексы массивов. Например, чтобы получить доступ к третьей сверхспособности второго героя, указанного в списке участников, вы должны сделать следующее:

- -
superHeroes['members'][1]['powers'][2]
- -
    -
  1. Сначала у нас есть имя переменной - superHeroes.
  2. -
  3. Внутри мы хотим получить доступ к свойству members, поэтому мы используем ['members'].
  4. -
  5. members содержат массив, заполненный объектами. Мы хотим получить доступ ко второму объекту внутри массива, поэтому мы используем [1].
  6. -
  7. Внутри этого объекта мы хотим получить доступ к свойству powers, поэтому мы используем ['powers'].
  8. -
  9. Внутри свойства powers находится массив, содержащий сверхспособности выбранного героя. Нам нужен третий, поэтому мы используем [2].
  10. -
- -
-

Примечание. Мы сделали JSON, видимый выше, доступным внутри переменной в нашем примере JSONTest.html (см. исходный код). Попробуйте загрузить это, а затем получить доступ к данным внутри переменной через консоль JavaScript вашего браузера.

-
- -

Массивы как JSON

- -

Выше мы упоминали ,что JSON текст выглядит практически так же как и JavaScript объект,и это почти правильно.Причина,по которой мы говорим почти правильно заключается в том ,что массив также валиден JSON  например:

- -
[
-  {
-    "name": "Molecule Man",
-    "age": 29,
-    "secretIdentity": "Dan Jukes",
-    "powers": [
-      "Radiation resistance",
-      "Turning tiny",
-      "Radiation blast"
-    ]
-  },
-  {
-    "name": "Madame Uppercut",
-    "age": 39,
-    "secretIdentity": "Jane Wilson",
-    "powers": [
-      "Million tonne punch",
-      "Damage resistance",
-      "Superhuman reflexes"
-    ]
-  }
-]
- -

Вышесказанное вполне справедливо для JSON. Вам просто нужно получить доступ к элементам массива (в его анализируемой версии), начиная с индекса массива, например [0]["powers"][0].

- -

Другие примечания

- - - -

Активное обучение: Работа с примером JSON

- -

Итак, давайте рассмотрим пример, чтобы показать то, как мы можем использовать некоторые данные JSON на веб-сайте.

- -

Начало работы

- -

Для начала создайте локальные копии наших файлов heroes.html и style.css. Последний содержит простой CSS для стилизации нашей страницы, в то время как первый содержит очень простой HTML-код сущности:

- -
<header>
-</header>
-
-<section>
-</section>
- -

Плюс {{HTMLElement("script")}}, чтобы содержать код JavaScript, который мы будем писать в этом упражнении. На данный момент он содержит только две строки, которые захватывают ссылки на элементы {{HTMLElement("header")}} и {{HTMLElement("section")}} и сохраняют их в переменных:

- -
var header = document.querySelector('header');
-var section = document.querySelector('section');
- -

Мы предоставили данные JSON на нашем GitHub, на https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json.

- -

Мы собираемся загрузить его на нашу страницу и использовать некоторые изящные манипуляции DOM, чтобы отобразить их, например:

- -

- -

Получение JSON

- -

Чтобы получить JSON, мы будем использовать API, называемый {{domxref("XMLHttpRequest")}} (часто называемый XHR). Это очень полезный объект JavaScript, который позволяет нам делать сетевые запросы для извлечения ресурсов с сервера через JavaScript (например, изображения, текст, JSON, даже фрагменты HTML), что означает, что мы можем обновлять небольшие разделы контента без необходимости перезагрузки всей страницы. Это привело к более отзывчивым веб-страницам и звучит захватывающе, но, к сожалению, выходит за рамки этой статьи, чтобы изучить это гораздо более подробно.

- -
    -
  1. Начнем с того, что мы собираемся сохранить URL-адрес JSON, который мы хотим получить в переменной. Добавьте нижеследующий код JavaScript: -
    var requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';
    -
  2. -
  3. Чтобы создать запрос, нам нужно создать новый экземпляр объекта запроса из конструктора XMLHttpRequest, используя ключевое слово new. Добавьте следующую ниже свою последнюю строку: -
    var request = new XMLHttpRequest();
    -
  4. -
  5. Теперь нам нужно открыть новый запрос, используя метод open(). Добавьте следующую строку: -
    request.open('GET', requestURL);
    - -

    Это занимает не менее двух параметров - есть другие доступные параметры. Нам нужно только два обязательных для этого простого примера:

    - -
      -
    • Метод HTTP, который следует использовать при выполнении сетевого запроса. В этом случае GET самый подходящий, так как мы просто извлекаем некоторые простые данные.
    • -
    • URL-адрес для запроса - это URL-адрес файла JSON, который мы сохранили ранее.
    • -
    -
  6. -
  7. Затем добавьте следующие две строки: здесь мы устанавливаем responseType в JSON, так что XHR знает, что сервер будет возвращать JSON и, что это должно быть преобразовано за кулисами в объект JavaScript. Затем мы отправляем запрос методом send(): -
    request.responseType = 'json';
    -request.send();
    -
  8. -
  9. Последний бит этого раздела предполагает ожидание ответа на возврат с сервера, а затем работы с ним. Добавьте следующий код ниже вашего предыдущего кода: -
    request.onload = function() {
    -  var superHeroes = request.response;
    -  populateHeader(superHeroes);
    -  showHeroes(superHeroes);
    -}
    -
  10. -
- -

Здесь мы сохраняем ответ на наш запрос (доступный в свойстве response) в переменной superHeroes; эта переменная теперь будет содержать объект JavaScript, основанный на JSON! Затем мы передаем этот объект двум вызовам функций - первый из них заполнит <header> правильными данными, а второй создаст информационную карту для каждого героя в команде и вставляет ее в <section>.

- -

Мы свернули код в обработчик событий, который запускается, когда событие загрузки запускается в объекте запроса (см. onload) - это связано с тем, что событие загрузки запускается, когда ответ успешно возвращается; поступая  таким образом,это гарантия того, что request.response определенно будет доступен, когда мы начнем работу с ним.

- -

Заполнение заголовка

- -

Теперь мы извлекли данные JSON и превратили его в объект JavaScript, давайте воспользуемся им, написав две функции, на которые мы ссылались выше. Прежде всего, добавьте следующее определение функции ниже предыдущего кода:

- -
function populateHeader(jsonObj) {
-  var myH1 = document.createElement('h1');
-  myH1.textContent = jsonObj['squadName'];
-  header.appendChild(myH1);
-
-  var myPara = document.createElement('p');
-  myPara.textContent = 'Hometown: ' + jsonObj['homeTown'] + ' // Formed: ' + jsonObj['formed'];
-  header.appendChild(myPara);
-}
- -

Мы назвали параметр jsonObj, чтобы напомнить себе, что этот объект JavaScript возник из JSON. Здесь мы сначала создаем элемент {{HTMLElement("h1")}} с createElement(), устанавливаем его textContent равным свойству squadName объекта, а затем добавляем его в заголовок с помощью appendChild(). Затем мы выполняем очень похожую операцию с абзацем: создаем его, устанавливаем его текстовое содержимое и добавляем его в заголовок. Единственное различие заключается в том, что его текст задан, как конкатенированная строка, содержащая как homeTown, так и formed свойства объекта.

- -

Создание информационных карт героя

- -

Затем добавьте следующую функцию внизу кода, которая создает и отображает карты супергероев:

- -
function showHeroes(jsonObj) {
-  var heroes = jsonObj['members'];
-
-  for (var i = 0; i < heroes.length; i++) {
-    var myArticle = document.createElement('article');
-    var myH2 = document.createElement('h2');
-    var myPara1 = document.createElement('p');
-    var myPara2 = document.createElement('p');
-    var myPara3 = document.createElement('p');
-    var myList = document.createElement('ul');
-
-    myH2.textContent = heroes[i].name;
-    myPara1.textContent = 'Secret identity: ' + heroes[i].secretIdentity;
-    myPara2.textContent = 'Age: ' + heroes[i].age;
-    myPara3.textContent = 'Superpowers:';
-
-    var superPowers = heroes[i].powers;
-    for (var j = 0; j < superPowers.length; j++) {
-      var listItem = document.createElement('li');
-      listItem.textContent = superPowers[j];
-      myList.appendChild(listItem);
-    }
-
-    myArticle.appendChild(myH2);
-    myArticle.appendChild(myPara1);
-    myArticle.appendChild(myPara2);
-    myArticle.appendChild(myPara3);
-    myArticle.appendChild(myList);
-
-    section.appendChild(myArticle);
-  }
-}
- -

Для начала сохраним свойство members объекта JavaScript в новой переменной. Этот массив содержит несколько объектов, которые содержат информацию для каждого героя.

- -

Затем мы используем for loop для циклического прохождения каждого объекта в массиве. Для каждого из них мы:

- -
    -
  1. Создаем несколько новых элементов: <article>, <h2>, три <p> и <ul>.
  2. -
  3. Установливаем <h2>, чтобы содержать name текущего героя.
  4. -
  5. Заполняем три абзаца своей secretIdentity, age и строкой, в которой говорится: «Суперспособности:», чтобы ввести информацию в список.
  6. -
  7. Сохраняем свойство powers в другой новой переменной под названием superPowers - где содержится массив, в котором перечислены сверхспособности текущего героя.
  8. -
  9. Используем другой цикл for, чтобы прокрутить сверхспособности текущего героя , для каждого из них мы создаем элемент <li>, помещаем в него сверхспособности, а затем помещаем listItem внутри элемента <ul> (myList) с помощью appendChild().
  10. -
  11. Последнее, что мы делаем, это добавляем <h2>, <p> и <ul> внутри <article> (myArticle), а затем добавляем <article> в <section>. Важное значение имеет порядок, в котором добавляются элементы, так как это порядок, который они будут отображать внутри HTML.
  12. -
- -
-

Примечание. Если вам не удается заставить этот пример работать, попробуйте обратиться к нашему исходному коду heroes-finished.html (см. также он работает в режиме live).

-
- -
-

Примечание. Если у вас возникли проблемы после нотации точек / скобок, которые мы используем для доступа к объекту JavaScript, в этом поможет открытие файла superheroes.json на другой вкладке или в текстовом редакторе ,и обращаться к нему каждый раз, когда вам нужен JavaScript. Вы также можете обратиться к нашей статье JavaScript objectbasics чтобы получить дополнительную информацию о нотации точек и скобок.

-
- -

Преобразование между объектами и текстом

- -

Вышеприведенный пример был прост с точки зрения доступа к объекту JavaScript, потому что мы задали XHR-запрос для прямого преобразования ответа JSON в объект JavaScript, используя:

- -
request.responseType = 'json';
- -

Но иногда нам не так везет - иногда мы получаем сырую строку JSON и нам нужно  преобразовать ее в объект самостоятельно. И когда мы хотим отправить объект JavaScript по сети, нам нужно  преобразовать его в JSON (строку) перед отправкой. К счастью, эти две проблемы настолько распространены в веб-разработке, что встроенный объект JSON доступен в браузерах, которые содержат следующие два метода:

- - - -

Вы можете увидеть первый метод в действии в нашем примере heroes-finished-json-parse.html (см. исходный код) - это то же самое, что и в примере, который мы создали ранее, за исключением того, что мы установили XHR для возврата сырого JSON текста, затем используется parse(), чтобы преобразовать его в фактический объект JavaScript. Ключевой фрагмент кода находится здесь:

- -
request.open('GET', requestURL);
-request.responseType = 'text'; // now we're getting a string!
-request.send();
-
-request.onload = function() {
-  var superHeroesText = request.response; // get the string from the response
-  var superHeroes = JSON.parse(superHeroesText); // convert it to an object
-  populateHeader(superHeroes);
-  showHeroes(superHeroes);
-}
- -

Как вы могли догадаться, stringify() работает обратным образом. Попробуйте ввести следующие строки в консоль JavaScript браузера один за другим, чтобы увидеть его в действии:

- -
var myJSON = { "name": "Chris", "age": "38" };
-myJSON
-var myString = JSON.stringify(myJSON);
-myString
- -

Здесь мы создаем объект JavaScript, затем проверяем, что он содержит, а затем преобразуем его в строку JSON, используя stringify() , сохраняя возвращаемое значение в новой переменной, а затем снова проверяем его.

- -

Резюме

- -

В этой статье мы предоставили вам простое руководство по использованию JSON в ваших программах, в том числе о том, как создавать и анализировать JSON, и как получить доступ к данным, заблокированным внутри него. В следующей статье мы рассмотрим объектно-ориентированный JavaScript.

- -

Смотрите также

- - - -

{{PreviousMenuNext("Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects/Object_building_practice", "Learn/JavaScript/Objects")}}

- -

В этом модуле

- - - -
- - -
- -
-
diff --git "a/files/ru/learn/javascript/\320\276\320\261\321\212\320\265\320\272\321\202\321\213/object-oriented_js/index.html" "b/files/ru/learn/javascript/\320\276\320\261\321\212\320\265\320\272\321\202\321\213/object-oriented_js/index.html" deleted file mode 100644 index 0299268a90..0000000000 --- "a/files/ru/learn/javascript/\320\276\320\261\321\212\320\265\320\272\321\202\321\213/object-oriented_js/index.html" +++ /dev/null @@ -1,286 +0,0 @@ ---- -title: Объектно-ориентированный JavaScript для начинающих -slug: Learn/JavaScript/Объекты/Object-oriented_JS -tags: - - Constructor - - Create - - JavaScript - - OOJS - - Object - - Новичку - - ООП - - экземпляр -translation_of: Learn/JavaScript/Objects/Object-oriented_JS ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/JavaScript/Objects/Basics", "Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects")}}
- -

Разобравшись с основами, сосредоточимся на объектно-ориентированном JavaScript (OOJS) — данная статья дает базовое представление о теории объектно-ориентированного программирования (ООП), далее рассмотрено как JavaScript эмулирует классы объектов с помощью функции-конструктора и как создаются экземпляры объектов.

- - - - - - - - - - - - -
Необходимые знания: -

Базовая компьютерная грамотность, базовое понимание HTML и CSS, знакомство с основами JavaScript (см. Первые шаги и Cтруктурные элементы JavaScript) и основы OOJS (см. Введение в объекты).

-
Цель:Понять основную теорию объектно-ориентированного программирования, как это относится к JavaScript («все является объектом») и как создавать конструкторы и экземпляры объектов.
- -

Объектно-ориентированное программирование: основы

- -

Начнём с упрощённого высокоуровневого представления о том, что такое объектно-ориентированное программирование (ООП). Мы говорим упрощённого, потому что ООП может быстро стать очень сложным, и если сейчас дать полный курс, вероятно, можно запутать больше, чем помочь. Основная идея ООП заключается в том, что мы используем объекты для отображения моделей из реального мира в наших программах и/или упрощения доступа к функциям, которые в противном случае было бы трудно или невозможно использовать.

- -

Объекты могут содержать данные и код, представляющие информацию о том, что вы пытаетесь смоделировать, а также о том, какие у этих объектов должны быть функциональные возможности или поведение. Данные объекта (а часто так же и функции) могут быть точно сохранены (официальный термин "инкапсулированы") внутри пакета объекта, упрощая структуру и доступ к ним. Пакету объекта может быть присвоено определенное имя, на которое можно сослаться и которое иногда называют пространством имен. Объекты также широко используются в качестве хранилищ данных, которые могут быть легко отправлены по сети.

- -

Определение шаблона объекта

- -

Рассмотрим простую программу, которая отображает информацию об учениках и учителях в школе. Здесь мы рассмотрим теорию ООП в целом, а не в контексте какого-либо конкретного языка программирования.

- -

Вернёмся к объекту Person из нашей статьи Основы объектов, который определяет общие сведения и функциональные возможности человека. Есть много вещей, которые вы можете узнать о человеке (его адрес, рост, размер обуви, профиль ДНК, номер паспорта, значимые черты личности ...), но в данном случае нас интересует только имя, возраст, пол и интересы, а также мы хотим иметь возможность написать краткую информацию о нём, основываясь на этих данных, и сделать так, чтобы он поздоровался. Это известно как абстракция — создание простой модели более сложной сущности, которая представляет её наиболее важные аспекты таким образом, чтобы с ней было удобно работать для выполнения целей нашей программы.

- -

- -

В некоторых языках ООП, это общее определение типа объекта называется class (JavaScript использует другой механизм и терминологию, как вы увидите ниже) — это на самом деле не объект, а шаблон, который определяет, какие характеристики должен иметь объект.

- -

Создание реальных объектов

- -

Из нашего класса мы можем создать экземпляры объектов — объекты, содержащие данные и функциональные возможности, определённые в классе. Из нашего класса Person мы теперь можем создавать модели реальных людей:

- -

- -

Когда экземпляр объекта создается из класса, для его создания выполняется функция-конструктор класса. Этот процесс создания экземпляра объекта из класса называется создание экземпляра (instantiation) — из класса создается экземпляр объекта.

- -

Специализированные классы

- -

В нашем случае нам не нужны все люди — нам требуются учителя и ученики, которые являются более конкретными типами людей. В ООП мы можем создавать новые классы на основе других классов — эти новые дочерние классы могут быть созданы для наследования данных и характеристик родительского класса, так чтобы можно было использовать функциональные возможности, общие для всех типов объекта, вместо того чтобы дублировать их. Когда функциональность различается между классами, можно по мере необходимости определять специализированные функции непосредственно на них.

- -

- -

Это действительно полезно — преподаватели и студенты имеют много общих характеристик, таких как имя, пол и возраст, и удобно определить их только один раз. Вы можете также задать одну и ту же характеристику отдельно в разных классах, поскольку каждое определение этой характеристики будет находиться в отдельном пространстве имен. Например, приветствие студента может быть в форме "Yo, I'm [firstName]" (например Yo, I'm Sam), в то время как учитель может использовать что-то более формальное, такое как "Hello, my name is [Prefix] [lastName], and I teach [Subject]." (например Hello, My name is Mr Griffiths, and I teach Chemistry).

- -
-

Примечание: Если вам интересно, существует специальный термин Polymorphism (Полиморфизм) - это забавное слово, обозначающее реализацию той же функциональности для нескольких типов объекта. 

-
- -

Теперь вы можете создавать экземпляры объекта из дочерних классов. Например:

- -

- -

Далее мы рассмотрим, как ООП теорию можно применить на практике в JavaScript.

- -

Конструкторы и экземпляры объектов

- -

JavaScript использует специальные функции, называемые функциями конструктора (constructor functions) для определения объектов и их свойств. Они полезны, потому что вы часто будете сталкиваться с ситуациями, в которых не известно, сколько объектов вы будете создавать; конструкторы позволяют создать столько объектов, сколько нужно эффективным способом, прикреплением данных и функций для объектов по мере необходимости.

- -

Рассмотрим создание классов через конструкторы и создание экземпляров объектов из них в JavaScript. Прежде всего, мы хотели бы, чтобы вы создали новую локальную копию файла oojs.html, который мы видели в нашей первой статье «Объекты».

- -

Простой пример

- -
    -
  1. Давайте рассмотрим как можно определить человека с нормальной функцией. Добавьте эту функцию в элемент script: - -
    function createNewPerson(name) {
    -  const obj = {};
    -  obj.name = name;
    -  obj.greeting = function() {
    -    alert('Hi! I\'m ' + this.name + '.');
    -  };
    -  return obj;
    -}
    -
  2. -
  3. Теперь вы можете создать нового человека, вызвав эту функцию - попробуйте следующие строки в консоли JavaScript браузера: -
    const salva = createNewPerson('Salva');
    -salva.name;
    -salva.greeting();
    - Это работает достаточно хорошо, но код излишне многословен; если мы знаем, что хотим создать объект, зачем нам явно создавать новый пустой объект и возвращать его? К счастью, JavaScript предоставляет нам удобный способ в виде функций-конструкторов - давайте сделаем это сейчас!
  4. -
  5. Замените предыдущую функцию следующей: -
    function Person(name) {
    -  this.name = name;
    -  this.greeting = function() {
    -    alert('Hi! I\'m ' + this.name + '.');
    -  };
    -}
    -
  6. -
- -

Функция-конструктор - это JavaScript версия класса. Вы заметите, что в нем есть все признаки, которые вы ожидаете от функции, хотя он ничего не возвращает и явно не создает объект - он в основном просто определяет свойства и методы. Вы также увидите, что ключевое слово this также используется здесь, - это в основном говорит о том, что всякий раз, когда создается один из этих экземпляров объектов, свойство имени объекта будет равно значению name, переданному вызову конструктора, и метод greeting() будет использовать значение имени, переданное также вызову конструктора.

- -
-

Примечание: Имя функции конструктора обычно начинается с заглавной буквы - это соглашение используется для упрощения распознавания функций конструктора в коде.

-
- -

Итак, как мы вызываем конструктор для создания некоторых объектов?

- -
    -
  1. Добавьте следующие строки под предыдущим добавлением кода: -
    let person1 = new Person('Bob');
    -let person2 = new Person('Sarah');
    -
  2. -
  3. Сохраните код и перезагрузите его в браузере и попробуйте ввести следующие строки в консоль JS: -
    person1.name
    -person1.greeting()
    -person2.name
    -person2.greeting()
    -
  4. -
- -

Круто! Теперь, как вы видите, у нас есть два новых объекта на странице, каждый из которых хранится в отдельном пространстве имен - при доступе к их свойствам и методам вы должны начинать вызовы с person1 или person2; функциональность, содержащаяся внутри, аккуратно упакована, поэтому она не будет конфликтовать с другими функциями. Тем не менее, у них есть одно и то же свойство name и greeting(). Обратите внимание, что они используют свое собственное значение name, которое было присвоено им, когда они были созданы; это одна из причин, почему очень важно использовать this, таким образом они будут использовать свои собственные значения, а не какие-либо другие.

- -

Давайте снова посмотрим на вызовы конструктора:

- -
let person1 = new Person('Bob');
-let person2 = new Person('Sarah');
- -

В каждом случае ключевое слово new используется, чтобы сообщить браузеру, что мы хотим создать экземпляр нового объекта, за которым следует имя функции с ее необходимыми параметрами, содержащимися в круглых скобках, и результат сохраняется в переменной - очень похоже на то, как вызывается стандартная функция. Каждый экземпляр создается в соответствии с этим определением:

- -
function Person(name) {
-  this.name = name;
-  this.greeting = function() {
-    alert('Hi! I\'m ' + this.name + '.');
-  };
-}
- -

После создания новых объектов переменные person1 и person2 содержат следующие объекты:

- -
{
-  name: 'Bob',
-  greeting: function() {
-    alert('Hi! I\'m ' + this.name + '.');
-  }
-}
-
-{
-  name: 'Sarah',
-  greeting: function() {
-    alert('Hi! I\'m ' + this.name + '.');
-  }
-}
- -

Обратите внимание, что когда мы вызываем нашу функцию-конструктор, мы определяем greeting() каждый раз, что не является идеальным. Чтобы этого избежать, вместо этого мы можем определить функции на прототипе, о которых мы поговорим позже.

- -

Создавая наш готовый конструктор

- -

Пример, рассмотренный выше, был лишь наглядным примером, чтобы вы поняли суть. Теперь, давайте создадим нашу конечную функцию-конструктор Person().

- -
    -
  1. Замените весь предыдущий код новой функцией конструктора - это, в принципе, тот же самое что и в наглядном примере, но несколько сложнее: -
    function Person(first, last, age, gender, interests) {
    -  this.name = {
    -    first : first,
    -    last: last
    -  };
    -  this.age = age;
    -  this.gender = gender;
    -  this.interests = interests;
    -  this.bio = function() {
    -    alert(this.name.first + ' ' + this.name.last + ' is ' + this.age + ' years old. He likes ' + this.interests[0] + ' and ' + this.interests[1] + '.');
    -  };
    -  this.greeting = function() {
    -    alert('Hi! I\'m ' + this.name.first + '.');
    -  };
    -};
    -
  2. -
  3. Теперь добавьте следующую строку ниже, чтобы создать экземпляр объекта из него: -
    let person1 = new Person('Bob', 'Smith', 32, 'male', ['music', 'skiing']);
    -
  4. -
- -

Как вы могли заметить, вы можете получить доступ к свойствам и методам, как это было ранее, - попробуйте использовать их в консоли JS:

- -
person1['age']
-person1.interests[1]
-person1.bio()
-// etc.
- -
Примечание: Если у Вас возникли проблемы с работой кода, попробуйте сравнить его с нашей версией - см. oojs-class-finished.html (также смотрите, как он работает в прямом эфире).
- -

Дальнейшие упражнения

- -

Для начала, попробуйте добавить еще пару собственных строк создания объекта и попробуйте получить и установить элементы полученных экземпляров объектов.

- -

Кроме того, есть несколько проблем с нашим методом bio() - вывод всегда включает местоимение «He» ("Он" в пер. с англ.), даже если ваш человек является женщиной или какой-либо другой предпочтительной гендерной классификацией. И bio будет включать только два интереса, даже если в массиве interests указано больше. Можете ли Вы решить, как исправить это в определении класса (конструкторе)? Вы можете поместить любой код, который вам нравится внутри конструктора (вам, вероятно, понадобятся несколько условий и цикл). Подумайте о том, как предложения должны быть структурированы по-разному в зависимости от пола и в зависимости от того, имеет ли число перечисленных интересов 1, 2 или более 2.

- -
-

Примечание: Если у Вас возникли трудности с решением задачи, мы предоставили ответ в нашем репозитории GitHub (см. это в действии) — но сначала попробуйте написать сами!

-
- -

Другие способы создания экземпляров объектов

- -

До сих пор мы видели два разных способа создания экземпляра объекта - объявление объектного литерала и использование функции конструктора (см. выше).

- -

Это имеет смысл, но есть и другие способы - мы бы хотели ознакомить Вас с ними на случай, если Вы встретите их в своих путешествиях по Сети.

- -

Конструктор Object ()

- -

Прежде всего, вы можете использовать конструктор Object() для создания нового объекта. Да, даже общие объекты имеют конструктор, который генерирует пустой объект.

- -
    -
  1. Попробуйте ввести это в консоль JavaScript вашего браузера: -
    let person1 = new Object();
    -
  2. -
  3. Это сохраняет ссылку на пустой объект в переменную person1. Затем вы можете добавить свойства и методы к этому объекту с использованием точечной или скобочной нотации по желанию; попробуйте эти примеры в консоли: -
    person1.name = 'Chris';
    -person1['age'] = 38;
    -person1.greeting = function() {
    -  alert('Hi! I\'m ' + this.name + '.');
    -};
    -
  4. -
  5. Вы также можете передать литерал объекта конструктору Object() в качестве параметра, чтобы заполнить его свойствами / методами. Попробуйте это в консоли JS: -
    let person1 = new Object({
    -  name: 'Chris',
    -  age: 38,
    -  greeting: function() {
    -    alert('Hi! I\'m ' + this.name + '.');
    -  }
    -});
    -
  6. -
- -

Использование метода create()

- -

Конструкторы могут помочь вам определить порядок кода - вы можете создать конструктор в одном месте, а затем создавать экземпляры по мере необходимости, и их происхождение будет понятным.

- -

Однако некоторые люди предпочитают создавать экземпляры объектов без предварительного создания конструкторов, особенно если они создают только несколько экземпляров объекта. JavaScript имеет встроенный метод create(), который позволяет вам это делать. С его помощью вы можете создать новый объект на основе любого существующего объекта.

- -
    -
  1. Закончив упражнение из предыдущего раздела, загруженное в браузер, попробуйте это в консоли JavaScript: -
    let person2 = Object.create(person1);
    -
  2. -
  3. Теперь попробуйте: -
    person2.name
    -person2.greeting()
    -
  4. -
- -

Вы увидите, что person2 был создан на основе person1 - он имеет те же свойства и метод, доступные для него.

- -

Одно ограничение метода create() заключается в том, что IE8 не поддерживает его. Поэтому конструкторы могут быть более эффективными, если вы хотите поддерживать старые браузеры.

- -

Подробнее мы рассмотрим особенности метода create() немного позже.

- -

Сводка

- -

В этой статье представлен упрощенный взгляд на объектно-ориентированную теорию — это еще не вся история, но она дает представление о том, с чем мы имеем дело. Кроме того, мы начали рассматривать различные способы создания экземпляров объектов.

- -

В следующей статье мы рассмотрим прототипы объектов JavaScript.

- -

{{PreviousMenuNext("Learn/JavaScript/Objects/Basics", "Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects")}}

- -

В этом модуле

- - diff --git "a/files/ru/learn/javascript/\320\276\320\261\321\212\320\265\320\272\321\202\321\213/object_building_practice/index.html" "b/files/ru/learn/javascript/\320\276\320\261\321\212\320\265\320\272\321\202\321\213/object_building_practice/index.html" deleted file mode 100644 index b06b769ca4..0000000000 --- "a/files/ru/learn/javascript/\320\276\320\261\321\212\320\265\320\272\321\202\321\213/object_building_practice/index.html" +++ /dev/null @@ -1,302 +0,0 @@ ---- -title: Практика построения объектов -slug: Learn/JavaScript/Объекты/Object_building_practice -tags: - - Guide - - JavaScript -translation_of: Learn/JavaScript/Objects/Object_building_practice ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects/Adding_bouncing_balls_features", "Learn/JavaScript/Objects")}}
- -

В предыдущих статьях мы рассмотрели всю существенную теорию объектов JavaScript и детали синтаксиса, давая вам прочную основу для начала. В этой статье мы погружаемся в практическое упражнение, давая вам больше практики в создании пользовательских объектов JavaScript, с веселым и красочным результатом.

- - - - - - - - - - - - -
Необходимые знания:Базовая компьютерная грамотность, базовые знания HTML и CSS, знакомство с основами JavaScript (see First steps and Building blocks) и основами OOJS (см. Introduction to objects).
Цель:Получение некоторой практики в использовании объектов и объектно-ориентированных методов в реальном мире.
- -

Давайте подбросим несколько мячей

- -

В этой статье мы напишем классическую демонстрацию «прыгающих шаров», чтобы показать вам, насколько полезными могут быть объекты в JavaScript. Наши маленькие шары будут подпрыгивать на экране и менять цвет, когда они касаются друг друга. Готовый пример будет выглядеть примерно так:

- -

- -
    -
- -

В этом примере будет использоваться Canvas API для рисования шаров на экране и API requestAnimationFrame для анимации всего экрана - вам не нужно иметь никаких предыдущих знаний об этих API, и мы надеемся, что к тому моменту, когда вы закончите эту статью, вам будет интересно изучить их больше. По пути мы воспользуемся некоторыми изящными объектами и покажем вам пару хороших приемов, таких как отскоки шаров от стен и проверка того, попали ли они друг в друга (иначе известный как обнаружение столкновения).

- -

Начало работы

- -

Для начала создайте локальные копии наших файловindex.html, style.css и main.js. Они содержат следующее:

- -
    -
  1. Очень простой HTML-документ, содержащий элемент {{HTMLElement("h1")}}, элемент {{HTMLElement("canvas")}} для рисования наших шаров и элементы для применения нашего CSS и JavaScript в нашем HTML.
  2. -
  3. Некоторые очень простые стили, которые в основном служат для стилизации и позиционирования <h1>, и избавляются от любых полос прокрутки или отступы по краю страницы (так что это выглядит красиво и аккуратно).
  4. -
  5. Некоторые JavaScript, которые служат для настройки элемента <canvas> и предоставляют общую функцию, которую мы собираемся использовать.
  6. -
- -

Первая часть скрипта выглядит так:

- -
var canvas = document.querySelector('canvas');
-
-var ctx = canvas.getContext('2d');
-
-var width = canvas.width = window.innerWidth;
-var height = canvas.height = window.innerHeight;
- -

Этот скрипт получает ссылку на элемент <canvas>, а затем вызывает метод getContext(), чтобы дать нам контекст, по которому мы можем начать рисовать. Результирующая переменная (ctx) - это объект, который непосредственно представляет область рисования холста и позволяет рисовать на ней 2D-фигуры.

- -

Затем мы устанавливаем переменные, называемые width и height, а также ширину и высоту элемента canvas (представленные свойствами canvas.width и canvas.height), чтобы равняться ширине и высоте окна просмотра браузера (область, на которой отображается веб-страница - это можно получить из свойств {{domxref("Window.innerWidth")}} и {{domxref("Window.innerHeight")}}).

- -

Вы увидите здесь, что мы объединяем несколько назначений вместе, чтобы все переменные были установлены быстрее - это совершенно нормально.

- -

Последний бит исходного скрипта выглядит следующим образом:

- -
function random(min, max) {
-  var num = Math.floor(Math.random() * (max - min + 1)) + min;
-  return num;
-}
- -

Эта функция принимает два числа в качестве аргументов и возвращает случайное число в диапазоне между ними.

- -

Моделирование мяча в нашей программе

- -

В нашей программе будет много шаров, подпрыгивающих вокруг экрана. Поскольку эти шары будут вести себя одинаково, имеет смысл представлять их в виде объекта. Начнем с добавления следующего конструктора в конец нашего кода.

- -
function Ball(x, y, velX, velY, color, size) {
-  this.x = x;
-  this.y = y;
-  this.velX = velX;
-  this.velY = velY;
-  this.color = color;
-  this.size = size;
-}
- -

Здесь мы включаем некоторые параметры, которые определяют свойства, которым должен соответствовать каждый шар в нашей программе:

- - - -

Этим мы сортируем свойства, но что насчет методов? Мы хотим заставить эти шары на самом деле сделать что-то в нашей программе.

- -

Рисование шара

- -

Сначала добавьте следующий метод draw() к Ball()'s prototype:

- -
Ball.prototype.draw = function() {
-  ctx.beginPath();
-  ctx.fillStyle = this.color;
-  ctx.arc(this.x, this.y, this.size, 0, 2 * Math.PI);
-  ctx.fill();
-}
- -

Используя эту функцию, мы можем сказать нашему шару нарисовать себя на экране, вызвав ряд членов контекста двумерного холста, который мы определили ранее (ctx). Контекст похож на бумагу, и теперь мы хотим, чтобы наше перо рисовало что-то на нем:

- - - -

Теперь вы можете начать тестирование своего объекта..

- -
    -
  1. Сохраните код и загрузите HTML-файл в браузер.
  2. -
  3. Откройте консоль JavaScript браузера, а затем обновите страницу, чтобы размер холста изменился в соответствии с новой шириной и высотой окна просмотра браузера после открытия консоли.
  4. -
  5. Чтобы создать новый экземпляр шара, введите следующее: -
    var testBall = new Ball(50, 100, 4, 4, 'blue', 10);
    -
  6. -
  7. Попробуйте вызвать его свойства и методы: -
    testBall.x
    -testBall.size
    -testBall.color
    -testBall.draw()
    -
  8. -
  9. После введения последней строки, вы должны увидеть, как мяч нарисовался где-то на вашем холсте.
  10. -
- -

Обновление данных мяча

- -

Мы можем нарисовать мяч в нужном положении, но чтобы начать движение мяча, нам нужна функция обновления. Добавьте следующий код внизу вашего файла JavaScript, чтобы добавить метод update() к Ball()'s prototype:

- -
Ball.prototype.update = function() {
-  if ((this.x + this.size) >= width) {
-    this.velX = -(this.velX);
-  }
-
-  if ((this.x - this.size) <= 0) {
-    this.velX = -(this.velX);
-  }
-
-  if ((this.y + this.size) >= height) {
-    this.velY = -(this.velY);
-  }
-
-  if ((this.y - this.size) <= 0) {
-    this.velY = -(this.velY);
-  }
-
-  this.x += this.velX;
-  this.y += this.velY;
-}
- -

Первые четыре части функции проверяют, достиг ли шар края холста. Если это так, мы изменяем полярность соответствующей скорости, чтобы заставить шар двигаться в противоположном направлении. Так, например, если мяч двигался вверх (положительный velY), то вертикальная скорость изменяется так, что он начинает двигаться вниз (отрицательная величина velY).

- -

В этих четырех случаях мы:

- - - -

В каждом случае мы включаем size шарика в расчет, потому что координаты x/y находятся в центре шара, но мы хотим, чтобы край шара отскакивал от периметра - мы не хотим, чтобы мяч на половину заходил за границу экрана прежде чем он начнет возвращаться назад.

- -

Последние две строки добавляют значение velX к координате x, а значение velY - координате y - шар фактически перемещается при каждом вызове этого метода.

- -

На сейчас этого достаточно, давайте продолжим анимацию!

- -

Анимация мяча

- -

Теперь давайте приступать к веселью! Сейчас мы начнем добавлять шары к холсту и анимировать их.

- -
    -
  1. Во-первых, нам нужно где-то хранить все наши шары. Следующий массив выполнит это задание - добавьте его внизу кода: -
    var balls = [];
    - -

    Все программы, которые оживляют вещи, обычно включают цикл анимации, который служит для обновления информации в программе, а затем визуализации результирующего представления для каждого кадра анимации; это основа для большинства игр и других подобных программ.

    -
  2. -
  3. Добавьте ниже эту часть кода: -
    function loop() {
    -  ctx.fillStyle = 'rgba(0, 0, 0, 0.25)';
    -  ctx.fillRect(0, 0, width, height);
    -
    -  while (balls.length < 25) {
    -    var ball = new Ball(
    -      random(0,width),
    -      random(0,height),
    -      random(-7,7),
    -      random(-7,7),
    -      'rgb(' + random(0,255) + ',' + random(0,255) + ',' + random(0,255) +')',
    -      random(10,20)
    -    );
    -    balls.push(ball);
    -  }
    -
    -  for (var i = 0; i < balls.length; i++) {
    -    balls[i].draw();
    -    balls[i].update();
    -  }
    -
    -  requestAnimationFrame(loop);
    -}
    - -

    Наша функция loop() выполняет следующие действия:

    - -
      -
    • Устанавливает цвет заливки на полупрозрачный черный, затем рисует прямоугольник цвета по всей ширине и высоте холста, используя fillRect() (четыре параметра обеспечивают начальную координату, а ширину и высоту для рисованного прямоугольника ). Это позволяет скрыть рисунок предыдущего кадра до того, как будет нарисован следующий. Если вы этого не сделаете, вы увидите, как длинные змеи пробираются вокруг холста, а не шары! Цвет заливки устанавливается на полупрозрачный, rgba(0,0,0,0,25), чтобы позволить нескольким кадрам слегка просвечивать, создавая маленькие тропы за шариками по мере их перемещения. Если вы изменили 0.25 на 1, вы больше не увидите их. Попробуйте изменить это число, чтобы увидеть эффект, который он имеет.
    • -
    • Создает новый экземпляр нашего Ball(), используя случайные значения, сгенерированные с помощью нашей функции random(), затем push() на конец нашего массива шаров, но только в том случае, когда количество шаров в массиве меньше 25. Итак когда у нас есть 25 мячей на экране, больше не появляется шаров. Вы можете попробовать изменить число в balls.length < 25, чтобы получить больше или меньше шаров на экране. В зависимости от того, сколько вычислительной мощности имеет ваш компьютер / браузер, если указать несколько тысячь шаров, это может довольно существенно повлиять на производительность анимации. 
    • -
    • перебирает все шары в массиве balls и запускает каждую функцию draw() и update() для рисования каждого из них на экране, а затем выполняет необходимые обновления по положению и скорости во времени для следующего кадра.
    • -
    • Выполняет функцию снова с помощью метода requestAnimationFrame() - когда этот метод постоянно запускается и передается одно и то же имя функции, он будет запускать эту функцию определенное количество раз в секунду для создания плавной анимации. Обычно это делается рекурсивно - это означает, что функция вызывает себя каждый раз, когда она запускается, поэтому она будет работать снова и снова.
    • -
    -
  4. -
  5. И последнее, но не менее важное: добавьте следующую строку в конец вашего кода - нам нужно вызвать функцию один раз, чтобы начать анимацию. -
    loop();
    -
  6. -
- -

Вот и все для основы - попробуйте сохранить и освежить, чтобы проверить свои прыгающие шары!

- -

Добавление обнаружения столкновений

- -

Теперь немного поиграем, давайте добавим в нашу программу обнаружение конфликтов, поэтому наши мячи узнают, когда они ударят по другому шару.

- -
    -
  1. Прежде всего, добавьте следующее определение метода ниже, где вы определили метод update() (т.е. блок Ball.prototype.update). - -
    Ball.prototype.collisionDetect = function() {
    -  for (var j = 0; j < balls.length; j++) {
    -    if (!(this === balls[j])) {
    -      var dx = this.x - balls[j].x;
    -      var dy = this.y - balls[j].y;
    -      var distance = Math.sqrt(dx * dx + dy * dy);
    -
    -      if (distance < this.size + balls[j].size) {
    -        balls[j].color = this.color = 'rgb(' + random(0, 255) + ',' + random(0, 255) + ',' + random(0, 255) +')';
    -      }
    -    }
    -  }
    -}
    - -

    Этот метод немного сложный, поэтому не беспокойтесь, если вы не понимаете, как именно это работает. Ниже приводится объяснение:

    - -
      -
    • Для каждого шара нам нужно проверить каждый другой шар, чтобы увидеть, столкнулся ли он с текущим мячом. Чтобы сделать это, мы открываем еще один цикл for  через все шары в массиве balls[].
    • -
    • Сразу же в нашем цикле for мы используем оператор if, чтобы проверить, проходит ли текущий шарик, тот же самый шар, что и тот, который мы сейчас проверяем. Мы не хотим проверять, что мяч столкнулся с самим собой! Для этого мы проверяем, является ли текущий мяч (т.е. мяч, метод которого вызван методом collisionDetect) такой же, как шар петли (т.е. шар, на который ссылается текущая итерация цикла for в collisionDetect метод). Затем мы используем ! чтобы отменить проверку, чтобы код внутри оператора if выполнялся только в том случае, если они не совпадают.
    • -
    • Затем мы используем общий алгоритм для проверки столкновения двух окружностей. Мы в основном проверяем, перекрывается ли какая-либо из областей круга. Это объясняется далее 2D collision detection.
    • -
    • Если обнаружено столкновение, выполняется код внутри внутреннего оператора if. В этом случае мы просто устанавливаем свойство color обоих кругов на новый случайный цвет. Мы могли бы сделать что-то гораздо более сложное, например, заставить шары отскакивать друг от друга реалистично, но это было бы гораздо сложнее реализовать. Для такого моделирования физики разработчики склонны использовать игры или библиотеку физики, такие как PhysicsJS, matter.js, Phaser и т.д.
    • -
    -
  2. -
  3. Вы также должны вызвать этот метод в каждом кадре анимации. Добавьте следующий код после строки balls[i].update(); -
    balls[i].collisionDetect();
    -
  4. -
  5. Сохраните и обновите демо снова, и вы увидите, как ваши мячи меняют цвет, когда они сталкиваются!
  6. -
- -
-

Примечание. Если вам не удается заставить этот пример работать, попробуйте сравнить код JavaScript с нашей готовой версией (также смотрите, как он работает в прямом эфире).

-
- -

Резюме

- -

Мы надеемся, что вам понравилось писать собственный пример случайных прыгающих шаров в реальном мире, используя различные объектные и объектно-ориентированные методы из всего модуля! Это должно было дать вам некоторую полезную практику использования объектов и хорошего контекста реального мира.

- -

Вот и все для предметных статей - все, что осталось сейчас, - это проверить свои навыки в оценке объекта.

- -

Смотрите также

- - - -

{{PreviousMenuNext("Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects/Adding_bouncing_balls_features", "Learn/JavaScript/Objects")}}

- -

В этом модуле

- - diff --git "a/files/ru/learn/javascript/\320\276\320\261\321\212\320\265\320\272\321\202\321\213/object_prototypes/index.html" "b/files/ru/learn/javascript/\320\276\320\261\321\212\320\265\320\272\321\202\321\213/object_prototypes/index.html" deleted file mode 100644 index 0a76580d9c..0000000000 --- "a/files/ru/learn/javascript/\320\276\320\261\321\212\320\265\320\272\321\202\321\213/object_prototypes/index.html" +++ /dev/null @@ -1,285 +0,0 @@ ---- -title: Прототипы объектов -slug: Learn/JavaScript/Объекты/Object_prototypes -tags: - - JavaScript - - create() - - Конструктор - - Начинающий - - ООП - - Обучение - - Обьект - - Статья - - прототип -translation_of: Learn/JavaScript/Objects/Object_prototypes ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects")}}
- -
Прототипы - это механизм, с помощью которого объекты JavaScript наследуют свойства друг от друга. В этой статье мы объясним, как работают цепочки прототипов, и рассмотрим, как свойство prototype можно использовать для добавления методов к существующим конструкторам.
- -
- - - - - - - - - - - - -
Необходимые знания: -

Базовая компьютерная грамотность, базовое понимание HTML и CSS, знакомство с основами JavaScript (см. Первые шаги и Строительные блоки) и основы OOJS (см. Введение в объекты).

-
Цель: -

Понять прототипы объектов JavaScript, как работают прототипные цепочки и как добавить новые методы в prototype свойство.

-
- -

Язык основанный на прототипах?

- -

JavaScript часто описывают как язык прототипного наследования — каждый объект, имеет объект-прототип, который выступает как шаблон, от которого объект наследует методы и свойства. Объект-прототип так же может иметь свой прототип и наследовать его свойства и методы и так далее. Это часто называется цепочкой прототипов и объясняет почему одним объектам доступны свойства и методы которые определены в других объектах.

- -

Точнее, свойства и методы определяются в свойстве prototype функции-конструктора объектов, а не в самих объектах.

- -

В JavaScript создается связь между экземпляром объекта и его прототипом (свойство __proto__, которое является производным от свойства prototype конструктора), а свойства и методы обнаруживаются при переходе по цепочке прототипов.

- -
-

Примечание: Важно понимать, что существует различие между прототипом объекта (который доступен через Object.getPrototypeOf(obj) или через устаревшее свойство __proto__) и свойством prototype в функциях-конструкторах. Первое свойство является свойством каждого экземпляра, а второе - свойством конструктора. То есть Object.getPrototypeOf(new Foobar()) относится к тому же объекту, что и Foobar.prototype.

-
- -

Давайте посмотрим на пример, чтобы стало понятнее.

- -

Понимание прототипа объектов

- -

Вернемся к примеру, когда мы закончили писать наш конструктор Person()- загрузите пример в свой браузер. Если у вас еще нет работы от последней статьи, используйте наш пример oojs-class-further-exercises.html (см. Также исходный код).

- -

В этом примере мы определили конструкторную функцию, например:

- -
function Person(first, last, age, gender, interests) {
-
-  // Определения методов и свойств
-  this.name = {
-    'first': first,
-    'last' : last
-  };
-  this.age = age;
-  this.gender = gender;
-  //...см. Введение в объекты для полного определения
-}
- -

Затем мы создаём экземпляр объекта следующим образом:

- -
var person1 = new Person('Bob', 'Smith', 32, 'male', ['music', 'skiing']);
- -

Если вы наберете «person1.» в вашей консоли JavaScript, вы должны увидеть, что браузер пытается автоматически заполнить это с именами участников, доступных на этом объекте:

- -

- -

В этом списке вы увидите элементы, определенные в конструкторе person 1 — Person() — name, age, gender, interests, bio, и greeting. Однако вы также увидите некоторые другие элементы — watch, valueOfи т. д. — они определены в объекте прототипа Person (), который является Object.

- -

- -

Итак, что произойдет, если вы вызываете метод в person1, который фактически определен в Object? Например:

- -
person1.valueOf()
- -

Этот метод — Object.valueOf()наследуется person1, потому что его конструктором является Person(), а прототипом Person() является Object(). valueOf() возвращает значение вызываемого объекта — попробуйте и убедитесь! В этом случае происходит следующее:

- - - -
-

Примечание: Мы хотим повторить, что методы и свойства не копируются из одного объекта в другой в цепочке прототипов - к ним обращаются, поднимаясь по цепочке, как описано выше.

-
- -
-

Примечание: Официально нет способа получить доступ к объекту прототипа объекта напрямую - «ссылки» между элементами в цепочке определены во внутреннем свойстве, называемом [[prototype]] в спецификации для языка JavaScript ( см. {{glossary("ECMAScript")}}). Однако у большинства современных браузеров есть свойство, доступное для них под названием __proto__ (это 2 подчеркивания с обеих сторон), который содержит объект-прототип объекта-конструктора. Например, попробуйте person1.__proto__ и person1.__proto__.__proto__, чтобы увидеть, как выглядит цепочка в коде!

- -

С ECMAScript 2015 вы можете косвенно обращаться к объекту прототипа объекта Object.getPrototypeOf (obj).

-
- -

Свойство prototype: Где определены унаследованные экземпляры

- -

Итак, где определены наследуемые свойства и методы? Если вы посмотрите на страницу со ссылкой Object, вы увидите в левой части большое количество свойств и методов - это намного больше, чем количество унаследованных членов, доступных для объекта person1. Некоторые из них унаследованы, а некоторые нет - почему это?

- -

Как упоминалось выше, наследованные свойства это те, что определены в свойстве prototype (вы можете называть это подпространством имен), то есть те, которые начинаются с Object.prototype., а не те, которые начинаются с простого Object. Значение свойства prototype - это объект, который в основном представляет собой контейнер для хранения свойств и методов, которые мы хотим наследовать объектами, расположенными дальше по цепочке прототипов.

- -

Таким образом Object.prototype.watch(), Object.prototype.valueOf() и т. д. доступны для любых типов объектов, которые наследуются от Object.prototype, включая новые экземпляры объектов, созданные из конструктора Person() .

- -

Object.is(), Object.keys() и другие члены, не определенные в контейнере prototype, не наследуются экземплярами объектов или типами объектов, которые наследуются от Object.prototype. Это методы / свойства, доступные только в конструкторе Object().

- -
-

Примечание: Это кажется странным - как у вас есть метод, определенный для конструктора, который сам по себе является функцией? Ну, функция также является типом объекта - см. Ссылку на конструктор Function(), если вы нам не верите.

-
- -
    -
  1. Вы можете проверить существующие свойства прототипа для себя - вернитесь к нашему предыдущему примеру и попробуйте ввести следующее в консоль JavaScript: -
    Person.prototype
    -
  2. -
  3. Результат покажет вам не много, ведь мы ничего не определили в прототипе нашего конструктора! По умолчанию prototype конструктора всегда пуст. Теперь попробуйте следующее: -
    Object.prototype
    -
  4. -
- -

Вы увидите большое количество методов, определенных для свойства prototype Object'а , которые затем доступны для объектов, которые наследуются от Object, как показано выше.

- -

Вы увидите другие примеры наследования цепочек прототипов по всему JavaScript - попробуйте найти методы и свойства, определенные на прототипе глобальных объектов String, Date, Number и Array, например. Все они имеют несколько элементов, определенных на их прототипе, поэтому, например, когда вы создаете строку, вот так:

- -
var myString = 'This is my string.';
- -

В myString сразу есть множество полезных методов, таких как split(), indexOf(), replace() и т. д.

- -
-

Важно: Свойство prototype является одной из наиболее противоречивых названий частей JavaScript - вы можете подумать, что this указывает на объект прототипа текущего объекта, но это не так (это внутренний объект, к которому можно получить доступ __proto__, помните ?). prototype вместо этого - свойство, содержащее объект, на котором вы определяете членов, которые вы хотите наследовать.

-
- -

Снова create()

- -

Ранее мы показали, как метод Object.create() может использоваться для создания нового экземпляра объекта.

- -
    -
  1. Например, попробуйте это в консоли JavaScript предыдущего примера: -
    var person2 = Object.create(person1);
    -
  2. -
  3. На самом деле create()создает новый объект из указанного объекта-прототипа. Здесь person2 создается с помощью person1 в качестве объекта-прототипа. Это можно проверить, введя в консоли следующее: -
    person2.__proto__
    -
  4. -
- -

Это вернет объект person1.

- -

Свойство constructor

- -

Каждая функция-конструктор имеет свойство prototype, значением которого является объект, содержащий свойство constructor. Это свойство constructor указывает на исходную функцию-конструктор. Как вы увидите в следующем разделе, свойства, определенные в свойстве Person.prototype (или в общем случае в качестве свойства прототипа функции конструктора, который является объектом, как указано в предыдущем разделе) становятся доступными для всех объектов экземпляра, созданных с помощью конструктор Person(). Следовательно, свойство конструктора также доступно для объектов person1 и person2.

- -
    -
  1. Например, попробуйте эти команды в консоли: -
    person1.constructor
    -person2.constructor
    - -

    Они должны возвращать конструктор Person(), поскольку он содержит исходное определение этих экземпляров.

    - -

    Хитрый трюк заключается в том, что вы можете поместить круглые скобки в конец свойства constructor (содержащие любые требуемые параметры) для создания другого экземпляра объекта из этого конструктора. Конструктор - это функция в конце концов, поэтому ее можно вызвать с помощью круглых скобок; вам просто нужно включить ключевое слово new, чтобы указать, что вы хотите использовать эту функцию в качестве конструктора.

    -
  2. -
  3. Попробуйте это в консоли: -
    var person3 = new person1.constructor('Karen', 'Stephenson', 26, 'female', ['playing drums', 'mountain climbing']);
    -
  4. -
  5. Теперь попробуйте получить доступ к функциям вашего нового объекта, например: -
    person3.name.first
    -person3.age
    -person3.bio()
    -
  6. -
- -

Это хорошо работает. Вам не нужно будет использовать его часто, но это может быть действительно полезно, если вы хотите создать новый экземпляр и не имеете ссылки на исходный конструктор, который легко доступен по какой-либо причине.

- -

Свойство constructor имеет другие применения. Например, если у вас есть экземпляр объекта и вы хотите вернуть имя конструктора этого экземпляра, вы можете использовать следующее:

- -
instanceName.constructor.name
- -

Например, попробуйте это:

- -
person1.constructor.name
-
- -
-

Примечание: Значение constructor.name может измениться (из-за прототипического наследования, привязки, препроцессоров, транспилеров и т. д.), Поэтому для более сложных примеров вы захотите использовать оператор instanceof.

-
- -
    -
- -

Изменение прототипов

- -

Давайте рассмотрим пример изменения свойства prototype функции-конструктора — методы, добавленные в прототип, затем доступны для всех экземпляров объектов, созданных из конструктора.

- -
    -
  1. Вернитесь к нашему примеру oojs-class-further-exercises.html и создайте локальную копию исходного кода. Ниже существующего JavaScript добавьте следующий код, который добавляет новый метод в свойство prototype конструктора: - -
    Person.prototype.farewell = function() {
    -  alert(this.name.first + ' has left the building. Bye for now!');
    -};
    -
  2. -
  3. Сохраните код и загрузите страницу в браузере и попробуйте ввести следующее в текстовый ввод: -
    person1.farewell();
    -
  4. -
- -

Должно появиться всплывающее окно, с именем пользователя, определенным в конструкторе. Это действительно полезно, но ещё более полезно то, что вся цепочка наследования обновляется динамически, автоматически делая этот новый метод доступным для всех экземпляров объектов, полученных из конструктора.

- -

Подумайте об этом на мгновение. В нашем коде мы определяем конструктор, затем мы создаем экземпляр объекта из конструктора, затем добавляем новый метод к прототипу конструктора:

- -
function Person(first, last, age, gender, interests) {
-
-  // определения свойств и методов
-
-}
-
-var person1 = new Person('Tammi', 'Smith', 32, 'neutral', ['music', 'skiing', 'kickboxing']);
-
-Person.prototype.farewell = function() {
-  alert(this.name.first + ' has left the building. Bye for now!');
-};
- -

Но метод farewell() по-прежнему доступен в экземпляре объекта person1 - его элементы были автоматически обновлены, чтобы включить недавно определенный метод farewell().

- -
-

Примечание: Если у вас возникли проблемы с получением этого примера для работы, посмотрите на наш пример oojs-class-prototype.html (см. также это running live).

-
- -

Вы редко увидите свойства, определенные в свойстве prototype, потому что они не очень гибки при таком определении. Например, вы можете добавить свойство следующим образом:

- -
Person.prototype.fullName = 'Bob Smith';
- -

Это не очень гибко, так как человека нельзя назвать так. Было бы намного лучше сделать это, создав fullName из name.first и name.last:

- -
Person.prototype.fullName = this.name.first + ' ' + this.name.last;
- -

Однако это не работает, поскольку в этом случае this будет ссылаться на глобальную область, а не на область функции. Вызов этого свойства вернет undefined undefined. Это отлично работало с методом, который мы определили ранее в прототипе, потому что он находится внутри области функций, которая будет успешно перенесена в область экземпляра объекта. Таким образом, вы можете определить постоянные свойства прототипа (т. е. те, которые никогда не нуждаются в изменении), но обычно лучше определять свойства внутри конструктора.

- -

Фактически, довольно распространенный шаблон для большего количества определений объектов - это определение свойств внутри конструктора и методов в прототипе. Это упрощает чтение кода, поскольку конструктор содержит только определения свойств, а методы разделены на отдельные блоки. Например:

- -
// Определение конструктора и его свойств
-
-function Test(a, b, c, d) {
-  // определение свойств...
-}
-
-// Определение первого метода
-
-Test.prototype.x = function() { ... };
-
-// Определение второго метода
-
-Test.prototype.y = function() { ... };
-
-//...и так далее
- -

Этот образец можно увидеть в действии в примере приложения плана школы Петра Залевы.

- -

Резюме

- -

В этой статье рассмотрены прототипы объектов JavaScript (в том числе и то, как прототип цепочки объектов позволяет объектам наследовать функции друг от друга), свойство прототипа и как его можно использовать для добавления методов к конструкторам и другие связанные с этой статьёй темы.

- -

В следующей статье мы рассмотрим то, как вы можете реализовать наследование функциональности между двумя собственными настраиваемыми объектами.

- -

{{PreviousMenuNext("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects")}}

- - - -

В этом модуле

- - diff --git "a/files/ru/learn/javascript/\320\276\320\261\321\212\320\265\320\272\321\202\321\213/\320\276\321\201\320\275\320\276\320\262\321\213/index.html" "b/files/ru/learn/javascript/\320\276\320\261\321\212\320\265\320\272\321\202\321\213/\320\276\321\201\320\275\320\276\320\262\321\213/index.html" deleted file mode 100644 index a4e7cc0071..0000000000 --- "a/files/ru/learn/javascript/\320\276\320\261\321\212\320\265\320\272\321\202\321\213/\320\276\321\201\320\275\320\276\320\262\321\213/index.html" +++ /dev/null @@ -1,257 +0,0 @@ ---- -title: Основы объектов в JavaScript -slug: Learn/JavaScript/Объекты/Основы -tags: - - JavaScript - - ООП -translation_of: Learn/JavaScript/Objects/Basics ---- -
{{LearnSidebar}}
- -
{{NextMenu("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects")}}
- -

В этой статье мы рассмотрим объекты в JavaScript. Мы будем разбирать основы синтаксиса объектов JavaScript и заново изучим некоторый функционал JavaScript, который мы уже исследовали ранее на курсе, подтвердив тот факт, что большая часть функционала, с которым мы уже столкнулись, в действительности является объектами.

- - - - - - - - - - - - -
Необходимые знания:Элементарная компьютерная грамотность, базовое понимание HTML и CSS, знакомство с основами JavaScript (см. Первые шаги и Структурные элементы).
Цель:Понимать основу теории перед началом объектно-ориентированного программирования, как это связано с JavaScript ("большинство сущностей являются объектами"), и как начать работу с объектами JavaScript.
- -

Основы объектов

- -

Объект — это совокупность связанных данных и/или функциональных возможностей. Обычно состоят из нескольких переменных и функций, которые называются свойства и методы, если они находятся внутри объектов. Разберём пример, чтобы показать, как они выглядят.

- -

Чтобы начать, скопируйте себе oojs.html файл. В нём содержится очень мало: {{HTMLElement("script")}} элемент для написания в нём исходного кода. Мы будем использовать это как основу для изучения основ синтаксиса объектов. Во время работы с этим примером у вас должна быть открытая консоль JavaScript инструментов разработчика, готовая к вводу некоторых команд.

- -

Как и во многих случаях в JavaScript, создание объекта часто начинается с определения и инициализации переменной. Попробуйте ввести следующий код JavaScript в ваш файл, а затем сохраните файл и обновите страницу браузера:

- -
const person = {};
- -

Если Вы введёте person в текстовое JS консоль и нажмёте клавишу Enter, должен получиться следующий результат:

- -
Object { }
- -

Поздравляем, Вы только что создали Ваш первый объект. Но это пустой объект, поэтому мы не можем с ним ничего сделать. Давайте обновим наш объект, чтобы он выглядел так:

- -
const person = {
-  name: ['Bob', 'Smith'],
-  age: 32,
-  gender: 'male',
-  interests: ['music', 'skiing'],
-  bio: function() {
-    alert(this.name[0] + ' ' + this.name[1] + ' is ' + this.age + ' years old. He likes ' + this.interests[0] + ' and ' + this.interests[1] + '.');
-  },
-  greeting: function() {
-    alert('Hi! I\'m ' + this.name[0] + '.');
-  }
-};
-
- -

После сохранения и обновления, попробуйте ввести что-нибудь следующее в консоль JavaScript браузера:

- -
person.name
-person.name[0]
-person.age
-person.interests[1]
-person.bio()
-person.greeting()
- -

Теперь внутри объекта есть некоторые данные и функционал, и теперь можно получить доступ к ним с помощью некоторого лёгкого и простого синтаксиса!

- -
-

Примечание: Если у вас возникли проблемы с применением файла в работе, попробуйте сравнить ваш код с нашей версией — см. oojs-finished.html (также see it running live). Одна из распространенных ошибок, когда Вы начинаете с объектами ставить запятую в конце последнего члена — это приводит к ошибке.

-
- -

Итак что здесь происходит? Объект состоит из нескольких элементов, каждый из которых имеет своё название (пример name и age выше), и значение (пример ['Bob', 'Smith'] и 32). Каждая пара название/значение должны быть разделены запятой, а название и значение в каждом случае разделяются двоеточием. Синтаксис всегда следует этому образцу:

- -
const objectName = {
-  member1Name: member1Value,
-  member2Name: member2Value,
-  member3Name: member3Value
-};
- -

Значение члена объекта может быть чем угодно — в нашем объекте person есть строка, число, два массива, и две функции. Первые четыре элемента это элементы данных, относящиеся к свойствам объекта. Последние два элемента являются функциями, которые позволяют объекту что-то сделать с элементами данных, и называются методами объекта.

- -

Такие объекты называются литералами объекта (object literal) — мы буквально вписали все содержимое объекта для его создания. Этот способ сильно отличается от объектов реализованных классами, которые мы рассмотрим позже.

- -

Очень часто для создания объекта используется литерал объекта когда вам нужно каким-то образом перенести ряд структурированных, связанных элементов данных, например, отправляя запрос на сервер, для размещения их в базе данных. Отправка одного объекта намного эффективнее, чем отправка нескольких элементов по отдельности, и с ним легче работать чем с массивом, если требуется идентифицировать отдельные элементы по имени. 

- -

Точечная запись (Dot notation)

- -

Выше Вы получили доступ к свойствам и методам используя точечную запись (dot notation). Имя объекта (person) действует как пространство имен (namespace) — оно должно быть введено первым, для того чтобы получить доступ ко всему что заключено (encapsulated) внутри объекта. Далее Вы пишете точку, затем элемент, к которому хотите получить доступ — это может быть имя простого свойства, элемент массива, или вызов одного из методов объекта, например:

- -
person.age
-person.interests[1]
-person.bio()
- -

Внутренние пространства имен (Sub-namespaces)

- -

Можно даже сделать значением элемента объекта другой объект. Например, попробуйте изменить значение свойства name с такого

- -
name: ['Bob', 'Smith'],
- -

на такое

- -
name : {
-  first: 'Bob',
-  last: 'Smith'
-},
- -

Здесь мы фактически создаем внутреннее пространство имен (sub-namespace). Это звучит сложно, но на самом деле это не так — для доступа к этим элементам Вам нужно сделать один дополнительный шаг с еще одной точкой. Попробуйте в консоли браузера следующее: 

- -
person.name.first
-person.name.last
- -

Важно: На этом этапе вам также нужно будет пересмотреть код метода и изменить все экземпляры с

- -
name[0]
-name[1]
- -

на

- -
name.first
-name.last
- -

Иначе ваши методы больше не будут работать.

- -

Скобочная запись (Bracket notation)

- -

Существует другой способ получить свойства объекта — использовать скобочную запись (bracket notation). Вместо написания этого кода:

- -
person.age
-person.name.first
- -

Вы можете использовать следующий

- -
person['age']
-person['name']['first']
- -

Это выглядит очень похоже на то, как Вы получаете элементы массива, и в принципе это так и есть — вместо использования числовых индексов для выбора элемента, Вы ассоциируете имя свойства для каждого значения. Ничего удивительного, что эти объекты иногда называют ассоциативными массивами — они сопоставляют строки со значениями так же, как массивы сопоставляют числовые индексы со значениями.

- -

Запись элементов в объект

- -

До сих пор мы рассмастривали только возврат (или получение) элементов объекта — Вы так же можете установить (обновить) значение элемента объекта просто объявив элемент, который Вы хотите установить (используя точечную или скобочную запись), например:

- -
person.age = 45;
-person['name']['last'] = 'Cratchit';
- -

Попробуйте ввести эти строки, а затем снова верните элементы, чтобы увидеть, как они изменились

- -
person.age
-person['name']['last']
- -

Вы можете не просто обновлять и устанавливать значения свойств и методов объекта, а так же устанавливать совершенно новые элементы. Попробуйте их в консоли JS:

- -
person['eyes'] = 'hazel';
-person.farewell = function() { alert("Bye everybody!"); }
- -

Теперь Вы можете проверить ваши новые элементы:

- -
person['eyes']
-person.farewell()
- -

Одним из полезных аспектов скобочной записи является то, что с ее помощью можно динамически задавать не только значения элементов, но и их имена. Предположим, что мы хотим, чтобы пользователи могли хранить пользовательские типы данных, введя имя и значение элемента в два следующих поля? Мы могли бы получить эти значения следующим образом:

- -
let myDataName = nameInput.value;
-let myDataValue = nameValue.value;
- -

Затем мы можем добавить имя и значение этого нового элемента в объект person таким образом:

- -
person[myDataName] = myDataValue;
- -

Чтобы проверить это, попробуйте добавить следующие строки в свой код, после закрывающей скобки объекта person :

- -
let myDataName = 'height';
-let myDataValue = '1.75m';
-person[myDataName] = myDataValue;
- -

Теперь попробуйте сохранить и обновить, затем введите следующее в консоль браузера:

- -
person.height
- -

Добавление свойства объекта с использованием вышеописанного метода невозможно с использованием точечной записи, которая может принимать только литеральное имя элемента, а не значение переменной указывающее на имя.

- -

Что такое "this"?

- -

Возможно, вы заметили что-то странное в наших методах. Посмотрите на этот пример:

- -
greeting: function() {
-  alert('Hi! I\'m ' + this.name.first + '.');
-}
- -

Вы, вероятно, задаетесь вопросом, что такое "this"? Ключевое слово this, ссылается на текущий объект, внутри которого пишется код — поэтому в нашем случае this равен объекту person. Но почему просто не написать person? Как Вы увидите в статье Object-oriented JavaScript for beginners (Объектно-ориентированный JavaScript для начинающих), когда мы начинаем создавать конструкторы и т.д., this очень полезен — он всегда будет гарантировать, что используется верное значение, когда контекст элемента изменяется (например, два разных экземпляра объекта person могут иметь разные имена, но захотят использовать свое собственное имя при приветствии.

- -

Давайте проиллюстритуем, что мы имеем в виду, с упрощенной парой объектов person :

- -
const person1 = {
-  name: 'Chris',
-  greeting: function() {
-    alert('Hi! I\'m ' + this.name + '.');
-  }
-}
-
-const person2 = {
-  name: 'Brian',
-  greeting: function() {
-    alert('Hi! I\'m ' + this.name + '.');
-  }
-}
- -

В этом случае, person1.greeting() выведет "Hi! I'm Chris.". person2.greeting(), с другой стороны, выведет "Hi! I'm Brian.", хотя код метода одинаковый в обоих случаях. Как мы сказали ранее, this равен объекту, внутри которого находится код — это не очень полезно, когда Вы пишите литералы объектов вручную, но оно действительно помогает, когда Вы генерируете объекты динамически (например используя конструкторы). Это станет понятнее чуть позже.

- -

Все это время вы использовали объекты

- -

Пока Вы проходили эти примеры, Вы вероятно заметили, что точечная запись, которую Вы использовали, выглядит очень знакомо. Это потому, что Вы использовали ее на протяжении всего курса! Каждый раз, когда мы работаем над примером, использующим встроенный API браузера или объект JavaScript, мы использовали объекты, потому что такие функции построены с использованием тех же структур объектов, которые мы здесь рассматривали, хотя и более сложные, чем наши собственные пользовательские примеры. 

- -

Поэтому, когда Вы использовали строковые методы, такие как:

- -
myString.split(',');
- -

Вы использовали метод доступный в экземпляре класса String. Каждый раз создавая строку в вашем коде, эта строка автоматически создается как экземпляр String, и поэтому имеет несколько общих методов/свойств, доступных на нем.

- -

Когда Вы обращались к объектной модели документа (DOM), используя следующие строки:

- -
const myDiv = document.createElement('div');
-const myVideo = document.querySelector('video');
- -

Вы использовали методы доступные в экземпляре класса Document. Для каждой загруженной веб-страницы создается экземпляр Document, называемый document, который представляет всю структуру страницы, ее содержимое и другие функции, такие как URL-адрес. Опять же, это означает, что он имеет несколько общих методов/свойств, доступных на нем.

- -

То же самое относится и к любому другому встроенному объекту/API, который вы использовали — Array, Math, и т. д.

- -

Обратите внимание, что встроенные объекты/API не всегда создают экземпляры объектов автоматически. Как пример, Notifications API — который позволяет новым браузерам запускать системные уведомления, требует, чтобы Вы создавали новый экземпляр объекта с помощью конструктора для каждого уведомления, которое Вы хотите запустить. Попробуйте ввести следующее в консоль JavaScript:

- -
const myNotification = new Notification('Hello!');
- -

Опять же, мы рассмотрим конструкторы в следующей статье.

- -
-

Примечание: Полезно подумать о том, как объекты взаимодействуют посредством передачи сообщений - когда объекту требуется другой объект для выполнения какого-либо действия, он часто отправляет сообщение другому объекту через один из его методов и ждет ответа, который мы знаем как возвращаемое (return) значение.

-
- -

Резюме

- -

Поздравляем, Вы достигли конца нашей первой статьи о объектах JS, теперь у вас должно быть хорошее представление о том, как работать с объектами в JavaScript - в том числе создавать свои собственные простые объекты. Вы также должны понимать, что объекты очень полезны в качестве структур для хранения связанных данных и функциональности - если бы мы пытались отслеживать все свойства и методы в нашем объекте person как отдельные переменные и функции, это было неэффективно, и мы бы рисковали столкнуться с другими переменными и функциями с такими же именами. Объекты позволяют нам безопасно хранить информацию в своем собственном блоке, вне опасности.

- -

В следующей статье мы начнем рассматривать теорию объектно-ориентированного программирования (OOП) и как эти техники могут быть использованны в JavaScript 

- -

{{NextMenu("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects")}}

- -

В этом модуле

- - diff --git "a/files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/a_first_splash/index.html" "b/files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/a_first_splash/index.html" deleted file mode 100644 index b2a811b992..0000000000 --- "a/files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/a_first_splash/index.html" +++ /dev/null @@ -1,675 +0,0 @@ ---- -title: Первое погружение в JavaScript -slug: Learn/JavaScript/Первые_шаги/A_first_splash -translation_of: Learn/JavaScript/First_steps/A_first_splash ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/What_is_JavaScript", "Learn/JavaScript/Первые_шаги/Что_пошло_не_так", "Learn/JavaScript/Первые_шаги")}}
- -

Теперь, когда вы получили базовое представление о JavaScript — самое время познакомиться с ним на практике! В данной статье представлен ускоренный практический курс, демонстрирующий основные возможности JavaScript. В этом курсе, шаг за шагом, вы создадите простую игру «Угадай число».

- - - - - - - - - - - - -
Необходимые навыки:Базовая компьютерная грамотность, знание основ HTML и CSS, понимание что такое и для чего нужен JavaScript.
Цели:Получение первого опыта в программировании на JavaScript.
- -

Вам не придется сразу понимать весь код — мы только хотим познакомить вас с базовыми концепциями языка и дать представление о том, как работает JavaScript (и другие языки программирования). В дальнейших статьях вы изучите эти концепции более подробно!

- -
-

Большинство языковых конструкций JavaScript, с которыми вы познакомитесь (функции, циклы и т.д.), имеют аналоги в других языках программирования — т.е. языки имеют разный синтаксис, но концепции в большинстве случаев те же самые.

-
- -

Думай как программист

- -

Одним из самых трудных и значимых моментов в обучении программированию является не изучение непосредственно синтаксиса языка, а понимание того как применять его для решения реальных задач. Вам нужно начать думать как программист, обычно это означает следующее:

- - - -

Всё вместе это потребует тяжелой работы, знания языка, практики в написании кода - и немного творчества. Чем больше вы будете заняты решением практических задач, тем быстрее будете расти в программировании. Мы не обещаем, что вы сразу начнете "думать как программист", но предоставим для этого достаточно возможностей в этой статье.

- -

Учитывая вышесказанное, на примере простой игры, давайте детально разберем каждый этап создания программы и познакомимся с некоторыми конструкциями языка.

- -

Игра «Угадай число»

- -

В этой статье мы покажем вам как создать простую игру, которую вы видите ниже:

- - - -

{{ EmbedLiveSample('Top_hidden_code', '100%', 320) }}

- -

Поиграйте в нее - познакомьтесь с игрой, прежде чем двигаться дальше.

- -

Давайте представим, что ваш босс дал вам следующую информацию для создания этой игры:

- -
-

Я хочу чтобы ты создал простую игру по принципу "Угадай число". Игра должна случайным образом генерировать число от 0 до 100, затем игрок должен отгадать это число за 10 попыток. После каждой попытки игроку сообщают угадал он число или не угадал и если он ошибся, то ему сообщается, что загаданное число больше или меньше того, которое он ввел. Так же необходимо показывать игроку числа из его предыдущих попыток. Игра будет окончена, если игрок угадал число верно или если у него кончатся все попытки. После окончания игры игроку будет дана возможность сыграть в игру еще раз.

-
- -

Поглядев на это краткое изложение, первое, что мы можем сделать - это начать разбивать его на простые действия, максимально думая как программист:

- -
    -
  1. Сгенерировать случайное число между 1 и 100.
  2. -
  3. Начать запись количества попыток игрока угадать число. Начать с 1.
  4. -
  5. Предоставить попытку угадать игроку загаданное число.
  6. -
  7. Как только попытка угадать была отправлена, сначала записать ее где-нибудь, чтобы пользователь мог увидеть свои предыдущие попытки
  8. -
  9. Далее, проверить было ли это число верным.
  10. -
  11. Если число верное: -
      -
    1. Показать поздравительное сообщение.
    2. -
    3. Оградить игрока от дальнейшей возможности ввода чисел (это испортит игру).
    4. -
    5. Предоставить возможность для перезапуска игры.
    6. -
    -
  12. -
  13. Если число не верное и есть попытки: -
      -
    1. Сказать игроку, что он не угадал.
    2. -
    3. Разрешить ему использовать еще попытку.
    4. -
    5. Повысить число попыток на 1.
    6. -
    -
  14. -
  15. Если число не верное и попыток нет: -
      -
    1. Сказать игроку, что игра окончена.
    2. -
    3. Оградить игрока от дальнейшей возможности ввода чисел (это испортит игру).
    4. -
    5. Предоставить возможность для перезапуска игры.
    6. -
    -
  16. -
  17. Во время перезапуска игры убедиться, что игровая логика и пользовательский интерфейс полностью сбросились на начальные значения и далее перейти обратно к пункту 1.
  18. -
- -

Давайте теперь перейдем к рассмотрению того, как мы можем превратить эти шаги в код, создавая примеры и исследуя возможности JavaScript по ходу.

- -

Подготовка

- -

В начале этого урока, мы хотели бы, чтобы вы создали локальную копию файла  number-guessing-game-start.html  (см. здесь).  Откройте его как в текстовом редакторе, так и в веб-браузере. На данный момент вы увидите простой заголовок, абзац с инструкцией и форму для ввода предположения, но форма в настоящее время ничего не сделает.

- -

Место, где мы будем добавлять весь наш код, находится внутри элемента {{htmlelement("script")}} в нижней части HTML:

- -
<script>
-
-  // Your JavaScript goes here
-
-</script>
-
- -

Добавление переменных для хранения данных

- -

Давайте начнем. Прежде всего добавьте следующие строки внутри элемента  {{htmlelement("script")}} :

- -
var randomNumber = Math.floor(Math.random() * 100) + 1;
-
-var guesses = document.querySelector('.guesses');
-var lastResult = document.querySelector('.lastResult');
-var lowOrHi = document.querySelector('.lowOrHi');
-
-var guessSubmit = document.querySelector('.guessSubmit');
-var guessField = document.querySelector('.guessField');
-
-var guessCount = 1;
-var resetButton;
- -

В этом разделе кода устанавливаются переменные, необходимые для хранения данных, которые будет использоваться нашей программой. Переменные - это в основном контейнеры для значений (например, числа или строки текста). Вы создаете переменную с ключевым словом var, за которой следует имя для вашей переменной. Затем вы можете присвоить значение своей переменной знак равенства (=), за которым следует значение, которое вы хотите дать.

- -

В нашем примере:

- - - -
-

Заметка: В дальнейшем вы узнаете намного больше о переменных, в следующей статье.

-
- -

Функции (Functions)

- -

Затем добавьте следующие ниже предыдущего JavaScript:

- -
function checkGuess() {
-  alert('I am a placeholder');
-}
- -

Функции представляют собой многократно используемые блоки кода, написав один раз вы можете запускать их снова и снова, сохраняя нужный постоянно повторяющийся код. Это действительно полезно. Существует несколько способов определить функцию, но пока мы сосредоточимся на одном простом варианте. Здесь мы определили функцию используя ключевое слово function, за ним идет имя с двумя скобками после него. После этого мы добавляем две фигурные скобки ({ }). Внутри фигурных скобок содержится весь код, запускающийся всякий раз, когда вызываем функцию.

- -

Код запускается вводом имени функции, за которым следуют две скобки.

- -

Сейчас попробуйте сохранить код и обновить его в браузере.

- -

Перейдите к консоли JavaScript в инструментах разработчика, и введите следующую строку:

- -
checkGuess();
- -

Вы должны увидеть предупреждение, в котором говорится "I am a placeholder"; в нашем коде мы определили функцию, которая создает предупреждение, когда ее вызывают.

- -
-

Заметка: В дальнейшем вы намного больше узнаете о функциях.

-
- -

Операторы (Operators)

- -

Операторы JavaScript позволяют нам проводить проверки, математические рассчеты, объединять строки вместе и выполнять другие подобные действия.

- -

Сохраните наш код и обновите страницу показанную в браузере. Откройте консоль JavaScript, если вы еще её не открыли, чтобы попробовать ввести текст из приведенных ниже примеров — введите каждую строчку из столбца "Пример", нажимая Enter после каждого из них, и посмотрите какие результаты они возвращают. Если у вас нет доступа к инструментам разработчика в браузере, вы всегда можете использовать простую встроенную консоль, показанную ниже:

- - - -

{{ EmbedLiveSample('Hidden_code', '100%', 300) }}

- -

Сначала давайте посмотрим на арифметические операторы, например:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ОператорИмяПример
+Сложение6 + 9
-Вычитание20 - 15
*Умножение3 * 7
/Деление10 / 5
- -

Вы также можете использовать оператор + для сложения строк текста (в программировании это называется конкатенацией). Попробуйте ввести следующие строки:

- -
var name = 'Bingo';
-name;
-var hello = ' says hello!';
-hello;
-var greeting = name + hello;
-greeting;
- -

Также есть сокращенные операторы, называемые расширенными операторами присваивания. Например, если вы просто хотите добавить новую строку к существующей и вернуть результат, вы можете сделать так:

- -
name += ' says hello!';
- -

Это эквивалентно этому:

- -
name = name + ' says hello!';
- -

Когда мы запускаем проверку true/false (истина/ложь) (например, внутри условных выражений — смотри {{anch("Conditionals", "ниже")}}), мы используем операторы сравнения, например:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ОператорИмяПример
===Строгое равенство (это точно одно и то же?)5 === 2 + 4
!==Строгое неравенство (это не одно и то же?)'Chris' !== 'Ch' + 'ris'
<Меньше чем10 < 6
>Больше чем10 > 20
- -

Условные выражения (Conditionals)

- -

Вернемся к нашей функции checkGuess(), я думаю, можно с уверенностью сказать, что мы не хотим, чтобы она просто выводила сообщение заполнитель. Мы хотим, чтобы она проверяла сделал игрок правильный выбор или нет, и соответсвующе реагировала.

- -

Теперь, заменим вашу текущую функциюcheckGuess() на эту версию:

- -
function checkGuess() {
-  var userGuess = Number(guessField.value);
-  if (guessCount === 1) {
-    guesses.textContent = 'Previous guesses: ';
-  }
-  guesses.textContent += userGuess + ' ';
-
-  if (userGuess === randomNumber) {
-    lastResult.textContent = 'Congratulations! You got it right!';
-    lastResult.style.backgroundColor = 'green';
-    lowOrHi.textContent = '';
-    setGameOver();
-  } else if (guessCount === 10) {
-    lastResult.textContent = '!!!GAME OVER!!!';
-    setGameOver();
-  } else {
-    lastResult.textContent = 'Wrong!';
-    lastResult.style.backgroundColor = 'red';
-    if(userGuess < randomNumber) {
-      lowOrHi.textContent = 'Last guess was too low!';
-    } else if(userGuess > randomNumber) {
-      lowOrHi.textContent = 'Last guess was too high!';
-    }
-  }
-
-  guessCount++;
-  guessField.value = '';
-  guessField.focus();
-}
- -

Как много кода — фу! Давайте отдельно рассмотрим каждый раздел и объясним, что он делает.

- - - -

События (Events)

- -

На данный момент у нас есть хорошо реализованная функция checkGuess(), но она ничего не сделает, потому что мы еще не вызвали ее. В идеале мы хотим вызывать её во время нажатия кнопки « Submit guess », и для этого нам нужно использовать событие. События - это действия, которые происходят в браузере, например, нажатие кнопки или загрузка страницы или воспроизведение видео, в ответ на которые мы можем запускать блоки кода. Конструкции, которые прослушивают событие, называются прослушивателями событий, а блоки кода, выполняемые в ответ на срабатывание событий, называются обработчиками событий.

- -

Добавьте следующую строку ниже закрывающей фигурной скобки функции checkGuess():

- -
guessSubmit.addEventListener('click', checkGuess);
- -

Здесь мы добавляем прослушиватель событий к кнопке guessSubmit. Это метод, который принимает два входных значения (называемые аргументами) - тип события, которое мы выслушиваем (в данном случае click) в виде строки, и код, который мы хотим запустить при возникновении события (в данном случае функция checkGuess() - обратите внимание, что нам не нужно указывать круглые скобки при записи внутри {{domxref("EventTarget.addEventListener", "addEventListener()")}}).

- -

Попробуйте сохранить и обновить код сейчас, и ваш пример должен теперь работать, но до определенного момента. Единственная проблема в том, что если вы угадаете правильный ответ или исчерпаете догадки, игра сломается, потому что мы еще не определили функцию setGameOver(), которая должна запускаться после завершения игры. Давайте добавим наш недостающий код и завершим пример функциональности.

- -

Завершение игры

- -

Давайте добавим функцию setGameOver() в конец нашего кода, а затем пройдем по ней. Добавьте это под нижней частью вашего JavaScript:

- -
function setGameOver() {
-  guessField.disabled = true;
-  guessSubmit.disabled = true;
-  resetButton = document.createElement('button');
-  resetButton.textContent = 'Start new game';
-  document.body.appendChild(resetButton);
-  resetButton.addEventListener('click', resetGame);
-}
- - - -

Теперь нам нужно также определить эту функцию! Добавьте следующий код, снова в нижнюю часть вашего JavaScript:

- -
function resetGame() {
-  guessCount = 1;
-
-  var resetParas = document.querySelectorAll('.resultParas p');
-  for (var i = 0 ; i < resetParas.length ; i++) {
-    resetParas[i].textContent = '';
-  }
-
-  resetButton.parentNode.removeChild(resetButton);
-
-  guessField.disabled = false;
-  guessSubmit.disabled = false;
-  guessField.value = '';
-  guessField.focus();
-
-  lastResult.style.backgroundColor = 'white';
-
-  randomNumber = Math.floor(Math.random() * 100) + 1;
-}
- -

Этот довольно длинный блок кода полностью сбрасывает все на то, как это было в начале игры, поэтому у игрока может быть еще один ход. Это:

- - - -

С этого момента у вас есть полностью работающая (простая) игра - поздравляем!

- -

Все, что нам осталось сделать в этой статье, - это поговорить о нескольких других важных функциях кода, которые вы уже видели, хотя вы, возможно, этого не осознали.

- -

Циклы (Loops) 

- -
-
-
Одна часть вышеприведенного кода, которую мы должны рассмотреть более подробно, - это цикл for. Циклы - очень важная концепция программирования, которая позволяет вам снова и снова запускать кусок кода, пока не будет выполнено определенное условие.
- -
Для начала перейдите в панель инструментов разработчика JavaScript-консоли и введите следующее:
-
-
- -
for (var i = 1 ; i < 21 ; i++) { console.log(i) }
- -

Что случилось? Номера с 1 по 20 были напечатаны в консоли. Это из-за цикла. Цикл for принимает три входных значения (аргументы):
- Начальное значение: в этом случае мы начинаем подсчет c 1, но это может быть любое число которое вам нравится. Вы можете заменить i любым другим именем, которое вам нравится, но я использую его как условность, потому что оно короткое и легко запоминается. Условие выхода: Здесь мы указали i <21 - цикл будет продолжаться до тех пор, пока i будет меньше 21. Когда i достигнет 21, цикл больше не будет работать. Инкремент: мы указали i ++, что означает «увеличить i на 1». Цикл будет выполняться один раз для каждого значения i, пока оно не достигнет значения 21 (как обсуждалось выше). В этом случае мы просто печатаем значение i в консоли на каждой итерации с помощью {{domxref ("Console.log", "console.log ()")}}.

- -

Теперь давайте посмотрим на цикл в нашей игре угадывания чисел - в функции resetGame () можно найти следующее:

- -
var resetParas = document.querySelectorAll('.resultParas p');
-for (var i = 0 ; i < resetParas.length ; i++) {
-  resetParas[i].textContent = '';
-}
- -

Этот код создает переменную, содержащую список всех абзацев внутри <div class = "resultParas">, используя метод {{domxref ("Document.querySelectorAll", "querySelectorAll ()")}}, затем он проходит через каждый из них, удаляя текстовое содержимое каждого из них.

- -

Немного об объектах (Objects)

- -

Давайте добавим еще одно окончательное улучшение, прежде чем перейти к обсуждению. Добавьте следующую строку чуть ниже var resetButton; в верхней части вашего JavaScript, затем сохраните файл:

- -
guessField.focus();
- -

Эта строка использует метод {{domxref("HTMLElement.focus", "focus()")}}, чтобы автоматически помещать текстовый курсор в текстовое поле {{htmlelement("input")}}, как только загрузится страница. Пользователь сможет сразу набрать свою первую догадку, не нажимая поле формы. Это всего лишь небольшое дополнение, но оно улучшает удобство использования - дает пользователю хорошую визуальную подсказку относительно того, что они должны делать в игре.

- -

Давайте проанализируем, что произошло. В JavaScript все элементы являются объектами. Объект - это набор связанных функций, хранящихся в одной группе. Вы можете создавать собственные объекты, но это требует мастерства, и мы не хотели бы раскрывать эту тему в рамках данного курса. Будет достаточно обсудить встроенные объекты вашего браузера, которые позволяют реализовывать множество полезных вещей.

- -

В нашем примере мы сначала создали переменную guessField, которая запоминает значение из поля ввода в нашем HTML - следующая строка находится среди первых в нашем коде:

- -
var guessField = document.querySelector('.guessField');
- -

Чтобы получить это значение, мы использовали метод {{domxref("document.querySelector", "querySelector()")}} объекта {{domxref("document")}}. querySelector() "берет" одну часть информации -  CSS selector, который выбирает нужный элемент.

- -

Поскольку guessField теперь содержит ссылку на элемент {{htmlelement("input")}}, теперь он будет иметь доступ к ряду свойств (в основном к переменным, хранящимся внутри объектов, некоторые значения которых нельзя изменять) и методы (в основном функции, хранящиеся внутри объектов). Одним из методов, доступных для ввода элементов, является focus (), поэтому мы можем теперь использовать эту строку для фокусировки ввода текста:

- -
guessField.focus();
- -

Для переменных, которые не содержат ссылок на элементы формы, не будет доступен focus(). Например, переменная guesses содержит ссылку на элемент {{htmlelement ("p")}}, а guessCount содержит число.

- -

Поиграем с объектами браузера

- -

Давайте немного поиграем с некоторыми объектами браузера.

- -
    -
  1. Для начала запустите свою программу в браузере.
  2. -
  3. Далее, откройте инструменты разработчика в вашем браузере, и убедитесь, что вы перешли во вкладку с консолью JavaScript.
  4. -
  5. Введите guessField и консоль покажет, что переменная содержит элемент {{htmlelement("input")}}. Вы также можете заметить, что консоль автоматически заполняет имена объектов, которые существуют внутри исполняющей среды, включая ваши переменные!
  6. -
  7. Теперь введите следующее: -
    guessField.value = 'Hello';
    - Свойство value представляет текущее значение, введенное в текстовое поле. Заметьте, что, введя эту команду, мы изменили его!
  8. -
  9. Попробуйте ввести guesses и нажать return. Консоль покажет, что в переменной содержится элемент {{htmlelement("p")}}.
  10. -
  11. Теперь попробуйте ввести: -
    guesses.value
    - Браузер вернет вам undefined, потому что value не существует в параграфах.
  12. -
  13. Для изменения текста внутри параграфа, взамен используйте свойство {{domxref("Node.textContent", "textContent")}}. Попробуйте: -
    guesses.textContent = 'Where is my paragraph?';
    -
  14. -
  15. Теперь немного повеселимся. Попробуйте ввести следующие строки, одну за другой: -
    guesses.style.backgroundColor = 'yellow';
    -guesses.style.fontSize = '200%';
    -guesses.style.padding = '10px';
    -guesses.style.boxShadow = '3px 3px 6px black';
    - Каждый элемент на странице имеет свойство style, которое само по себе содержит объект, свойства которого содержат все встроенные стили CSS, применяемые к этому элементу. Это позволяет нам динамически задавать новые стили CSS для элементов с помощью JavaScript.
  16. -
- -

Теперь можно отдохнуть...

- -

Итак, на этом пример закончился - отлично, вы добрались до конца! Попробуйте свой финальный код или поиграйте с нашей готовой версией здесь. Если вы не можете запустить этот пример, сверьтесь с исходным кодом.

- -

{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/What_is_JavaScript", "Learn/JavaScript/Первые_шаги/Что_пошло_не_так", "Learn/JavaScript/Первые_шаги")}}

diff --git "a/files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/arrays/index.html" "b/files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/arrays/index.html" deleted file mode 100644 index 7f38ce4a50..0000000000 --- "a/files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/arrays/index.html" +++ /dev/null @@ -1,678 +0,0 @@ ---- -title: Массивы -slug: Learn/JavaScript/Первые_шаги/Arrays -tags: - - JavaScript - - Pop - - Push - - shift - - unshift - - Для начинающих - - Массивы - - Статья -translation_of: Learn/JavaScript/First_steps/Arrays ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/Useful_string_methods", "Learn/JavaScript/Первые_шаги/Создатель_глуых_историй", "Learn/JavaScript/Первые_шаги")}}
- -

В финальной статье этого раздела, мы познакомимся с массивами — лаконичным способом хранения списка элементов под одним именем. Мы поймем, чем они полезны, затем узнаем, как создать массив, получить, добавить и удалить элементы, хранящиеся в массиве.

- - - - - - - - - - - - -
Необходимые навыки:Базовая компьютерная грамотность, базовое понимание HTML и CSS, понимание о том, что такое JavaScript.
Цель:Понять, что такое массивы и как использовать их в JavaScript.
- -

Что такое массив?

- -

Массивы обычно описываются как «объекты, подобные спискам»; они представляют собой в основном отдельные объекты, которые содержат несколько значений, хранящихся в списке. Объекты массива могут храниться в переменных и обрабатываться во многом так же, как и любой другой тип значения, причем разница заключается в том, что мы можем получить доступ к каждому значению внутри списка отдельно и делать супер полезные и эффективные вещи со списком, а также делать то же самое для каждого из значений. Представим, что у нас есть список продуктов и их цены, хранящиеся в массиве, и мы хотим их просмотреть и распечатать на счете-фактуре, общая сумма всех цен и распечатка общей цены внизу.

- -

Если бы у нас не было массивов, мы должны были бы хранить каждый элемент в отдельной переменной, а затем вызывать код, выполняющий печать и добавляющий отдельно каждый элемент. Написание такого кода займет намного больше времени, сам код будет менее эффективным и подверженным  ошибкам. Если бы у нас было 10 элементов для добавления в счет-фактуру, это еще куда ни шло, но как насчет 100 предметов? Или 1000? Мы вернемся к этому примеру позже в статье.

- -

Как и в предыдущих статьях, давайте узнаем о реальных основах массивов, введя некоторые примеры в консоль JavaScript. Мы предоставили один ниже (вы также можете open this console в отдельном окне, или использовать browser developer console, если вам угодно).

- - - -

{{ EmbedLiveSample('Hidden_code', '100%', 300) }}

- -

Создание массива

- -

Массивы создаются из квадратных скобок , которые содержат список элементов, разделённых запятыми.

- -
    -
  1. Допустим, мы бы хотели хранить список покупок в массиве — мы бы сделали что-то вроде этого. Введите следующие строчки в вашу консоль: -
    var shopping = ['bread', 'milk', 'cheese', 'hummus', 'noodles'];
    -shopping;
    -
  2. -
  3. В данном случае, каждый элемент в массиве — это строка , но имейте в виду, что вы можете хранить любой элемент в массиве — строку, число, объект, другую переменную, даже другой массив. Вы также можете перемешивать типы элементов — они не должны все быть числами, строками, и так далее. Попробуйте это: -
    var sequence = [1, 1, 2, 3, 5, 8, 13];
    -var random = ['tree', 795, [0, 1, 2]];
    -
  4. -
  5. Попробуйте сами создать несколько массивов, перед тем как двигаться дальше.
  6. -
- -

Получение и изменение элементов массива

- -

Вы можете после этого получать доступ к отдельным элементам в массиве, используя квадратные скобки, таким же способом каким вы получаете доступ к буквам в строке.

- -
    -
  1. Введите следующее в вашу консоль: -
    shopping[0];
    -// возвращает "bread"
    -
  2. -
  3. Вы также можете изменять элемент в массиве, просто дав отдельному элементу массива новое значение. Попробуйте это: -
    shopping[0] = 'tahini';
    -shopping;
    -// shopping теперь возвратит [ "tahini", "milk", "cheese", "hummus", "noodles" ]
    - -
    Заметка: Мы уже упоминали это прежде, но просто как напоминание — компьютеры начинают считать с нуля!
    -
  4. -
  5. Заметьте, что массив внутри массива называется многомерным массивом. Вы можете получить доступ к элементу внутри массива, который сам находится внутри другого массива, объединив два набора квадратных скобок. Например, для доступа к одному из элементов внутри массива, который является третьим элементом внутри массива random (см. предыдущую секцию данной статьи), мы могли бы сделать что-то вроде этого: -
    random[2][2];
    -
  6. -
  7. Попробуйте внести некоторые дополнительные изменения в свои примеры массивов, прежде чем двигаться дальше.
  8. -
- -

Нахождение длины массива

- -

Вы можете найти длину массива (количество элементов в нём) точно таким же способом, как вы находите длину строки (в символах) — используя свойство {{jsxref("Array.prototype.length","length")}}. Попробуйте следующее:

- -
sequence.length;
-// должно возвратить 7
- -

Это свойство имеет и другие применения, но чаще всего используется, чтобы сказать, что цикл продолжается, пока он не зациклится на всех элементах массива. Так, например:

- -
var sequence = [1, 1, 2, 3, 5, 8, 13];
-for (var i = 0; i < sequence.length; i++) {
-  console.log(sequence[i]);
-}
- -

В будущих статьях вы узнаете о циклах, но вкратце этот код говорит:

- -
    -
  1. Начать цикл с номера позиции 0 в массиве.
  2. -
  3. Остановить цикл на номере элемента, равном длине массива. Это будет работать для массива любой длины, но в этом случае он остановит цикл на элементе номер 7 (это хорошо, поскольку последний элемент, который мы хотим, чтобы цикл был закрыт, равен 6).
  4. -
  5. Для каждого элемента вернуть его значение в консоли браузера с помощью console.log().
  6. -
- -

Некоторые полезные методы массивов

- -

В этом разделе мы рассмотрим некоторые полезные методы, связанные с массивом, которые позволяют нам разбивать строки на элементы массива и наоборот, а также добавлять новые элементы в массивы.

- -

Преобразование между строками и массивами

- -

Часто у Вас могут быть некоторые необработанные данные, содержащиеся в большой длинной строке, и вы можете захотеть разделить полезные пункты до более удобной и полезной формы, а затем сделать что-то для них, например отобразить их в таблице данных. Для этого мы можем использовать метод {{jsxref ("String.prototype.split ()", "split ()")}}. В его простейшей форме он принимает единственный параметр, символ, который вы хотите отделить в строке, и возвращает подстроки между разделителем как элементы в массиве.

- -
-

Заметка: Хорошо, технически это строковый метод, не метод массива, но мы поместили его в массивы, так как он хорошо подходит для них.

-
- -
    -
  1. Поиграем с этим, посмотрим как это работает. Сначала, создадим строку в вашей консоли: -
    var myData = 'Manchester,London,Liverpool,Birmingham,Leeds,Carlisle';
    -
  2. -
  3. Теперь разделим ee посредством запятой: -
    var myArray = myData.split(',');
    -myArray;
    -
  4. -
  5. Наконец, попробуйте найти длину вашего нового массива и извлечь из него некоторые элементы: -
    myArray.length;
    -myArray[0]; // первый элемент в массиве
    -myArray[1]; // второй элемент в массиве
    -myArray[myArray.length-1]; // последний элемент в массиве
    -
  6. -
  7. Вы можете сделать обратное используя метод{{jsxref("Array.prototype.join()","join()")}} . Попробуйте следующее: -
    var myNewString = myArray.join(',');
    -myNewString;
    -
  8. -
  9.  Другой способ преобразования массива в строку - использовать метод {{jsxref("Array.prototype.toString()","toString()")}} . toString() ,возможно, проще,чем join() поскольку он не принимает параметр, но это ограничивает его. С join()вы можете указать разные разделители (попробуйте выполнить шаг 4 с другим символом, кроме запятой). -
    var dogNames = ["Rocket","Flash","Bella","Slugger"];
    -dogNames.toString(); //Rocket,Flash,Bella,Slugger
    -
  10. -
- -

Добавление и удаление элементов массива

- -

Мы еще не рассмотрели добавление и удаление элементов массива - давайте посмотрим на это сейчас. Мы будем использовать массив myArray , с которым мы столкнулись в предыдущем разделе. Если вы еще не прошли этот раздел, сначала создайте массив в консоли:

- -
var myArray = ['Manchester', 'London', 'Liverpool', 'Birmingham', 'Leeds', 'Carlisle'];
- -

Прежде всего, чтобы добавить или удалить элемент с конца массива, мы можем использовать {{jsxref("Array.prototype.push()","push()")}} и {{jsxref("Array.prototype.pop()","pop()")}} соответственно.

- -
    -
  1. Давайте сначала используем метод push() — заметьте, что вам нужно указать один или более элементов, которые вы хотите добавить в конец своего массива. Попробуйте это: - -
    myArray.push('Cardiff');
    -myArray;
    -myArray.push('Bradford', 'Brighton');
    -myArray;
    -
    -
  2. -
  3. При завершении вызова метода возвращается новая длина массива. Если бы вы хотели сохранить новую длину массива в переменной, вы бы могли сделать что-то вроде этого: -
    var newLength = myArray.push('Bristol');
    -myArray;
    -newLength;
    -
  4. -
  5. Удаление последнего элемента массива можно совершить с помощью вызова метода pop(). Попробуйте это: -
    myArray.pop();
    -
  6. -
  7. Когда вызов метода завершается, возвращается удалённый элемент. Вы бы могли также сделать такое: -
    var removedItem = myArray.pop();
    -myArray;
    -removedItem;
    -
  8. -
- -

{{jsxref("Array.prototype.unshift()","unshift()")}} и {{jsxref("Array.prototype.shift()","shift()")}} работают точно таким же способом, за исключением того что они работают в начале массива, а не в конце.

- -
    -
  1. Сначала, попробуем метод unshift(): - -
    myArray.unshift('Edinburgh');
    -myArray;
    -
  2. -
  3. Теперь shift(); попробуйте эти! -
    var removedItem = myArray.shift();
    -myArray;
    -removedItem;
    -
  4. -
- -

Практика: Печать продуктов!

- -

Вернемся к описанному выше примеру - распечатываем названия продуктов и цен на счет-фактуру, затем суммируем цены и печатаем их внизу. В приведенном ниже редактируемом примере есть комментарии, содержащие числа - каждая из этих отметок является местом, где вы должны добавить что-то в код. Они заключаются в следующем:

- -
    -
  1. Ниже комментария // number 1  имеется ряд строк, каждая из которых содержит название продукта и цену, разделенные двоеточием. Нужно превратить их в массив и сохранить его  под названием  products.
  2. -
  3. На строке с комментарием // number 2  начинается цикл for. В строке цикла имеется i <= 0, что является условием , которое заставляет цикл for выполняться только один раз, так как это значение i сообщает циклу: «останавливаться, когда i меньше или равен 0», при этом i начинается с 0. Нужно заменить i <= 0 условным тестом, который останавливает цикл, когда i перестает быть меньше длины массива products .
  4. -
  5. Под комментарием // number 3 мы хотим, чтобы вы написали строку кода, которая разбивает текущий элемент массива (name:price) на два отдельных элемента: один содержит только имя, а другой - содержащее только цену. Если не знаете, как это сделать, еще раз просмотрите статью Полезные строковые методы, а лучше, посмотрите раздел {{anch("Преобразование между строками и массивами")}} этой статьи.
  6. -
  7. В рамках приведенной выше строки нужно преобразовать цену из строки в число. Если не помните, как это сделать, ознакомьтесь со статьей строки в JavaScript.
  8. -
  9. В верхней части кода есть переменная с именем total , которая содержит значение 0. Внутри цикла (под комментарием // number 4) нужно добавить строку, которая добавляет текущую цену товара к этой сумме на каждой итерации цикла, так чтобы в конце кода была выведена корректная сумма в счет-фактуре. Для этого вам может понадобится оператор присваивания.
  10. -
  11. Под комментарием // number 5 нужно изменить строку так, чтобы переменная itemText была равна "current item name — $current item price",  например "Shoes — $23.99" для каждого случая, чтобы корректная информация для каждого элемента была напечатана в счете-фактуре. Здесь обычная конкатенация строк, которая должна быть вам знакома.
  12. -
- - - -

{{ EmbedLiveSample('Playable_code', '100%', 730, "", "", "hide-codepen-jsfiddle") }}

- -

Практика: Топ 5 поисовых запросов

- -

Хорошим тоном, является использование методов массива, таких как {{jsxref ("Array.prototype.push ()", "push ()")}} и {{jsxref ("Array.prototype.pop ()", "pop ()") }} - это когда вы ведете запись активных элементов в веб-приложении. Например, в анимированной сцене может быть массив объектов, представляющих текущую отображаемую фоновую графику и вам может потребоваться только 50 одновременных отображений по причинам производительности или беспорядка. Когда новые объекты создаются и добавляются в массив, более старые могут быть удалены из массива для поддержания нужного числа.

- -

В этом примере мы собираемся показать гораздо более простое использование - ниже мы даем вам поддельный поисковый сайт с полем поиска. Идея заключается в том, что когда в поле поиска вводятся запросы, в списке отображаются 5 предыдущих поисковых запросов. Когда число терминов превышает 5, последний член начинает удаляться каждый раз, когда новый член добавляется в начало, поэтому всегда отображаются 5 предыдущих терминов.

- -
-

Примечание: В реальном приложении для поиска вы, вероятно, сможете щелкнуть предыдущие условия поиска, чтобы вернуться к предыдущим поисковым запросам и отобразите фактические результаты поиска! На данный момент мы просто сохраняем его.

-
- -

Чтобы завершить приложение, вам необходимо:

- -
    -
  1. Добавьте строку под комментарием // number 1, которая добавляет текущее значение, введенное в ввод поиска, к началу массива. Его можно получить с помощью searchInput.value.
  2. -
  3. Добавьте строку под комментарием // number 2, которая удаляет значение, находящееся в конце массива.
  4. -
- - - -

{{ EmbedLiveSample('Playable_code_2', '100%', 700, "", "", "hide-codepen-jsfiddle") }}

- -

Заключение

- -

Прочитав эту статью, мы уверены, что вы согласитесь, что массивы кажутся довольно полезными; вы увидите, что они появляются повсюду в JavaScript, часто в сочетании с циклами, чтобы делать то же самое для каждого элемента массива. Мы научим вас всем полезным основам, которые нужно знать о циклах в следующем модуле, но пока вы должны себе похлопать и воспользоваться заслуженным перерывом; вы проработали все статьи в этом модуле!

- -

Осталось только выполнить тестовую задачу, которая проверит ваше понимание статей, которые Вы прочли до этого момента. Удачи!

- -

Посмотрите также

- - - -

{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/Useful_string_methods", "Learn/JavaScript/Первые_шаги/Создатель_глуых_историй", "Learn/JavaScript/Первые_шаги")}}

- -

В этом разделе

- - diff --git "a/files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/index.html" "b/files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/index.html" deleted file mode 100644 index bd435e920f..0000000000 --- "a/files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/index.html" +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: Первые шаги в JavaScript -slug: Learn/JavaScript/Первые_шаги -tags: - - JavaScript - - Массивы - - Новичкам -translation_of: Learn/JavaScript/First_steps ---- -
{{LearnSidebar}}
- -

В нашем первом модуле, прежде чем перейти к практике написания кода на языке JavaScript, сначала мы дадим ответы на некоторые фундаментальные вопросы, а именно: "Что же такое JavaScript?", "Что он из себя представляет?" и "Что он может делать?". После этого мы внимательно рассмотрим некоторые из ключевых элементов, такие как переменные, строки, числа и массивы.

- -

Предисловие

- -

Вам не нужно иметь никаких предварительных знаний JavaScript чтобы приступить к этому модулю, но у вас должно быть некоторое представление о HTML и CSS. Рекомендуем ознакомиться со следующими материалами, прежде чем начинать знакомство с JavaScript:

- - - -
-

Примечание:  Если Вы работаете на компьютере, планшете или другом устройстве, где нет возможности полноценно работать с файлами, можете использовать такие онлайн сервисы как  JSBin или Thimble, для запуска примеров кода. 

-
- -

Руководства

- -
-
Что такое JavaScript?
-
Добро пожаловать на курс начинающего JavaScript разработчика от MDN! В первой статье мы рассмотрим JavaScript в общем приближении и постараемся ответить на вопросы "Что такое JavaScript?" и "Для чего он предназначен?", и закрепим верное понимание его назначения. 
-
Первое погружение в JavaScript
-
Теперь, когда вы знаете кое-что о JavaScript, и что он может делать, мы предлагаем вам пройти интенсивный практический урок по базовой функциональности JavaScript. Здесь вы, шаг за шагом, создадите простую игру "Угадай число".
-
Что пошло не так? Устранение ошибок JavaScript
-
В процессе создания игры "Угадай число" из предыдущего урока, вы могли заметить что она не работала. Не стоит унывать - данная статья научит вас беречь собственные нервы, а так же, даст несколько советов о том как решать такие проблемы, искать и исправлять неполадки в JavaScript коде.
-
Хранение нужной вам информации - Переменные
-
После прочтения предыдущих статей вы должны знать что из себя представляет JavaScript, что он может, как взаимодействует с другими web технологиями, и каковы его основные особенности в общем приближении. В этой статье спустимся к самым основам языка и поработаем с Переменными.
-
Базовая математика в JavaScript — числа и операторы
-
Здесь мы обсуждаем математику в JavaScript - каким образом мы можем манипулировать числами и операторами для работы с ними.
-
Работа с текстом — строки в JavaScript
-
Теперь мы обратим своё внимание на строки - так называются кусочки текста в программировании. В этой статье мы рассмотрим то что действительно необходимо знать про строки в JavaScript: как создать строку, делать escape (экранирование) символов с помощью кавычек, и объединять их.
-
Полезные строковые методы
-
После того как мы рассмотрели основы работы со строками, давайте двинемся дальше и поговорим о том какие полезные операторы и методы существуют для строк, такие как вычисление длины, соединение и разделение строк, замена отдельных символов и многие другие. 
-
Массивы
-
В последней статье этого модуля мы рассмотрим массивы - изящный способ хранения различных наборов информации в имени всего одной переменной. Здесь мы поговорим о том почему это может быть полезным, рассмотрим как создать массив, получить, добавить или удалить элемент массива, и прочее.
-
- -

Проверка полученных знаний

- -

Предложенное тестовое задание проверит ваше понимание основ JavaScript, которые вы получили пройдя предложенные выше уроки. 

- -
-
Генератор глупых историй
-
Вашим заданием будет применить на практике полученные знания и создать развлекательное приложение которое будет генерировать случайные нелепые истории.
-
diff --git "a/files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/math/index.html" "b/files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/math/index.html" deleted file mode 100644 index 29ff9258bf..0000000000 --- "a/files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/math/index.html" +++ /dev/null @@ -1,423 +0,0 @@ ---- -title: Базовая математика в JavaScript — числа и операторы -slug: Learn/JavaScript/Первые_шаги/Math -tags: - - JavaScript - - Гайд - - Математика - - Начинающий - - Операторы - - Руководство - - Скриптинг - - Статья - - кодинг -translation_of: Learn/JavaScript/First_steps/Math ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/Variables", "Learn/JavaScript/Первые_шаги/Строки", "Learn/JavaScript/Первые_шаги")}}
- -

В этой части курса мы обсуждаем математику в JavaScript — как мы можем использовать {{Glossary("Operator","operators")}} и другие функции, чтобы успешно манипулировать числами для выполнения наших задач.

- - - - - - - - - - - - -
Необходимые условия:Базовая компьютерная грамотность, базовое понимание HTML и CSS, понимание того, что такое JavaScript.
Цель:Ознакомление с основами математики в JavaScript.
- -

Все любят математику

- -

Хорошо, может быть, не все. Некоторые из нас любят математику, некоторые из нас ненавидели математику с тех пор, как мы изучали таблицу умножения в школе, а некоторые из нас находятся где-то между ними. Но никто из нас не может отрицать, что математика является фундаментальной частью жизни, и мы не можем обойтись без нее. Это особенно актуально, когда мы учимся программировать на JavaScript (или на любом другом языке, если на то пошло) — большая часть того, что мы делаем, опирается на обработку числовых данных, вычисление новых значений и т.д. Так что не удивительно, что JavaScript имеет полнофункциональный набор математических функций.

- -

В этой статье обсуждаются только основные разделы, которые вам нужно знать сейчас.

- -

Типы чисел

- -

В программировании даже скромная система десятичных чисел, которую мы все так хорошо знаем, сложнее, чем вы думаете. Мы используем разные термины для описания различных типов десятичных чисел. Например:

- - - -

У нас даже есть разные типы числовых систем:

- - - -

Прежде чем взорвется ваш мозг, остановитесь прямо здесь и сейчас! 

- -

Во-первых, мы просто будем придерживаться десятичных чисел на протяжении всего курса; вы редко когда будете сталкиваться с необходимостью думать в других числовых системах, если вообще когда-либо с ней сталкнетесь.

- -

Во-вторых, в отличие от некоторых других языков программирования, JavaScript имеет только один тип данных для чисел, как вы догадались это {{jsxref("Number")}}. Это означает, независимо от типа чисел, с которыми вы работаете в JavaScript, обрабатывать вы их будете точно так же.

- -

Для меня всё — числа

- -

Давайте быстро поиграем с некоторыми числами, чтобы снова познакомиться с основным синтаксисом, который нам нужен. Введите команды, перечисленные ниже, в вашу консоль (developer tools JavaScript console), или используйте простую встроенную консоль.

- -
    -
  1. Прежде всего, давайте объявим пару переменных и инициализируем их целым числом и числом с плавающей точкой, соответственно, затем введите имена переменных обратно, чтобы проверить, что все в порядке: -
    var myInt = 5;
    -var myFloat = 6.667;
    -myInt;
    -myFloat;
    -
  2. -
  3. Числовые значения набираются без кавычек. Попробуйте объявить и инициализировать еще пару переменных, содержащих числа, прежде чем двигаться дальше.
  4. -
  5. Теперь давайте убедимся, что обе переменные содержат одинаковый тип данных. Для этого есть оператор {{jsxref("Operators/typeof", "typeof")}}, который позволяет проверить какой тип данных содержит в себе переменная. Введите две приведенные ниже строки: -
    typeof myInt;
    -typeof myFloat;
    - В обоих случаях вы должны получить "number" — это все упрощает, чем если бы разные числа имели разные типы данных, и нам приходилось иметь дело с ними по-разному.
  6. -
- -

Арифметические операторы

- -

Арифметические операторы — это основные операторы, которые мы используем для различных математических операций, например таких, как сложение или вычитание:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ОператорИмяФункцияПример
+СложениеОбъединение чисел в одно целое.6 + 9
-ВычитаниеВычитает правое число от левого.20 - 15
*УмножениеУмножает два числа вместе.3 * 7
/ДелениеДелит левое число на правое.10 / 5
%Модуль числа -

Возвращает значение остатка при делении первого числа на второе. Результат будет иметь тот же знак, что и первое число.

-
-

11 % 3 = 2 (поскольку число 3 вмещается три раза, остатком будет число 2)

-
**показатель степениВозводит базовое число в указанную степень, то есть количество базовых чисел, указанных экспонентой, умножается вместе. Впервые он был представлен в EcmaScript 2016.5 ** 5 (возвращает 3125, или как: 5*5*5*5*5)
- -
-

Примечание: Иногда числа участвующие в математических операциях называют операндами ( {{Glossary("Operand", "operands")}} ).

-
- -

Нам, вероятно, не нужно учить вас базовым математическим операциям, но мы хотели бы проверить ваше понимание синтаксиса. Попробуйте ввести приведенные ниже примеры в свою консоль (developer tools JavaScript console), или используйте встроенную консоль, с которой вы уже знакомы, чтобы ознакомиться с синтаксисом.

- -
    -
  1. Для начала попробуйте ввести простые примеры, такие как: -
    10 + 7
    -9 * 8
    -60 % 3
    -
  2. -
  3. Вы также можете попробовать объявить переменные и присвоить им различные числа. Попробуйте вместо чисел использовать ранее объявленные переменные — переменные будут вести себя точно так же, как значения, которые они хранят. Например: -
    var num1 = 10;
    -var num2 = 50;
    -9 * num1;
    -num2 / num1;
    -
  4. -
  5. И напоследок, попробуйте ввести более сложные выражения, например: -
    5 + 10 * 3;
    -num2 % 9 * num1;
    -num2 + num1 / 8 + 2;
    -
  6. -
- -

Некоторые примеры выше могут дать вам не тот результат, которого вы ожидали; приведенный ниже раздел может дать ответ на вопрос о том, почему.

- -

Приоритет операторов

- -

Давайте взглянем на последний пример сверху. Предположим, что num2 содержит значение 50 и num1 содержит значение 10 (как и было обозначено выше):

- -
num2 + num1 / 8 + 2;
- -

Будучи человеком, вы, вероятно, прочитаете это как "50 плюс 10 равно 60", затем "8 плюс 2 равно 10", и, наконец, "60 делить на 10 равно 6".

- -

Но браузер видит это по-другому: "10 делить на 8 равно 1.25", затем "50 плюс 1.25 плюс 2 равно 53.25".

- -

Это происходит из-за приоритета операторов - некоторые операторы будут применены перед другими в процесс вычисления суммы (в программировании ее называют выражением). Приоритет операторов в JavaScript ничем не отличается от приоритета арифметических операций, который вы изучали в школе - умножение и деление всегда выполняются первыми, затем сложение и вычитание (сумма всегда вычисляется слева направо).

- -

Если вы хотите переопределить порядок выполнения операторов, вы можете окружить парными скобками часть выражения, которая должна быть выполнена первой. Для получения результата 6 вам следует сделать следующее:

- -
(num2 + num1) / (8 + 2);
- -

Результат этого выражения равен 6.

- -
-

Заметка: полный список операторов JavaScript и приоритетов их выполнения можно найти по этой ссылке: Expressions and operators.

-
- -

Операторы инкремента и декремента

- -

Иногда вам захочется повторно добавить или вычесть единцу к/из значению числовой переменной. Это можно сделать с помощью оператора инкремента (++) и декремента (--). Мы использовали ++ в нашей игре "Угадай число" в статье первое погружение в JavaScript, где мы добавляли 1 к переменной guessCount, в которой хранилось значение количества попыток пользователя после каждого хода.

- -
guessCount++;
- -
-

Замечание: инкремент и декремент часто используются в циклах, о которых вы узнаете позже. Например, если вы захотите пройтись по списку цен и добавить к каждой налог с продаж, вам придется в цикле обойти каждую цену и провести необходимые вычисления для учета налога. Инкремент будет использован для перехода на новую ячейку списка при необходимости. У нас есть несложный пример реализации такого списка - попробуйте и взгляните на код чтобы посмотреть, сможете ли вы найти инкременты! Мы взглянем на циклы поближе позже по ходу курса.

-
- -

Давайте попробуем сыграть с этим в вашей консоли. Для начала заметим, что вы не можете использовать инкремент/декремент непосредсвенно к числу, что может показаться странным. Дело в том, что мы присваиваем к переменной новое обновленное число, а не просто вычисляем значение. Следующий пример приведет к ошибке:

- -
3++;
- -

Таким образом, вы можете применить инкремент только к существующим переменным:

- -
var num1 = 4;
-num1++;
- -

Так, вторая странность! Если вы сделаете это, вы получите значение 4 - бразуер возвращает текущее число, после чего применяет к нему оператор инкремента. Вы можете удостовериться в том, что инкремент был применен, узнав значение переменной еще раз:

- -
num1;
- -

То же самое для --: попробуйте пример ниже

- -
var num2 = 6;
-num2--;
-num2;
- -
-

Замечание: вы можете заставить делать это в другом порядке - применить инкремент/декремент и только потом вернуть значение. Для этого необходимо записать оператор слева от переменной, а не справа. Попробуйте пример сверху еще раз, но в этот раз используйте ++num1 и --num2

-
- -

Операторы присваивания

- -

Операторы присваивания - операторы, которые присваивают значение переменным. Мы уже много раз использовали самый простой из них, =, он просто приравнивает значение переменной слева к значению справа:

- -
var x = 3; // x содержит значение 3
-var y = 4; // y содержит значение 4
-x = y; // x теперь содержит значение y (x == 4)
- -

Однако есть еще несколько сложных конструкций, которые позволяют делать ваш код более простым и аккуратным. Наиболее часто используемые перечислены ниже:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OperatorNamePurposeExampleShortcut for
+=Присваивание сложенияПрибавляет значение справа к переменной слева и возвращает новое значение переменнойx = 3;
- x += 4;
x = 3;
- x = x + 4;
-=Присваивание вычитанияВычитает значение справа из переменной слева и возвращает новое зачение переменнойx = 6;
- x -= 3;
x = 6;
- x = x - 3;
*= -

Присваивание умножения

-
Умножает переменную слева на значение справа и возвращает новое зачение переменнойx = 2;
- x *= 3;
x = 2;
- x = x * 3;
/=Присваивание деленияДелит переменную слева на значение справа и возвращает новое зачение переменнойx = 10;
- x /= 5;
x = 10;
- x = x / 5;
- -

Попробуйте использовать такие конструкции, что понять, как они работают. Сможете ли вы определить значение до того, как напишите вторую строку?

- -

Замьтете, что значение справа может быть как числом (константой), так и переменной, например:

- -
var x = 3; // x содержит значение 3
-var y = 4; // y содержит значение 4
-x *= y; // x содержит значение 12
- -
-

Заметка: есть еще другие операторы присваивания, в этой статье перечислены только самые базовые.

-
- -

Активное обучение: меняем размеры коробки

- -

В этом упражнении вы будете пользоваться числами и операторами для работы с размерами коробки. Коробка рисуется с помощью API браузера, которое назывется Canvas API. Вам не следует беспокоиться о том, как это работает - просто сосредоточьтесь на математике. Ширина и высота коробки (в пикселях) определяются переменными x и y, которые изначально равны 50.

- -

{{EmbedGHLiveSample("learning-area/javascript/introduction-to-js-1/maths/editable_canvas.html", '100%', 520)}}

- -

Открыть в новом окне

- -

В коде сверху, который вы можете изменять, под комментарием есть две строчки, с помощью которых вы можете увеличивать/уменьшать размеры коробки. Мы хотим, чтобы вы выполнили несколько заданий:

- - - -

Не расстраивайтесть, если вы не поняли код сверху. Нажмите кнопку Reset для запуска программы снова. Если вы смогли ответить верно на все вопросы, попробуйте поэкспериментировать с кодом еще (или, например, предложить друзьям несколько заданий).

- -

Операторы сравнения

- -

Иногда нам может понадобиться проверить какое-либо условие, а затем поступить в зависимости от результата - для этого мы используем операторы сравнения.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ОператорИмяНазначениеПример
===Строгое равенствоПроверяет левое и правое значения на идентичность5 === 2 + 4
!==Строгое неравенствоПроверяет левое и правое значения на неидентичность5 !== 2 + 3
<МеньшеПроверяет, меньше ли левое значение правого10 < 6
>БольшеПроверяет, больше ли левое значение правого10 > 20
<=Меньше или равноПроверят, меньше ли левое значение правому (или равно ему)3 <= 2
>=Больше или равноПроверят, больше ли левое значение левого (или равно ему)5 >= 4
- -
-

Заметка: вы можете заметить, что некоторые люди используют == и != в их программах для сравнения на равенство и неравенство — это валидные JavaScript-операторы, но они отличаются от ===/!== — первая пара проверяет на равенство/неравенство значений, не рассматривая их типы. Вторая пара - строгая версия первой, которая проверяет типы операндов. При использовании строгой версии выявляется больше ошибок, поэтому мы рекомендуем использовать именно ее.

-
- -

Если вы попробуете использовать эти операторы в консоли, вы увидите, что все они возвращают значения true/false — о типе данных boolean мы писали в прошлой статье. С их помощью мы можем принимать решения в нашей программе, например:

- - - -

Мы взглянем на то, как реализовать такую логику после знакомства с условными выражениями в следующей статье. Сейчас мы рассмотрим небольшой пример:

- -
<button>Запустить машину</button>
-<p>Машина остановлена</p>
-
- -
var btn = document.querySelector('button');
-var txt = document.querySelector('p');
-
-btn.addEventListener('click', updateBtn);
-
-function updateBtn() {
-  if (btn.textContent === 'Start machine') {
-    btn.textContent = 'Stop machine';
-    txt.textContent = 'The machine has started!';
-  } else {
-    btn.textContent = 'Start machine';
-    txt.textContent = 'The machine id stopped.';
-  }
-}
- -

{{EmbedGHLiveSample("learning-area/javascript/introduction-to-js-1/maths/conditional.html", '100%', 100)}}

- -

Открыть в новом окне

- -

Мы использовали оператор равенства внутри функции updateBtn(). В этом случае мы не проверяем пару математических выражений на равенcтво значений — мы просто смотрим, является ли текст на кнопке определенной строкой — что по сути является тем же самым. Если кнопка при нажатии содержит "Start machine", мы меняем содержимое метки на "Stop machine" и обновляем метку. Если же текст кнопки — "Stop machine", при нажатии мы возвращем все обратно. 

- -
-

Заметка: Такой элемент управления, который переключается между двумя состояниями, обычно называется тумблером. Он переключается между одним состоянием и другим: свет включен, свет выключен и т. д.

-
- -

Итого

- -

В этой статье мы привели основную информацию, необходимую для работы с числами в JavaScript. Вы постоянно будете использовать числа в процессе обучения языку, поэтому желательно разобраться в этом сейчас. Если вам действительно не нравится математика, пусть вас утешит, что эта статья была сравнительно короткой.

- -

В следующей статье мы изучим текст и то, как мы работаем с ним в JavaScript.

- -
-

Примечание: если вам хочется узнать подробнее о том, как математика реализуется в JavaScript, вы можете посмотерть главный раздел JavaScript MDN. Статьи Числа и даты и Выражения и операторы - хороший вариант для начала.

-
- -

{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/Variables", "Learn/JavaScript/Первые_шаги/Строки", "Learn/JavaScript/Первые_шаги")}}

diff --git "a/files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/useful_string_methods/index.html" "b/files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/useful_string_methods/index.html" deleted file mode 100644 index 1318ee39ac..0000000000 --- "a/files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/useful_string_methods/index.html" +++ /dev/null @@ -1,723 +0,0 @@ ---- -title: Полезные строковые методы -slug: Learn/JavaScript/Первые_шаги/Useful_string_methods -tags: - - Beginner - - CodingScripting - - JavaScript - - Learn - - length - - lower - - replace - - split - - upper - - Обучение - - Регистр -translation_of: Learn/JavaScript/First_steps/Useful_string_methods ---- -

{{LearnSidebar}}

- -

{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/Строки", "Learn/JavaScript/Первые_шаги/Arrays", "Learn/JavaScript/Первые_шаги")}}

- -

Мы рассмотрели базовые понятия, касающиеся строк. Давайте пойдем дальше и рассмотрим, какие полезные операции мы можем выполнять со строками, используя встроенные функции, такие как поиск длины текстовой строки, объединение и разделение строк, замена одного символа из строки другим и многое другое.

- - - - - - - - - - - - -
Необходимые знания:Базовая компьютерная грамотность, базовое понимание HTML и CSS, понимание того, что такое JavaScript.
Задача:Понять, что строки являются объектами, и изучить, как использовать некоторые из основных методов, доступных для этих объектов для управления строками.
- -

Строки как объекты

- -

Почти всё в JavaScript является объектами. Когда вы создаете строку, например: 

- -
let string = 'This is my string';
- -

ваша переменная становится строковым объектом, и, как результат, ей доступно множество свойств и методов. Можете убедиться в этом, перейдя на страницу {{jsxref ("String")}} и просмотрев на ней список свойств и методов!

- -

Только не волнуйтесь! Большинство из них вам не нужно знать сейчас на ранней стадии вашего обучения. Но некоторые из них вы, возможно, будете использовать довольно часто. Их мы и рассмотрим.

- -

Приведем несколько примеров в новой консоли. Ниже вы можете открыть данную консоль в отдельной вкладке или окне, или, если вам так удобней, использовать браузер консоли разработчика.

- - - -

{{ EmbedLiveSample('Hidden_code', '100%', 300, "", "", "hide-codepen-jsfiddle") }}

- -

Поиск длины строки

- -

Это легко — вы просто используете свойство {{jsxref ("String.prototype.length", "length")}}. Попробуйте ввести следующие строки:

- -
let browserType = 'mozilla';
-browserType.length;
- -

Результатом должно быть число 7, потому что слово «mozilla» состоит из 7 символов. Это свойство можно применить, например, если вы захотите найти длины серии имен, чтобы их можно было отображать по порядку длины или сообщить пользователю, что имя пользователя, которое он ввёл в поле формы, слишком длинное, если оно превышает определённую длину.

- -

Получение определенного строкового символа

- -

Вы можете вернуть любой символ внутри строки, используя обозначение в квадратных скобках. Это означает, что вы добавляете квадратные скобки ([ ]) в конце вашего имени переменной. В квадратных скобках вы указываете номер символа, который хотите вернуть. Например, чтобы получить первую букву, нужно написать:

- -
browserType[0];
- -

Компьютеры считают от 0, а не 1! Чтобы получить последний символ любой строки, мы могли бы использовать следующую строку, объединив эту технику с свойством length:

- -
 browserType[browserType.length-1];
- -

Длина слова «mozilla» равна 7, но, поскольку счет начинается с 0, позиция последнего символа равна 6, поэтому нам нужна length-1. Такой способ можно использовать, чтобы найти первую букву ряда строк и упорядочить их по алфавиту.

- -

Поиск подстроки внутри строки и ее извлечение

- -
    -
  1. Иногда вам может понадобиться выяснить, присутствует ли меньшая строка внутри большей (обычно мы говорим, что внутри строки есть подстрока). Это можно сделать с помощью метода {{jsxref ("String.prototype.indexOf ()", "indexOf ()")}}, который принимает одну {{glossary ("parameter")}} - подстроку, которую вы хотите найти. Введите: -
    browserType.indexOf('zilla');
    - Это дает нам результат 2, потому что подстрока «zilla» начинается в позиции 2 ("m" — 0, "o" — 1, "z" — 2) внутри «mozilla». Такой код можно использовать для фильтрации строк. Например, если есть список веб-адресов и вы хотите распечатать только те, которые содержат «mozilla».
  2. -
- -
    -
  1. Это можно сделать по-другому, что, возможно, ещё более эффективно. Введите следующее: -
    browserType.indexOf('vanilla');
    - Это должно дать вам результат -1. Такое значение возвращается, когда подстрока, в данном случае «vanilla», не найдена в основной строке.
    -
    - Вы можете использовать это, чтобы найти все экземпляры строк, которые не содержат подстроку «mozilla» (для обратного эффекта, используйте оператор отрицания): -
    if(browserType.indexOf('mozilla') === -1) {
    -  // сделать что-то, если 'mozilla'
    -  // не является частью этой строки
    -}
    -
    -if(browserType.indexOf('mozilla') !== -1) {
    -  // сделать что-то, если 'mozilla'
    -  // является частью этой строки
    -}
    -
  2. -
  3. Когда вы знаете, где подстрока начинается внутри строки, и вы знаете, на каком символе вы хотите её завершить, можно использовать {{jsxref ("String.prototype.slice ()", "slice ()")}}  для извлечения. Попробуйте следующее: -
    browserType.slice(0,3);
    - Это возвращает «moz». Первым параметром является позиция символа, с которого начинается извлечение, а второй параметр — позиция последнего символа, перед которым нужно отсечь строку. Таким образом, срез происходит с первой позиции, вплоть до последней позиции, но не включая её (помним, что счет идёт с 0, а не с 1). Также можно сказать, что второй параметр равен длине возвращаемой строки.
  4. -
  5. Кроме того, если вы знаете, что хотите извлечь все остальные символы в строке после определённого символа, вам не нужно включать второй параметр. Достаточно включить только положение символа, с которого вы хотите начать извлечение оставшихся символов в строке. Введите: -
    browserType.slice(2);
    - Этот код возвращает «zilla» — это потому, что позиция символа 2 — это буква z, и поскольку вы не указали второй параметр, возвращаемая подстрока состояла из всех остальных символов в строке.
  6. -
- -
-

Примечание: второй параметр slice() не обязателен: если вы его не включите в код, обрезание закончится на конце оригинальной строки. Есть и другие варианты; изучите страницу {{jsxref ("String.prototype.slice ()", "slice ()")}}, чтобы узнать, что ещё вы можете узнать.

-
- -

Изменение регистра

- -

Строковые методы {{jsxref ("String.prototype.toLowerCase ()", "toLowerCase ()")}} и {{jsxref ("String.prototype.toUpperCase ()", "toUpperCase ()")}} преобразовывают все символы в строке в нижний или верхний регистр соответственно. Этот способ можно применить, если вы хотите нормализовать все введенные пользователем данные перед их сохранением в базе данных.

- -

Попробуем ввести следующие строки, чтобы узнать, что происходит:

- -
var radData = 'My NaMe Is MuD';
-radData.toLowerCase();
-radData.toUpperCase();
- -

Обновление частей строки

- -

Вы можете заменить одну подстроку внутри строки на другую подстроку, используя метод {{jsxref ("String.prototype.replace ()", "replace ()")}}. Этот метод работает очень просто на базовом уровне, но у него есть некоторые продвинутые свойства, но мы пока не будем вдаваться в детали.

- -

Он принимает два параметра — строку, которую вы хотите заменить, и строку, которую вы хотите вставить вместо заменяемой. Попробуйте этот пример:

- -
browserType.replace('moz','van');
- -

Обратите внимание, что для фактического получения обновленного значения, отраженного в переменной browserType в реальной программе, вам нужно будет установить значение переменной в результате операции; он не просто обновляет значение подстроки автоматически. Таким образом, вы должны были бы написать это: browserType = browserType.replace('moz','van');

- -

Активные примеры обучения

- -

В этом разделе мы дадим вам попробовать набить руку и вместе напишем код строковой манипуляции. В каждом упражнении ниже у нас есть массив строк и цикл, который обрабатывает каждое значение в массиве и отображает его в маркированном списке. Вам не нужно понимать массивы или циклы прямо сейчас — это будет объяснено в будущих статьях. Все, что вам нужно сделать в каждом случае, — написать код, который выводит строки в том формате, в котором мы предлагаем.

- -

В каждом примере есть кнопка Сбросить, которую вы можете использовать для сброса кода, если вы допустили ошибку и не можете заставить его работать снова, а кнопку Показать решение вы можете нажать, чтобы увидеть потенциальный ответ, если вы действительно застрянете на решении.

- -

Фильтрация приветственных сообщений

- -

В первом упражнении мы начнем с простого: у нас есть множество сообщений поздравительных открыток, но мы хотим отсортировать их, чтобы перечислять только рождественские сообщения. Мы хотим, чтобы вы заполнили условный тест внутри структуры if( ... ), чтобы проверить каждую строку и отобразить её в списке, только если это рождественское сообщение.

- -
    -
  1. Сначала подумайте о том, как вы можете проверить, является ли сообщение в каждом случае рождественским сообщением. Какая строка присутствует во всех этих сообщениях и какой метод вы можете использовать для проверки?
  2. -
  3. Затем вам нужно будет написать условный тест операнд1 оператор операнд2. Соответствует ли результат слева результату справа? Или в этом случае вызов метода слева возвращает результат справа?
  4. -
  5. Подсказка. В этом случае, вероятно, полезнее проверить, не является ли часть строки не равной (!==) определенному результату.
  6. -
- - - -

{{ EmbedLiveSample('Playable_code', '100%', 590, "", "", "hide-codepen-jsfiddle") }}

- -

Исправление регистра (размера букв в тексте—прим. пер.)

- -

В этом упражнении у нас есть названия городов в Великобритании, но написанных разным регистром. Мы хотим, чтобы вы изменили их так, чтобы они были в нижнем регистре, за исключением первой буквы. Хороший способ сделать это:

- -
    -
  1. Преобразуйте всю строку, содержащуюся в переменной input, в нижний регистр и сохраните ее в новой переменной.
  2. -
  3. Возьмите первую букву строки в этой новой переменной и сохраните ее в другой переменной.
  4. -
  5. Используя эту последнюю переменную в качестве подстроки, замените первую букву строчной строки первой буквой строчной строки, измененной на верхний регистр. Сохраните результат этой процедуры замены в другой новой переменной.
  6. -
  7. Измените значение переменной result на равную конечному результату (не input).
  8. -
- -
-

Примечание: Подсказка — параметры строковых методов не обязательно должны быть строковыми литералами; они также могут быть переменными или даже переменными с вызываемым ими методом.

-
- - - -

{{ EmbedLiveSample('Playable_code_2', '100%', 550, "", "", "hide-codepen-jsfiddle") }}

- -

Создание новых строк из старых частей

- -

В этом последнем упражнении массив содержит кучу строк, содержащих информацию о железнодорожных станциях на севере Англии. Строки представляют собой элементы данных, которые содержат трехбуквенный код станции, за которым следуют некоторые машиночитаемые данные, за которыми следует точка с запятой, а затем название станции, пригодное для чтения человеком. Например:

- -
MAN675847583748sjt567654;Manchester Piccadilly
- -

Мы хотим извлечь код станции и имя и поместить их в строку со следующей структурой:

- -
MAN: Manchester Piccadilly
- -

Мы бы рекоменовали реализовать это следующим образом:

- -
    -
  1. Извлеките трехбуквенный код станции и сохраните его в новой переменной.
  2. -
  3. Найдите номер символьного номера точки с запятой.
  4. -
  5. Извлеките название для чтения человеком, используя номер индекса точки с запятой в качестве контрольной точки и сохраните его в новой переменной.
  6. -
  7. Объедините две новые переменные и строковый литерал, чтобы сделать финальную строку.
  8. -
  9. Измените значение переменной result равной конечной строке (не input). 
  10. -
- - - -

{{ EmbedLiveSample('Playable_code_3', '100%', 585, "", "", "hide-codepen-jsfiddle") }}

- -

Заключение

- -

Нельзя не согласиться с тем, что способность обрабатывать слова и предложения в программировании очень важна — особенно в JavaScript, поскольку веб-сайты — все связаны с людьми. Эта статья дала вам основы, которые вам нужно знать о манипуляции строками на данный момент. Это пойдет вам на пользу, когда вы займётесь более сложными темами в будущем. Далее мы рассмотрим последний важный тип данных, на который нам нужно сосредоточиться в краткосрочной перспективе — массивы.

- -

{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/Строки", "Learn/JavaScript/Первые_шаги/Arrays", "Learn/JavaScript/Первые_шаги")}}

- -

В этом модуле

- - diff --git "a/files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/variables/index.html" "b/files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/variables/index.html" deleted file mode 100644 index e1195effd5..0000000000 --- "a/files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/variables/index.html" +++ /dev/null @@ -1,372 +0,0 @@ ---- -title: Переменные - место хранения необходимой информации -slug: Learn/JavaScript/Первые_шаги/Variables -translation_of: Learn/JavaScript/First_steps/Variables ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/Что_пошло_не_так", "Learn/JavaScript/Первые_шаги/Math", "Learn/JavaScript/Первые_шаги")}}
- -

После прочтения последних двух статей вы знаете, что такое JavaScript, что он может сделать для вас, как использовать его вместе с другими веб-технологиями и какими он обладает функциями высокого уровня. В этой статье мы перейдем к реальным основам, рассмотрим, как работать с большинством базовых блоков JavaScript — Переменными.

- - - - - - - - - - - - -
Необходимые навыки:Базовая компьютерная грамотность, базовое понимание HTML и CSS, понимание того, что такое JavaScript.
Цель:Ознакомиться с основами переменных в JavaScript.
- -

Инструменты, которые вам нужны

- -

В этой статье вам будет предложено ввести строки кода, чтобы проверить ваше понимание материала. Если вы используете браузер для настольных компьютеров, лучшим примером для ввода кода примера является консоль JavaScript вашего браузера (см. What are browser developer tools для получения дополнительной информации о том, как получить доступ к этому инструменту).

- -

Также мы предоставили простую консоль JavaScript, встроенную ниже в странице, для ввода кода, если вы не используете браузер с консолью JavaScript или консоль на странице окажется для вас более комфортной.

- -

Что такое переменные?

- -

Переменные — это контейнер для таких значений, как числа, используемые в сложении, или строка, которую мы могли бы использовать как часть предложения. Но одна из особенностей переменных — их значение может меняться. Давайте взглянем на простой пример:

- -
<button>Нажми на меня</button>
- -
const button = document.querySelector('button');
-
-button.onclick = function() {
-  let name = prompt('Как Вас зовут?');
-  alert('Привет ' + name + ', рады видеть Вас!');
-}
- -

{{ EmbedLiveSample('What_is_a_variable', '100%', 50, "", "", "hide-codepen-jsfiddle") }}

- -

В примере, по нажатию кнопки выполнится несколько строк кода. Первая строка в функции покажет пользователю окно, где попросит ввести его имя и сохранит значение в переменной. Вторая строка отобразит приветствие с включенным введенным именем, взятым из значения переменной.

- -

Чтобы лучше понять действие переменной здесь, давайте подумаем о том, как мы будем писать этот пример без использования переменной. Это будет выглядеть примерно так:

- -
var name = prompt('Как вас зовут?');
-
-if (name === 'Адам') {
-  alert('Привет, Адам, рады тебя видеть!');
-} else if (name === 'Алан') {
-  alert('Привет, Алан, рады тебя видеть!');
-} else if (name === 'Бэлла') {
-  alert('Привет, Бэлла, рады тебя видеть!');
-} else if (name === 'Бьянка') {
-  alert('Привет, Бьянка, рады тебя видеть!');
-} else if (name === 'Крис') {
-  alert('Привет, Крис, рады тебя видеть!');
-}
-
-// ... и так далее ...
- -

Вам сейчас не обязательно понимать синтаксис, который мы используем (пока!), но вы должны понять идею: если бы у нас не было доступных переменных, нам пришлось бы реализовать гигантский блок кода, который проверял, какое имя было введено, а затем отображал соответствующее сообщение для этого имени. Очевидно, что это неэффективно (код намного больше, даже для четырех вариантов), и он просто не сработает, так как вы не можете хранить все возможные варианты.

- -

Переменные имеют смысл, и, когда вы узнаете больше о JavaScript, они начнут становиться второй натурой.

- -

Еще одна особенность переменных заключается в том, что они могут содержать практически все, а не только строки и числа. Переменные могут также содержать сложные данные и даже целые функции. Об этом вы узнаете больше при дальнейшем изучении курса..

- -

Заметьте: мы говорим, что переменные содержат значения. Это важное различие. Переменные не являются самими значениями; они представляют собой контейнеры для значений. Представьте, что они похожи на маленькие картонные коробки, в которых вы можете хранить вещи.

- -

- -

Объявление переменной

- -

Чтобы использовать переменную, вы сначала должны ее создать, или, если быть точнее, объявить переменную. Чтобы сделать это, мы вводим ключевое слово var, за которым следует имя, которое вы хотите дать своей переменной:

- -
var myName;
-var myAge;
- -

Здесь мы создаем две переменные myName и myAge. Попробуйте ввести эти строки сейчас в консоли вашего веб-браузера или в консоли ниже (можно открыть эту консоль в отдельной вкладке или в новом окне). После этого попробуйте создать переменную (или две) с вашими именами.

- - - -

{{ EmbedLiveSample('Hidden_code', '100%', 300) }}

- -
-

Заметка: в JavaScript все инструкции кода должны заканчиваться точкой с запятой (;) - ваш код может работать правильно для отдельных строк, но, вероятно, не будет, когда вы пишете несколько строк кода вместе. Попытайтесь превратить написание точки с запятой в привычку.

-
- -

Теперь проверим, существуют ли эти значения в среде выполненияв Для этого введем только имя переменной.

- -
myName;
-myAge;
- -

В настоящее время они не содержат значения, это пустые контейнеры. В этом случае, когда вы вводите имена переменных, вы должны получить значение  undefined . Если они не существуют, вы получите сообщение об ошибке - попробуйте сейчас ввести в консоли имя переменной ниже:

- -
scoobyDoo;
- -
-

Заметка: Не путайте переменную, которая существует, но не имеет значения, с переменной, которая вообще не существует - это разные вещи.

-
- -

Присвоение значения переменной

- -

Как только переменная объявлена, ей можно присвоить значение. Для этого пишется имя переменной, затем следует знак равенства (=), а за ним значение, которое вы хотите присвоить. Например:

- -
myName = 'Chris';
-myAge = 37;
- -

Попробуйте вернуться в консоль и ввести эти строки. Вы должны увидеть значение, которое вы назначили переменной, возвращаемой в консоли. Чтобы посмотреть значения переменных, нужно набрать их имя в консоли:

- -
myName;
-myAge;
- -

Вы можете объявить переменную и задать ей значение одновременно:

- -
var myName = 'Chris';
- -

Скорее всего, так вы будете писать большую часть времени, так как запись и выполнения кода с одно строки происходит быстрее, чем выполнение двух действий на двух отдельных строках.

- -
-

Заметка: Если вы пишете многострочную программу JavaScript, которая объявляет и инициализирует (задает значение) переменную, вы можете объявить ее после ее инициализации, и она все равно будет работать. Это связано с тем, что объявления переменных обычно выполняются первыми, прежде чем остальная часть кода будет выполнена. Это называется hoisting - прочитайте var hoisting для более подробной информации по этому вопросу.

-
- -

Обновление переменной

- -

Когда переменной присваивается значение, вы можете изменить (обновить) это значение, просто указав другое значение. Попробуйте ввести следующие строки в консоль:

- -
myName = 'Bob';
-myAge = 40;
- -

Правила именования переменных

- -

Вы можете назвать переменную как угодно, но есть ограничения. Как правило, вы должны придерживаться только латинских символов (0-9, a-z, A-Z) и символа подчеркивания.

- - - -
-

Заметка: По ссылке можно найти довольно полный список зарезервированных ключевых слов: Lexical grammar — keywords.

-
- -

Примеры хороших имен переменных:

- -
age
-myAge
-init
-initialColor
-finalOutputValue
-audio1
-audio2
-
- -

Примеры плохих имен переменных:

- -
1
-a
-_12
-myage
-MYAGE
-var
-Document
-skjfndskjfnbdskjfb
-thisisareallylongstupidvariablenameman
- -

Примеры имен переменных, которые вызовут ошибки:

- -
var
-Document
-
- -

Попытайтесь создать еще несколько переменных прямо сейчас, используя знания, изложенные выше.

- -

Типы переменных

- -

Есть несколько различных типов данных, которые мы можем хранить в переменных. В этом разделе мы кратко опишем их, а затем в будущих статьях вы узнаете о них более подробно.

- -

Числа (Numbers)

- -

Вы можете хранить числа в переменных (целые числа, такие как 30, или десятичные числа, такие как 2.456, также называемые числами с плавающей точкой или с плавающей запятой). Вам не нужно объявлять типы переменных в JavaScript, в отличие от некоторых других языков программирования Если давать переменной значение числа,кавычки не используются:

- -
var myAge = 17;
- -

Строки ('Strings')

- -

Строки - это фрагменты текста. Когда вы даете переменной значение строки, вам нужно обернуть ее в одиночные или двойные кавычки, в противном случае JavaScript попытается проиндексировать ее как другое имя переменной.

- -
var dolphinGoodbye = 'So long and thanks for all the fish';
- -

Логические (Booleans)

- -

Booleans - истинные / ложные значения - они могут иметь два значения: true или false. Они обычно используются для проверки состояния, после чего код запускается соответствующим образом. Вот простой пример:

- -
var iAmAlive = true;
- -

В действительности вы чаще будете использовать этот тип переменных так:

- -
var test = 6 < 3;
-
- -

Здесь используется оператор «меньше» (<), чтобы проверить, является ли 6 меньше 3. В данном примере, он вернет false, потому что 6 не меньше 3! В дальнейшем вы узнаете больше о таких операторах.

- -

Массивы (Arrays)

- -

Массив - это один объект, который содержит несколько значений, заключенных в квадратные скобки и разделенных запятыми. Попробуйте ввести следующие строки в консоль:

- -
var myNameArray = ['Chris', 'Bob', 'Jim'];
-var myNumberArray = [10,15,40];
- -

Как только эти массивы определены, можно получить доступ к каждому значению по их местоположению в массиве. Наберите следующие строки:

- -
myNameArray[0]; // should return 'Chris'
-myNumberArray[2]; // should return 40
- -

Квадратные скобки указывают значение индекса, соответствующее позиции возвращаемого значения. Возможно, вы заметили, что массивы в JavaScript индексируются с нулевой отметкой: первый элемент имеет индекс 0.

- -

В следующей статье вы узнаете больше о массивах.

- -

Объекты (Objects)

- -

В программировании объект представляет собой структуру кода, который моделирует объект реальной жизни. У вас может быть простой объект, представляющий автостоянку, и содержит информацию о её ширине и длине; или вы можете иметь объект, который представляет человека, и содержит данные о его имени, росте, весе, на каком языке он говорит, как сказать ему привет и многое другое.

- -

Попробуйте ввести следующую строку в консоль:

- -
var dog = { name : 'Spot', breed : 'Dalmatian' };
- -

Чтобы получить информацию, хранящуюся в объекте, вы можете использовать следующий синтаксис:

- -
dog.name
- -

Мы больше не будем рассматривать объекты в данном курсе - вы можете больше узнать о них в будущем модуле.

- -

Свободная типизация

- -

JavaScript - это «свободно типизируемый язык», что означает, что в отличие от некоторых других языков вам не нужно указывать, какой тип данных будет содержать переменная (например, числа, строки, массивы и т. д.).

- -

Например, если вы объявите переменную и присвоите ей значение, заключенное в кавычки, браузер будет обрабатывать переменную как строку:

- -
var myString = 'Привет';
- -

Он все равно будет строкой, даже если он содержит числа, поэтому будьте осторожны:

- -
var myNumber = '500'; // упс, это все еще строка (string)
-typeof(myNumber);
-myNumber = 500; // так-то лучше, теперь это число (number)
-typeof(myNumber);
- -

Попробуйте ввести четыре строки выше в консоль одну за другой и посмотреть результаты. Вы заметите, что мы используем специальную функцию typeof()  - она возвращает тип данных переменной, которую вы передаете в нее. В первый раз, когда она вызывается, она должа возвращать строку, так как переменная myNumber содержит строку '500'. Посмотрите, что она вернет во второй раз, когда вы ее вызовите.

- -

Подведение итогов

- -

К настоящему времени вы должны знать достаточно о переменных JavaScript и о том, как их создавать. В следующей статье мы остановимся на числах более подробно, рассмотрев, как сделать базовую математику в JavaScript.

- -

{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/Что_пошло_не_так", "Learn/JavaScript/Первые_шаги/Math", "Learn/JavaScript/Первые_шаги")}}

diff --git "a/files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/what_is_javascript/index.html" "b/files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/what_is_javascript/index.html" deleted file mode 100644 index f34dac6902..0000000000 --- "a/files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/what_is_javascript/index.html" +++ /dev/null @@ -1,339 +0,0 @@ ---- -title: Что такое JavaScript? -slug: Learn/JavaScript/Первые_шаги/What_is_JavaScript -translation_of: Learn/JavaScript/First_steps/What_is_JavaScript ---- -
{{LearnSidebar}}
- -
{{NextMenu("Learn/JavaScript/Первые_шаги/A_first_splash", "Learn/JavaScript/Первые_шаги")}}
- -

Добро пожаловать на курс MDN JavaScript для начинающих! В первой статье курса мы дадим базовое определение JavaScript, ответим на вопросы «Что такое JavaScript?» и «Что он делает?», узнаем как работает JavaScript и как добавить его на веб-страницу.

- - - - - - - - - - - - -
Необходимые навыки:Базовая компьютерная грамотность, знание основ HTML и CSS.
Цели:Знакомство с JavaScript и его возможностями, способами его подключения к веб-странице.
- -

Определение высокого уровня

- -

JavaScript это язык, который позволяет Вам применять сложные вещи на web странице — каждый раз, когда на web странице происходит что-то большее, чем просто её статичное отображение — отображение периодически обновляемого контента, или интерактивных карт, или анимация 2D/3D графики, или прокрутка видео в проигрывателе, и т.д. — можете быть уверены, что скорее всего, не обошлось без JavaScript. Это третий слой слоёного пирога стандартных web технологий, два из которых (HTML и CSS) мы детально раскрыли в других частях учебного пособия.

- -

- - - -

Три слоя прекрасно выстраиваются друг над другом. Возьмем простой текст для примера. Для придания структуры и смыслового назначения тексту, разметим его с помощью HTML:

- -
<p>Player 1: Chris</p>
- -

- -

Затем мы добавим немного CSS, что бы это выглядело симпатичнее:

- -
p {
-  font-family: 'helvetica neue', helvetica, sans-serif;
-  letter-spacing: 1px;
-  text-transform: uppercase;
-  text-align: center;
-  border: 2px solid rgba(0,0,200,0.6);
-  background: rgba(0,0,200,0.3);
-  color: rgba(0,0,200,0.6);
-  box-shadow: 1px 1px 2px rgba(0,0,200,0.4);
-  border-radius: 10px;
-  padding: 3px 10px;
-  display: inline-block;
-  cursor:pointer;
-}
- -

- -

И наконец, добавим немного JavaScript для придания динамического поведения:

- -
const para = document.querySelector('p');
-
-para.addEventListener('click', updateName);
-
-function updateName() {
-  let name = prompt('Enter a new name');
-  para.textContent = 'Player 1: ' + name;
-}
- -

{{ EmbedLiveSample('Определение_высокого_уровня', '100%', 80) }}

- -

Попробуйте кликнуть по тексту чтобы увидеть, что произойдет (Вы так же можете найти это демо на GitHub — смотрите исходный код, или запустите вживую)!

- -

JavaScript может делать намного больше — давайте выясним это более детально.

- -

Так что же он действительно может делать?

- -

Ядро языка JavaScript состоит из некоторого количества обычных возможностей, которые позволяют делать следующее:

- - - -

Еще более увлекательным является функциональность, созданная поверх основного языка JavaScript. Так называемые интерфейсы прикладного программирования (API) предоставляют вам дополнительные сверхспособности для использования в вашем коде JavaScript.

- -

API - это готовые наборы блоков кода, которые позволяют разработчику реализовывать программы, которые в противном случае было бы трудно или невозможно реализовать. Они делают то же самое для программирования, что готовые комплекты мебели делают для домашнего строительства - гораздо проще брать готовые панели и скручивать их вместе, чтобы сделать книжную полку, чем самому разрабатывать дизайн, ходить в поисках правильной древесины, вырезать все панели необходимого размера и формы, найти подходящие винты, а затем собрать их вместе, чтобы сделать книжную полку.

- -

Они обычно делятся на две категории.

- -

- -

API-интерфейсы браузера встроены в ваш веб-браузер и могут отображать данные из окружающего компьютерного окружения или делать полезные сложные вещи. Например:    

- - - -
-

Заметка: Большинство наших демо не будут корректно работать в старых браузерах — поэтому будет хорошей идеей,  для запуска вашего кода установить один из современных браузеров , таких как Firefox, Chrome, Edge или Opera . Также понадобится более подробно рассмотреть раздел по кроссбраузерному тестированию, когда вы приблизитесь к разработке производственного кода (т.е реального кода, который будут использовать клиенты).

-
- -

По умолчанию сторонние API-интерфейсы  не встроены в браузер, и вам придётся захватывать их код и информацию из какого-либо места в Сети. Для примера: 

- - - -
-

Заметка: Эти API-и являются продвинутыми, и мы не будем их рассматривать в нашем курсе, но ссылки, данные выше, предлагают полную документацию, если вы заинтересованы в более подробной информации.

-
- -

Доступно еще больше! Но пока не заостряйте на этом внимание. Вы не сможете создать следующий Facebook, Google Maps или Instagram после 24 часов изучения JavaScript — сначала нужно изучить основы. И именно для этого вы здесь — давайте двигаться дальше!

- -

Что JavaScript делает на вашей странице?

- -

В этой главе мы рассмотрим код и увидим что же действительно происходит, когда на странице запускается JavaScript.

- -

Давайте составим краткий бриф, что же происхоит когда мы загружаем страничку в браузере (первое упоминание в статье Как работает CSS). Когда вы загружаете страничку в браузере, вы запускаете ваш код (HTML, CSS и JavaScript) внутри исполняемой среды (внутри вкладки браузера). Это как будто фабрика берет сырьё (некий код) и выдает продукцию (веб-страничку).

- -

- -

Код JavaScript выполняется JavaScript-движком браузера, после того как код HTML и CSS был обработан и сформирован в веб-страницу. Это гарантирует, что структура и стиль страницы уже сформированы к моменту запуска JavaScript.

- -

Это хорошо, так как часто использование JavaScript заключается в динамическом изменении HTML и CSS в целях обновления пользовательского интерфейса посредством Document Object Model API (как упоминалось выше). Если бы запуск JavaScript осуществлялся прежде загрузки HTML и CSS, то это привело бы к возникновению ошибок.  

- -

Безопасность браузера

- -

Каждая вкладка браузера представляет собой отдельную коробку для запуска кода (в техническом языке, эти коробки называются "средами исполнения") — это значит, что в большинстве случаев код на каждой вкладке запускается полностью отдельно, а код одной вкладки не может напрямую влиять на код другой вкладки или на другом веб-сайте. Это хорошая мера безопасности — если бы это было иначе, пираты могли написать код, который крал информацию с других сайтов или делал другие плохие вещи.

- -
-

Заметка: Есть способы отправлять код и данные между разными веб-сайтами/вкладками безопасным способом, но это продвинутые методы, которые мы не будем рассматривать в рамках этого курса.

-
- -

Последовательность выполнения JavaScript

- -

Обычно, когда браузер сталкивается с блоком JavaScript, он запускает его по порядку, сверху вниз. Это значит, что вам нужно осторожно выбирать порядок. Например, вернемся к блоку JavaScript, который мы видели в первом примере:

- -
const para = document.querySelector('p');
-
-para.addEventListener('click', updateName);
-
-function updateName() {
-  let name = prompt('Enter a new name');
-  para.textContent = 'Player 1: ' + name;
-}
- -

Здесь мы выбираем абзац текста (строка 1), а затем добавляем к нему обнаружение событий (строка 3), чтобы при нажатии на этот абзац выполнялся блок кода updateName() (строки 5–8). Блок кода updateName() (эти типы многократно используемых блоков кода называются "функции") запрашивает у пользователя новое имя, а затем вставляет это имя в абзац для обновления отображения.

- -

Если вы поменяете порядок первых двух строк кода, он перестанет работать — вместо этого вы получите ошибку возвращаемую в консоль браузераTypeError: para is undefined. Это значит, что объект para еще не существует и вы не можете добавить к нему обнаружение событий.

- -
-

Заметка: Это очень частая ошибка — вы должны быть осторожны, чтобы объекты, на которые ссылается ваш код, существовали до того, как вы попытаетесь что-то с ними сделать.

-
- -

Интерпретируемый против компилируемого кода

- -

В контексте программирования, вы можете услышать термины интерпретация и компиляция. JavaScript является интерпретируемым языком — код запускается сверху вниз и результат запуска немедленно возвращается. Вам не нужно преобразовывать код в другую форму, перед запуском в браузере.

- -

С другой стороны, компилируемые языки преобразуются (компилируются) в другую форму, прежде чем они будут запущены компьютером. Например, C / C ++ компилируются в язык ассемблера, который затем запускается компьютером.

- -

Оба подхода имеют разные преимущества, которые на данном этапе мы обсуждать не будем.

- -

Серверный против клиентского кода

- -

Вы так же можете услышать термины серверный и клиентский код, особенно в контексте веб-разработки. Клиентский код — это код, который запускается на компьютере пользователя. При просмотре веб-страницы, клиентский код загружается, а затем запускается и отображается браузером. В этом модуле JavaScript мы явно говорим о клиентском JavaScript.

- -

С другой стороны, серверный код запускается на сервере, затем его результаты загружаются и отображаются в браузере. Примеры популярных серверных веб-языков включают PHP, Python, Ruby и ASP.NET. И JavaScript! JavaScript так же может использоваться, как серверный язык, например в популярной среде Node.js — вы можете больше узнать о серверном JavaScript в нашем разделе Dynamic Websites – Server-side programming.

- -

Слово динамический используется для описания и клиентского JavaScript, и серверного языка — это относится к возможности обновления отображения веб-страницы/приложения, чтобы показывать разные вещи в разных обстоятельствах, генерируя новый контент по мере необходимости. Серверный код динамически генерирует новый контент на сервере, например достает данные из базы данных, тогда как клиентский JavaScript динамически генерирует новое содержание внутри браузера на клиенте, например создает новую HTML таблицу, вставляя в нее данные полученные с сервера, затем отображает таблицу на веб-странице, которую видит пользователь. В этих двух контекстах значение немного отличается, но связано, и обычно оба подхода (серверный и клиентский) работают вместе.

- -

Веб-страница без динамического обновления контента называется статической — она просто показывает один и тотже контент все время.

- -

Как добавить JavaScript на вашу страницу?

- -

JavaScript применяется к вашей HTML странице точно так же, как CSS. И если CSS использует элементы {{htmlelement("link")}} для внешних стилей и {{htmlelement("style")}} для встроеных в HTML, то для JavaScript нужен только один друг в HTML мире — элемент {{htmlelement("script")}}. Давайте узнаем, как это работает.

- -

Внутренний JavaScript

- -
    -
  1. Сначала, сделайте локальную копию нашего файла-примера apply-javascript.html. Сохраните его в удобное для вас место.
  2. -
  3. Откройте этот файл в вашем браузере и в вашем текстовом редакторе. Вы увидите, что HTML создает простую веб-страницу с активной кнопкой.
  4. -
  5. Затем, перейдите в текстовый редактор и добавьте следующие строки перед закрывающим тегом </head>: -
    <script>
    -
    -  // здесь будет JavaScript
    -
    -</script>
    -
  6. -
  7. Теперь добавим JavaScript внутрь элемента {{htmlelement("script")}}, чтобы сделать страницу более интересной — добавьте следующий код ниже строки "// здесь будет JavaScript": -
    document.addEventListener("DOMContentLoaded", function() {
    -  function createParagraph() {
    -    let para = document.createElement('p');
    -    para.textContent = 'You clicked the button!';
    -    document.body.appendChild(para);
    -  }
    -
    -  const buttons = document.querySelectorAll('button');
    -
    -  for(let i = 0; i < buttons.length ; i++) {
    -    buttons[i].addEventListener('click', createParagraph);
    -  }
    -});
    -
  8. -
  9. Сохраните файл и обновите страницу в браузере — теперь вы должны увидеть, что при нажатии на кнопку создается новый абзац и помещается ниже.
  10. -
- -
-

Заметка: Если ваш пример не работает, пройдите еще раз все шаги и проверьте, сделали ли вы все правильно. Сохранили ли вы вашу локальную копию начального кода, как .html файл? Добавили ли ваш {{htmlelement("script")}} элемент после тэга </body>? Ввели ли вы JavaScript именно так, как показано? JavaScript регистрозависимый, и очень привередливый. Поэтому вам нужно вводить синтаксис именно так, как показано, в противном случае оно может не работать.

-
- -
-

Заметка: Вы можете увидеть эту версию на GitHub-е как apply-javascript-internal.html (посмотреть вживую).

-
- -

Внешний JavaScript

- -

Это отлично работает, но что если мы хотим поместить наш JavaScript в отдельный файл? Давайте сейчас разберемся с этим.

- -
    -
  1. Сначала, создайте новый файл в той же папке, что и ваш файл-пример HTML. Назовите его script.js — убедитесь, что у имени файла расширение .js, так как оно распознается, как JavaScript.
  2. -
  3. Замените ваше текущий элемент {{htmlelement("script")}} на следующий: -
    <script src="script.js" defer></script>
    -
  4. -
  5. Внутри script.js добавьте следующий скрипт: -
    function createParagraph() {
    -  let para = document.createElement('p');
    -  para.textContent = 'You clicked the button!';
    -  document.body.appendChild(para);
    -}
    -
    -const buttons = document.querySelectorAll('button');
    -
    -for(let i = 0; i < buttons.length ; i++) {
    -  buttons[i].addEventListener('click', createParagraph);
    -}
    -
  6. -
  7. Сохраните и обновите страницу в браузере, и вы увидите то же самое! Все работает точно так же, но теперь у нас есть JavaScript во внешнем файле. Это, как правило, хорошо с точки зрения организации кода и его повторного использования в нескольких HTML файлах. Кроме того, HTML легче читать без огромных кусков кода, который скапливается в нем.
  8. -
- -
-

Заметка: Вы можете увидеть эту версию на GitHub-е как apply-javascript-external.html и script.js (посмотреть вживую).

-
- -

Инлайновые JavaScript обработчики

- -

Обратите внимание, что иногда можно столкнуться с частями JavaScript кода, который живет внутри HTML. Это может выглядеть примерно так:

- -
-
function createParagraph() {
-  var para = document.createElement('p');
-  para.textContent = 'You clicked the button!';
-  document.body.appendChild(para);
-}
- -
<button onclick="createParagraph()">Click me!</button>
-
- -

Вы можете попробовать эту версию в нашей демонстрации ниже:

- -

{{ EmbedLiveSample('Inline_JavaScript_handlers', '100%', 150) }}

- -

Эта демонстрация имеет те же функциональные возможности, что и в предыдущих двух разделах, за исключением того, что элемент {{htmlelement("button")}} содержит встроенный обработчик onclick, который запускает функцию при нажатии кнопки.

- -

Но пожалуйста, не делайте этого. Это плохая практика — загрязнять ваш HTML кодом JavaScript, и она не эффективна — вам нужно будет добавить атрибут onclick="createParagraph()" к каждой кнопке, к которой вы хотите подключить JavaScript.

- -

Использование чистой JavaScript конструкции, позволит вам выбрать все кнопки, используя одну команду. Код, который можно использовали для этой цели, выглядит следующим образом:

- -
const buttons = document.querySelectorAll('button');
-
-for(let i = 0; i < buttons.length ; i++) {
-  buttons[i].addEventListener('click', createParagraph);
-}
- -

Это может выглядеть немного длиннее, чем атрибут onclick, но это будет работать для всех кнопок, независимо от того, сколько их на странице, и сколько их удалят или добавят. JavaScript менять не нужно.

- -
-

Заметка: Попробуйте отредактировать вашу версию apply-javascript.html и добавить еще несколько кнопок в файл. После перезагрузки вы должны увидеть, что все кнопки создают параграф, если кликнуть на них. Классно, да?

-
- -

Стратегии загрузки скриптов

- -

Существует ряд проблем, связанных с загрузкой скриптов в нужное время. Всё не так просто, как кажется! Распространённой проблемой является то, что весь HTML-код на странице загружается в том порядке, в котором отображается. Если вы используете JavaScript для манипуляции элементами на странице (или, точнее, в DOM – Объектной Модели Документа), ваш код не будет работать, если JavaScript-код загрузится и распознается раньше HTML-кода, с которым вы пытаетесь взаимодействовать.

- -

Комментарии

- -

Так же, как и в HTML и CSS, возможно писать комментарии в вашем JavaScript коде, что будет проигнорировано браузером, и существует только для того, чтобы давать подсказки вашим друзьям-разработчикам о том, как работает код (и лично вам, если вы вернетесь к коду спустя 6 месяцев и не сможете вспомнить, что вы делали). Комментарии очень полезны, и вы должны часто их использовать, особенно для больших приложений. Вот два типа комментариев:

- - - -

Так, например, мы можем описать наш последний демо-пример JavaScript подобными комментариями:

- -
// Функция: создает новый параграф и добавляет его вниз тела HTML.
-
-function createParagraph() {
-  var para = document.createElement('p');
-  para.textContent = 'You clicked the button!';
-  document.body.appendChild(para);
-}
-
-/*
-  1. Получаем ссылки на все кнопки на странице в виде массива.
-  2. Перебераем все кнопки и добавляем к ним отслеживатель события нажатия.
-
-  При нажатии любой кнопки, будет выполняться функция createParagraph().
-*/
-
-var buttons = document.querySelectorAll('button');
-
-for (var i = 0; i < buttons.length ; i++) {
-  buttons[i].addEventListener('click', createParagraph);
-}
- -

Выводы

- -

Поздравляем, вы сделали ваш первый шаг в мир JavaScript. Мы начали всего-лишь с теории, чтобы вы привыкли к тому, что вы будете использовать JavaScript, и что именно вы можете делать с его помощью. На этом пути вы увидели несколько примеров кода и выучили, как JavaScript вписывается в остальной код на вашем сайте среди всего прочего.

- -

JavaScript может показаться немного пугающим в данным момент, но не переживайте - в этом курсе мы проведем вас сквозь него простыми шагами, которые имеют смысл, забегая наперед. В следующей главе мы погрузимся непосредственно в практику, подталкивая вас погрузиться в код и сделать ваши собственные примеры JavaScript.

- -

{{NextMenu("Learn/JavaScript/Первые_шаги/A_first_splash", "Learn/JavaScript/Первые_шаги")}}

diff --git "a/files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/\321\201\320\276\320\267\320\264\320\260\321\202\320\265\320\273\321\214_\320\263\320\273\321\203\321\213\321\205_\320\270\321\201\321\202\320\276\321\200\320\270\320\271/index.html" "b/files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/\321\201\320\276\320\267\320\264\320\260\321\202\320\265\320\273\321\214_\320\263\320\273\321\203\321\213\321\205_\320\270\321\201\321\202\320\276\321\200\320\270\320\271/index.html" deleted file mode 100644 index 139e478847..0000000000 --- "a/files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/\321\201\320\276\320\267\320\264\320\260\321\202\320\265\320\273\321\214_\320\263\320\273\321\203\321\213\321\205_\320\270\321\201\321\202\320\276\321\200\320\270\320\271/index.html" +++ /dev/null @@ -1,148 +0,0 @@ ---- -title: Генератор глупых историй -slug: Learn/JavaScript/Первые_шаги/Создатель_глуых_историй -tags: - - JavaScript - - Задание - - Изучение - - Испытание - - Массивы - - НаписаниеКода - - НачальныйУровень - - Операторы - - Переменные - - Проверка - - Числа -translation_of: Learn/JavaScript/First_steps/Silly_story_generator ---- -
{{LearnSidebar}}
- -
{{PreviousMenu("Learn/JavaScript/Первые_шаги/Arrays", "Learn/JavaScript/Первые_шаги")}}
- -

В этом испытании вам будет нужно, используя знания, полученные в статьях этого модуля, применить их для создания забавного приложения, создающего случайные глупые истории. Удачно повеселиться!

- - - - - - - - - - - - -
Требования:Перед началом выполнения этого испытания вам следует проработать все статьи в этом модуле.
Задача:Протестировать понимание основ языка JavaScript, таких как переменные, числа, операторы, строки и массивы.
- -

Начальная точка

- -

Для начала испытания вам следует:

- - - -
-

Замечание:  Так же вы можете использовать такие сайты как  JSBin или Thimble для выполнения вашего испытания. Вы можете вставить HTML, CSS и JavaScript в один из этих онлайн редакторов. Если онлайн редактор, который вы используете, не имеет отдельного окна для JavaScript - не стесняйтесь вставить все скрипты в <script> элемент внутри  HTML страницы.

-
- -

Краткое описание проекта

- -

Вам предоставили некоторый необработанный HTML/CSS, несколько текстовых строк и функций JavaScript; вам необходимо написать необходимый JavaScript код, чтобы превратить это в рабочую программу, которая выполняет следующие действия:

- - - -

Следующий скриншот показывает пример того, что должна выводить законченная программа:

- -

- -

Чтобы вы больше поняли идею опробуйте готовый пример (не заглядывая в исходный код!)

- -

Шаги к цели

- -

Следующие разделы описывают, что вам нужно будет сделать.

- -

Начальная подготовка:

- -
    -
  1. Создайте новый файл под названием main.js в той же папке, что и index.html.
  2. -
  3. Подключите данный JavaScript документ в ваш HTML файл с помощью {{htmlelement("script")}} элемента привязки main.js. Разместите его прямо перед закрывающимся </body> тегом.
  4. -
- -

Задайте переменные и функции:

- -
    -
  1. В исходном текстовом документе скопируйте весь код под заголовком "1. COMPLETE VARIABLE AND FUNCTION DEFINITIONS" и вставьте в начало файла main.js. Это даст вам три переменные, ссылающиеся на текстовое поле "Enter custom name" (customName),  кнопку "Generate random story" (randomize), и элемент снизу HTML страницы, куда будет помещена сама история {{htmlelement("p")}} (story), соответственно. Также у вас должна быть функцияrandomValueFromArray(), котрая принимает массив и случайным образом возвращает оттуда один из элементов.
  2. -
  3. Теперь взгляните на второй параграф исходного документа — "2. RAW TEXT STRINGS". Он содержит строки текста, которые будут использоваться как входные данные вашей программы. Вам следует поместить их внутрь переменных в файле main.js: -
      -
    1. Сохраните первую большую строку текста в переменную storyText.
    2. -
    3. Сохраните первый блок из трех строк как массив, назвав его insertX.
    4. -
    5. Сохраните второй блок из трех строк как массив, назвав его insertY.
    6. -
    7. Сохраните третий блок из трех строк как массив, назвав его insertZ.
    8. -
    -
  4. -
- -

Создание обработчика событий и неполной функции:

- -
    -
  1. Теперь возвращаемся к исходному текстовому файлу.
  2. -
  3. Скопируйте код под заголовком "3. EVENT LISTENER AND PARTIAL FUNCTION DEFINITION" и вставте его в конец файла main.js. Это: -
      -
    • Добавит обработчик события кликанья в переменную randomize,  Так что, когда кнопка будет нажата -  функция result() запустится.
    • -
    • Добавляет в код частично завершенную функцию result(). В течении оставшейся части испытания вам предстоит, заполняя строчки внутри этой функции, завершить ее и заставить работать должным образом.
    • -
    -
  4. -
- -

Завершение функции result():

- -
    -
  1. Создайте новую переменную newStory и установите ее значение равным storyText. Это необходимо, чтобы мы могли создавать новую случайную историю каждый раз, когда нажимается кнопка, и функция запускается. Если бы мы внесли изменения непосредственно в storyText, мы могли бы генерировать новую историю только один раз.
  2. -
  3. Создайте три новые переменные, называемые xItem, yItem и zItem, и сделайте их равными результату вызова randomValueFromArray() на трех ваших массивах (результат в каждом случае будет случайным элементом из каждого массива, на который он вызывается). Например, вы можете вызвать функцию и получить ее, чтобы вернуть одну случайную строку из insertX, записав randomValueFromArray (insertX).
  4. -
  5. Затем мы хотим заменить три заполнителя строки newStory - :insertx:, :inserty :  и :insertz: - со строками, хранящимися в xItem, yItem и zItem. Здесь вам поможет определенный строковый метод - в каждом случае сделать вызов метода равным newStory, при этом каждый раз, когда он вызывается, newStory делается равным самому себе, но с выполненными заменами. Поэтому каждый раз, когда нажимается кнопка, эти заполнители заменяются случайной строкой. Подсказка: рассматриваемый метод заменяет только первый экземпляр найденной подстроки, поэтому вам, возможно, придется сделать один из вызовов дважды.
  6. -
  7. Внутри первого блока if добавьте другой метод замены строки, чтобы заменить имя «Боб», найденное в строке newStory, с помощью переменной name. В этом блоке мы говорим: «Если значение введено в текстовый ввод customName, замените Боба в истории этим пользовательским именем».
  8. -
  9. Внутри второго блока if мы проверяем, была ли выбрана радиокнопка uk. Если это так, мы хотим преобразовать значения веса и температуры в историю из фунтов и Фаренгейта в метры и по Цельсию. Что вам нужно сделать, так это: -
      -
    1. Посмотрите формулу преобразования фунтов в стоуны и Фаренгейта в по Цельсию.
    2. -
    3. Внутри линии, которая определяет weight переменную, замените 300 на расчет, который преобразует 300 фунтов в стоуны. Добавьте 'stone' в конце результата общего вызова Math.round().
    4. -
    5. Внутри линии, определяющей temperature переменную, замените 94 на расчет, который преобразует 94 градуса по Фаренгейту в по Цельсию. Добавьте 'centigrade' в конце результата общего вызова Math.round().
    6. -
    7. Просто под двумя определениями переменных добавьте еще две строки замены строк, которые заменяют «94 farenheit» на содержимое переменной temperature и«300  pounds» на содержимое weight переменной.
    8. -
    -
  10. -
  11. Наконец, в предпоследней строке функции сделайте свойство textContent переменной story (которая ссылается на абзац) равным newStory.
  12. -
- -

Советы и подсказки

- - - -

Оценка и помощь

- -

Если вы хотите, чтобы ваша работа была оценена, или застряли и хотите обратиться за помощью:

- -
    -
  1. Разместите свою работу в онлайн-редакторе, таком как CodePen, jsFiddle или Glitch.
  2. -
  3. Напишите сообщение с просьбой об оценке и / или помощи на форуме MDN Discourse. Добавьте тег «learning» к своему сообщению, чтобы мы могли легче его найти. Ваш пост должен включать: -
      -
    • Описательное название, такое как «Требуется оценка для генератора глупых историй».
    • -
    • Подробная информация о том, что вы хотели бы, чтобы мы делали, например, что вы уже пробовали, если вы застряли и нуждаетесь в помощи.
    • -
    • Ссылка на пример, который вы хотите оценить или нуждаетесь в помощи, в онлайн-редакторе. Это хорошая практика - очень сложно помочь кому-то с проблемой кодирования, если вы не видите его код.
    • -
    • Ссылка на актуальную задачу или страницу оценки, чтобы мы могли найти вопрос, с которым вы хотите помочь.
    • -
    -
  4. -
- -

{{PreviousMenu("Learn/JavaScript/Первые_шаги/Arrays", "Learn/JavaScript/Первые_шаги")}}

diff --git "a/files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/\321\201\321\202\321\200\320\276\320\272\320\270/index.html" "b/files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/\321\201\321\202\321\200\320\276\320\272\320\270/index.html" deleted file mode 100644 index 583e29182e..0000000000 --- "a/files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/\321\201\321\202\321\200\320\276\320\272\320\270/index.html" +++ /dev/null @@ -1,284 +0,0 @@ ---- -title: Работа с текстом — строки в JavaScript -slug: Learn/JavaScript/Первые_шаги/Строки -translation_of: Learn/JavaScript/First_steps/Strings ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/Math", "Learn/JavaScript/Первые_шаги/Useful_string_methods", "Learn/JavaScript/Первые_шаги")}}
- -

Теперь мы обратим внимание на строки — в программировании так называют части текста. В этой статье мы рассмотрим все распростанённые вещи, которые вы должны действительно знать о строках при изучении JavaScript, например, создание строк, экранирование кавычек в строках и объединение строк вместе.

- - - - - - - - - - - - -
Необходимые навыки:Базовая компьютерная грамотность, базовое понимание HTML и CSS, понимание что такое JavaScript.
Цель:Знакомство с основами строк в JavaScript.
- -

Сила слов

- -

Слова очень важны для людей это основа нашего общения. Интернет представляет собой преимущественно текстовую среду, предназначенную для того что бы люди общались и делились информацией, поэтому нам полезно иметь контроль над словами, которые появляются в нем. {{glossary ("HTML")}} предоставляет визуальную и смысловую структуру для нашего текста, {{glossary ("CSS")}} позволяет нам стилизовать его, а JavaScript содержит ряд функций для управления строками, создания пользовательских приветственных сообщений, при необходимости отображая нужные текстовые метки, сортируя элементы в желаемом порядке и многое другое.

- -

Практически во всех программах, которые мы показали вам на данный момент,  были задействованы некоторые манипуляции со строками.

- -

Строки — основы

- -

С первого взгляда строки обрабатываются аналогично числам, но если копнуть глубже, вы увидите некоторые заметные отличия. Давайте начнем с ввода некоторых основных строк в консоль, чтобы ознакомиться с ними. Мы предоставили одну ниже (вы также можете открыть эту консоль в отдельной вкладке или окне или использовать консоль разработчика браузера, если хотите).

- - - -

{{ EmbedLiveSample('Hidden_code', '100%', 300) }}

- -

Создание строки

- -
    -
  1. Для начала введите следующие строки: -
    var string = 'The revolution will not be televised.';
    -string;
    -
  2. -
  3. Как и в случае с числами, мы объявляем переменную, инициализируя ее строковым значением, а затем возвращаем значение. Единственное различие здесь в том, что при написании строки вам нужно окружить значение кавычками. 
  4. -
  5. Если вы не сделаете этого или пропустите одну из кавычек, вы получите сообщение об ошибке. Попробуйте ввести следующие строки: -
    var badString = This is a test;
    -var badString = 'This is a test;
    -var badString = This is a test';
    - Эти строки не работают, потому что любая текстовая строка без кавычек считается именем переменной, именем свойства, зарезервированным словом или чем-то подобным. Если браузер не может найти его, возникает ошибка (например, «missing, before statement»). Если браузер может видеть, где начинается строка, но не может найти конец строки, как указано во 2-й строке, она жалуется на ошибку (с «unterminated string literal»). Если ваша программа выявляет такие ошибки, вернитесь назад и проверьте все свои строки, чтобы убедиться, что у вас нет пропущенных кавычек.
  6. -
  7. Следующий код будет выполнен только в том случае, если ранее была объявлена переменная string — убедитесь сами: -
    var badString = string;
    -badString;
    - В настоящее время строка badString имеет то же значение, что и строка string.
  8. -
- -

Одиночные кавычки vs. Двойные кавычки

- -
    -
  1. В JavaScript вы можете выбрать одинарные кавычки или двойные кавычки, чтобы обернуть ваши строки. Оба варианта будут работать нормально: -
    var sgl = 'Single quotes.';
    -var dbl = "Double quotes";
    -sgl;
    -dbl;
    -
  2. -
  3. Существует очень мало различий между одиночными и двойными кавычками, и решение какие из них использовать в коде остается на ваше усмотрение. Однако вы должны выбрать один вариант и придерживаться его, иначе ваш код может выдать ошибку, особенно если вы используете разные кавычки в одной строке! Ниже приведен пример: -
    var badQuotes = 'What on earth?";
    -
  4. -
  5. Браузер будет считать, что строка не была закрыта, потому что в строке может появиться другой тип цитаты, который вы не используете, чтобы хранить ваши строки в переменных. Из примера можно понять, о чем идет речь (в коде ошибок нет): -
    var sglDbl = 'Would you eat a "fish supper"?';
    -var dblSgl = "I'm feeling blue.";
    -sglDbl;
    -dblSgl;
    -
  6. -
  7. Однако вы не можете включить один и тот же знак кавычки внутри строки, если он используется для их хранения. Ниже приведена ошибка, браузер ошибочно определяет место, где строка кончается: -
    var bigmouth = 'I've got no right to take my place...';
    - Что приводит нас к следующей теме.
  8. -
- -

Экранирование кавычек в строках

- -

Чтобы исправить нашу предыдущую строку кода, нам нужно дать понять браузеру, что кавычка в середине строки не является меткой ее конца. Экранирование символов означает, что мы делаем что-то с ними, чтобы убедиться, что они распознаются как текст, а не часть кода. В JavaScript мы делаем это, помещая обратную косую черту непосредственно перед символом. Введите эти строки:

- -
var bigmouth = 'I\'ve got no right to take my place...';
-bigmouth;
- -

Так лучше. Таким же образом можно экранировать и другие символы, например "\. Кроме того существуют специальные коды. Для дополнительной информации см. Escape notation.

- -

Конкатенация строк

- -
    -
  1. Конкатенация — это новомодное программистское слово, которое означает «объединить». Объединение строк в JavaScript использует оператор плюс (+), тот же, который мы используем для сложения чисел, но в этом контексте он делает кое-что другое. Попробуем пример в нашей консоли.
  2. -
  3. -
    var one = 'Hello, ';
    -var two = 'how are you?';
    -var joined = one + two;
    -joined;
    - Результат этой программы - это переменная joined, содержащая значение "Hello, how are you?".
  4. -
  5. В последнем случае мы просто объединим две строки вместе, но на самом деле, вы можете объединить столько строк, сколько хотите, до тех пор, пока вы ставите + между ними. Попробуйте это: -
    var multiple = one + one + one + one + two;
    -multiple;
    -
  6. -
  7. Вы также можете использовать сочетание переменных и фактических строк. Попробуйте это: -
    var response = one + 'I am fine — ' + two;
    -response;
    -
  8. -
- -
-

Примечание: Когда вы вводите фактическую строку в свой код, заключенную в одинарные или двойные кавычки, она называется строковым литералом.

-
- -

Конкатенация строк в контексте

- -

Давайте посмотрим на конкатенацию строк в действии — вот пример из предыдущего курса:

- -
<button>Press me</button>
- -
var button = document.querySelector('button');
-
-button.onclick = function() {
-  var name = prompt('What is your name?');
-  alert('Hello ' + name + ', nice to see you!');
-}
- -

{{ EmbedLiveSample('Concatenation_in_context', '100%', 50) }}

- -

Здесь мы используем функцию {{domxref ("Window.prompt ()", "Window.prompt ()")}} в строке 4, которая просит пользователя ответить на вопрос через всплывающее диалоговое окно, а затем сохраняет введенный текст внутри заданной переменной — в этом случае name. Затем мы используем функцию {{domxref ("Window.alert ()", "Window.alert ()")}} в строке 5 для отображения другого всплывающего окна, содержащего строку, которую мы собрали из двух строковых литералов и переменной name.

- -

Числа vs. строки

- -
    -
  1. Итак, что происходит, когда мы пытаемся добавить (или конкатенировать) строку и число? Попробуем это в нашей консоли: -
    'Front ' + 242;
    -
    - Вы можете ожидать, что это вызовет ошибку, но все работает отлично. Попытка представить строку как число на самом деле не имеет смысла, но число как строку — имеет, поэтому браузер довольно умно преобразует число в строку и объединяет две строки вместе.
  2. -
  3. Вы даже можете сделать это с двумя числами, вы можете заставить число стать строкой, обернув ее в кавычки. Попробуйте следующее (мы используем оператор typeof для того, чтобы установить является ли переменная числом или строкой): -
    var myDate = '19' + '67';
    -typeof myDate;
    -
  4. -
  5. Если у вас есть числовая переменная, которую вы хотите преобразовать в строчную без внесения каких-либо иных изменений или строковую переменную, которую вы хотите преобразовать в число, вы можете использовать следующие две конструкции: -
      -
    • Объект {{jsxref ("Number")}} преобразует всё переданное в него в число, если это возможно. Попробуйте следующее: -
      var myString = '123';
      -var myNum = Number(myString);
      -typeof myNum;
      -
    • -
    • С другой стороны, каждое число имеет метод, называемый toString(), который преобразует его в эквивалентную строку. Попробуй это: -
      var myNum = 123;
      -var myString = myNum.toString();
      -typeof myString;
      -
    • -
    - Эти конструкции могут быть действительно полезны в некоторых ситуациях. Например, если пользователь вводит число в текстовое поле формы, данные будут распознаны как строка. Однако, если вы хотите добавить это число к чему-то, вам понадобится его значение, поэтому вы можете передать его через Number(), чтобы справиться с этим. Именно это мы сделали в нашей Number Guessing Game,  в строке 61.
  6. -
- -

Заключение

- -

Итак, это основы строк, используемых в JavaScript. В следующей статье мы рассмотрим некоторые из встроенных методов, доступных для строк в JavaScript и то, как мы можем использовать их для управления нашими строками только в той форме, в которой мы хотим.

- -
{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/Math", "Learn/JavaScript/Первые_шаги/Useful_string_methods", "Learn/JavaScript/Первые_шаги")}}
- -

В этом модуле

- - diff --git "a/files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/\321\207\321\202\320\276_\320\277\320\276\321\210\320\273\320\276_\320\275\320\265_\321\202\320\260\320\272/index.html" "b/files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/\321\207\321\202\320\276_\320\277\320\276\321\210\320\273\320\276_\320\275\320\265_\321\202\320\260\320\272/index.html" deleted file mode 100644 index dbb0a4577a..0000000000 --- "a/files/ru/learn/javascript/\320\277\320\265\321\200\320\262\321\213\320\265_\321\210\320\260\320\263\320\270/\321\207\321\202\320\276_\320\277\320\276\321\210\320\273\320\276_\320\275\320\265_\321\202\320\260\320\272/index.html" +++ /dev/null @@ -1,249 +0,0 @@ ---- -title: Что пошло не так? Устранение ошибок JavaScript -slug: Learn/JavaScript/Первые_шаги/Что_пошло_не_так -translation_of: Learn/JavaScript/First_steps/What_went_wrong ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/A_first_splash", "Learn/JavaScript/Первые_шаги/Variables", "Learn/JavaScript/Первые_шаги")}}
- -

Когда вы создали игру «Угадай номер» в предыдущей статье, вы, возможно, обнаружили, что она не работает. Не бойтесь — эта статья призвана избавить вас от разрыва волос над такими проблемами, предоставив вам несколько простых советов о том, как найти и исправить ошибки в программах JavaScript.

- - - - - - - - - - - - -
-

Нужно:

-
базовая компьютерная грамотность, базовое понимание HTML и CSS, понимание того, что такое JavaScript.
Цельполучить способность и уверенность в том, чтобы приступить к исправлению простых проблем в вашем собственном коде.
- -

Типы ошибок

- -

Когда вы делаете что-то не так в коде, есть два основных типа ошибок, с которыми вы столкнетесь:

- - - -

Ладно, все не так просто — есть и другие отличия, которые вы поймете, пока будете изучать язык JavaScript глубже. Однако вышеуказанной классификации достаточно на раннем этапе вашей карьеры. Мы рассмотрим оба эти типа в дальнейшем.

- -

Ошибочный пример

- -

Чтобы начать работу, давайте вернемся к нашей игре с угадыванием чисел — за исключением того, что мы будем изучать версию с некоторыми преднамеренными ошибками. Перейдите в Github и сделайте себе локальную копию number-game-errors.html (см. здесь как это работает).

- -
    -
  1. Чтобы начать работу, откройте локальную копию внутри вашего любимого текстового редактора и вашего браузера.
  2. -
  3. Попробуйте сыграть в игру — вы заметите, что когда вы нажимаете кнопку «Submit guess», она не работает!
  4. -
- -
-

Примечание: Возможно, у вас может быть собственная версия игрового примера, которая не работает, которую вы можете исправить! Мы по-прежнему хотели бы, чтобы вы работали над статьей с нашей версией, чтобы вы могли изучать методы, которые мы здесь преподаем. Затем вы можете вернуться и попытаться исправить ваш пример.

-
- -

На этом этапе давайте рассмотрим консоль разработчика, чтобы увидеть, можем ли мы видеть какие-либо синтаксические ошибки, а затем попытаемся их исправить. Вы узнаете, как это сделать, ниже.

- -

Исправление синтаксических ошибок

- -

Раньше в курсе мы заставили вас набрать некоторые простые команды JavaScript в консоль разработчика JavaScript (если вы не можете вспомнить, как открыть это в своем браузере, следуйте предыдущей ссылке, чтобы узнать, как это сделать). Что еще более полезно, так это то, что консоль предоставляет вам сообщения об ошибках всякий раз, когда существует синтаксическая ошибка внутри JavaScript, которая подается в механизм JavaScript браузера. Теперь пойдем на охоту.

- -
    -
  1. Перейдите на вкладку, в которой у вас есть number-game-errors.html, и откройте консоль JavaScript. Вы должны увидеть сообщение об ошибке в следующих строках:
  2. -
  3. Это довольно простая ошибка для отслеживания, и браузер дает вам несколько полезных бит информации, которые помогут вам (скриншот выше от Firefox, но другие браузеры предоставляют аналогичную информацию). Слева направо, у нас есть: -
      -
    • Красный «x» означает, что это ошибка.
    • -
    • Сообщение об ошибке, указывающее, что пошло не так: «TypeError: guessSubmit.addeventListener не является функцией»
    • -
    • Ссылка «Узнать больше», которая ссылается на страницу MDN, которая объясняет, что эта ошибка означает в огромных количествах деталей.
    • -
    • Имя файла JavaScript, который ссылается на вкладку «Отладчик» консоли разработчика. Если вы перейдете по этой ссылке, вы увидите точную строку, где подсвечивается ошибка.
    • -
    • Номер строки, в которой находится ошибка, и номер символа в этой строке, где первая ошибка. В этом случае у нас есть строка 86, символ номер 3.
    • -
    -
  4. -
  5. Если мы посмотрим на строку 86 в нашем редакторе кода, мы найдем эту строку: -
    guessSubmit.addeventListener('click', checkGuess);
    -
  6. -
  7. В сообщении об ошибке говорится, что «guessSubmit.addeventListener не является функцией», поэтому мы, вероятно, где-то ошиблись. Если вы не уверены в правильности написания синтаксиса, часто бывает полезно найти функцию на MDN. Лучший способ сделать это в настоящее время — поиск «mdn имя-функции» в вашей любимой поисковой системе. Вот ссылка, которая поможет сократить вам некоторое время в данном случае: addEventListener().
  8. -
  9. Итак, глядя на эту страницу, кажется, что ошибка в том, что мы неправильно назвали имя функции! Помните, что JavaScript чувствителен к регистру, поэтому любые незначительные отличия в орфографии или регистре текста могут вызвать ошибку. Изменение этого параметра в addEventListener должно быть исправлено. Сделайте это сейчас.
  10. -
- -
-

Примечание: См. наш TypeError: «x» не является справочной страницей функций для получения дополнительной информации об этой ошибке.

-
- -

Синтаксические ошибки: второй раунд

- -
-

Примечание: console.log() это часто используемая функция отладки, которая выводит значение в консоль. Поэтому она будет выводить значение lowOrHi в консоли, как только мы попытаемся установить его в строке 48.

-
- -
    -
  1. Сохраните и обновите страницу, и вы увидите, что ошибка исчезла.
  2. -
  3. Теперь, если вы попробуете ввести значение и нажать кнопку "Submit guess", вы увидите ... другую ошибку! 
  4. -
  5. На этот раз сообщается об ошибке: "TypeError: lowOrHi is null", в строке 78. -
    Примечание: Null — это специальное значение, которое означает "ничего" или "не значение". Поэтому lowOrHi был объявлен и инициализирован без значения — у него нет типа или значения.
    - -
    Примечание: Эта ошибка не появилась, как только страница была загружена, потому что эта ошибка произошла внутри функции (внутри checkGuess() { ... } block). Об этом вы узнаете более подробно в нашей более поздней статье о функциях, код внутри функций выполняется в отдельной области для кода внешних функций. В этом случае код не был запущен, и ошибка не была брошена до тех пор, пока функция checkGuess() не была запущена строкой 86.
    -
  6. -
  7. Посмотрите на строку 78, и вы увидите следующий код: -
    lowOrHi.textContent = «Последнее предположение было слишком высоко!»;
    -
  8. -
  9. Эта строка пытается установить свойство textContent переменной lowOrHi как текстовую строку, но это не работает, поскольку lowOrHi не содержит того, что должна. Давайте посмотрим, почему так происходит — попробуйте найти другие экземпляры lowOrHi в коде. Самый ранний экземпляр, который вы найдете в JavaScript, находится в строке 48: -
    var lowOrHi = document.querySelector('lowOrHi');
    -
  10. -
  11. На этом этапе мы пытаемся заставить переменную содержать ссылку на элемент документа HTML. Давайте проверим, является ли значение  null после выполнения этой строки. Добавьте следующий код в строку 49: -
    console.log(lowOrHi);
    -
    -
  12. -
  13. Сохраните и обновите, и вы должны увидеть результат работы console.log() в консоли браузера. Разумеется, значение lowOrHi на данный момент равно null, поэтому определенно существует проблема в строке 48.
  14. -
  15. Давайте подумаем о том, что может быть проблемой. Строка 48 использует метод document.querySelector() для получения ссылки на элемент, выбирая его с помощью селектора CSS. Посмотрев далее наш файл, мы можем найти обсуждаемый элемент <p>: -
    <p class="lowOrHi"></p>
    -
    -
  16. -
  17. Поэтому нам нужен селектор классов, который начинается с точки (.), но селектор, передаваемый в метод querySelector() в строке 48, не имеет точки. Возможно, это и есть проблема! Попробуйте изменить lowOrHi на .lowOrHi в строке 48.
  18. -
  19. Повторите попытку сохранения и обновления, и ваш вызов console.log() должен вернуть элемент <p>, который мы хотим. Уф! Еще одна ошибка исправлена! Вы можете удалить строку с  console.log() сейчас, или оставить для дальнейшего применения — выбирайте сами.
  20. -
- -
-

Примечание: Загляните на справочную страницу TypeError: "x" is (not) "y", чтобы узнать больше об этой ошибке.

-
- -

Синтаксические ошибки: третий раунд

- -
    -
  1. Теперь, если вы снова попробуете сыграть в игру, вы должны добиться большего успеха — игра должна играть абсолютно нормально, пока вы не закончите игру, либо угадав нужное число, либо потеряв жизни.
  2. -
  3. На данном этапе игра снова слетает, и выводится такая же ошибка, как и в начале — "TypeError: resetButton.addeventListener is not a function"! Однако, теперь она происходит из-за строки 94.
  4. -
  5. Посмотрев на строку 94, легко видеть, что здесь сделана такая же ошибка. Нам просто нужно изменить addeventListener на addEventListener.
  6. -
- -

Логическая ошибка

- -

На этом этапе игра должна проходить отлично, однако, поиграв несколько раз, вы, несомненно заметите, что случайное число, которое вы должны угадать, всегда 0 или 1. Определенно не совсем так, как мы хотим, чтобы игра была разыграна!

- -

Безусловно, где-то в игре есть логическая ошибка — игра не возвращает ошибку, она просто работает неправильно.

- -
    -
  1. Найдем переменную randomNumber , и строку где в первый раз устанавливали случайное число. Пример, в котором мы храним случайное число, которое должны угадать, на строке 44: - -
    var randomNumber = Math.floor(Math.random()) + 1;
    -
    - И на строке 113, где мы генерируем случайное число, каждый раз после окончания игры: - -
    randomNumber = Math.floor(Math.random()) + 1;
    -
    -
  2. -
  3. Чтобы проверить, действительно ли проблема в этом, давайте обратимся к нашему другу console.log() снова — вставьте ее ниже строк с ошибками: -
    console.log(randomNumber);
    -
    -
  4. -
  5. Сохраните и обновите, а дальше попробуйте пару раз сыграть — в консоли вы увидите что randomNumber равна 1 в каждой точке, где вы ее записали после строк с ошибками.
  6. -
- -

Работаем через логику

- -

Чтобы исправить это, давайте рассмотрим как работает строка. Первое, мы вызываем Math.random(), котрый генерирует случайное десятичное число, между 0 и 1, например 0.5675493843.

- -
Math.random()
- -

Дальше, мы передаем результат вызова Math.random() через Math.floor(), который округляет число вниз, до ближайшего целого числа. Затем мы добавляем 1 к данному результату:

- -
Math.floor(Math.random()) + 1;
- -

Округление случайного десятичного числа к меньшему, всегда будет возвращать 0, так что добавление к нему единицы будет возвращать всегда 1.  Нам нужно умножить случайное число на 100, прежде чем мы округлим его к меньшему. Следующая строка вернет нам случайное число между 0 и 99:

- -
Math.floor(Math.random() * 100);
- -

поэтому нам нужно добавить 1, чтоб нам возвращалось случайное число между 1 и 100:

- -
Math.floor(Math.random() * 100) + 1;
- -

А теперь, исправьте обе строки с ошибками, затем сохраните и обновите, игра должна работать так, как мы и планировали!

- -

Другие распространенные ошибки

- -

Существуют и другие распространенные ошибки, которые вы обнаружите в своем коде. В этом разделе показано большинство из них.

- -

SyntaxError: отсутствует ; перед постановкой

- -

Эта ошибка обычно означает что вы упустили точку с запятой в конце одной из ваших строк кода, но иногда ошибка может быть более загадочной. Например, если мы изменим эту строку внутри функции checkGuess() :

- -
var userGuess = Number(guessField.value);
- -

на эту

- -
var userGuess === Number(guessField.value);
- -

Это вызовет данную ошибку, потому что браузер подумает, что вы пытались сделать что-то другое. Вы должны быть уверены, что вы не перепутали оператор присваивания (=), который присваивает значение переменной — с оператором сравнения (===), который строго сравнивает операнды, и возвращает true/false .

- -
-

Примечание: Загляните на справочную страницу Синтаксическая ошибка: пропущен символ ; до объявления инструкции для получения дополнительной информации об этой ошибке.

-
- -

В программе всегда говорится, что вы выиграли, независимо от того, что вы ввели

- -

Причиной этому является все то же перепутывание оператора присваивания (=) со строгим сравнением (===). Например, если мы изменим внутри checkGuess() эту строку кода:

- -
if (userGuess === randomNumber) {
- -

на эту

- -
if (userGuess = randomNumber) {
- -

мы всегда будем получать true, заставляя программу сообщать, что игра была выиграна. Будьте осторожны!

- -

SyntaxError: отсутствует ) после списка аргументов

- -

Эта ошибка проста — обычно она означает, что вы пропустили закрывающую скобку с конца вызова функции / метода.

- -
-

Примечание: Загляните на справочную страницу  SyntaxError: missing ) after argument list для получения дополнительной информации об этой ошибке.

-
- -

SyntaxError: missing : after property id

- -

Эта ошибка обычно связана с неправильно сформированным объектом JavaScript, но в этом случае нам удалось получить ее, изменив

- -
function checkGuess() {
- -

на

- -
function checkGuess( {
-
- -

Это заставило браузер думать, что мы пытаемся передать содержимое функции в функцию в качестве аргумента. Будьте осторожны с этими скобками!

- -

SyntaxError: missing } after function body

- -

Это легко — обычно это означает, что вы пропустили одну из ваших фигурных скобок из функции или условной структуры. Мы получили эту ошибку, удалив одну из закрывающих фигурных скобок возле нижней части функции  checkGuess().

- -

SyntaxError: expected expression, got 'string' or SyntaxError: unterminated string literal

- -

Эти ошибки обычно означает, что вы пропустили открывающую или закрывающую кавычку для строковых значений. В первой ошибки выше,  строка  будет заменена на неожиданный персонаж (ей) , что браузер нашел вместо кавычек в начале строки. Вторая ошибка означает , что строка не закончилась кавычки.

- -

При всех этих ошибках действуйте так, как в наших  примерах, которые мы рассмотрели в пошаговом руководстве. Когда возникает ошибка, посмотрите полученный номер строки, перейдите к этой строке и посмотрите, можете ли вы определить, что случилось. Имейте в виду, что ошибка не обязательно будет на этой строке, а также, что ошибка может быть вызвана не такой же проблемой, которую мы привели выше!

- -
-

Примечание : Смотрите наш SyntaxError: Неожиданный токен и SyntaxError: незавершенная строка эталонных страниц для получения более подробной информации об этих ошибках.

-
- -

Резюме

- -

Итак, мы научились основам  выяснения ошибок в простых программах JavaScript. Не всегда так просто разобраться, что не так в вашем коде, но, по крайней мере, это сэкономит вам несколько часов сна и позволит вам продвигаться немного быстрее, когда что-либо заработает не так, как ожидалось, в вашем учебном путешествии.

- -

Смотрите также

- -
-
    -
  • Есть много других типов ошибок, которые не перечислены здесь; мы составляем ссылку , которая объясняет , что они означают подробно - см. ссылку ошибки JavaScript .
  • -
  • Если вы столкнетесь с любыми ошибками в коде, которые вы не знаете , как исправить после прочтения этой статьи, вы можете получить помощь! Спросите на нить обучения Область дискурсе , или в #mdn IRC канал на Mozilla IRC. Расскажите нам, какая у вас ошибка, и мы постараемся вам помочь. Приложите пример своего кода для большей ясности проблемы.
  • -
-
- -

{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/A_first_splash", "Learn/JavaScript/Первые_шаги/Variables", "Learn/JavaScript/Первые_шаги")}}

diff --git a/files/ru/learn/pages_sites_servers_and_search_engines/index.html b/files/ru/learn/pages_sites_servers_and_search_engines/index.html deleted file mode 100644 index 0a9b7a643f..0000000000 --- a/files/ru/learn/pages_sites_servers_and_search_engines/index.html +++ /dev/null @@ -1,118 +0,0 @@ ---- -title: 'Веб-страницы, веб-сайты, веб серверы и поисковики' -slug: Learn/Pages_sites_servers_and_search_engines -tags: - - ActiveLearning - - Beginner - - WebMechanics - - Активное изучение - - Новичку - - Программисту -translation_of: Learn/Common_questions/Pages_sites_servers_and_search_engines ---- -
-

В этой статье мы расскажем о различных понятиях связанных с Веб: о веб-страницах, веб-сайтах, веб-серверах и о поисковых системах. Эти термины часто ставят в тупик как начинающих работу с Веб, так и людей, редко пользующихся сетью. Давайте же разберемся, что именно эти понятия означают!

-
- - - - - - - - - - - - -
Необходимые знания: -

Вы должны знать,  как работает Интернет.

-
Цель:Изучить различия между веб-страницами, веб-сайтами, веб-серверами и поисковыми системами.
- -

В двух словах

- -

Как и любая другая область знаний, Веб полон специфичных терминов. Но не волнуйтесь, мы не хотим перегружать Вас в самом начале Вашего пути (а если любопытство всё же берёт верх, то у нас есть словарь). Однако, для начала несколько базовых терминов всё же придётся усвоить, так как Вы будете встречать их в наших статьях довольно часто. Иногда эти термины легко перепутать, так как они связаны между собой, но имеют разные функции. Вы, наверное, не раз замечали их неправильное употребление в новостях или где-либо ещё.

- -

Мы разберём эти понятия и технологии чуть позже, а сейчас краткие определения ниже станут для Вас очень хорошим началом:

- -
-
Веб-страница
-
Документ, который может быть отображён веб-браузерами, такими как: Firefox, Google Chrome, Microsoft Internet Explorer / Edge или Safari от Apple. Само понятие "веб-страница" для краткости будем называть просто "страница".
-
Веб-сайт
-
Коллекция веб-страниц, связанных между собой какими-либо способами. Употребление в лексике: "веб-сайт" или просто "сайт".
-
Веб-сервер
-
Компьютер, предоставляющий компьютерное и программное обеспечение, необходимое для функционирования веб-сайта.
-
Поисковая система
-
Веб-сайт, помогающий в поиске других веб-страниц, например такие как: Google, Bing или Yahoo.
-
- -

Активное изучение

- -

Пока что активное изучение не доступно. Если Вы можете предоставить полезную информацию, то, пожалуйста, окажите нам содействие

- -

Погружаемся глубже

- -

Итак, давайте копнем чуть глубже и узнаем, как эти 4 термина связаны между собой, и почему данные понятия зачастую путают друг с другом.

- -

Веб-страница

- -

Веб-страница - простой документ, отображаемый на экране компьютера посредством браузера. Такой документ написан языком HTML  (который мы рассмотрим более детально в других статьях). Веб-страница может содержать множество различных материалов, таких как:

- - - -
-

Примечание: браузеры зачастую могут отображать некоторые документы в формате PDF файла или изображения, но термин веб-страница больше относится непосредственно к HTML-документам. До конца статьи, в данном случае, мы будем использовать понятие  документ.

-
- -

Все веб-страницы в сети имеют свой уникальный адрес. Чтобы получить доступ к нужной странице просто наберите ее адрес в адресной строке Вашего браузера:

- -

Example of a web page address in the browser address bar

- - - - - - - - - - - - - -

Веб-сайт - это коллекция страниц, связанных между собой какими-либо способами (включая их связи с иными ресурсами), которые доступны под единым доменным именем. Каждая страница сайта содержит прямые ссылки (практически всегда выделенные части текста, по которым можно кликнуть мышью), что позволяет пользователю быстро переходить от одной страницы веб-сайта к другой.

- -

Чтобы получить доступ к веб-сайту, наберите его доменное имя в адресной строке браузера, и Ваш браузер отобразит главную страницу сайта или, по-другому, домашнюю страницу:

- -

Example of a web site domain name in the browser address bar

- -

Веб-страницу и веб-сайт особенно легко спутать между собой, когда сайт содержит всего одну страницу. Такой сайт иногда называют одностраничным веб-сайтом.

- -

Веб-сервер

- -

Веб-сервер - это компьютер, предоставляющий в сеть один или множество веб-сайтов (хостинг). Понятие "хостинг" - означает, что все страницы и прикрепленные к ним файлы содержатся на данном компьютере. Т.е. Веб-сервер будет отправлять любую страницу с сайта по запросу любого пользователя, что и будет хостингом для браузера пользователя.

- -

Не путайте понятия веб-сайта и веб-сервера. Например, если Вы слышите, что кто-либо говорит: "Мой веб-сайт не отвечает", на самом деле это означает, что это веб-сервер не отвечает на запрос, и поэтому недоступен и сам сайт. Более того, так как веб-сервер может разместить несколько сайтов, термин веб-сервер никогда не используется для обозначения веб-сайта, так как это могло бы привести к большой путанице. Вернемся к предыдущему примеру: если бы мы сказали: "Мой веб-сервер не отвечает", это значило бы, что на этом сервере нет доступных сайтов в данный момент.

- -

Поисковая система

- -

Поисковые системы являются распространенной причиной путаницы в сети. Поисковая система - это специальный вид веб-сайта, который помогает пользователям найти нужные страницы других сайтов.

- -

Наиболее популярные поисковые системы: Google, Bing, Yandex, DuckDuckGo, и многие другие. Некоторые из них универсальны, а какие-то ориентированы на определенную область. Используйте тот поисковик, который удобен Вам.

- -

Многие начинающие пользователи сети путают между собой поисковую систему и браузер. Давайте поясним: браузер - это программное обеспечение, которое находит и отображает веб-страницы; поисковая система - это специальный вид сайта, который помогает пользователям найти нужные страницы других сайтов. Путаница возникает из-за того, что когда кто-либо впервые запускает браузер, тот отображает домашнюю страницу поисковой системы. Это именно так, ведь первое, что Вы делаете, запуская браузер, это находите веб-страницу и открываете ее. Но не путайте инфраструктуру (т.е. браузер) с сервисом (т.е. поисковой системой). Это отличие несколько поможет Вам, но даже некоторые специалисты произвольно употребляют данные понятия, так что из-за этого не следует особо переживать. 

- -

Ниже пример того, как браузер Firerox по умолчанию отображает окно поиска Google на стартовой (домашней) странице:

- -

Example of Firefox nightly displaying a custom Google page as default

- -

Смотрите также

- - diff --git a/files/ru/learn/server-side/django/authentication/index.html b/files/ru/learn/server-side/django/authentication/index.html new file mode 100644 index 0000000000..807db42a90 --- /dev/null +++ b/files/ru/learn/server-side/django/authentication/index.html @@ -0,0 +1,688 @@ +--- +title: 'Руководство Django Часть 8: Аутентификация и авторизация пользователя' +slug: Learn/Server-side/Django/Аутентификация +tags: + - Python + - Аутентификация + - Аутентификация django + - Джанго + - Начинающий + - Обучение + - Разграничение доступа + - Руководство + - Сервер + - Статья + - Формы + - на стороне сервера + - сессии +translation_of: Learn/Server-side/Django/Authentication +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Server-side/Django/Sessions", "Learn/Server-side/Django/Forms", "Learn/Server-side/Django")}}
+ +

В данном руководстве мы продемонстрируем вам систему входа пользователя на ваш сайт используя его собственный аккаунт. Кроме того, мы покажем как реализовать  контроль того, что может видеть и делать пользователь, в зависимости от того, залогинен он, или нет, а также имеет ли он соответствующий уровень прав доступа (permissions). Для того чтобы продемонстрировать все это, мы расширим LocalLibrary, добавив страницы для входа/выхода, а также страницы просмотра/редактирования книг, специфические для пользователя и персонала.

+ + + + + + + + + + + + +
Требования:Завершить изучение предыдущих тем руководства, включая Руководство Django Часть 7: Работа с сессиями.
Цель:Понимать как настроить и использовать механизм аутентификации пользователя и разграничений прав доступа.
+ +

Обзор

+ +

Django предоставляет систему аутентификации и авторизации ("permission") пользователя, реализованную на основе фреймворка работы с сессиями, который мы рассматривали в предыдущей части. Система аутентификации и авторизации позволяет вам проверять учетные данные пользователей и определять какие действия какой пользователь может выполнять. Данный фреймворк включает в себя встроенные модели для Пользователей и Групп (основной способ применения прав доступа для более чем одного пользователя), непосредственно саму систему прав доступа (permissions)/флаги, которые определяют может ли пользователь выполнить задачу, с какой формой и отображением для авторизованых пользователей, а так же получить доступ к контенту с ограниченым доступом.

+ +
+

Примечание: В соответствии с идеологией Django система аутентификации является очень общей и, таким образом, не предоставляет некоторые возможности, которые присутствуют в других системах веб-аутентификации. Решениями некоторых общих задач занимаются пакеты сторонних разработчиков, например, защита от подбора пароля (через стороннюю библиотеку OAuth).

+
+ +

В данном разделе руководства мы покажем вам реализацию аутентификации пользователя на сайте LocalLibrary, создание страниц входа/выхода, добавления разграничения доступа (permissions) к вашим моделям, а также продемонстрируем контроль за доступом к некоторым страницам. Мы будем использовать аутентификацию/авторизацию для показа пользователям и сотрудникам библиотеки, списков книг, которые были взяты на прокат.

+ +

Система аутентификации является очень гибкой и позволяет вам формировать свои собственные URL-адреса, формы, отображения, а также шаблоны страниц, если вы пожелаете, с нуля, через простой вызов функций соответствующего API для авторизации пользователя. Тем не менее, в данной статье мы будем использовать "встроенные" в Django методы отображений и форм аутентификации, а также методы построения страниц входа и выхода. Нам все еще необходимо создавать шаблоны страниц, но это будет достаточно несложно.

+ +

Мы покажем вам как реализовать разграничение доступа (permissions), а также выполнять соответствующую проверку статусов авторизации и прав доступа, в отображениях, и в шаблонах страниц.

+ +

Подключение аутентификации

+ +

Аутентификация была подключена автоматически когда мы создали скелет сайта (в части 2), таким образом на данный момент вам ничего не надо делать.

+ +
+

Примечание: Необходимые настройки были выполнены для нас, когда мы создали приложение при помощи команды django-admin startproject. Таблицы базы данных для пользователей и модели авторизации были созданы, когда в первый раз выполнили команду python manage.py migrate.

+
+ +

Соответствующие настройки сделаны в параметрах INSTALLED_APPS и MIDDLEWARE файла проекта (locallibrary/locallibrary/settings.py), как показано ниже:

+ +
INSTALLED_APPS = [
+    ...
+    'django.contrib.auth',  # Фреймворк аутентификации и моделей по умолчанию.
+    'django.contrib.contenttypes',  # Django контент-типовая система (даёт разрешения, связанные с моделями).
+    ....
+
+MIDDLEWARE = [
+    ...
+    'django.contrib.sessions.middleware.SessionMiddleware',  # Управление сессиями между запросами
+    ...
+    'django.contrib.auth.middleware.AuthenticationMiddleware',  # Связывает пользователей, использующих сессии, запросами.
+    ....
+
+ +

Создание пользователей и групп

+ +

Вы уже создали своего первого пользователя когда мы рассматривали Административная панель сайта Django в части 4 (это был суперпользователь, созданный при помощи команды python manage.py createsuperuser). Наш суперпользователь уже авторизован и имеет все необходимые уровни доступа к данным и функциям, таким образом нам необходимо создать тестового пользователя для отработки соответствующей работы сайта. В качестве наиболее быстрого способа, мы будем использовать административную панель сайта для создания соответствующих групп и акканутов locallibrary.

+ +
+

Примечание: Вы можете создавать пользователей программно, как показано ниже. Например, вам мог бы подойти данный способ в том случае, если вы разрабатываете интерфейс, который позволяет пользователям создавать их собственные аккаунты (вы не должны предоставлять доступ пользователям к административной панели вашего сайта).

+ +
from django.contrib.auth.models import User
+
+# Создайте пользователя и сохраните его в базе данных
+user = User.objects.create_user('myusername', 'myemail@crazymail.com', 'mypassword')
+
+# Обновите поля и сохраните их снова
+user.first_name = 'John'
+user.last_name = 'Citizen'
+user.save()
+
+
+ +

Ниже мы создадим группу, а затем пользователя. Несмотря на то, что у нас пока нет никаких  разрешений для добавления к нашей библиотеке каких-либо членов, если мы захотим это сделать в будущем, то будет намного проще добавлять их к уже созданной группе, с заданной аутентификацией.

+ +

Запустите сервер разработки и перейдите к административной панели вашего сайта (http://127.0.0.1:8000/admin/). Залогиньтесь на сайте при помощи параметров (имя пользователя и пароля) аккаунта суперпользователя. Самая "верхняя" страница панели Администратора показывает все наши модели. Для того, чтобы увидеть записи в разделе Authentication and Authorisation вы можете нажать на ссылку Users, или Groups.

+ +

Admin site - add groups or users

+ +

В первую очередь, в качестве нового члена нашего сайта, давайте создадим новую группу.

+ +
    +
  1. Нажмите на кнопку Add (Добавить) (рядом с Group) и создайте новую группу; для данной группы введите Name (Имя) "Library Members".Admin site - add group
  2. +
  3. Для данной группы не нужны какие-либо разрешения, поэтому мы просто нажимаем кнопку SAVE (Сохранить) (вы перейдете к списку групп).
  4. +
+ +

Теперь давайте создадим пользователя:

+ +
    +
  1. Перейдите обратно на домашнюю страницу административной панели
  2. +
  3. Для перехода к диалогу добавления пользователя нажмите на кнопку Add, соответствующую строке Users (Пользователи).Admin site - add user pt1
  4. +
  5. Введите соответствующие Username (имя пользователя) и Password/Password confirmation (пароль/подтверждение пароля) для вашего тестового пользователя
  6. +
  7. Нажмите SAVE для завершения процесса создания пользователя.
    +
    + Административная часть сайта создаст нового пользователя и немедленно перенаправит вас на страницу Change user (Изменение параметров пользователя) где вы можете, соответственно, изменить ваш username, а кроме того добавить информацию для дополнительных полей модели User. Эти поля включают в себя имя пользователя, фамилию, адрес электронной почты, статус пользователя, а также соответствующие параметры доступа (может быть установлен только флаг  Active). Ниже вы можете определить группу для пользователя и необходимые параметры доступа, а кроме того, вы можете увидеть важные даты, относящиеся к пользователю (дату подключения к сайту и дату последнего входа).Admin site - add user pt2
  8. +
  9. В разделе Groups, из списка Доступные группы выберите группу Library Member, а затем переместите ее в блок "Выбранные группы" (нажмите стрелку-"направо", находящуюся между блоками).Admin site - add user to group
  10. +
  11. Больше нам не нужно здесь нечего делать, просто нажмите "Save"(Сохранить), и вы вернетесь к списку созданых пользователей.
  12. +
+ +

Вот и все! Теперь у вас есть учетная запись «обычного члена библиотеки», которую вы сможете использовать для тестирования (как только добавим страницы, чтобы пользователи могли войти в систему).

+ +
+

Note: Попробуйте создать другого пользователя, например "Библиотекаря". Так же создайте группу "Библиотекарей" и добавьте туда своего только что созданного библиотекаря

+
+ +

Настройка представлений проверки

+ +

Django предоставляет почти все, что нужно для создания страниц аутентификации входа, выхода из системы и управления паролями из коробки. Это включает в себя url-адреса, представления (views) и формы,но не включает шаблоны — мы должны создать свой собственный шаблон!

+ +

В этом разделе мы покажем, как интегрировать систему по умолчанию в Сайт LocalLibrary и создать шаблоны.  Мы поместим их в основные URL проекта.

+ +
+

Заметка: Вы не должны использовать этот код, но вполне вероятно, что вы хотите, потому что это делает вещи намного проще. Вам почти наверняка потребуется изменить код обработки формы, если вы измените свою модель пользователя (сложная тема!) но даже в этом случае вы все равно сможете использовать функции просмотра запасов.

+
+ +
+

Заметка: В этом случае мы могли бы разумно поместить страницы аутентификации, включая URL-адреса и шаблоны, в наше приложение каталога. Однако, если бы у нас было несколько приложений, было бы лучше отделить это общее поведение входа в систему и иметь его доступным на всем сайте, так что это то, что мы показали здесь!

+
+ +

Проектирование URLs

+ +

Добавьте следующее в нижней части проекта urls.py файл (locallibrary/locallibrary/urls.py) файл:

+ +
#Add Django site authentication urls (for login, logout, password management)
+urlpatterns += [
+    path('accounts/', include('django.contrib.auth.urls')),
+]
+
+ +

Перейдите по http://127.0.0.1:8000/accounts/ URL (обратите внимание на косую черту!), Django покажет ошибку, что он не смог найти этот URL, и перечислить все URL, которые он пытался открыть. Из этого Вы можете увидеть URL-адреса, которые будут работать, например:

+ +
+

Примечание. Использование вышеуказанного метода добавляет следующие URL-адреса с именами в квадратных скобках, которые могут использоваться для изменения сопоставлений URL-адресов. Вам не нужно реализовывать что-либо еще - приведенное выше сопоставление URL-адресов автоматически отображает указанные ниже URL-адреса.

+
+ +
+
accounts/ login/ [name='login']
+accounts/ logout/ [name='logout']
+accounts/ password_change/ [name='password_change']
+accounts/ password_change/done/ [name='password_change_done']
+accounts/ password_reset/ [name='password_reset']
+accounts/ password_reset/done/ [name='password_reset_done']
+accounts/ reset/<uidb64>/<token>/ [name='password_reset_confirm']
+accounts/ reset/done/ [name='password_reset_complete']
+
+ +

Теперь попробуйте перейти к URL-адресу входа (http://127.0.0.1:8000/accounts/login/). Это приведет к сбою снова, но с ошибкой, сообщающей вам, что нам не хватает требуемого шаблона (registration / login.html) в пути поиска шаблона. Вы увидите следующие строки, перечисленные в желтом разделе вверху:

+ +
Exception Type:    TemplateDoesNotExist
+Exception Value:    registration/login.html
+ +

Следующий шаг - создать каталог регистрации в пути поиска, а затем добавить файл login.html.

+ +

Каталог шаблонов

+ +

URL-адреса (и неявные представления), которые мы только что добавили, ожидают найти связанные с ними шаблоны в каталоге / регистрации / где-то в пути поиска шаблонов.
+
+ Для этого сайта мы разместим наши HTML-страницы в каталоге templates / registration /. Этот каталог должен находиться в корневом каталоге проекта, то есть в том же каталоге, что и в каталоге и папках locallibrary). Создайте эти папки сейчас.

+ +
+

Примечание: Ваша структура папок теперь должна выглядеть как показано внизу:
+ locallibrary (django project folder)
+    |_catalog
+    |_locallibrary
+    |_templates (new)
+                 |_registration

+
+ +

Чтобы сделать эти директории видимыми для загрузчика шаблонов   (т. е. помещать этот каталог в путь поиска шаблона) откройте настройки проекта (/locallibrary/locallibrary/settings.py), и обновите в секции TEMPLATES строку 'DIRS' как показано.

+ +
TEMPLATES = [
+    {
+        ...
+        'DIRS': [os.path.join(BASE_DIR, 'templates')],
+        'APP_DIRS': True,
+        ...
+
+ +

Шаблон аутентификации

+ +
+

Важно: Шаблоны аутентификации, представленные в этой статье, являются очень простой / слегка измененной версией шаблонов логина демонстрации Django. Возможно, вам придется настроить их для собственного использования!

+
+ +

Создайте новый HTML файл, названный /locallibrary/templates/registration/login.html. дайте ему следующее содержание:

+ +
{% extends "base_generic.html" %}
+
+{% block content %}
+
+{% if form.errors %}
+  <p>Your username and password didn't match. Please try again.</p>
+{% endif %}
+
+{% if next %}
+  {% if user.is_authenticated %}
+    <p>Your account doesn't have access to this page. To proceed,
+    please login with an account that has access.</p>
+  {% else %}
+    <p>Please login to see this page.</p>
+  {% endif %}
+{% endif %}
+
+<form method="post" action="{% url 'login' %}">
+{% csrf_token %}
+<table>
+
+<tr>
+  <td>\{{ form.username.label_tag }}</td>
+  <td>\{{ form.username }}</td>
+</tr>
+
+<tr>
+  <td>\{{ form.password.label_tag }}</td>
+  <td>\{{ form.password }}</td>
+</tr>
+</table>
+
+<input type="submit" value="login" />
+<input type="hidden" name="next" value="\{{ next }}" />
+</form>
+
+{# Assumes you setup the password_reset view in your URLconf #}
+<p><a href="{% url 'password_reset' %}">Lost password?</a></p>
+
+{% endblock %}
+ +

Этот шаблон имеет сходство с тем, что мы видели раньше - он расширяет наш базовый шаблон и переопределяет блок контента. Остальная часть кода - это довольно стандартный код обработки формы, о котором мы поговорим в следующем учебном пособии. Все, что вам нужно знать, это показ формы, в которой вы можете ввести свое имя пользователя и пароль, а если вы введете недопустимые значения, вам будет предложено ввести правильные значения, когда страница обновится.

+ +

Перейдите на страницу входа (http://127.0.0.1:8000/accounts/login/) когда вы сохраните свой шаблон, и вы должны увидеть что-то наподобие этого:

+ +

Library login page v1

+ +

Если ваша попытка войти в систему будет успешной,  вы будете перенаправлены на другую страницу (по умолчанию это будет http://127.0.0.1:8000/accounts/profile/). Проблема здесь в том, что по умолчанию Django ожидает, что после входа в систему вы захотите перейти на страницу профиля, что может быть или не быть. Поскольку вы еще не определили эту страницу, вы получите еще одну ошибку!
+
+ Откройте настройки проекта (/locallibrary/locallibrary/settings.py) и добавьте текст ниже. Теперь, когда вы входите в систему, вы по умолчанию должны перенаправляться на домашнюю страницу сайта.

+ +
# Redirect to home URL after login (Default redirects to /accounts/profile/)
+LOGIN_REDIRECT_URL = '/'
+
+ +

Шаблон выхода

+ +

Если вы перейдете по URL-адресу выхода (http://127.0.0.1:8000/accounts/logout/), то увидите странное поведение - ваш пользователь наверняка выйдет из системы, но вы попадете на страницу выхода администратора. Это не то, что вам нужно, хотя бы потому, что ссылка для входа на этой странице приведет вас к экрану входа в систему администратора. (и это доступно только для пользователей, у которых есть разрешение is_staff).
+
+ Создайте и откройте /locallibrary/templates/registration/logged_out.html. Скопируйте текст ниже:

+ +
{% extends "base_generic.html" %}
+
+{% block content %}
+<p>Logged out!</p>
+
+<a href="{% url 'login'%}">Click here to login again.</a>
+{% endblock %}
+ +

Этот шаблон очень прост. Он просто отображает сообщение, информирующее вас о том, что вы вышли из системы, и предоставляет ссылку, которую вы можете нажать, чтобы вернуться на экран входа в систему. Если вы снова перейдете на страницу выхода из системы, вы увидите эту страницу:

+ +

Library logout page v1

+ +

Шаблон сброса пароля

+ +

Система сброса пароля по умолчанию использует электронную почту, чтобы отправить пользователю ссылку на сброс. Вам необходимо создать формы, чтобы получить адрес электронной почты пользователя, отправить электронное письмо, разрешить им вводить новый пароль и отметить, когда весь процесс будет завершен.
+
+ В качестве отправной точки можно использовать следующие шаблоны.

+ +

Форма сброса пароля

+ +

Это форма, используемая для получения адреса электронной почты пользователя (для отправки пароля для сброса пароля). Создайте /locallibrary/templates/registration/password_reset_form.html и дайте ему следующее содержание:

+ +
{% extends "base_generic.html" %}
+{% block content %}
+
+<form action="" method="post">{% csrf_token %}
+    {% if form.email.errors %} \{{ form.email.errors }} {% endif %}
+        <p>\{{ form.email }}</p>
+    <input type="submit" class="btn btn-default btn-lg" value="Reset password" />
+</form>
+
+{% endblock %}
+
+ +

Сброс пароля

+ +

Эта форма отображается после того, как ваш адрес электронной почты будет собран. Создайте /locallibrary/templates/registration/password_reset_done.html, и дайте ему следующее содержание:

+ +
{% extends "base_generic.html" %}
+{% block content %}
+<p>We've emailed you instructions for setting your password. If they haven't arrived in a few minutes, check your spam folder.</p>
+{% endblock %}
+
+ +

Сброс пароля по email

+ +

Этот шаблон предоставляет текст электронной почты HTML, содержащий ссылку на сброс, которую мы отправим пользователям. Создайте /locallibrary/templates/registration/password_reset_email.html и дайте ему следующее содержание:

+ +
Someone asked for password reset for email \{{ email }}. Follow the link below:
+\{{ protocol}}://\{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
+
+ +

Подтверждение на сброс пароля

+ +

На этой странице вы вводите новый пароль после нажатия ссылки в электронном письме с возвратом пароля. Создайте /locallibrary/templates/registration/password_reset_confirm.html и дайте ему следующее содержание:

+ +
{% extends "base_generic.html" %}
+
+{% block content %}
+
+    {% if validlink %}
+        <p>Please enter (and confirm) your new password.</p>
+        <form action="" method="post">
+            {% csrf_token %}
+            <table>
+                <tr>
+                    <td>\{{ form.new_password1.errors }}
+                        <label for="id_new_password1">New password:</label></td>
+                    <td>\{{ form.new_password1 }}</td>
+                </tr>
+                <tr>
+                    <td>\{{ form.new_password2.errors }}
+                        <label for="id_new_password2">Confirm password:</label></td>
+                    <td>\{{ form.new_password2 }}</td>
+                </tr>
+                <tr>
+                    <td></td>
+                    <td><input type="submit" value="Change my password" /></td>
+                </tr>
+            </table>
+        </form>
+    {% else %}
+        <h1>Password reset failed</h1>
+        <p>The password reset link was invalid, possibly because it has already been used. Please request a new password reset.</p>
+    {% endif %}
+
+{% endblock %}
+
+ +

Сброс пароля завершен

+ +

Это последний шаблон сброса пароля, который отображается, чтобы уведомить вас о завершении сброса пароля. Создайте /locallibrary/templates/registration/password_reset_complete.html и дайте ему следующее содержание:

+ +
{% extends "base_generic.html" %}
+{% block content %}
+
+<h1>The password has been changed!</h1>
+<p><a href="{% url 'login' %}">log in again?</a></p>
+
+{% endblock %}
+ +

Тестирование новых страниц аутентификации

+ +

Теперь, когда вы добавили конфигурацию URL и создали все эти шаблоны, теперь страницы аутентификации должны работать! Вы можете протестировать новые страницы аутентификации, попытавшись войти в систему, а затем выйдите из учетной записи суперпользователя, используя эти URL-адреса:

+ + + +

Вы сможете проверить функцию сброса пароля по ссылке на странице входа. Имейте в виду, что Django отправляет только сбросные электронные письма на адреса (пользователи), которые уже хранятся в его базе данных!

+ +
+

Заметка: Система сброса пароля требует, чтобы ваш сайт поддерживал электронную почту, что выходит за рамки этой статьи, поэтому эта часть еще не будет работать. Чтобы разрешить тестирование, поместите следующую строку в конец файла settings.py. Это регистрирует любые письма, отправленные на консоль (чтобы вы могли скопировать ссылку на сброс пароля с консоли).

+ +
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
+
+ +

Для получения дополнительной информации см. Отправка email (Django docs).

+
+ +

Тестирование проверки подлинности пользователей

+ +

В этом разделе мы рассмотрим, что мы можем сделать, чтобы выборочно контролировать контент, который видят пользователи, на основе того, вошли ли они в систему или нет.

+ +

Тестирование в шаблонах

+ +

Вы можете получить информацию о текущем зарегистрированном пользователе в шаблонах с переменной шаблона \{{user}} (это добавляется в контекст шаблона по умолчанию при настройке проекта, как и в нашем скелете).

+ +

Обычно вы сначала проверяете переменную шаблона \{{user.is_authenticated}}, чтобы определить, имеет ли пользователь право видеть конкретный контент. Чтобы продемонстрировать это, мы обновим нашу боковую панель, чтобы отобразить ссылку «Вход», если пользователь вышел из системы, и ссылку «Выход», если он вошёл в систему.

+ +

Откройте базовый шаблон (/locallibrary/catalog/templates/base_generic.html) и скопируйте следующий текст в sidebar блок непосредственно перед тегом шаблона endblock.

+ +
  <ul class="sidebar-nav">
+
+    ...
+
+   {% if user.is_authenticated %}
+     <li>User: \{{ user.get_username }}</li>
+     <li><a href="{% url 'logout'%}?next=\{{request.path}}">Logout</a></li>
+   {% else %}
+     <li><a href="{% url 'login'%}?next=\{{request.path}}">Login</a></li>
+   {% endif %} 
+  </ul>
+ +

Как вы можете видеть, мы используем теги шаблона if-else-endif для условного отображения текста на основе того, является ли \{{user.is_authenticated}} истинным. Если пользователь аутентифицирован, мы знаем, что у нас есть действительный пользователь, поэтому мы вызываем \{{user.get_username}}, чтобы отобразить их имя.

+ +

Мы создаем URL-адрес для входа и выхода из системы, используя тег шаблона URL-адреса и имена соответствующих конфигураций URLs. Также обратите внимание на то, как мы добавили ?next=\{{request.path}} в конец URLs. Это означает, что следующий URL-адрес содержит адрес (URL) текущей страницы, в конце связанного URL-адреса. После того, как пользователь успешно выполнил вход в систему, представления будут использовать значение "next" чтобы перенаправить пользователя обратно на страницу, где они сначала нажали ссылку входа / выхода из системы.

+ +
+

Примечание: Попробуйте! Если вы находитесь на главной странице и вы нажимаете «Вход / Выход» на боковой панели, то после завершения операции вы должны вернуться на ту же страницу.

+
+ +

Тестирование в представлениях

+ +

Если вы используете функциональные представления, самым простым способом ограничить доступ к вашим функциям является применение login_required декоратор к вашей функции просмотра, как показано ниже. Если пользователь вошел в систему, ваш код просмотра будет выполняться как обычно. Если пользователь не вошел в систему, это перенаправит URL-адрес входа, определенный в настройках проекта. (settings.LOGIN_URL), передав текущий абсолютный путь в качестве next параметра URL. Если пользователю удастся войти в систему, они будут возвращены на эту страницу, но на этот раз аутентифицированы.

+ +
from django.contrib.auth.decorators import login_required
+
+@login_required
+def my_view(request):
+    ...
+ +
+

Заметка: Вы можете сделать то же самое вручную, путём тестирования request.user.is_authenticated, но декоратор намного удобнее!

+
+ +

Аналогичным образом, самый простой способ ограничить доступ к зарегистрированным пользователям в ваших представлениях на основе классов - это производные от LoginRequiredMixin. Вы должны объявить этот mixin сначала в списке суперкласса, перед классом основного представления.

+ +
from django.contrib.auth.mixins import LoginRequiredMixin
+
+class MyView(LoginRequiredMixin, View):
+    ...
+ +

Это имеет такое же поведение при переадресации, что и  login_required декоратор. Вы также можете указать альтернативное местоположение для перенаправления пользователя, если он не аутентифицирован (login_url), и имя параметра URL вместо "next" , чтобы вставить текущий абсолютный путь (redirect_field_name).

+ +
class MyView(LoginRequiredMixin, View):
+    login_url = '/login/'
+    redirect_field_name = 'redirect_to'
+
+ +

Для получения дополнительной информации ознакомьтесь с  Django docs here.

+ +

Пример - перечисление книг текущего пользователя

+ +

Теперь, когда мы знаем, как ограничить страницу определенному пользователю, создайте представление о книгах, которые заимствовал текущий пользователь.

+ +

К сожалению, у нас пока нет возможности пользователям использовать книги! Поэтому, прежде чем мы сможем создать список книг, мы сначала расширим BookInstance модель для поддержки концепции заимствования и использования приложения Django Admin для заимствования ряда книг нашему тестовому пользователю.

+ +

Модели

+ +

Прежде всего, мы должны предоставить пользователям возможность кредита на BookInstance (у нас уже есть status и due_back дата, но у нас пока нет связи между этой моделью и пользователем. Мы создадим его с помощью поля ForeignKey (один ко многим). Нам также нужен простой механизм для проверки того, просрочена ли заемная книга.

+ +

Откройте catalog/models.py, и импортируйте модель User из django.contrib.auth.models (добавьте это чуть ниже предыдущей строки импорта в верхней части файла, так User доступен для последующего кода, что позволяет использовать его):

+ +
from django.contrib.auth.models import User
+
+ +

Затем добавьте поле borrower в модель BookInstance:

+ +
borrower = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
+
+ +

Пока мы здесь, давайте добавим свойство, которое мы можем вызвать из наших шаблонов, чтобы указать, просрочен ли конкретный экземпляр книги. Хотя мы могли бы рассчитать это в самом шаблоне, использование свойства, как показано ниже, будет намного более эффективным. Добавьте это где-нибудь в верхней части файла:

+ +
from datetime import date
+ +

Теперь добавьте следующее определение свойства внутри класса BookInstance:

+ +
@property
+def is_overdue(self):
+    if self.due_back and date.today() > self.due_back:
+        return True
+    return False
+ +
+

Примечание. Сначала мы проверим, является ли due_back пустым, прежде чем проводить сравнение. Пустое поле due_back заставило Django выкидывать ошибку, а не показывать страницу: пустые значения не сопоставимы. Это не то, что мы хотели бы, чтобы наши пользователи испытывали!

+
+ +

Теперь, когда мы обновили наши модели, нам нужно будет внести новые изменения в проект, а затем применить эти миграции:

+ +
python3 manage.py makemigrations
+python3 manage.py migrate
+
+ +

Admin

+ +

Теперь откройте каталог catalog/admin.py, и добавьте поле borrower в класс BookInstanceAdmin , как в list_display , так и в полях fieldsets , как показано ниже. Это сделает поле видимым в разделе Admin, так что мы можем при необходимости назначить User в BookInstance.

+ +
@admin.register(BookInstance)
+class BookInstanceAdmin(admin.ModelAdmin):
+    list_display = ('book', 'status', 'borrower', 'due_back', 'id')
+    list_filter = ('status', 'due_back')
+
+    fieldsets = (
+        (None, {
+            'fields': ('book','imprint', 'id')
+        }),
+        ('Availability', {
+            'fields': ('status', 'due_back','borrower')
+        }),
+    )
+ +

Займите несколько книг

+ +

Теперь, когда возможно кредитовать книги конкретному пользователю, зайдите и заработайте на нескольких записей в BookInstance. Установите borrowed поле вашему тестовому пользователю, сделайте status «В займе» и установите сроки оплаты как в будущем, так и в прошлом.

+ +
+

Заметка: Мы не будем описывать процесс, так как вы уже знаете, как использовать Admin сайт!

+
+ +

Займ в представлении

+ +

Теперь мы добавим представление для получения списка всех книг, которые были предоставлены текущему пользователю. Мы будем использовать один и тот же общий класс, с которым мы знакомы, но на этот раз мы также будем импортировать и выводить из  LoginRequiredMixin, так что только вошедший пользователь сможет вызвать это представление. Мы также решили объявить  template_name, вместо того, чтобы использовать значение по умолчанию, потому что у нас может быть несколько разных списков записей BookInstance, с разными представлениями и шаблонами.

+ +

Добавьте следующее в catalog/views.py:

+ +
from django.contrib.auth.mixins import LoginRequiredMixin
+
+class LoanedBooksByUserListView(LoginRequiredMixin,generic.ListView):
+    """
+    Generic class-based view listing books on loan to current user.
+    """
+    model = BookInstance
+    template_name ='catalog/bookinstance_list_borrowed_user.html'
+    paginate_by = 10
+
+    def get_queryset(self):
+        return BookInstance.objects.filter(borrower=self.request.user).filter(status__exact='o').order_by('due_back')
+ +

Чтобы ограничить наш запрос только объектами BookInstance для текущего пользователя, мы повторно реализуем get_queryset(), как показано выше. Обратите внимание, что "o" это сохраненный код для "on loan" и мы сортируем по дате due_back, чтобы сначала отображались самые старые элементы.

+ +

URL-адрес для заёмных книг

+ +

Теперь откройте /catalog/urls.py и добавьте url() , указывая на приведённое выше представление (вы можете просто скопировать текст ниже в конец файла).

+ +
urlpatterns += [
+    url(r'^mybooks/$', views.LoanedBooksByUserListView.as_view(), name='my-borrowed'),
+]
+ +

Шаблон для заёмных книг

+ +

Теперь все, что нам нужно сделать для этой страницы, - это добавить шаблон. Сначала создайте файл шаблона /catalog/templates/catalog/bookinstance_list_borrowed_user.html и дайте ему следующее содержание:

+ +
{% extends "base_generic.html" %}
+
+{% block content %}
+    <h1>Borrowed books</h1>
+
+    {% if bookinstance_list %}
+    <ul>
+
+      {% for bookinst in bookinstance_list %}
+      <li class="{% if bookinst.is_overdue %}text-danger{% endif %}">
+        <a href="{% url 'book-detail' bookinst.book.pk %}">\{{bookinst.book.title}}</a> (\{{ bookinst.due_back }})
+      </li>
+      {% endfor %}
+    </ul>
+
+    {% else %}
+      <p>There are no books borrowed.</p>
+    {% endif %}
+{% endblock %}
+ +

Этот шаблон очень похож на тот, который мы создали ранее для объектов Book и Author. Единственное, что «новое» здесь, это то, что мы проверяем метод, который мы добавили в модель (bookinst.is_overdue) с целью использовать его для изменения цвета просроченных предметов.

+ +

Когда сервер разработки запущен, вы должны теперь иметь возможность просматривать список для зарегистрированного пользователя в своем браузере по адресу  http://127.0.0.1:8000/catalog/mybooks/. Попробуйте это, когда ваш пользователь войдет в систему и выйдет из системы (во втором случае вы должны быть перенаправлены на страницу входа в систему).

+ +

Добавить список на боковую панель

+ +

Последний шаг - добавить ссылку на эту новую страницу в sidebar. Мы поместим это в тот же раздел, где мы покажем другую информацию для зарегистрированного пользователя.

+ +

Откройте базовый шаблон (/locallibrary/catalog/templates/base_generic.html) и добавьте выделенную строку из sidebar, как показано на рисунке.

+ +
 <ul class="sidebar-nav">
+   {% if user.is_authenticated %}
+   <li>User: \{{ user.get_username }}</li>
+   <li><a href="{% url 'my-borrowed' %}">My Borrowed</a></li>
+   <li><a href="{% url 'logout'%}?next=\{{request.path}}">Logout</a></li>
+   {% else %}
+   <li><a href="{% url 'login'%}?next=\{{request.path}}">Login</a></li>
+   {% endif %}
+ </ul>
+
+ +

На что это похоже?

+ +

Когда любой пользователь войдет в систему, он будет видеть ссылку «Мной позаимствовано (My Borrowed)» в боковой колонке, и список книг, показанных ниже (первая книга не имеет установленной даты, что является ошибкой, которую мы надеемся исправить в более позднем уроке!).

+ +

Library - borrowed books by user

+ +

Права доступа

+ +

Права доступа связаны с моделями и определяют операции, которые могут выполняться на экземпляре модели самим пользователем, у которого есть разрешение. По умолчанию Django автоматически дает добавить, изменить, и удалить разрешения у всех моделей, которые позволяют пользователям с правом доступа выполнять связанные действия через администратора сайта. Вы можете определить свои собственные разрешения для моделей и предоставить их конкретным пользователям. Вы также можете изменить разрешения, связанные с разными экземплярами одной и той же модели. Тестирование разрешений в представлениях и шаблонах очень похоже на тестирование по статусу аутентификации (фактически, тестирование прав доступа также проверяет аутентификацию).

+ +

Модели

+ +

Определение разрешений выполняется в разделе моделей "class Meta" , используется permissions поле. Вы можете указать столько разрешений, сколько необходимо в кортеже, причем каждое разрешение определяется во вложенном кортеже, содержащем имя разрешения и отображаемое значение разрешения. Например, мы можем определить разрешение, позволяющее пользователю отметить, что книга была возвращена, как показано здесь:

+ +
class BookInstance(models.Model):
+    ...
+    class Meta:
+        ...
+        permissions = (("can_mark_returned", "Set book as returned"),)   
+ +

Затем мы могли бы назначить разрешение группе «Библиотекарь» (Librarian) на сайте администратора.

+ +

Откройте catalog/models.py, и добавьте разрешение, как показано выше. Вам нужно будет повторно выполнить миграцию (вызвав python3 manage.py makemigrations и python3 manage.py migrate) для надлежащего обновления базы данных.

+ +

Шаблоны

+ +

Разрешения текущего пользователя хранятся в переменной шаблона, называемой  \{{ perms }}. Вы можете проверить, имеет ли текущий пользователь определенное разрешение, используя конкретное имя переменной в соответствующем приложении «Django» - например, \{{ perms.catalog.can_mark_returned }} будет True если у пользователя есть это разрешение, а False - в противном случае. Обычно мы проверяем разрешение с использованием шаблона {% if %}, как показано в:

+ +
{% if perms.catalog.can_mark_returned %}
+    <!-- We can mark a BookInstance as returned. -->
+    <!-- Perhaps add code to link to a "book return" view here. -->
+{% endif %}
+
+ +

Представления

+ +

Разрешения можно проверить в представлении функции, используя  permission_required декоратор или в представлении на основе классов, используя PermissionRequiredMixin. шаблон и поведение такие же, как для аутентификации входа в систему, хотя, конечно, вы можете разумно добавить несколько разрешений.

+ +

Функция в представлении с декоратором:

+ +
from django.contrib.auth.decorators import permission_required
+
+@permission_required('catalog.can_mark_returned')
+@permission_required('catalog.can_edit')
+def my_view(request):
+    ...
+ +

Требуется разрешение mixin для представлений на основе классов.

+ +
from django.contrib.auth.mixins import PermissionRequiredMixin
+
+class MyView(PermissionRequiredMixin, View):
+    permission_required = 'catalog.can_mark_returned'
+    # Or multiple permissions
+    permission_required = ('catalog.can_mark_returned', 'catalog.can_edit')
+    # Note that 'catalog.can_edit' is just an example
+    # the catalog application doesn't have such permission!
+ +

Пример

+ +

Мы не будем обновлять LocalLibrary здесь; возможно, в следующем уроке!

+ +

Испытайте себя

+ +

 Ранее в этой статье мы показали вам, как создать страницу для текущего пользователя, в которой перечислены книги, которые они заимствовали. Теперь задача состоит в том, чтобы создать аналогичную страницу, которая видна только для библиотекарей, которая отображает  все книги, которые были заимствованы, и которая показывает имя каждого заемщика.

+ +

 Вы должны следовать той же схеме, что и для другого представления. Главное отличие состоит в том, что вам нужно ограничить представление только библиотекарями. Вы можете сделать это на основе того, является ли пользователь сотрудником (декоратор функции:  staff_member_required, переменная шаблона: user.is_staff) но мы рекомендуем вам вместо этого использовать  can_mark_returned разрешения и PermissionRequiredMixin, как описано в предыдущем разделе.

+ +
+

Важно: Не забудьте использовать вашего суперпользователя для тестирования на основе разрешений (проверки разрешений всегда возвращают true для суперпользователей, даже если разрешение еще не определено!). Вместо этого создайте пользователя-библиотекаря и добавьте необходимые возможности.

+
+ +

 Когда вы закончите, ваша страница должна выглядеть примерно, как на скриншоте ниже.

+ +

All borrowed books, restricted to librarian

+ + + +

Подводим итоги

+ +

 Отличная работа - теперь вы создали веб-сайт, на котором участники библиотеки могут входить в систему и просматривать собственный контент, и библиотекари (с правом доступа) могут просматривать все заемные книги с их читатетелями. На данный момент мы все еще просто просматриваем контент, но те же принципы и методы используются, когда вы хотите начать изменять и добавлять данные.

+ +

 В следующей статье мы рассмотрим, как вы можете использовать формы Django для сбора пользовательского ввода, а затем начнём изменять некоторые из наших сохраненных данных.

+ +

Смотрите также

+ + + +

{{PreviousMenuNext("Learn/Server-side/Django/Sessions", "Learn/Server-side/Django/Forms", "Learn/Server-side/Django")}}

diff --git a/files/ru/learn/server-side/django/deployment/index.html b/files/ru/learn/server-side/django/deployment/index.html new file mode 100644 index 0000000000..640527b63d --- /dev/null +++ b/files/ru/learn/server-side/django/deployment/index.html @@ -0,0 +1,680 @@ +--- +title: 'Django Руководство часть 11: Разворачивание сайта на сервере' +slug: Learn/Server-side/Django/Разворачивание +tags: + - Веб-сервер + - Для начинающих + - Разворачивание на сервере + - Развёртывание Django +translation_of: Learn/Server-side/Django/Deployment +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Server-side/Django/Testing", "Learn/Server-side/Django/web_application_security", "Learn/Server-side/Django")}}
+ +

Теперь, когда вы создали (и протестировали) свой шикарный сайт LocalLibrary, у вас скорее всего, есть желание разместить его на публичном веб-сервере, чтобы он стал доступен через интернет персоналу  и посетителям библотеки. Данная статья дает общее представление о том, каким образом подойти к поиску хостинга для рамещения сайта, а также, что нужно сделать чтобы подготовить свой сайт к публикации.

+ + + + + + + + + + + + +
Требования:Завершить изучение всех предыдущих частей руководства, включая Django Руководство часть 10:  Тестирование веб-приложений в Django.
Цель:Изучить, где и как вы можете развернуть приложение Django для публичного доступа.
+ +

Обзор

+ +

Даже когда разработка вашего сайта завершена (или "достаточно" завершена для начала публичного тестирования), то для публичного доступа вам надо его где-то разместить.

+ +

До сего момента вы работали в каком-то рабочем окружении - чтобы получать отладочную и другую частную информацию, вы использовали веб-сервер Django в локальной сети при этом запускали сайт с (небезопасными) настройками разработки. Перед тем как разместить сайт публично, вы должны сделать следующее:

+ + + +

Данное руководство предоставляет небольшой обзор выбора хостинга, приготовления сайта к публичному размещению, а также практический пример установки сайта LocalLibrary на облачный сервис Heroku.

+ +

Что такое окружение развертывания?

+ +

Окружение развертывания - это среда, которое предоставляет сервер, на котором вы будете размещать свой веб-сайт для публичного запуска и доступа. Данное окружение включает в себя:

+ + + +
+

Примечание: У вас может быть потребность в обратном прокси, балансировщике загрузки и так далее.

+
+ +

Сервер может быть вашим собственным с подключением к интернету по скоростному каналу, но более общим подходом является применение "облачных решений". Что действительно имеет значение, так это то, что ваш код запускается на некотором удаленном компьютере (возможно и "виртуальном"), в хостинговом дата-центре. Удаленный сервер обычно предоставляет определенный доступ к компьютерным ресурсам (процессору, оперативной памяти, памяти на жестких носителях и так далее) и соединение с интернетом за некоторую цену.

+ +

Такой тип удаленного доступа к вычислительному/сетевому железу называется Инфраструктура как Сервис (Infrastructure as a Service - IaaS). Множество IaaS поставщиков предлагают услуги по предустановке какой-либо операционной системы, на которую вы можете установить необходимые для вашего рабочего окружения компоненты. Другие поставщики предлагают вам выбрать уже готовые полноценные рабочие окружения, возможно, включающие в себя Django и настроенный веб-сервер.

+ +
+

Примечание: Готовые окружения могут сделать настройку вашего веб-сайта очень простой задачей, поскольку они имеют минимальную конфигурацию, однако, либо количество доступных опций может быть недостаточным, или они будут соответствовать устаревшей операционной системе. Часто, более предпочтительно установить необходимые компоненты самостоятельно, таким образом вы получите то, что вам необходимо, а в последующем, при обновлении системы, уже будете знать что нужно делать!

+
+ +

Некоторые провайдеры поддерживают Django как часть своего предложения Платформа как Сервис (Platform as a Service - PaaS). При данном виде хостинга вам не нужно беспокоиться о большей части окружения (веб-сервере, сервере приложений, балансировщике загрузки), так как сама платформа берет это на себя (включая все моменты, касающиеся роста и развития вашего приложения). В данном случае развертывание приложения является достаточно простой задачей, - вам нужно сконцентрироваться только на вашем приложении, а не на инфраструктуре.

+ +

Некоторые разработчики выбирают более гибкое решение, предоставляемое IaaS, в то время как другие предпочитают иметь наименьшие накладные расходы и простое масштабирование, предоставляемое PaaS. Когда вы только начинаете, то система типа PaaS является предпочтительной и это именно то, что мы будем использовать в данном руководстве.

+ +
+

Примечание: Если вы выбираете хостинг с поддержкой Python/Django, то он должен иметь инструкцию по установке веб-сайта Django, учитывающую различные конфигурации веб-сервера, сервера приложений, обратного прокси и так далее (это не имеет значение, если вы выбрали PaaS). Например, существует множество инструкций "шаг-за-шагом" для различный конфигураций в Документации DigitalOcean по Django.

+
+ +

Выбор хостинг провайдера

+ +

Существует более 100 хорошо известных хостинг провайдеров, которые либо активно поддерживают, или работают с Django (их список можно увидеть в Django-дружественные хостинги). Данные поставщики предоставляют различные типы окружений (IaaS, PaaS), и различные уровни доступа к вычислительным и сетевым ресурсам, за разную цену.

+ +

Некоторые вещи на которые надо обратить внимание при выборе хостинга:

+ + + +

Хорошей новостью является то, что для того, чтобы начать существует достаточное количество компаний, которые предоставляют пробные "бесплатные" тарифы типа "evaluation" (для пробы), "developer" (разработка), или "hobbyist" (хобби). Всегда существуют ресурсы с ограниченым окружением, при использовании которых вам надо беспокоиться лишь о том, что они могут быть доступны лишь в течении определенного периода времени. Тем не менее, они являются отличным решением для тестирования сайтов с небольшим трафиком в реальном окружении, а также могут предоставлять простой доступ к платным ресурсам, в случае необходимости. Наиболее популярными провайдерами являются Heroku, Python Anywhere, Amazon Web Services, Microsoft Azure и так далее.

+ +

Многие провайдеры имеют "basic" (базовый) тариф, предоставляющий достаточный уровень вычислительной мощности с небольшим количеством ограничений. Digital Ocean и Python Anywhere являются примерами провайдеров, которые предлагают относительно недорой базовый тариф (от $5 до $10USD в месяц).

+ +
+

Примечание: Необходимо помнить, что цена не является единственным критерием выбора. Если ваш сайт успешен, то может так случиться, что масштабирование станет самым важным элементом вашего внимания при выборе услуг хостинга.

+
+ +

Подготовка веб-сайта к публикации

+ +

Скелет сайта был создан при помощи инструментов django-admin и manage.py, которые настроены таким образом, чтобы сделать разработку проще. Многие настройки файла проекта (определенных в settings.py) должны быть изменены перед публикацией сайта, либо из-за вопросов безопастности, либо производительности.

+ +
+

Примечание: Общепринятым решением является иметь отдельный файл settings.py для публикации, который импортирует важные настройки из внешних файлов, или из переменных окружения. Доступ к данному файлу должен быть ограничен, даже если остальная часть исходного кода доступна в публичном репозитории.

+
+ +

Критически важные настройки файла settings.py:

+ + + +

Давайте изменим приложение LocalLibrary таким образом, чтобы читать SECRET_KEY и DEBUG из переменных окружения, если те определены, иначе использовать значения по умолчанию.

+ +

Откройте /locallibrary/settings.py, закомментируйте исходное значение SECRET_KEY и добавьте новые строки, как указано ниже жирным. В течении разработки, никаких переменных окружения определено не было, таким образом будут использоваться значения по умолчанию (не имеет значения какой ключ вы используете в процессе разработки, поскольку при развертывании проекта вы будете использовать другой).

+ +
# SECURITY WARNING: keep the secret key used in production secret!
+# SECRET_KEY = 'cg#p$g+j9tax!#a3cup@1$8obt2_+&k3q+pmu)5%asj6yjpkag'
+import os
+SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY', 'cg#p$g+j9tax!#a3cup@1$8obt2_+&k3q+pmu)5%asj6yjpkag')
+
+ +

Затем закомментируйте строку с настройкой DEBUG, а затем, добавьте новую, указанную ниже.

+ +
# SECURITY WARNING: don't run with debug turned on in production!
+# DEBUG = True
+DEBUG = bool( os.environ.get('DJANGO_DEBUG', True) )
+
+ +

Значение DEBUG будет True по умолчанию и станет False, в том случае, если переменная окружения DJANGO_DEBUG будет проинициализирована пустой строкой, то есть, DJANGO_DEBUG=''.

+ +
+

Примечание: Было бы более понятным, если бы мы могли просто установить и снять с  DJANGO_DEBUG непосредственно на True и False , напрямую, а не использовать «любую строку» или «пустую строку» (соответственно). К сожалению, значения переменных среды хранятся как строки Python и единственная строка, которая оценивается как False является пустой строкой (например, bool('')==False).

+
+ +

Весь перечень настроек для разворачивания вашего сайта находится по ссылке Deployment checklist (Django docs). Кроме того, вы можете получить список настроек, выполнив в терминале команду:

+ +
python3 manage.py check --deploy
+
+ +

Пример: Установка LocalLibrary на Heroku

+ +

Данный раздел предоставляет демонстрацию того, как установить LocalLibrary на Heroku PaaS cloud.

+ +

Почему Heroku?

+ +

Heroku - один из самых продолжительных и популярных облачных сервисов PaaS. Первоначально он поддерживал только приложения Ruby, но теперь его можно использовать для размещения приложений из многих сред программирования, включая Django!

+ +

Мы выбираем для использования Heroku по нескольким причинам:

+ + + +

Хотя Heroku идеально подходит для проведения этой демонстрации, она может быть не идеальна для вашего реального сайта. Heroku упрощает настройку и масштабирование за счет меньшей гибкости и, возможно, обойдется намного дороже, когда вы выходите из свободного уровня.

+ +

Как работает Heroku?

+ +

Heroku запускает сайты Django внутри одного, или более,  изолированых друг от друга "Dynos", которые являются виртуальными Unix-контейнерами, предоставляющими необходимое окружение для вашего приложения. Данные dynos полностью изолированы и имеют эфемерную файловую систему ("короткоживущая" файловая система, которая полностью очищается и обновляется каждый раз, когда dyno перезапускается). Единственной сущностью, которую предоставляет dynos по умолчанию, является приложение по конфигурации переменных. Heroku внутри себя применяет балансировщик загрузки для распределения веб-трафика среди всех "веб"-dynos. Поскольку dynos изолированы, Heroku может масштабировать приложение горизонтально, просто добавляя больше dynos (хотя, конечно, у вас может появиться необходимость расширить базу данных для обработки дополнительных соединений).

+ +

Файловая система эфемерна, поэтому вы не можете напрямую установить необходимые для вашего приложения сервисы (то есть, базы данных, очереди, системы кэширования, хранения, сервисы электронной почты и так далее). Взамен этого, Heroku предоставляет сервисы, доступные как независимые "дополнения" ("add-ons") либо от самой Heroku, или от сторонних разработчиков. В тот момент когда ваше приложение запускается в системе, dynos получает доступ к сервисам, используя информацию, содержащуюся в переменных настройки вашего приложения.

+ +

Для того, чтобы выполнить ваше приложение Heroku необходимо иметь возможность установить соответствующее окружение и зависимости, а также понимать как его (приложение) запустить. В случае приложений Django мы предоставляем соответствующую информацию в нескольких текстовых файлах:

+ + + +

Разработчики Developers взаимодействуют с Heroku при помощи специального клиентского приложения/терминала, который сильно похож на bash-скрипт Unix. Оно позволяет вам загружать код, находящийся в git-репозитории, контроллировать выполняемые процессы, смотреть логи, устанавливать конфигурационные переменные и многое другое!

+ +

Для того, чтобы заставить ваше приложение работать с Heroku, нам нужно разместить наше веб-приложение в git-репозитории, добавить, перечисленные ранее, файлы, подключить дополнение (add-on) базы данных и выполнить настройки для правильной работы со статическими файлами.

+ +

Когда мы выполним все, что необходимо для нашего сайта мы можем создать аккаунт Heroku, получить доступ к клиенту Heroku и использовать его, для установки нашего веб-сайта.

+ +
+

Примечание: Инструкции, перечисленные ниже, соответствуют процессу работы с Heroku во время написания данной статьи (английской версии - прим. перев.). Если Heroku значительно изменит этот процесс, вы можете воспользоваться соответствующим описанием: Heroku начало работы с Django.

+
+ +

На этом завершается краткий обзор начала работы с Heroku (более подробное руководство Как работает Heroku).

+ +

Создание репозитория приложения на Github

+ +

Heroku тесно интегрирована с системой управления версиями исходного кода git, используя ее для загрузки / синхронизации любых изменений, которые вы вносите в живую систему. Он делает это, добавляя новый «удаленный» репозиторий heroku с именем heroku, указывающий на репозиторий для вашего источника в облаке Heroku. Во время разработки вы используете git для хранения изменений в вашем «master» репозитории. Когда вы хотите развернуть свой сайт, вы синхронизируете свои изменения в репозитории Heroku.

+ +
+

Примечание: Если вы привыкли следовать хорошей практике разработки программного обеспечения, вы, вероятно, уже используете git или какую-либо другую систему SCM. Если у вас уже есть git-репозиторий, вы можете пропустить этот шаг.

+
+ +

Существует множество способов работы с git, но одним из самых простых является создание учетной записи в Github, создание репозитория там, а затем синхронизация с ним локально:

+ +
    +
  1. Посетите https://github.com/ и создайте аккаунт.
  2. +
  3. После входа в систему нажмите ссылку + в верхней панели инструментов и выберите Новый репозиторий.
  4. +
  5. Заполните все поля на этой форме. Хотя они не являются обязательными, они настоятельно рекомендуются. +
      +
    • Введите имя нового репозитория (например django_local_library), и комментарий к репозиторию (например "Local Library website written in Django".
    • +
    • Нажмите на кнопку Add .gitignore и в появившемся списке выберите Python.
    • +
    • Выберите подходящую вам лицензию из списка Add license. Если не знаете для чего это - оставьте как было.
    • +
    • +

      Установите галочку напротив Initialize this repository with a README.

      +
    • +
    +
  6. +
  7. Нажмите кнопку Create repository, тем самым создав ваш репозиторий.
  8. +
  9. Перейдите на страницу вашего репозитория. Там нажмите на зелёную кнопку "Clone or download". Скопируйте URL  из текстового поляиз появившегося диалогового окна (Это будет похоже на: https://github.com/<your_git_user_id>/django_local_library.git). Здесь <your_git_user_id> - это будет ваш id пользователя git.
  10. +
+ +

Когда ваш репозиторий будет создан - загрузите его себе на компьтер, следуя инструкции, описанной ниже:

+ +
    +
  1. Установите git себе на компьютер (Вы можете найти версию для своей платформы здесь).
  2. +
  3. Откройте командную строку (или терминал) и выполните в нём следующую команду, используя ссылку, которую вы получили с github: +
    git clone https://github.com/<your_git_user_id>/django_local_library.git
    +
    + Это создаст подпапку (с содержанием вашего репозитория и именем вашего репозитория) внутри папки, в котрой выполнялась команда.
  4. +
  5. Перейдите в эту папку: +
    cd django_local_library.git
    +
  6. +
+ +

Последний шаг. Нужно скопировать ваше Django-приложение и добавить его файлы в новый репозиторий, используя git:

+ +
    +
  1. Скопируйте ваше приложение в папку репозитория (все файлы с таким же уровнем, как у manage.py, БЕЗ папки проекта, в которой эти файлы находятся).
  2. +
  3. Откройте файл с расширением .gitignore в текстовом редакторе, вставьте в самый его конец строки, приведённые ниже, а затем сохраните (этот файл "говорит" о файлах, которые не должны быть  загружены в git по умолчанию). +
    # Text backup files
    +*.bak
    +
    +#Database
    +*.sqlite3
    +
  4. +
  5. +

    Откройте командную строку или терминал и используйте add команду с флагом -A. Эта комманда сохранит изменения в репозиторий:

    + +
    git add -A
    +
  6. +
  7. Используйте команду status,  что бы убедиться, что все файлы, которые вы собираетесь добавить верны (вы хотите включить исходные файлы, а не бинарные файлы, временные файлы и т. д.). В консоль выведется что то вроде этого: +
    > git status
    +On branch master
    +Your branch is up-to-date with 'origin/master'.
    +Changes to be committed:
    +  (use "git reset HEAD <file>..." to unstage)
    +
    +        modified:   .gitignore
    +        new file:   catalog/__init__.py
    +        ...
    +        new file:   catalog/migrations/0001_initial.py
    +        ...
    +        new file:   templates/registration/password_reset_form.html
    +
  8. +
  9. Теперь, зафиксируйте файлы в локальном репозитории: +
    git commit -m "First version of application moved into github"
    +
  10. +
  11. Синхронизируете свой локальный репозиторий с сайтом Github: +
    git push origin master
    +
  12. +
+ +

Когда эти операции завершатся, вернитесь на страницу Github где вы создали свой репозиторий, обновите страницу, и убедитесь, что ваше приложение полностью загружено. При надобности обновить файлы на репозитории - повторите цикл ввода команд add/commit/push.

+ +
+

Подсказка: Это хороший момент для создания резервной копии вашего «ванильного» проекта — в то время как некоторые изменения, которые мы собираемся сделать в следующих разделах, могут быть полезны для развертывания на любой платформе (или разработке), которые другие могут не использовать.

+ +

Лучший способ сделать это - использовать git для управления вашими изменениями. С git вы можете не только вернуться к определенной старой версии, но и сохранить ее в отдельной «ветке» ваших производственных изменений, and cherry-pick - выбрать любые изменения для перемещения между ветвями производства и развития. Изучение Git будет стоить усилий, но это выходит за рамки данной темы. Самый простой способ сделать это - просто скопировать файлы в другое место. Используйте тот подход, который наилучшим образом соответствует вашим знаниям git!

+
+ +

Обновить приложение для Heroku 

+ +

В этой части говорится об изменениях, которые мы должны сделать на нашем приложении LocalLibrary, что бы оно работало на  Heroku. В то время как документация "начало работы с Heroku с инструкциями Django" предполагает, что вы будете использовать Heroku client для запуска локальной среды разработки, наши изменения здесь совместимы с существующим сервером разработки Django и способами работы, которые мы уже узнали.

+ +

Procfile

+ +

 Создайте файл с именем Procfile (без расширения) в корне нашего GitHub репозитории объявить типы процессов и точки входа приложения. Скопируйте в него следующий текст:

+ +
web: gunicorn locallibrary.wsgi --log-file -
+ +

«web:» сообщает Heroku, что это веб динамический и может быть отправлен HTTP-трафик. Процесс, который начнется в этом динамически, - это gunicorn, который является популярным сервером веб-приложений, который рекомендует Heroku. Мы запускаем Gunicorn, используя конфигурационную информацию в модуле locallibrary.wsgi (созданный с помощью нашего скелета приложения: /locallibrary/wsgi.py).

+ +

Gunicorn

+ +

Gunicorn рекомендуемый http сервер с Django на Heroku (Как указанов Procfile выше). Это чистый python http сервер для WSGI приложений  которые могут запускать множество параллельных python процессов в пределах одного динамического (посмотрите Deploying Python applications with Gunicorn для получения большей информации).

+ +

Также нам не понадобится Gunicorn для обслушивания нашей LocalLibrary приложения в течение разработки, мы установим это так, чтобы он стал частью наших требований к Heroku для настройки на удаленном сервере.

+ +

Установка Gunicorn локально в командной строке используя пакетный менеджер pip (которые мы установили когда настраивали среду разработки):

+ +
pip3 install gunicorn
+
+ +

Настройка Базы Данных

+ +

Мы не можем использовать базу данных SQLite по умолчанию на Heroku, потому что она основана на файлах, и она будет удалена из эфемерной файловой системы каждый раз, когда приложение перезагружается (обычно один раз в день и каждый раз, когда изменяется приложение или его переменные конфигурации ).

+ +

Механизм Heroku для обработки этой ситуации заключается в использовании надстройки базы данных и настройке веб-приложения с использованием информации из переменной конфигурации среды, установленной надстройкой. Существует множество опций базы данных, но мы будем использовать hobby уровень в базе данных postgres Heroku, поскольку это бесплатно, поддерживается Django и автоматически добавляется в наши новые приложения Heroku при использовании бесплатного уровня динамического плана для хобби.

+ +

Информация о подключении базы данных предоставляется на web dyno, используя конфигурационную переменную с именем DATABASE_URL. Вместо того, чтобы жестко кодировать эту информацию в Django, Heroku рекомендует разработчикам использовать dj-database-url пакет для анализа DATABASE_URL переменную окружения и автоматически преобразовать ее в желаемый формат конфигурации Django. В дополнение к установке пакета dj-database-url нам также потребуется установить psycopg2, поскольку Django нуждается в этом, чтобы взаимодействовать с базами данных Postgres.

+ +
dj-database-url (Django конфигурации базы данных из переменной окружения)
+ +

Установите dj-database-url локально, чтобы он стал частью наших требований к настройке Heroku на удаленном сервере:

+ +
$ pip3 install dj-database-url
+
+ +
settings.py
+ +

Откройте /locallibrary/settings.py и скопируйте следующую конфигурацию в нижнюю часть файла:

+ +
# Heroku: Update database configuration from $DATABASE_URL.
+import dj_database_url
+db_from_env = dj_database_url.config(conn_max_age=500)
+DATABASES['default'].update(db_from_env)
+ +
+

Заметка:

+ +
    +
  • Мы все еще будем использовать SQLite во время разработки, поскольку DATABASE_URL переменная среды не будет установлена ​​на нашем компьютере разработки.
  • +
  • Значение conn_max_age=500 делает соединение постоянным, что намного эффективнее, чем воссоздавать соединение в каждом цикле запросов. Однако это необязательно и при необходимости можно удалить.
  • +
+
+ +
psycopg2 (Python Postgres database support)
+ +

Django нуждается в psycopg2 для работы с базами данных Postgres, и вам нужно будет добавить это в файл требований.txt для Heroku, чтобы установить это на удаленном сервере (как описано в разделе требований ниже).

+ +

Django будет использовать нашу базу данных SQLite локально по умолчанию, поскольку переменная среды DATABASE_URL не задана в нашей локальной среде. Если вы хотите полностью перейти на Postgres и использовать нашу бесплатную базу данных Heroku для разработки и производства, то вы можете. Например, чтобы установить psycopg2 и его зависимости локально в системе на базе Linux, вы должны использовать следующие команды bash / terminal:

+ +
sudo apt-get install python-pip python-dev libpq-dev postgresql postgresql-contrib
+pip3 install psycopg2
+
+ +

Инструкции по установке для других платформ можно найти на веб-сайте psycopg2.

+ +

Однако вам не нужно это делать - вам не нужно, чтобы PostGreSQL был активным на локальном компьютере, если вы передаете его в Heroku в качестве требования в файле требований.txt (см. Ниже).

+ +

Обслуживание статических файлов в производстве

+ +


+ Во время разработки мы использовали Django и веб-сервер разработки Django для обслуживания наших статических файлов (CSS, JavaScript и т. Д.). В производственной среде вместо этого мы обычно обслуживаем статические файлы из сети доставки контента (CDN) или веб-сервера.

+ +
+

Примечание. Обслуживание статических файлов через Django / веб-приложение неэффективно, потому что запросы должны проходить через ненужный дополнительный код (Django), а не обрабатываться непосредственно веб-сервером или полностью отдельным CDN. Хотя это не имеет значения для местного использования во время разработки, это будет иметь значительное влияние на производительность, если мы будем использовать тот же подход в производстве.

+
+ +

Чтобы упростить размещение статических файлов отдельно от веб-приложения Django, Django предоставляет средство сбора данных для сбора этих файлов для развертывания (имеется переменная параметров, определяющая, где файлы должны собираться при запуске collectstatic). Шаблоны Django относятся к месту размещения статических файлов относительно переменной параметров (STATIC_URL), так что это можно изменить, если статические файлы перемещаются на другой хост / сервер.

+ +

Соответствующими параметрами настройки являются:

+ +

     STATIC_URL: это базовое расположение URL, из которого будут загружены статические файлы, например, на CDN. Это используется для переменной статического шаблона, доступ к которой осуществляется в нашем базовом шаблоне (см. Учебник по Django Part 5: Создание нашей домашней страницы).
+       STATIC_ROOT: Это абсолютный путь к каталогу, в котором инструмент «collectstatic» Django будет собирать любые статические файлы, упомянутые в наших шаблонах. После их сбора они затем могут быть загружены в группу, где бы файлы не размещались.
+       STATICFILES_DIRS: В этом списке перечислены дополнительные каталоги, в которых инструмент коллективного поиска Django должен искать статические файлы.

+ +
settings.py
+ +

Откройте /locallibrary/settings.py и скопируйте следующую конфигурацию в нижнюю часть файла. BASE_DIR уже должен быть определен в вашем файле (STATIC_URL, возможно, уже был определен в файле, когда он был создан. В то время как это не причинит вреда, вы также можете удалить дублируемую предыдущую ссылку).

+ +
# Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/1.10/howto/static-files/
+
+# The absolute path to the directory where collectstatic will collect static files for deployment.
+STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
+
+# The URL to use when referring to static files (where they will be served from)
+STATIC_URL = '/static/'
+
+ +

Фактически мы будем делать файл, используя библиотеку WhiteNoise, которую мы устанавливаем и настраиваем в следующем разделе.

+ +

Для получения дополнительной информации см. Django и Static Assets (документы Heroku).

+ +

WhiteNoise
+ Существует множество способов обслуживания статических файлов на производстве (мы видели соответствующие настройки Django в предыдущих разделах). Heroku рекомендует использовать проект WhiteNoise для обслуживания статических активов непосредственно из Gunicorn в производстве.

+ +
+

Заметка: Heroku автоматически вызывает collectstatic и готовит ваши статические файлы для использования WhiteNoise после того, как он загрузит ваше приложение. Посмотрите WhiteNoise документацию для объяснения того, как она работает, и почему реализация является относительно эффективным методом для обслуживания этих файлов.

+
+ +

Шаги по настройке WhiteNoise для использования в проекте:

+ +
WhiteNoise
+ +

Установите WhiteNoise локально, используя следующую команду:

+ +
$ pip3 install whitenoise
+
+ +
settings.py
+ +

Чтобы установить WhiteNoise в приложение Django, откройте /locallibrary/settings.py, найдите параметр MIDDLEWARE и добавьте WhiteNoiseMiddleware в верхней части списка, чуть ниже SecurityMiddleware:

+ +
MIDDLEWARE = [
+    'django.middleware.security.SecurityMiddleware',
+    'whitenoise.middleware.WhiteNoiseMiddleware',
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.middleware.common.CommonMiddleware',
+    'django.middleware.csrf.CsrfViewMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.contrib.messages.middleware.MessageMiddleware',
+    'django.middleware.clickjacking.XFrameOptionsMiddleware',
+]
+
+ +

При желании вы можете уменьшить размер статических файлов при их обслуживании (это более эффективно). Просто добавьте следующее в конец /locallibrary/settings.py:

+ +
# Simplified static file serving.
+# https://warehouse.python.org/project/whitenoise/
+STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
+
+ +

Requirements

+ +

Требования Python вашего веб-приложения должны храниться в файле requirements.txt в корневом каталоге вашего репозитория. После этого Heroku автоматически установит их при восстановлении вашей среды. Вы можете создать этот файл с помощью pip в командной строке (запустите в корне repo):

+ +
pip3 freeze > requirements.txt
+ +

После установки всех разных зависимостей выше, файл requirements.txt должен иметь по меньшей мере эти перечисленные элементы (хотя номера версий могут отличаться). Удалите любые другие зависимости, не перечисленные ниже, если вы явно не добавили их для этого приложения.

+ +
dj-database-url==0.4.1
+Django==1.10.2
+gunicorn==19.6.0
+psycopg2==2.6.2
+whitenoise==3.2.2
+
+ +
+

Убедитесь, что строка  psycopg2, подобная приведенной выше, присутствует! Даже если вы не установили это локально, вы должны добавить это в requirements.txt.

+
+ +

Среда выполнения

+ +

Файл runtime.txt, если определён, говорит Heroku, какой язык программирования использовать. Создайте файл в корне репо и добавьте следующий текст:

+ +
python-3.5.2
+ +
+

Заметка: Heroku поддерживает только небольшое количество Python runtimes. (на момент написания статьи, в том числе и выше). Heroku будет использовать поддерживаемую среду выполнения независимо от значения, указанного в этом файле.

+
+ +

Сохраните изменения в Github и перепроверьте

+ +

Далее мы сохраним все наши изменения в Github. В терминале (whist внутри нашего репозитория) введите следующие команды:

+ +
git add -A
+git commit -m "Added files and changes required for deployment to heroku"
+git push origin master
+ +

Прежде чем продолжить, дайте возможность проверить сайт снова локально и убедиться, что это не повлияло ни на одно из наших изменений выше. Запустите веб-сервер разработки как обычно, а затем проверьте, работает ли сайт, как вы ожидаете в своем браузере.

+ +
python3 manage.py runserver
+ +

Теперь мы должны быть готовы начать развертывание LocalLibrary на Heroku.

+ +

Получить аккаунт в heroku

+ +

Чтобы начать использовать Heroku, вам сначала нужно создать учетную запись:

+ + + +

Установка клиента

+ +

Загрузите и установите клиент Heroku, следуя инструкциям Heroku здесь.

+ +

После установки клиента вам будут дотупны команды. Например, чтобы получить справку о клиенте:

+ +
heroku help
+
+ +

Создание и загрузка веб-сайта

+ +

Чтобы создать приложение, мы запускаем команду «create» в корневом каталоге нашего репозитория. Это создает git remote («указатель на удаленный репозиторий»), названный heroku в нашей локальной среде git.

+ +
heroku create
+ +
+

Заметка: Вы можете назвать удаленный, если хотите, указав значение после «create». Если вы этого не сделаете, вы получите случайное имя. Имя используется в URL-адресе по умолчанию.

+
+ +

Затем мы можем подтолкнуть наше приложение в репозиторий heroku как показано ниже. Это позволит загрузить приложение, упаковать его в dyno, запустить collectstatic, и запустить сам сайт.

+ +
git push heroku master
+ +

Если нам повезет, приложение «заработает» на сайте, но оно не будет работать должным образом, потому что мы не настроили таблицы базы данных для использования нашим приложением. Для этого нам нужно использовать команду  heroku run и запустить "one off dyno" для выполнения операции переноса. Введите в терминал следующую команду:

+ +
heroku run python manage.py migrate
+ +

Мы также должны будем иметь возможность добавлять книги и авторов, поэтому давайте также создадим суперпользователя, снова используя одноразовый динамический режим:

+ +
heroku run python manage.py createsuperuser
+ +

Как только это будет завершено, мы можем посмотреть сайт. Он должен работать, хотя в нем еще нет книг. Чтобы открыть браузер на новом веб-сайте, используйте команду:

+ +
heroku open
+ +

Создайте несколько книг на сайте администратора и проверьте, работает ли сайт, как вы ожидаете.

+ +

Управление аддонами

+ +

Вы можете проверить дополнения в своем приложении, используя heroku addons команду. Это будет список всех аддонов, их ценовая категория и состояние.

+ +
>heroku addons
+
+Add-on                                     Plan       Price  State
+─────────────────────────────────────────  ─────────  ─────  ───────
+heroku-postgresql (postgresql-flat-26536)  hobby-dev  free   created
+ └─ as DATABASE
+ +

Здесь мы видим, что у нас есть только одна надстройка, база данных postgres SQL. Это бесплатно и автоматически создается при создании приложения. Вы можете открыть веб-страницу, чтобы более подробно изучить надстройку базы данных (или любое другое дополнение), используя следующую команду:

+ +
heroku addons:open heroku-postgresql
+
+ +

Другие команды позволяют создавать, уничтожать, обновлять и понижать аддоны (используя аналогичный синтаксис для открытия). Для получения дополнительной информации см.  Managing Add-ons (Heroku docs).

+ +

Настройка переменных конфигурации

+ +

Вы можете проверить конфигурационные переменные для сайта, используя команду  heroku config. Ниже вы можете видеть, что у нас есть только одна переменная DATABASE_URL , используемая для настройки нашей базы данных.

+ +
>heroku config
+
+=== locallibrary Config Vars
+DATABASE_URL: postgres://uzfnbcyxidzgrl:j2jkUFDF6OGGqxkgg7Hk3ilbZI@ec2-54-243-201-144.compute-1.amazonaws.com:5432/dbftm4qgh3kda3
+ +

Если вы вспомните из раздела, посвященного  getting the website ready to publish, мы должны установить переменные среды для DJANGO_SECRET_KEY и DJANGO_DEBUG. Давайте сделаем это сейчас.

+ +
+

Заметка: Секретный ключ должен быть действительно секретным! Один из способов генерации нового ключа - создать новый проект Django (django-admin startproject someprojectname) а затем получить ключ, который генерируется для вас в его settings.py.

+
+ +

Мы устанавливаем  DJANGO_SECRET_KEY используя команду config:set (как показано ниже). Не забудьте использовать свой секретный ключ!

+ +
>heroku config:set DJANGO_SECRET_KEY=eu09(ilk6@4sfdofb=b_2ht@vad*$ehh9-)3u_83+y%(+phh&=
+
+Setting DJANGO_SECRET_KEY and restarting locallibrary... done, v7
+DJANGO_SECRET_KEY: eu09(ilk6@4sfdofb=b_2ht@vad*$ehh9-)3u_83+y%(+phh
+
+ +

Аналогично мы устанавливаем  DJANGO_DEBUG:

+ +
>heroku config:set DJANGO_DEBUG=''
+
+Setting DJANGO_DEBUG and restarting locallibrary... done, v8
+ +

Если вы посетите веб-сайт сейчас, вы получите ошибку "Bad request" , потому что в  ALLOWED_HOSTS надо внести параметры, если у вас DEBUG=False (в качестве меры безопасности). Откройте /locallibrary/settings.py и измените ALLOWED_HOSTS для включения вашего базового URL-адреса приложения (например, 'locallibrary1234.herokuapp.com') URL, который вы обычно используете на локальном сервере разработки.

+ +
ALLOWED_HOSTS = ['<your app URL without the https:// prefix>.herokuapp.com','127.0.0.1']
+# For example:
+# ALLOWED_HOSTS = ['fathomless-scrubland-30645.herokuapp.com','127.0.0.1']
+
+ +

Затем сохраните настройки и передайте их в репозиторий Github и в Heroku:

+ +
git add -A
+git commit -m 'Update ALLOWED_HOSTS with site and development server URL'
+git push origin master
+git push heroku master
+ +
+

После завершения обновления сайта на Heroku введите URL-адрес, который не существует (например,  /catalog/doesnotexist/). Раньше это отображало бы подробную страницу отладки, но теперь вы должны просто увидеть простую страницу «Не найдено».

+
+ +

Отладка

+ +

Клиент Heroku предоставляет несколько инструментов для отладки:

+ +
heroku logs  # Show current logs
+heroku logs --tail # Show current logs and keep updating with any new results
+heroku config:set DEBUG_COLLECTSTATIC=1 # Add additional logging for collectstatic (this tool is run automatically during a build)
+heroku ps   #Display dyno status
+
+ +

Если вам нужно больше информации, предоставленной здесь, вам нужно будет начать изучать Django Logging.

+ + + +

Итоги

+ +

Это конец этого руководства по настройке и развёртывании приложений Django, а также серия руководств по работе с Django. Надеемся, вы нашли их полезными. Вы можете проверить полностью проработанную версию по исходникам на Github.
+ Следующий шаг - прочитать наши последние несколько статей, а затем завершить оценочную задачу.

+ +

Смотрите также

+ + + +

{{PreviousMenuNext("Learn/Server-side/Django/Testing", "Learn/Server-side/Django/web_application_security", "Learn/Server-side/Django")}}

+ +

В этом модуле

+ + diff --git a/files/ru/learn/server-side/django/introduction/index.html b/files/ru/learn/server-side/django/introduction/index.html new file mode 100644 index 0000000000..4bff707908 --- /dev/null +++ b/files/ru/learn/server-side/django/introduction/index.html @@ -0,0 +1,257 @@ +--- +title: Django введение +slug: Learn/Server-side/Django/Введение +tags: + - Python + - django + - Вступление + - Джанго + - Начинающим + - Серверное программирование +translation_of: Learn/Server-side/Django/Introduction +--- +
{{LearnSidebar}}
+ +
{{NextMenu("Learn/Server-side/Django/development_environment", "Learn/Server-side/Django")}}
+ +

В первой статье о Django мы отвечаем на вопрос «Что такое Django?» и даём обзор того, что делает его особенным. Мы опишем основные функции, в том числе некоторые из расширенных функций, которые у нас не будет времени подробно рассмотреть в этом модуле. Мы также покажем вам некоторые основные строительные блоки приложения Django (хотя на данный момент у вас ещё не будет среды разработки для тестирования).

+ + + + + + + + + + + + +
Требования:Базовая компьютерная грамотность. Общее понимание server-side website programming, и в частности, механики client-server interactions in websites.
Задача:Узнать, что такое Django, какие функции он предоставляет, и основные строительные блоки приложения Django.
+ +

Что такое Django?

+ +

Django — это высокоуровневый Python веб-фреймворк, который позволяет быстро создавать безопасные и поддерживаемые веб-сайты. Созданный опытными разработчиками, Django берёт на себя большую часть хлопот веб-разработки, поэтому вы можете сосредоточиться на написании своего веб-приложения без необходимости изобретать велосипед. Он бесплатный и с открытым исходным кодом, имеет растущее и активное сообщество, отличную документацию и множество вариантов как бесплатной, так и платной поддержки.

+ +

Django помогает писать программное обеспечение, которое будет:

+ +
+
Полным
+
Django следует философии «Всё включено» и предоставляет почти всё, что разработчики могут захотеть сделать «из коробки». Поскольку всё, что вам нужно, является частью единого «продукта», всё это безупречно работает вместе, соответствует последовательным принципам проектирования и имеет обширную и актуальную документацию.
+
Разносторонним
+
Django может быть (и был) использован для создания практически любого типа веб-сайтов — от систем управления контентом и wiki до социальных сетей и новостных сайтов. Он может работать с любой клиентской средой и может доставлять контент практически в любом формате (включая HTML, RSS-каналы, JSON, XML и т. д.). Сайт, который вы сейчас читаете, создан с помощью Django!
+
Хотя Django предоставляет решения практически для любой функциональности, которая вам может понадобиться (например, для нескольких популярных баз данных, шаблонизаторов и т. д.), внутренне он также может быть расширен сторонними компонентами, если это необходимо.
+
Безопасным
+
Django помогает разработчикам избежать многих распространённых ошибок безопасности, предоставляя фреймворк, разработанный чтобы «делать правильные вещи» для автоматической защиты сайта. Например, Django предоставляет безопасный способ управления учётными записями пользователей и паролями, избегая распространённых ошибок, таких как размещение информации о сеансе в файлы cookie, где она уязвима (вместо этого файлы cookie содержат только ключ, а фактические данные хранятся в базе данных) или непосредственное хранение паролей вместо хэша пароля.
+
Хэш пароля это значение фиксированной длины, созданное путём обработки пароля через криптографическую хэш-функцию. Django может проверить правильность введённого пароля, пропустив его через хэш-функцию и сравнив вывод с сохранённым значением хэша. Благодаря «одностороннему» характеру функции, даже если сохранённое хэш-значение скомпрометировано, злоумышленнику будет сложно определить исходный пароль.
+
Django, по умолчанию, обеспечивает защиту от многих уязвимостей, включая SQL-инъекцию, межсайтовый скриптинг, подделку межсайтовых запросов и кликджекинг (см. Website security для получения дополнительной информации об этих атаках).
+
Масштабируемым
+
Django использует компонентную “shared-nothing” архитектуру (каждая её часть  независима от других и, следовательно, может быть заменена или изменена, если это необходимо). Чёткое разделение частей означает, что Django может масштабироваться при увеличении трафика, путём добавления оборудования на любом уровне: серверы кэширования, серверы баз данных или серверы приложений. Одни из самых загруженных сайтов успешно масштабировали Django (например, Instagram и Disqus, если назвать только два из них).
+
Удобным в сопровождении
+
Код Django написан с использованием принципов и шаблонов проектирования, которые поощряют создание поддерживаемого и повторно используемого кода. В частности, в нём используется принцип «Don't Repeat Yourself» (DRY, «не повторяйся»), поэтому нет ненужного дублирования, что сокращает объём кода. Django также способствует группированию связанных функциональных возможностей в повторно используемые «приложения» и, на более низком уровне, группирует связанный код в модули (в соответствии с шаблоном Model View Controller (MVC)).
+
Переносным
+
Django написан на Python, который работает на многих платформах. Это означает, что вы не привязаны к какой-либо конкретной серверной платформе и можете запускать приложения на многих версиях Linux, Windows и Mac OS X. Кроме того, Django хорошо поддерживается многими веб-хостингами, которые часто предоставляют определённую инфраструктуру и документацию для размещения сайтов Django.
+
+ +

Как он появился?

+ +

Django был разработан в период с 2003 по 2005 год командой, которая занималась созданием и обслуживанием газетных веб-сайтов. После создания нескольких сайтов, команда начала повторно использовать множество общего кода и шаблонов проектирования. Этот общий код эволюционировал в веб-фреймворк, который превратился в проект "Django" с открытым исходным кодом в июле 2005 года.

+ +

Django продолжает расти и улучшаться с момента его первого релиза (1.0) в сентябре 2008 года до недавно выпущенной версии 3.1 (2020). В каждой версии добавлены новые функциональные возможности и исправлены ошибки, начиная от поддержки новых типов баз данных, шаблонизаторов и кэширования, до добавления «общих» функций просмотра и классов (уменьшающих объём кода, который разработчики должны писать для ряда программных задач).

+ +
+

Заметка: Ознакомтесь с примечаниями к версии на сайте Django, чтобы увидеть что изменилось в последних версиях и как много работы было проделано, чтобы улучшить Django.

+
+ +

Django — это процветающий совместный проект с открытым исходным кодом, в котором заняты многие тысячи пользователей и участников. Несмотря на то, что у него всё ещё есть некоторые особенности, которые отражают его происхождение, Django превратился в универсальный фреймворк, способный разрабатывать веб-сайты любого типа.

+ +

Насколько популярен Django?

+ +

Нет никаких доступных и окончательных оценок популярности серверных фреймворков (хотя сайты наподобие Hot Framework и пытаются оценить популярность, используя такие механизмы, как подсчёт количества проектов на GitHub и вопросов на StackOverflow для каждой платформы). Лучший вопрос — «достаточно ли Django популярен», чтобы избежать проблем непопулярных платформ. Продолжает ли он развиваться? Можете ли вы получить помощь, если вам нужно? Найдёте ли вы оплачиваемую работу, если изучите Django?

+ +

Основываясь на количестве крупных сайтов, которые используют Django, количестве участников и количестве людей, предоставляющих как бесплатную, так и платную поддержку, можно ответить: да, Django — популярный фреймворк!

+ +

Django используют такие крупные сайты, как Disqus, Instagram, Knight Foundation, MacArthur Foundation, Mozilla, National Geographic, Open Knowledge Foundation, Pinterest и Open Stack (источник: обзорная страница Django).

+ +

Является ли Django гибким?

+ +

Веб-фрейморки часто можно поделить на "гибкие" и "негибкие".

+ +

Негибкие - это те, у которых есть "правильный путь" для решения какой-либо конкретной задачи. Они часто поддерживают быстрое развёртывание в определенной области (решение проблем определенного типа), потому что правильный способ сделать что-либо обычно хорошо понимается и хорошо документируется. Однако они могут быть менее гибкими при решении проблем за пределами их основной сферы и, как правило, предлагают меньше вариантов того, какие компоненты и подходы они могут использовать.

+ +

Напротив, у гибких фреймворков гораздо меньше ограничений на лучший способ склеивания компонентов для достижения цели или даже того, какие компоненты следует использовать. Они облегчают разработчикам использование наиболее подходящих инструментов для выполнения конкретной задачи, хотя и за счет того, что вам нужно самим найти эти компоненты.

+ +

Django «умеренно гибкий» и, следовательно, обеспечивает «лучшее из обоих миров». Он предоставляет набор компонентов для обработки большинства задач веб-разработки и один (или два) предпочтительных способа их использования. Однако такая архитектура Django означает, что вы обычно можете выбирать из нескольких различных опций или при необходимости добавлять поддержку для совершенно новых.

+ +

Как выглядит код Django?

+ +

На традиционном информационом веб-сайте веб-приложение ожидает HTTP-запросы от веб-браузера (или другого клиента). Когда запрос получен, приложение разрабатывает то, что необходимо на основе URL-адреса и, возможно, данных в POST или GET запросах. В зависимости от того, что требуется, далее он может читать или записывать информацию из базы данных или выполнять другие задачи, необходимые для удовлетворения запроса. Затем приложение вернёт ответ веб-браузеру, часто динамически создавая HTML-страницу для отображения в браузере, вставляя полученные данные в HTML-шаблон.

+ +

Веб-приложения, написанные на Django, обычно группируют код, который обрабатывает каждый из этих шагов, в отдельные файлы:

+ +

+ + + +
+

Заметка: Django реализует уровневую архитектуру "Model View Template (MVT)". Она имеет много общего с более известной архитектурой Model View Controller

+
+ + + +

Следующие разделы дадут вам понимание того, как выглядят основные части Django (мы их изучим более детально чуть позже на курсе, когда будет настраивать окружение разработчика). 

+ +

Отправка запроса в правильное view (urls.py)

+ +

Сопоставитель URL-адресов обычно содержится в файле urls.py. В примере ниже сопоставитель (urlpatterns) определяет список сопоставлений междумаршрутами (определёнными URL-шаблонами) и соотвествующими функциями отображения (view). Если получен HTTP-запрос, который имеет URL-адрес, соответствующий определённому шаблону, то затем будет вызвана связанная функция отображения (view) и передана в запрос.

+ +
urlpatterns = [
+    path('admin/', admin.site.urls),
+    path('book/<int:id>/', views.book_detail, name='book_detail'),
+    path('catalog/', include('catalog.urls')),
+    re_path(r'^([0-9]+)/$', views.best),
+]
+ +

Объект urlpatterns является списком функций path() и/или re_path() (в Python списки определяются с помощью квадратных скобок, внутри которых элементы разделены запятыми и могут содержать необязательную завершающую запятую. Например: [item1, item2, item3,]).

+ +

Первый аргумент в обоих методах - маршрут (шаблон), который будет сопоставлен. В методе path() угловые скобки используются для определения частей URL-адреса, которые будут захвачены и переданы в функцию отображения (view) в качестве именованных аргументов. Функция re_path() использует гибкий подход к сопоставлению с шаблоном, известный как регулярное выражение. Мы поговорим об этом в следующей статье!

+ +

Второй аргумент — это ещё одна функция, которая будет вызываться при сопоставлении шаблона. Обозначение views.book_detail указывает, что функция называется book_detail() и может быть обнаружена в модуле с именем views (т.е. внутри файла с именем views.py).

+ +

Обработка запроса (views.py)

+ +

Отображения (views) — это сердце веб-приложения, принимающего HTTP-запросы от веб-клиентов и возвращающего HTTP-ответы. Между этим они используют другие ресурсы фреймворка для доступа к базам данных, шаблонам визуализации и т. д.  

+ +

В приведённом ниже примере показана минимальная функция представления index(), которая могла быть вызвана нашим сопоставителем URL-адресов в предыдущем разделе. Как и все функции отображения (view), она получает объект HttpRequest в качестве параметра (request) и возвращает объект HttpResponse. В этом случае мы ничего не делаем с запросом, и наш ответ просто возвращает жёстко запрограммированную строку. Мы покажем вам запрос, который делает что-то более интересное в следующем разделе.

+ +
## filename: views.py (Django view functions)
+
+from django.http import HttpResponse
+
+def index(request):
+    # Получить HttpRequest — параметр запроса
+    # Выполнить операции, используя информацию из запроса.
+    # Вернуть HttpResponse
+    return HttpResponse('Hello from Django!')
+
+ +
+

Заметка: Немного Python:

+ +
    +
  • Модули Python это библиотеки функций, сохранённые в различных файлах, которые мы можем использовать в нашем коде. Здесь мы импортируем только объект HttpResponse из модуля django.http чтобы использовать его в нашем отображении (view): from django.http import HttpResponse . Также есть другие способы импортирования некоторых или всех объектов модуля.
  • +
  • Функции объявляются с помощью ключевого слова def, как показано выше, с именованными параметрами, перечисленными в скобках после имени функции; строка завершается двоеточием. Заметьте, что следующие строки содержат отступы.  Отступы важны, так как они определяют, какие строки кода находятся внутри конкретного блока (обязательные отступы — это ключевая особенность Python и одна из причин, почему код на Python так легко читать).
  • +
+
+ + + +

Отображения (view) обычно содержатся в файле views.py.

+ +

Определение данных модели (models.py)

+ +

Веб-приложения Django обрабатывают и запрашивают данные через объекты Python, называемые моделями. Модели определяют структуру хранимых данных, включая типы полей и, возможно, их максимальный размер, значения по умолчанию, параметры списка выбора, текст справки для документации, текст меток для форм и т. д. Определение модели не зависит от используемой базы данных — ваши модели будут работать в любой из них. После того как вы выбрали базу данных, которую хотите использовать, вам не нужно напрямую обращатся к ней — вы просто пишете свою структуру модели и другой код, а Django выполняет всю «грязную работу» по обращению к базе данных за вас.

+ +

В приведённом ниже фрагменте кода показана очень простая модель Django для объекта Team. Класс Team наследуется от класса models.Model. Он определяет имя команды и командный уровень в качестве полей символов и задаёт максимальное количество символов, которые могут быть сохранены для каждой записи. Team_level может быть одним из нескольких значений, поэтому мы определяем его как поле выбора и предоставляем сопоставление между отображаемыми вариантами и хранимыми данными вместе со значением по умолчанию.

+ +
# filename: models.py
+
+from django.db import models
+
+class Team(models.Model):
+    team_name = models.CharField(max_length=40)
+
+    TEAM_LEVELS = (
+        ('U09', 'Under 09s'),
+        ('U10', 'Under 10s'),
+        ('U11', 'Under 11s'),
+        ...  #список других командных уровней
+    )
+    team_level = models.CharField(max_length=3,choices=TEAM_LEVELS,default='U11')
+
+ +
+

Заметка: Немного Python:

+ +
    +
  • Python поддерживает «объектно-ориентированное программирование», то есть стиль программирования, в котором мы организуем наш код в объекты, которые включают связанные данные и функции для работы с этими данными. Объекты также могут наследовать / расширять / выводить из других объектов, позволяя использовать одинаковое поведение между связанными объектами. В Python мы используем ключевое слово class, чтобы определить «скелет» для объекта. Мы можем создать несколько конкретных экземпляров типа объекта на основе модели в классе.
    +
    + Так, например, мы имеем класс Team, который происходит от класса Model. Это означает, что эта модель будет содержать все методы модели, но мы также можем дать ей специализированные возможности. В нашей модели мы определяем поля нашей базы данных, в которой будем хранить данные, присваивая им конкретные имена. Django использует эти определения, включая имена полей, для создания основной базы данных.
  • +
+
+ +

Запросы данных (views.py)

+ +

Модель Django предоставляет простой API запросов для поиска в базе данных. Поиск может осуществляться по нескольким полям одновременно, используя различные критерии (такие как exact («точный»), case-insensitive («без учёта регистра»), greater than («больше чем») и т. д.), и может поддерживать сложные выражения (например, вы можете указать поиск в командах U11, у которых есть имя команды, начинающееся с «Fr» или заканчивается на «al»).

+ +

Фрагмент кода показывает функцию view (обработчик ресурсов) для отображения всех команд U09. Выделенная жирным строка показывет, как мы можем использовать модель API-запросов для того, чтобы отфильтровать все записи, где поле team_level в точности содержит текст 'U09' (обратите внимание, как эти критерии передаются функции filter() в качестве аргумента с именем поля и типом соответствия, разделённым двойным подчеркиванием: team_level__exact). 

+ +
## filename: views.py
+
+from django.shortcuts import render
+from .models import Team
+
+def index(request):
+    list_teams = Team.objects.filter(team_level__exact="U09")
+    context = {'youngest_teams': list_teams}
+    return render(request, '/best/index.html', context)
+
+ +
+
+ +

Данная функция использует функцию render() для того, чтобы создать HttpResponse, который будет отправлен назад браузеру. Эта функция является ярлыком; она создаёт HTML-файл, комбинируя указанный HTML-шаблон и некоторые данные для вставки в шаблон (предоставляется в переменной с именем «context»). В следующем разделе мы  покажем как данные вставляются в шаблон для создания HTML-кода.

+ +

Вывод данных (HTML-шаблоны)

+ +

Системы шаблонов позволяют указать структуру выходного документа, используя заполнители для данных, которые будут вставлены при генерировании страницы. Шаблоны часто используются для создания HTML, но также могут создавать другие типы документов. Django «из коробки» поддерживает как собственную систему шаблонов, так и другую популярную библиотеку Python под названием Jinja2 (она также может быть использована для поддержки других систем, если это необходимо).

+ +

Фрагмент кода показывает, как может выглядеть HTML-шаблон, вызванный функцией  render() из предыдущего раздела. Этот шаблон был написан с предположением, что во время отрисовки он будет иметь доступ к переменной списка, названной youngest_teams (содержащейся в контекстной переменной внутри функции render() выше). Внутри скелета HTML мы имеем выражение, которое сначала проверяет, существует ли переменная youngest_teams, а затем повторяет её в цикле for. При каждом повторе шаблон отображает значение team_name каждой команды в элементе {{htmlelement("li")}}.

+ +
## filename: best/templates/best/index.html
+
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="utf-8">
+  <title>Home page</title>
+</head>
+<body>
+  {% if youngest_teams %}
+    <ul>
+      {% for team in youngest_teams %}
+        <li>\{\{ team.team_name \}\}</li>
+      {% endfor %}
+    </ul>
+  {% else %}
+    <p>No teams are available.</p>
+  {% endif %}
+</body>
+</html>
+ +

Что ещё можно сделать?

+ +

В предыдущих разделах показаны основные особенности, которые вы будете использовать почти в каждом веб-приложении: сопоставление URL-адресов, отображение, модели и шаблоны. Также Django предоставляет несколько других вещей:

+ + + +

Резюме

+ +

Поздравляем, вы завершили первый шаг в своем путешествии по Django! Теперь вы должны понимать основные преимущества Django, немного его истории, и примерно как может выглядеть каждая из основных частей приложения Django. Вы должны также изучить несколько вещей о языке программирования Python, включая синтаксис списков, функций и классов.

+ +

Вы уже видели код на Django выше, но в отличие от клиентского кода вам нужно настроить среду разработки для её запуска. Это наш следующий шаг.

+ +
{{NextMenu("Learn/Server-side/Django/development_environment", "Learn/Server-side/Django")}}
diff --git a/files/ru/learn/server-side/django/sessions/index.html b/files/ru/learn/server-side/django/sessions/index.html new file mode 100644 index 0000000000..5f7d492c72 --- /dev/null +++ b/files/ru/learn/server-side/django/sessions/index.html @@ -0,0 +1,181 @@ +--- +title: 'Руководство часть 7: Сессии' +slug: Learn/Server-side/Django/Сессии +tags: + - django + - Джанго + - Для начинающих + - Изучение + - Питон + - Руководство + - Серверная сторона + - Статья + - применение сессий + - сессии +translation_of: Learn/Server-side/Django/Sessions +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Server-side/Django/Generic_views", "Learn/Server-side/Django/authentication_and_sessions", "Learn/Server-side/Django")}}
+ +

Эта часть раширяет наш сайт LocalLibrary, добавляя счетчик посещений домашней страницы, реализованного при помощи сессий. Это относительно простой пример, но он демонстрирует то, как при помощи сессий реализовать анализ поведения анонимных пользователей на сайте.

+ + + + + + + + + + + + +
Требования:Завершить изучение всех предыдущих разделов, включая Django Руководство Часть 6: Обобщенные отображения списков и детальной информации
Цель:Понимать как применять сессии.
+ +

Обзор

+ +

В предыдущих частях мы создали сайт LocalLibrary, который позволяет пользователям получать из каталога списки книг и авторов. На данный момент каждый посетитель сайта получает доступ к одним и тем же страницам и типам информации динамически сформированными из базы данных.

+ +

В "настоящей" библиотеке вам хотелось бы предоставить пользователю индивидуальные услуги, которые зависят от его предпочтений и предыдущего опыта использования сайта, его настроек и тому подобное. Например, при очередном посещении сайта вы можете скрыть сообщения об ошибках для тех пользователей, которые их уже получали, или сохранить и учитывать пользовательские настройки (например, количество выводимых данных на странице как результат какого-либо поиска). 

+ +

Сессии позволяют вам реализовать такой род функциональности, который позволит вам хранить и получать произвольные данные, полученные на основе индивидуального поведения пользователя на сайте.

+ +

Что такое сессии?

+ +

Все взаимодействия между браузерами и серверами осуществляются при помощи протокола HTTP, который не сохраняет свое состояние (stateless). Данный факт означает, что сообщения между клиентом и сервером являются полностью независимыми один от другого — то есть не существует какого-либо представления "последовательности", или поведения в зависимости от предыдущих сообщений. В результате, если вы хотите создать сайт который будет отслеживать взаимодействие с клиентом (браузером), вам нужно реализовать это самостоятельно.

+ +

Сессии являются механизмом, который использует Django (да и весь остальной "Интернет") для отслеживания "состояния" между сайтом и каким-либо браузером. Сессии позволяют вам хранить произвольные данные браузера и получать их в тот момент, когда между данным браузером и сайтом устанавливается соединение. Данные получаются и сохраняются в сессии при помощи соответствующего "ключа".

+ +

Django использует куки (cookie), которые содержат специальный идентификатор сессии, который выделяет среди остальных, каждый браузер и соответствующую сессию. Реальные данные сессии, по умолчанию, хранятся в базе данных сайта (это более безопасно, чем сохранять данные в куки, где они могут быть уязвими для злоумышленников). Однако, у вас есть возможность настроить Django так, чтобы сохранять данные сессий в других местах (кэше, файлах, "безопасных" куки). Но все же хранение по умолчанию является хорошей и безопасной возможностью.

+ +

Подключение сессий

+ +

Сессии стали доступны автоматически в тот момент, когда мы создали скелет сайта (во второй части руководства).

+ +

Необходимые конфигурации выполняются в разделах INSTALLED_APPS и MIDDLEWARE файла проекта (locallibrary/locallibrary/settings.py), как показано ниже:

+ +
INSTALLED_APPS = [
+    ...
+    'django.contrib.sessions',
+    ....
+
+MIDDLEWARE = [
+    ...
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    ....
+ +

Применение сессий

+ +

Вы можете получить доступ к переменной session, в соответствующем отображении, через параметр request (HttpRequest передается как первый аргумент в каждое отображение). Переменная сессии является связью с определенным пользователем (или, если быть более точным, связью с определенным браузером, который определяется при помощи идентификатора (id) сессии, получаемого из куки браузера).

+ +

Переменная (или поле) session является объектом-словарем, который служит для чтения и записи неограниченное число раз. С ним вы можете выполнять любые стандартные операции, включая очистку всех данных, проверку наличия ключа, циклы по данным и так далее. Большую часть времени вы будете тратить на  обычные "словарные" операции - получения и установки значений.

+ +

Ниже представлены фрагменты кода, которые показывают вам как получать, задавать и удалять некоторые данные при помощи ключа "my_car", связанного с текущей сессией (браузером). 

+ +
+

Примечание: Одной из самых грандиозных вещей в Django является то, что вам не надо думать о механизме, который связывает сессию с текущим запросом в отображении. Во фрагменте ниже, все что вам надо знать, это то, что  my_car связана с тем браузером, который отправил текущий запрос.

+
+ +
# Получение значения сессии при помощи ключа(то есть, 'my_car').
+# Если такого ключа нет, то возникнет ошибка KeyError
+my_car = request.session['my_car']
+
+# Получение значения сессии. Если значения не существует,
+# то вернется значение по умолчанию ('mini')
+my_car = request.session.get('my_car', 'mini')
+
+# Передача значения в сессию
+request.session['my_car'] = 'mini'
+
+# Удаление значения из сессии
+del request.session['my_car']
+
+ +

Данное API имеет другие методы, которые большей частью используются для управления куки, связанных с сессией.  Например, существуют методы проверки того, что куки поддерживаются клиентским браузером, другие методы служат для установки и проверки предельных дат жизни куки, а также для очистки просроченных сессий из хранилища. Подробное описание API вы можете найти в разделе Как использовать сессии (Django docs).

+ +

Хранение данных сессии

+ +

По умолчанию Django сохраняет данные сессии в базу данных и отправляет соответствующие куки клиенту только тогда, когда сессия была изменена, или удалена. Если вы обновляете какие-либо данные при помощи ключа сессии, как показано в предыдущем фрагменте, тогда вам не надо беспокоиться о процессе сохранения! Например:

+ +
# Данное присваивание распознается как обновление сессии
+# и данные будут сохранены
+request.session['my_car'] = 'mini'
+ +

Если вы обновлете информацию внутри данных сессии, тогда Django не распознает эти изменения и не выполнит сохранение данных (например, если вы изменили "wheels" внутри переменной "my_car", как показано ниже). В таких случаях вам надо явно указывать, что сессия была изменена.

+ +
# Объект сессии модифицируется неявно.
+# Изменения НЕ БУДУТ сохранены!
+request.session['my_car']['wheels'] = 'alloy'
+
+# Явное указание, что данные изменены.
+# Сессия будет сохранена, куки обновлены (если необходимо).
+request.session.modified = True
+
+ +
+

Примечание: Вы можете изменить поведение сессий таким образом, чтобы они записывали любое свое изменение в базу данных и отправляли куки, при каждом запросе, путем установки SESSION_SAVE_EVERY_REQUEST = True, в файле настроек проекта (locallibrary/locallibrary/settings.py).

+
+ +

Простой пример — получение числа визитов

+ +

В качестве примера из реального мира мы обновим нашу библиотеку так, чтобы сообщать пользователю количество совершенных им визитов главной страницы сайта LocalLibrary

+ +

Откройте /locallibrary/catalog/views.py и добавьте изменения, выделенных жирным, ниже. 

+ +
def index(request):
+    ...
+
+    num_authors=Author.objects.count()  # The 'all()' is implied by default.
+
+    # Number of visits to this view, as counted in the session variable.
+    num_visits=request.session.get('num_visits', 0)
+    request.session['num_visits'] = num_visits+1
+
+    # Render the HTML template index.html with the data in the context variable.
+    return render(
+        request,
+        'index.html',
+        context={'num_books':num_books,'num_instances':num_instances,'num_instances_available':num_instances_available,'num_authors':num_authors,
+            'num_visits':num_visits}, # num_visits appended
+    )
+ +

В первую очередь мы получаем значение 'num_visits' из сессии, возвращая 0, если оно не было установлено ранее. Каждый раз при получении запроса, мы увеличиваем данное значение на единицу и сохраняем его обратно в сессии (до следующего посещения данной страницы пользователем). Затем переменная num_visits передается в шаблон через переменную контекста context.  

+ +
+

Примечание: Можно проверить наличие поддержки куки в браузере (для примера, смотрите Как использовать сессии), или разработать наш UI таким образом, чтобы это не имело значения.

+
+ +

Для показа значения переменной, из следующего фрагмента добавьте нижнюю строчку кода в ваш шаблон главной страницы сайта (/locallibrary/catalog/templates/index.html), в его нижний раздел "Dynamic content":

+ +
<h2>Dynamic content</h2>
+
+<p>The library has the following record counts:</p>
+<ul>
+<li><strong>Books:</strong> \{{ num_books }}</li>
+<li><strong>Copies:</strong> \{{ num_instances }}</li>
+<li><strong>Copies available:</strong> \{{ num_instances_available }}</li>
+<li><strong>Authors:</strong> \{{ num_authors }}</li>
+</ul>
+
+<p>You have visited this page \{{ num_visits }}{% if num_visits == 1 %} time{% else %} times{% endif %}.</p>
+
+ +

Сохраните ваши изменения и перезапустите сервер. Данное значение должно изменяться всякий раз, когда вы обновляете страницу.

+ + + +

Итоги

+ +

Вы узнали как применять сессии для улучшения взаимодейстсвие с анонимными пользователями. 

+ +

В наших следующих статьях мы рассмотрим фреймворк аутентификации и авторизации (разрешение доступа, permission), и покажем вам как поддерживать пользовательские аккаунты.

+ +

Смотрите также

+ + + +

{{PreviousMenuNext("Learn/Server-side/Django/Generic_views", "Learn/Server-side/Django/Authentication", "Learn/Server-side/Django")}}

diff --git "a/files/ru/learn/server-side/django/\320\260\321\203\321\202\320\265\320\275\321\202\320\270\321\204\320\270\320\272\320\260\321\206\320\270\321\217/index.html" "b/files/ru/learn/server-side/django/\320\260\321\203\321\202\320\265\320\275\321\202\320\270\321\204\320\270\320\272\320\260\321\206\320\270\321\217/index.html" deleted file mode 100644 index 807db42a90..0000000000 --- "a/files/ru/learn/server-side/django/\320\260\321\203\321\202\320\265\320\275\321\202\320\270\321\204\320\270\320\272\320\260\321\206\320\270\321\217/index.html" +++ /dev/null @@ -1,688 +0,0 @@ ---- -title: 'Руководство Django Часть 8: Аутентификация и авторизация пользователя' -slug: Learn/Server-side/Django/Аутентификация -tags: - - Python - - Аутентификация - - Аутентификация django - - Джанго - - Начинающий - - Обучение - - Разграничение доступа - - Руководство - - Сервер - - Статья - - Формы - - на стороне сервера - - сессии -translation_of: Learn/Server-side/Django/Authentication ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/Server-side/Django/Sessions", "Learn/Server-side/Django/Forms", "Learn/Server-side/Django")}}
- -

В данном руководстве мы продемонстрируем вам систему входа пользователя на ваш сайт используя его собственный аккаунт. Кроме того, мы покажем как реализовать  контроль того, что может видеть и делать пользователь, в зависимости от того, залогинен он, или нет, а также имеет ли он соответствующий уровень прав доступа (permissions). Для того чтобы продемонстрировать все это, мы расширим LocalLibrary, добавив страницы для входа/выхода, а также страницы просмотра/редактирования книг, специфические для пользователя и персонала.

- - - - - - - - - - - - -
Требования:Завершить изучение предыдущих тем руководства, включая Руководство Django Часть 7: Работа с сессиями.
Цель:Понимать как настроить и использовать механизм аутентификации пользователя и разграничений прав доступа.
- -

Обзор

- -

Django предоставляет систему аутентификации и авторизации ("permission") пользователя, реализованную на основе фреймворка работы с сессиями, который мы рассматривали в предыдущей части. Система аутентификации и авторизации позволяет вам проверять учетные данные пользователей и определять какие действия какой пользователь может выполнять. Данный фреймворк включает в себя встроенные модели для Пользователей и Групп (основной способ применения прав доступа для более чем одного пользователя), непосредственно саму систему прав доступа (permissions)/флаги, которые определяют может ли пользователь выполнить задачу, с какой формой и отображением для авторизованых пользователей, а так же получить доступ к контенту с ограниченым доступом.

- -
-

Примечание: В соответствии с идеологией Django система аутентификации является очень общей и, таким образом, не предоставляет некоторые возможности, которые присутствуют в других системах веб-аутентификации. Решениями некоторых общих задач занимаются пакеты сторонних разработчиков, например, защита от подбора пароля (через стороннюю библиотеку OAuth).

-
- -

В данном разделе руководства мы покажем вам реализацию аутентификации пользователя на сайте LocalLibrary, создание страниц входа/выхода, добавления разграничения доступа (permissions) к вашим моделям, а также продемонстрируем контроль за доступом к некоторым страницам. Мы будем использовать аутентификацию/авторизацию для показа пользователям и сотрудникам библиотеки, списков книг, которые были взяты на прокат.

- -

Система аутентификации является очень гибкой и позволяет вам формировать свои собственные URL-адреса, формы, отображения, а также шаблоны страниц, если вы пожелаете, с нуля, через простой вызов функций соответствующего API для авторизации пользователя. Тем не менее, в данной статье мы будем использовать "встроенные" в Django методы отображений и форм аутентификации, а также методы построения страниц входа и выхода. Нам все еще необходимо создавать шаблоны страниц, но это будет достаточно несложно.

- -

Мы покажем вам как реализовать разграничение доступа (permissions), а также выполнять соответствующую проверку статусов авторизации и прав доступа, в отображениях, и в шаблонах страниц.

- -

Подключение аутентификации

- -

Аутентификация была подключена автоматически когда мы создали скелет сайта (в части 2), таким образом на данный момент вам ничего не надо делать.

- -
-

Примечание: Необходимые настройки были выполнены для нас, когда мы создали приложение при помощи команды django-admin startproject. Таблицы базы данных для пользователей и модели авторизации были созданы, когда в первый раз выполнили команду python manage.py migrate.

-
- -

Соответствующие настройки сделаны в параметрах INSTALLED_APPS и MIDDLEWARE файла проекта (locallibrary/locallibrary/settings.py), как показано ниже:

- -
INSTALLED_APPS = [
-    ...
-    'django.contrib.auth',  # Фреймворк аутентификации и моделей по умолчанию.
-    'django.contrib.contenttypes',  # Django контент-типовая система (даёт разрешения, связанные с моделями).
-    ....
-
-MIDDLEWARE = [
-    ...
-    'django.contrib.sessions.middleware.SessionMiddleware',  # Управление сессиями между запросами
-    ...
-    'django.contrib.auth.middleware.AuthenticationMiddleware',  # Связывает пользователей, использующих сессии, запросами.
-    ....
-
- -

Создание пользователей и групп

- -

Вы уже создали своего первого пользователя когда мы рассматривали Административная панель сайта Django в части 4 (это был суперпользователь, созданный при помощи команды python manage.py createsuperuser). Наш суперпользователь уже авторизован и имеет все необходимые уровни доступа к данным и функциям, таким образом нам необходимо создать тестового пользователя для отработки соответствующей работы сайта. В качестве наиболее быстрого способа, мы будем использовать административную панель сайта для создания соответствующих групп и акканутов locallibrary.

- -
-

Примечание: Вы можете создавать пользователей программно, как показано ниже. Например, вам мог бы подойти данный способ в том случае, если вы разрабатываете интерфейс, который позволяет пользователям создавать их собственные аккаунты (вы не должны предоставлять доступ пользователям к административной панели вашего сайта).

- -
from django.contrib.auth.models import User
-
-# Создайте пользователя и сохраните его в базе данных
-user = User.objects.create_user('myusername', 'myemail@crazymail.com', 'mypassword')
-
-# Обновите поля и сохраните их снова
-user.first_name = 'John'
-user.last_name = 'Citizen'
-user.save()
-
-
- -

Ниже мы создадим группу, а затем пользователя. Несмотря на то, что у нас пока нет никаких  разрешений для добавления к нашей библиотеке каких-либо членов, если мы захотим это сделать в будущем, то будет намного проще добавлять их к уже созданной группе, с заданной аутентификацией.

- -

Запустите сервер разработки и перейдите к административной панели вашего сайта (http://127.0.0.1:8000/admin/). Залогиньтесь на сайте при помощи параметров (имя пользователя и пароля) аккаунта суперпользователя. Самая "верхняя" страница панели Администратора показывает все наши модели. Для того, чтобы увидеть записи в разделе Authentication and Authorisation вы можете нажать на ссылку Users, или Groups.

- -

Admin site - add groups or users

- -

В первую очередь, в качестве нового члена нашего сайта, давайте создадим новую группу.

- -
    -
  1. Нажмите на кнопку Add (Добавить) (рядом с Group) и создайте новую группу; для данной группы введите Name (Имя) "Library Members".Admin site - add group
  2. -
  3. Для данной группы не нужны какие-либо разрешения, поэтому мы просто нажимаем кнопку SAVE (Сохранить) (вы перейдете к списку групп).
  4. -
- -

Теперь давайте создадим пользователя:

- -
    -
  1. Перейдите обратно на домашнюю страницу административной панели
  2. -
  3. Для перехода к диалогу добавления пользователя нажмите на кнопку Add, соответствующую строке Users (Пользователи).Admin site - add user pt1
  4. -
  5. Введите соответствующие Username (имя пользователя) и Password/Password confirmation (пароль/подтверждение пароля) для вашего тестового пользователя
  6. -
  7. Нажмите SAVE для завершения процесса создания пользователя.
    -
    - Административная часть сайта создаст нового пользователя и немедленно перенаправит вас на страницу Change user (Изменение параметров пользователя) где вы можете, соответственно, изменить ваш username, а кроме того добавить информацию для дополнительных полей модели User. Эти поля включают в себя имя пользователя, фамилию, адрес электронной почты, статус пользователя, а также соответствующие параметры доступа (может быть установлен только флаг  Active). Ниже вы можете определить группу для пользователя и необходимые параметры доступа, а кроме того, вы можете увидеть важные даты, относящиеся к пользователю (дату подключения к сайту и дату последнего входа).Admin site - add user pt2
  8. -
  9. В разделе Groups, из списка Доступные группы выберите группу Library Member, а затем переместите ее в блок "Выбранные группы" (нажмите стрелку-"направо", находящуюся между блоками).Admin site - add user to group
  10. -
  11. Больше нам не нужно здесь нечего делать, просто нажмите "Save"(Сохранить), и вы вернетесь к списку созданых пользователей.
  12. -
- -

Вот и все! Теперь у вас есть учетная запись «обычного члена библиотеки», которую вы сможете использовать для тестирования (как только добавим страницы, чтобы пользователи могли войти в систему).

- -
-

Note: Попробуйте создать другого пользователя, например "Библиотекаря". Так же создайте группу "Библиотекарей" и добавьте туда своего только что созданного библиотекаря

-
- -

Настройка представлений проверки

- -

Django предоставляет почти все, что нужно для создания страниц аутентификации входа, выхода из системы и управления паролями из коробки. Это включает в себя url-адреса, представления (views) и формы,но не включает шаблоны — мы должны создать свой собственный шаблон!

- -

В этом разделе мы покажем, как интегрировать систему по умолчанию в Сайт LocalLibrary и создать шаблоны.  Мы поместим их в основные URL проекта.

- -
-

Заметка: Вы не должны использовать этот код, но вполне вероятно, что вы хотите, потому что это делает вещи намного проще. Вам почти наверняка потребуется изменить код обработки формы, если вы измените свою модель пользователя (сложная тема!) но даже в этом случае вы все равно сможете использовать функции просмотра запасов.

-
- -
-

Заметка: В этом случае мы могли бы разумно поместить страницы аутентификации, включая URL-адреса и шаблоны, в наше приложение каталога. Однако, если бы у нас было несколько приложений, было бы лучше отделить это общее поведение входа в систему и иметь его доступным на всем сайте, так что это то, что мы показали здесь!

-
- -

Проектирование URLs

- -

Добавьте следующее в нижней части проекта urls.py файл (locallibrary/locallibrary/urls.py) файл:

- -
#Add Django site authentication urls (for login, logout, password management)
-urlpatterns += [
-    path('accounts/', include('django.contrib.auth.urls')),
-]
-
- -

Перейдите по http://127.0.0.1:8000/accounts/ URL (обратите внимание на косую черту!), Django покажет ошибку, что он не смог найти этот URL, и перечислить все URL, которые он пытался открыть. Из этого Вы можете увидеть URL-адреса, которые будут работать, например:

- -
-

Примечание. Использование вышеуказанного метода добавляет следующие URL-адреса с именами в квадратных скобках, которые могут использоваться для изменения сопоставлений URL-адресов. Вам не нужно реализовывать что-либо еще - приведенное выше сопоставление URL-адресов автоматически отображает указанные ниже URL-адреса.

-
- -
-
accounts/ login/ [name='login']
-accounts/ logout/ [name='logout']
-accounts/ password_change/ [name='password_change']
-accounts/ password_change/done/ [name='password_change_done']
-accounts/ password_reset/ [name='password_reset']
-accounts/ password_reset/done/ [name='password_reset_done']
-accounts/ reset/<uidb64>/<token>/ [name='password_reset_confirm']
-accounts/ reset/done/ [name='password_reset_complete']
-
- -

Теперь попробуйте перейти к URL-адресу входа (http://127.0.0.1:8000/accounts/login/). Это приведет к сбою снова, но с ошибкой, сообщающей вам, что нам не хватает требуемого шаблона (registration / login.html) в пути поиска шаблона. Вы увидите следующие строки, перечисленные в желтом разделе вверху:

- -
Exception Type:    TemplateDoesNotExist
-Exception Value:    registration/login.html
- -

Следующий шаг - создать каталог регистрации в пути поиска, а затем добавить файл login.html.

- -

Каталог шаблонов

- -

URL-адреса (и неявные представления), которые мы только что добавили, ожидают найти связанные с ними шаблоны в каталоге / регистрации / где-то в пути поиска шаблонов.
-
- Для этого сайта мы разместим наши HTML-страницы в каталоге templates / registration /. Этот каталог должен находиться в корневом каталоге проекта, то есть в том же каталоге, что и в каталоге и папках locallibrary). Создайте эти папки сейчас.

- -
-

Примечание: Ваша структура папок теперь должна выглядеть как показано внизу:
- locallibrary (django project folder)
-    |_catalog
-    |_locallibrary
-    |_templates (new)
-                 |_registration

-
- -

Чтобы сделать эти директории видимыми для загрузчика шаблонов   (т. е. помещать этот каталог в путь поиска шаблона) откройте настройки проекта (/locallibrary/locallibrary/settings.py), и обновите в секции TEMPLATES строку 'DIRS' как показано.

- -
TEMPLATES = [
-    {
-        ...
-        'DIRS': [os.path.join(BASE_DIR, 'templates')],
-        'APP_DIRS': True,
-        ...
-
- -

Шаблон аутентификации

- -
-

Важно: Шаблоны аутентификации, представленные в этой статье, являются очень простой / слегка измененной версией шаблонов логина демонстрации Django. Возможно, вам придется настроить их для собственного использования!

-
- -

Создайте новый HTML файл, названный /locallibrary/templates/registration/login.html. дайте ему следующее содержание:

- -
{% extends "base_generic.html" %}
-
-{% block content %}
-
-{% if form.errors %}
-  <p>Your username and password didn't match. Please try again.</p>
-{% endif %}
-
-{% if next %}
-  {% if user.is_authenticated %}
-    <p>Your account doesn't have access to this page. To proceed,
-    please login with an account that has access.</p>
-  {% else %}
-    <p>Please login to see this page.</p>
-  {% endif %}
-{% endif %}
-
-<form method="post" action="{% url 'login' %}">
-{% csrf_token %}
-<table>
-
-<tr>
-  <td>\{{ form.username.label_tag }}</td>
-  <td>\{{ form.username }}</td>
-</tr>
-
-<tr>
-  <td>\{{ form.password.label_tag }}</td>
-  <td>\{{ form.password }}</td>
-</tr>
-</table>
-
-<input type="submit" value="login" />
-<input type="hidden" name="next" value="\{{ next }}" />
-</form>
-
-{# Assumes you setup the password_reset view in your URLconf #}
-<p><a href="{% url 'password_reset' %}">Lost password?</a></p>
-
-{% endblock %}
- -

Этот шаблон имеет сходство с тем, что мы видели раньше - он расширяет наш базовый шаблон и переопределяет блок контента. Остальная часть кода - это довольно стандартный код обработки формы, о котором мы поговорим в следующем учебном пособии. Все, что вам нужно знать, это показ формы, в которой вы можете ввести свое имя пользователя и пароль, а если вы введете недопустимые значения, вам будет предложено ввести правильные значения, когда страница обновится.

- -

Перейдите на страницу входа (http://127.0.0.1:8000/accounts/login/) когда вы сохраните свой шаблон, и вы должны увидеть что-то наподобие этого:

- -

Library login page v1

- -

Если ваша попытка войти в систему будет успешной,  вы будете перенаправлены на другую страницу (по умолчанию это будет http://127.0.0.1:8000/accounts/profile/). Проблема здесь в том, что по умолчанию Django ожидает, что после входа в систему вы захотите перейти на страницу профиля, что может быть или не быть. Поскольку вы еще не определили эту страницу, вы получите еще одну ошибку!
-
- Откройте настройки проекта (/locallibrary/locallibrary/settings.py) и добавьте текст ниже. Теперь, когда вы входите в систему, вы по умолчанию должны перенаправляться на домашнюю страницу сайта.

- -
# Redirect to home URL after login (Default redirects to /accounts/profile/)
-LOGIN_REDIRECT_URL = '/'
-
- -

Шаблон выхода

- -

Если вы перейдете по URL-адресу выхода (http://127.0.0.1:8000/accounts/logout/), то увидите странное поведение - ваш пользователь наверняка выйдет из системы, но вы попадете на страницу выхода администратора. Это не то, что вам нужно, хотя бы потому, что ссылка для входа на этой странице приведет вас к экрану входа в систему администратора. (и это доступно только для пользователей, у которых есть разрешение is_staff).
-
- Создайте и откройте /locallibrary/templates/registration/logged_out.html. Скопируйте текст ниже:

- -
{% extends "base_generic.html" %}
-
-{% block content %}
-<p>Logged out!</p>
-
-<a href="{% url 'login'%}">Click here to login again.</a>
-{% endblock %}
- -

Этот шаблон очень прост. Он просто отображает сообщение, информирующее вас о том, что вы вышли из системы, и предоставляет ссылку, которую вы можете нажать, чтобы вернуться на экран входа в систему. Если вы снова перейдете на страницу выхода из системы, вы увидите эту страницу:

- -

Library logout page v1

- -

Шаблон сброса пароля

- -

Система сброса пароля по умолчанию использует электронную почту, чтобы отправить пользователю ссылку на сброс. Вам необходимо создать формы, чтобы получить адрес электронной почты пользователя, отправить электронное письмо, разрешить им вводить новый пароль и отметить, когда весь процесс будет завершен.
-
- В качестве отправной точки можно использовать следующие шаблоны.

- -

Форма сброса пароля

- -

Это форма, используемая для получения адреса электронной почты пользователя (для отправки пароля для сброса пароля). Создайте /locallibrary/templates/registration/password_reset_form.html и дайте ему следующее содержание:

- -
{% extends "base_generic.html" %}
-{% block content %}
-
-<form action="" method="post">{% csrf_token %}
-    {% if form.email.errors %} \{{ form.email.errors }} {% endif %}
-        <p>\{{ form.email }}</p>
-    <input type="submit" class="btn btn-default btn-lg" value="Reset password" />
-</form>
-
-{% endblock %}
-
- -

Сброс пароля

- -

Эта форма отображается после того, как ваш адрес электронной почты будет собран. Создайте /locallibrary/templates/registration/password_reset_done.html, и дайте ему следующее содержание:

- -
{% extends "base_generic.html" %}
-{% block content %}
-<p>We've emailed you instructions for setting your password. If they haven't arrived in a few minutes, check your spam folder.</p>
-{% endblock %}
-
- -

Сброс пароля по email

- -

Этот шаблон предоставляет текст электронной почты HTML, содержащий ссылку на сброс, которую мы отправим пользователям. Создайте /locallibrary/templates/registration/password_reset_email.html и дайте ему следующее содержание:

- -
Someone asked for password reset for email \{{ email }}. Follow the link below:
-\{{ protocol}}://\{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
-
- -

Подтверждение на сброс пароля

- -

На этой странице вы вводите новый пароль после нажатия ссылки в электронном письме с возвратом пароля. Создайте /locallibrary/templates/registration/password_reset_confirm.html и дайте ему следующее содержание:

- -
{% extends "base_generic.html" %}
-
-{% block content %}
-
-    {% if validlink %}
-        <p>Please enter (and confirm) your new password.</p>
-        <form action="" method="post">
-            {% csrf_token %}
-            <table>
-                <tr>
-                    <td>\{{ form.new_password1.errors }}
-                        <label for="id_new_password1">New password:</label></td>
-                    <td>\{{ form.new_password1 }}</td>
-                </tr>
-                <tr>
-                    <td>\{{ form.new_password2.errors }}
-                        <label for="id_new_password2">Confirm password:</label></td>
-                    <td>\{{ form.new_password2 }}</td>
-                </tr>
-                <tr>
-                    <td></td>
-                    <td><input type="submit" value="Change my password" /></td>
-                </tr>
-            </table>
-        </form>
-    {% else %}
-        <h1>Password reset failed</h1>
-        <p>The password reset link was invalid, possibly because it has already been used. Please request a new password reset.</p>
-    {% endif %}
-
-{% endblock %}
-
- -

Сброс пароля завершен

- -

Это последний шаблон сброса пароля, который отображается, чтобы уведомить вас о завершении сброса пароля. Создайте /locallibrary/templates/registration/password_reset_complete.html и дайте ему следующее содержание:

- -
{% extends "base_generic.html" %}
-{% block content %}
-
-<h1>The password has been changed!</h1>
-<p><a href="{% url 'login' %}">log in again?</a></p>
-
-{% endblock %}
- -

Тестирование новых страниц аутентификации

- -

Теперь, когда вы добавили конфигурацию URL и создали все эти шаблоны, теперь страницы аутентификации должны работать! Вы можете протестировать новые страницы аутентификации, попытавшись войти в систему, а затем выйдите из учетной записи суперпользователя, используя эти URL-адреса:

- - - -

Вы сможете проверить функцию сброса пароля по ссылке на странице входа. Имейте в виду, что Django отправляет только сбросные электронные письма на адреса (пользователи), которые уже хранятся в его базе данных!

- -
-

Заметка: Система сброса пароля требует, чтобы ваш сайт поддерживал электронную почту, что выходит за рамки этой статьи, поэтому эта часть еще не будет работать. Чтобы разрешить тестирование, поместите следующую строку в конец файла settings.py. Это регистрирует любые письма, отправленные на консоль (чтобы вы могли скопировать ссылку на сброс пароля с консоли).

- -
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
-
- -

Для получения дополнительной информации см. Отправка email (Django docs).

-
- -

Тестирование проверки подлинности пользователей

- -

В этом разделе мы рассмотрим, что мы можем сделать, чтобы выборочно контролировать контент, который видят пользователи, на основе того, вошли ли они в систему или нет.

- -

Тестирование в шаблонах

- -

Вы можете получить информацию о текущем зарегистрированном пользователе в шаблонах с переменной шаблона \{{user}} (это добавляется в контекст шаблона по умолчанию при настройке проекта, как и в нашем скелете).

- -

Обычно вы сначала проверяете переменную шаблона \{{user.is_authenticated}}, чтобы определить, имеет ли пользователь право видеть конкретный контент. Чтобы продемонстрировать это, мы обновим нашу боковую панель, чтобы отобразить ссылку «Вход», если пользователь вышел из системы, и ссылку «Выход», если он вошёл в систему.

- -

Откройте базовый шаблон (/locallibrary/catalog/templates/base_generic.html) и скопируйте следующий текст в sidebar блок непосредственно перед тегом шаблона endblock.

- -
  <ul class="sidebar-nav">
-
-    ...
-
-   {% if user.is_authenticated %}
-     <li>User: \{{ user.get_username }}</li>
-     <li><a href="{% url 'logout'%}?next=\{{request.path}}">Logout</a></li>
-   {% else %}
-     <li><a href="{% url 'login'%}?next=\{{request.path}}">Login</a></li>
-   {% endif %} 
-  </ul>
- -

Как вы можете видеть, мы используем теги шаблона if-else-endif для условного отображения текста на основе того, является ли \{{user.is_authenticated}} истинным. Если пользователь аутентифицирован, мы знаем, что у нас есть действительный пользователь, поэтому мы вызываем \{{user.get_username}}, чтобы отобразить их имя.

- -

Мы создаем URL-адрес для входа и выхода из системы, используя тег шаблона URL-адреса и имена соответствующих конфигураций URLs. Также обратите внимание на то, как мы добавили ?next=\{{request.path}} в конец URLs. Это означает, что следующий URL-адрес содержит адрес (URL) текущей страницы, в конце связанного URL-адреса. После того, как пользователь успешно выполнил вход в систему, представления будут использовать значение "next" чтобы перенаправить пользователя обратно на страницу, где они сначала нажали ссылку входа / выхода из системы.

- -
-

Примечание: Попробуйте! Если вы находитесь на главной странице и вы нажимаете «Вход / Выход» на боковой панели, то после завершения операции вы должны вернуться на ту же страницу.

-
- -

Тестирование в представлениях

- -

Если вы используете функциональные представления, самым простым способом ограничить доступ к вашим функциям является применение login_required декоратор к вашей функции просмотра, как показано ниже. Если пользователь вошел в систему, ваш код просмотра будет выполняться как обычно. Если пользователь не вошел в систему, это перенаправит URL-адрес входа, определенный в настройках проекта. (settings.LOGIN_URL), передав текущий абсолютный путь в качестве next параметра URL. Если пользователю удастся войти в систему, они будут возвращены на эту страницу, но на этот раз аутентифицированы.

- -
from django.contrib.auth.decorators import login_required
-
-@login_required
-def my_view(request):
-    ...
- -
-

Заметка: Вы можете сделать то же самое вручную, путём тестирования request.user.is_authenticated, но декоратор намного удобнее!

-
- -

Аналогичным образом, самый простой способ ограничить доступ к зарегистрированным пользователям в ваших представлениях на основе классов - это производные от LoginRequiredMixin. Вы должны объявить этот mixin сначала в списке суперкласса, перед классом основного представления.

- -
from django.contrib.auth.mixins import LoginRequiredMixin
-
-class MyView(LoginRequiredMixin, View):
-    ...
- -

Это имеет такое же поведение при переадресации, что и  login_required декоратор. Вы также можете указать альтернативное местоположение для перенаправления пользователя, если он не аутентифицирован (login_url), и имя параметра URL вместо "next" , чтобы вставить текущий абсолютный путь (redirect_field_name).

- -
class MyView(LoginRequiredMixin, View):
-    login_url = '/login/'
-    redirect_field_name = 'redirect_to'
-
- -

Для получения дополнительной информации ознакомьтесь с  Django docs here.

- -

Пример - перечисление книг текущего пользователя

- -

Теперь, когда мы знаем, как ограничить страницу определенному пользователю, создайте представление о книгах, которые заимствовал текущий пользователь.

- -

К сожалению, у нас пока нет возможности пользователям использовать книги! Поэтому, прежде чем мы сможем создать список книг, мы сначала расширим BookInstance модель для поддержки концепции заимствования и использования приложения Django Admin для заимствования ряда книг нашему тестовому пользователю.

- -

Модели

- -

Прежде всего, мы должны предоставить пользователям возможность кредита на BookInstance (у нас уже есть status и due_back дата, но у нас пока нет связи между этой моделью и пользователем. Мы создадим его с помощью поля ForeignKey (один ко многим). Нам также нужен простой механизм для проверки того, просрочена ли заемная книга.

- -

Откройте catalog/models.py, и импортируйте модель User из django.contrib.auth.models (добавьте это чуть ниже предыдущей строки импорта в верхней части файла, так User доступен для последующего кода, что позволяет использовать его):

- -
from django.contrib.auth.models import User
-
- -

Затем добавьте поле borrower в модель BookInstance:

- -
borrower = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
-
- -

Пока мы здесь, давайте добавим свойство, которое мы можем вызвать из наших шаблонов, чтобы указать, просрочен ли конкретный экземпляр книги. Хотя мы могли бы рассчитать это в самом шаблоне, использование свойства, как показано ниже, будет намного более эффективным. Добавьте это где-нибудь в верхней части файла:

- -
from datetime import date
- -

Теперь добавьте следующее определение свойства внутри класса BookInstance:

- -
@property
-def is_overdue(self):
-    if self.due_back and date.today() > self.due_back:
-        return True
-    return False
- -
-

Примечание. Сначала мы проверим, является ли due_back пустым, прежде чем проводить сравнение. Пустое поле due_back заставило Django выкидывать ошибку, а не показывать страницу: пустые значения не сопоставимы. Это не то, что мы хотели бы, чтобы наши пользователи испытывали!

-
- -

Теперь, когда мы обновили наши модели, нам нужно будет внести новые изменения в проект, а затем применить эти миграции:

- -
python3 manage.py makemigrations
-python3 manage.py migrate
-
- -

Admin

- -

Теперь откройте каталог catalog/admin.py, и добавьте поле borrower в класс BookInstanceAdmin , как в list_display , так и в полях fieldsets , как показано ниже. Это сделает поле видимым в разделе Admin, так что мы можем при необходимости назначить User в BookInstance.

- -
@admin.register(BookInstance)
-class BookInstanceAdmin(admin.ModelAdmin):
-    list_display = ('book', 'status', 'borrower', 'due_back', 'id')
-    list_filter = ('status', 'due_back')
-
-    fieldsets = (
-        (None, {
-            'fields': ('book','imprint', 'id')
-        }),
-        ('Availability', {
-            'fields': ('status', 'due_back','borrower')
-        }),
-    )
- -

Займите несколько книг

- -

Теперь, когда возможно кредитовать книги конкретному пользователю, зайдите и заработайте на нескольких записей в BookInstance. Установите borrowed поле вашему тестовому пользователю, сделайте status «В займе» и установите сроки оплаты как в будущем, так и в прошлом.

- -
-

Заметка: Мы не будем описывать процесс, так как вы уже знаете, как использовать Admin сайт!

-
- -

Займ в представлении

- -

Теперь мы добавим представление для получения списка всех книг, которые были предоставлены текущему пользователю. Мы будем использовать один и тот же общий класс, с которым мы знакомы, но на этот раз мы также будем импортировать и выводить из  LoginRequiredMixin, так что только вошедший пользователь сможет вызвать это представление. Мы также решили объявить  template_name, вместо того, чтобы использовать значение по умолчанию, потому что у нас может быть несколько разных списков записей BookInstance, с разными представлениями и шаблонами.

- -

Добавьте следующее в catalog/views.py:

- -
from django.contrib.auth.mixins import LoginRequiredMixin
-
-class LoanedBooksByUserListView(LoginRequiredMixin,generic.ListView):
-    """
-    Generic class-based view listing books on loan to current user.
-    """
-    model = BookInstance
-    template_name ='catalog/bookinstance_list_borrowed_user.html'
-    paginate_by = 10
-
-    def get_queryset(self):
-        return BookInstance.objects.filter(borrower=self.request.user).filter(status__exact='o').order_by('due_back')
- -

Чтобы ограничить наш запрос только объектами BookInstance для текущего пользователя, мы повторно реализуем get_queryset(), как показано выше. Обратите внимание, что "o" это сохраненный код для "on loan" и мы сортируем по дате due_back, чтобы сначала отображались самые старые элементы.

- -

URL-адрес для заёмных книг

- -

Теперь откройте /catalog/urls.py и добавьте url() , указывая на приведённое выше представление (вы можете просто скопировать текст ниже в конец файла).

- -
urlpatterns += [
-    url(r'^mybooks/$', views.LoanedBooksByUserListView.as_view(), name='my-borrowed'),
-]
- -

Шаблон для заёмных книг

- -

Теперь все, что нам нужно сделать для этой страницы, - это добавить шаблон. Сначала создайте файл шаблона /catalog/templates/catalog/bookinstance_list_borrowed_user.html и дайте ему следующее содержание:

- -
{% extends "base_generic.html" %}
-
-{% block content %}
-    <h1>Borrowed books</h1>
-
-    {% if bookinstance_list %}
-    <ul>
-
-      {% for bookinst in bookinstance_list %}
-      <li class="{% if bookinst.is_overdue %}text-danger{% endif %}">
-        <a href="{% url 'book-detail' bookinst.book.pk %}">\{{bookinst.book.title}}</a> (\{{ bookinst.due_back }})
-      </li>
-      {% endfor %}
-    </ul>
-
-    {% else %}
-      <p>There are no books borrowed.</p>
-    {% endif %}
-{% endblock %}
- -

Этот шаблон очень похож на тот, который мы создали ранее для объектов Book и Author. Единственное, что «новое» здесь, это то, что мы проверяем метод, который мы добавили в модель (bookinst.is_overdue) с целью использовать его для изменения цвета просроченных предметов.

- -

Когда сервер разработки запущен, вы должны теперь иметь возможность просматривать список для зарегистрированного пользователя в своем браузере по адресу  http://127.0.0.1:8000/catalog/mybooks/. Попробуйте это, когда ваш пользователь войдет в систему и выйдет из системы (во втором случае вы должны быть перенаправлены на страницу входа в систему).

- -

Добавить список на боковую панель

- -

Последний шаг - добавить ссылку на эту новую страницу в sidebar. Мы поместим это в тот же раздел, где мы покажем другую информацию для зарегистрированного пользователя.

- -

Откройте базовый шаблон (/locallibrary/catalog/templates/base_generic.html) и добавьте выделенную строку из sidebar, как показано на рисунке.

- -
 <ul class="sidebar-nav">
-   {% if user.is_authenticated %}
-   <li>User: \{{ user.get_username }}</li>
-   <li><a href="{% url 'my-borrowed' %}">My Borrowed</a></li>
-   <li><a href="{% url 'logout'%}?next=\{{request.path}}">Logout</a></li>
-   {% else %}
-   <li><a href="{% url 'login'%}?next=\{{request.path}}">Login</a></li>
-   {% endif %}
- </ul>
-
- -

На что это похоже?

- -

Когда любой пользователь войдет в систему, он будет видеть ссылку «Мной позаимствовано (My Borrowed)» в боковой колонке, и список книг, показанных ниже (первая книга не имеет установленной даты, что является ошибкой, которую мы надеемся исправить в более позднем уроке!).

- -

Library - borrowed books by user

- -

Права доступа

- -

Права доступа связаны с моделями и определяют операции, которые могут выполняться на экземпляре модели самим пользователем, у которого есть разрешение. По умолчанию Django автоматически дает добавить, изменить, и удалить разрешения у всех моделей, которые позволяют пользователям с правом доступа выполнять связанные действия через администратора сайта. Вы можете определить свои собственные разрешения для моделей и предоставить их конкретным пользователям. Вы также можете изменить разрешения, связанные с разными экземплярами одной и той же модели. Тестирование разрешений в представлениях и шаблонах очень похоже на тестирование по статусу аутентификации (фактически, тестирование прав доступа также проверяет аутентификацию).

- -

Модели

- -

Определение разрешений выполняется в разделе моделей "class Meta" , используется permissions поле. Вы можете указать столько разрешений, сколько необходимо в кортеже, причем каждое разрешение определяется во вложенном кортеже, содержащем имя разрешения и отображаемое значение разрешения. Например, мы можем определить разрешение, позволяющее пользователю отметить, что книга была возвращена, как показано здесь:

- -
class BookInstance(models.Model):
-    ...
-    class Meta:
-        ...
-        permissions = (("can_mark_returned", "Set book as returned"),)   
- -

Затем мы могли бы назначить разрешение группе «Библиотекарь» (Librarian) на сайте администратора.

- -

Откройте catalog/models.py, и добавьте разрешение, как показано выше. Вам нужно будет повторно выполнить миграцию (вызвав python3 manage.py makemigrations и python3 manage.py migrate) для надлежащего обновления базы данных.

- -

Шаблоны

- -

Разрешения текущего пользователя хранятся в переменной шаблона, называемой  \{{ perms }}. Вы можете проверить, имеет ли текущий пользователь определенное разрешение, используя конкретное имя переменной в соответствующем приложении «Django» - например, \{{ perms.catalog.can_mark_returned }} будет True если у пользователя есть это разрешение, а False - в противном случае. Обычно мы проверяем разрешение с использованием шаблона {% if %}, как показано в:

- -
{% if perms.catalog.can_mark_returned %}
-    <!-- We can mark a BookInstance as returned. -->
-    <!-- Perhaps add code to link to a "book return" view here. -->
-{% endif %}
-
- -

Представления

- -

Разрешения можно проверить в представлении функции, используя  permission_required декоратор или в представлении на основе классов, используя PermissionRequiredMixin. шаблон и поведение такие же, как для аутентификации входа в систему, хотя, конечно, вы можете разумно добавить несколько разрешений.

- -

Функция в представлении с декоратором:

- -
from django.contrib.auth.decorators import permission_required
-
-@permission_required('catalog.can_mark_returned')
-@permission_required('catalog.can_edit')
-def my_view(request):
-    ...
- -

Требуется разрешение mixin для представлений на основе классов.

- -
from django.contrib.auth.mixins import PermissionRequiredMixin
-
-class MyView(PermissionRequiredMixin, View):
-    permission_required = 'catalog.can_mark_returned'
-    # Or multiple permissions
-    permission_required = ('catalog.can_mark_returned', 'catalog.can_edit')
-    # Note that 'catalog.can_edit' is just an example
-    # the catalog application doesn't have such permission!
- -

Пример

- -

Мы не будем обновлять LocalLibrary здесь; возможно, в следующем уроке!

- -

Испытайте себя

- -

 Ранее в этой статье мы показали вам, как создать страницу для текущего пользователя, в которой перечислены книги, которые они заимствовали. Теперь задача состоит в том, чтобы создать аналогичную страницу, которая видна только для библиотекарей, которая отображает  все книги, которые были заимствованы, и которая показывает имя каждого заемщика.

- -

 Вы должны следовать той же схеме, что и для другого представления. Главное отличие состоит в том, что вам нужно ограничить представление только библиотекарями. Вы можете сделать это на основе того, является ли пользователь сотрудником (декоратор функции:  staff_member_required, переменная шаблона: user.is_staff) но мы рекомендуем вам вместо этого использовать  can_mark_returned разрешения и PermissionRequiredMixin, как описано в предыдущем разделе.

- -
-

Важно: Не забудьте использовать вашего суперпользователя для тестирования на основе разрешений (проверки разрешений всегда возвращают true для суперпользователей, даже если разрешение еще не определено!). Вместо этого создайте пользователя-библиотекаря и добавьте необходимые возможности.

-
- -

 Когда вы закончите, ваша страница должна выглядеть примерно, как на скриншоте ниже.

- -

All borrowed books, restricted to librarian

- - - -

Подводим итоги

- -

 Отличная работа - теперь вы создали веб-сайт, на котором участники библиотеки могут входить в систему и просматривать собственный контент, и библиотекари (с правом доступа) могут просматривать все заемные книги с их читатетелями. На данный момент мы все еще просто просматриваем контент, но те же принципы и методы используются, когда вы хотите начать изменять и добавлять данные.

- -

 В следующей статье мы рассмотрим, как вы можете использовать формы Django для сбора пользовательского ввода, а затем начнём изменять некоторые из наших сохраненных данных.

- -

Смотрите также

- - - -

{{PreviousMenuNext("Learn/Server-side/Django/Sessions", "Learn/Server-side/Django/Forms", "Learn/Server-side/Django")}}

diff --git "a/files/ru/learn/server-side/django/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265/index.html" "b/files/ru/learn/server-side/django/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265/index.html" deleted file mode 100644 index 4bff707908..0000000000 --- "a/files/ru/learn/server-side/django/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265/index.html" +++ /dev/null @@ -1,257 +0,0 @@ ---- -title: Django введение -slug: Learn/Server-side/Django/Введение -tags: - - Python - - django - - Вступление - - Джанго - - Начинающим - - Серверное программирование -translation_of: Learn/Server-side/Django/Introduction ---- -
{{LearnSidebar}}
- -
{{NextMenu("Learn/Server-side/Django/development_environment", "Learn/Server-side/Django")}}
- -

В первой статье о Django мы отвечаем на вопрос «Что такое Django?» и даём обзор того, что делает его особенным. Мы опишем основные функции, в том числе некоторые из расширенных функций, которые у нас не будет времени подробно рассмотреть в этом модуле. Мы также покажем вам некоторые основные строительные блоки приложения Django (хотя на данный момент у вас ещё не будет среды разработки для тестирования).

- - - - - - - - - - - - -
Требования:Базовая компьютерная грамотность. Общее понимание server-side website programming, и в частности, механики client-server interactions in websites.
Задача:Узнать, что такое Django, какие функции он предоставляет, и основные строительные блоки приложения Django.
- -

Что такое Django?

- -

Django — это высокоуровневый Python веб-фреймворк, который позволяет быстро создавать безопасные и поддерживаемые веб-сайты. Созданный опытными разработчиками, Django берёт на себя большую часть хлопот веб-разработки, поэтому вы можете сосредоточиться на написании своего веб-приложения без необходимости изобретать велосипед. Он бесплатный и с открытым исходным кодом, имеет растущее и активное сообщество, отличную документацию и множество вариантов как бесплатной, так и платной поддержки.

- -

Django помогает писать программное обеспечение, которое будет:

- -
-
Полным
-
Django следует философии «Всё включено» и предоставляет почти всё, что разработчики могут захотеть сделать «из коробки». Поскольку всё, что вам нужно, является частью единого «продукта», всё это безупречно работает вместе, соответствует последовательным принципам проектирования и имеет обширную и актуальную документацию.
-
Разносторонним
-
Django может быть (и был) использован для создания практически любого типа веб-сайтов — от систем управления контентом и wiki до социальных сетей и новостных сайтов. Он может работать с любой клиентской средой и может доставлять контент практически в любом формате (включая HTML, RSS-каналы, JSON, XML и т. д.). Сайт, который вы сейчас читаете, создан с помощью Django!
-
Хотя Django предоставляет решения практически для любой функциональности, которая вам может понадобиться (например, для нескольких популярных баз данных, шаблонизаторов и т. д.), внутренне он также может быть расширен сторонними компонентами, если это необходимо.
-
Безопасным
-
Django помогает разработчикам избежать многих распространённых ошибок безопасности, предоставляя фреймворк, разработанный чтобы «делать правильные вещи» для автоматической защиты сайта. Например, Django предоставляет безопасный способ управления учётными записями пользователей и паролями, избегая распространённых ошибок, таких как размещение информации о сеансе в файлы cookie, где она уязвима (вместо этого файлы cookie содержат только ключ, а фактические данные хранятся в базе данных) или непосредственное хранение паролей вместо хэша пароля.
-
Хэш пароля это значение фиксированной длины, созданное путём обработки пароля через криптографическую хэш-функцию. Django может проверить правильность введённого пароля, пропустив его через хэш-функцию и сравнив вывод с сохранённым значением хэша. Благодаря «одностороннему» характеру функции, даже если сохранённое хэш-значение скомпрометировано, злоумышленнику будет сложно определить исходный пароль.
-
Django, по умолчанию, обеспечивает защиту от многих уязвимостей, включая SQL-инъекцию, межсайтовый скриптинг, подделку межсайтовых запросов и кликджекинг (см. Website security для получения дополнительной информации об этих атаках).
-
Масштабируемым
-
Django использует компонентную “shared-nothing” архитектуру (каждая её часть  независима от других и, следовательно, может быть заменена или изменена, если это необходимо). Чёткое разделение частей означает, что Django может масштабироваться при увеличении трафика, путём добавления оборудования на любом уровне: серверы кэширования, серверы баз данных или серверы приложений. Одни из самых загруженных сайтов успешно масштабировали Django (например, Instagram и Disqus, если назвать только два из них).
-
Удобным в сопровождении
-
Код Django написан с использованием принципов и шаблонов проектирования, которые поощряют создание поддерживаемого и повторно используемого кода. В частности, в нём используется принцип «Don't Repeat Yourself» (DRY, «не повторяйся»), поэтому нет ненужного дублирования, что сокращает объём кода. Django также способствует группированию связанных функциональных возможностей в повторно используемые «приложения» и, на более низком уровне, группирует связанный код в модули (в соответствии с шаблоном Model View Controller (MVC)).
-
Переносным
-
Django написан на Python, который работает на многих платформах. Это означает, что вы не привязаны к какой-либо конкретной серверной платформе и можете запускать приложения на многих версиях Linux, Windows и Mac OS X. Кроме того, Django хорошо поддерживается многими веб-хостингами, которые часто предоставляют определённую инфраструктуру и документацию для размещения сайтов Django.
-
- -

Как он появился?

- -

Django был разработан в период с 2003 по 2005 год командой, которая занималась созданием и обслуживанием газетных веб-сайтов. После создания нескольких сайтов, команда начала повторно использовать множество общего кода и шаблонов проектирования. Этот общий код эволюционировал в веб-фреймворк, который превратился в проект "Django" с открытым исходным кодом в июле 2005 года.

- -

Django продолжает расти и улучшаться с момента его первого релиза (1.0) в сентябре 2008 года до недавно выпущенной версии 3.1 (2020). В каждой версии добавлены новые функциональные возможности и исправлены ошибки, начиная от поддержки новых типов баз данных, шаблонизаторов и кэширования, до добавления «общих» функций просмотра и классов (уменьшающих объём кода, который разработчики должны писать для ряда программных задач).

- -
-

Заметка: Ознакомтесь с примечаниями к версии на сайте Django, чтобы увидеть что изменилось в последних версиях и как много работы было проделано, чтобы улучшить Django.

-
- -

Django — это процветающий совместный проект с открытым исходным кодом, в котором заняты многие тысячи пользователей и участников. Несмотря на то, что у него всё ещё есть некоторые особенности, которые отражают его происхождение, Django превратился в универсальный фреймворк, способный разрабатывать веб-сайты любого типа.

- -

Насколько популярен Django?

- -

Нет никаких доступных и окончательных оценок популярности серверных фреймворков (хотя сайты наподобие Hot Framework и пытаются оценить популярность, используя такие механизмы, как подсчёт количества проектов на GitHub и вопросов на StackOverflow для каждой платформы). Лучший вопрос — «достаточно ли Django популярен», чтобы избежать проблем непопулярных платформ. Продолжает ли он развиваться? Можете ли вы получить помощь, если вам нужно? Найдёте ли вы оплачиваемую работу, если изучите Django?

- -

Основываясь на количестве крупных сайтов, которые используют Django, количестве участников и количестве людей, предоставляющих как бесплатную, так и платную поддержку, можно ответить: да, Django — популярный фреймворк!

- -

Django используют такие крупные сайты, как Disqus, Instagram, Knight Foundation, MacArthur Foundation, Mozilla, National Geographic, Open Knowledge Foundation, Pinterest и Open Stack (источник: обзорная страница Django).

- -

Является ли Django гибким?

- -

Веб-фрейморки часто можно поделить на "гибкие" и "негибкие".

- -

Негибкие - это те, у которых есть "правильный путь" для решения какой-либо конкретной задачи. Они часто поддерживают быстрое развёртывание в определенной области (решение проблем определенного типа), потому что правильный способ сделать что-либо обычно хорошо понимается и хорошо документируется. Однако они могут быть менее гибкими при решении проблем за пределами их основной сферы и, как правило, предлагают меньше вариантов того, какие компоненты и подходы они могут использовать.

- -

Напротив, у гибких фреймворков гораздо меньше ограничений на лучший способ склеивания компонентов для достижения цели или даже того, какие компоненты следует использовать. Они облегчают разработчикам использование наиболее подходящих инструментов для выполнения конкретной задачи, хотя и за счет того, что вам нужно самим найти эти компоненты.

- -

Django «умеренно гибкий» и, следовательно, обеспечивает «лучшее из обоих миров». Он предоставляет набор компонентов для обработки большинства задач веб-разработки и один (или два) предпочтительных способа их использования. Однако такая архитектура Django означает, что вы обычно можете выбирать из нескольких различных опций или при необходимости добавлять поддержку для совершенно новых.

- -

Как выглядит код Django?

- -

На традиционном информационом веб-сайте веб-приложение ожидает HTTP-запросы от веб-браузера (или другого клиента). Когда запрос получен, приложение разрабатывает то, что необходимо на основе URL-адреса и, возможно, данных в POST или GET запросах. В зависимости от того, что требуется, далее он может читать или записывать информацию из базы данных или выполнять другие задачи, необходимые для удовлетворения запроса. Затем приложение вернёт ответ веб-браузеру, часто динамически создавая HTML-страницу для отображения в браузере, вставляя полученные данные в HTML-шаблон.

- -

Веб-приложения, написанные на Django, обычно группируют код, который обрабатывает каждый из этих шагов, в отдельные файлы:

- -

- - - -
-

Заметка: Django реализует уровневую архитектуру "Model View Template (MVT)". Она имеет много общего с более известной архитектурой Model View Controller

-
- - - -

Следующие разделы дадут вам понимание того, как выглядят основные части Django (мы их изучим более детально чуть позже на курсе, когда будет настраивать окружение разработчика). 

- -

Отправка запроса в правильное view (urls.py)

- -

Сопоставитель URL-адресов обычно содержится в файле urls.py. В примере ниже сопоставитель (urlpatterns) определяет список сопоставлений междумаршрутами (определёнными URL-шаблонами) и соотвествующими функциями отображения (view). Если получен HTTP-запрос, который имеет URL-адрес, соответствующий определённому шаблону, то затем будет вызвана связанная функция отображения (view) и передана в запрос.

- -
urlpatterns = [
-    path('admin/', admin.site.urls),
-    path('book/<int:id>/', views.book_detail, name='book_detail'),
-    path('catalog/', include('catalog.urls')),
-    re_path(r'^([0-9]+)/$', views.best),
-]
- -

Объект urlpatterns является списком функций path() и/или re_path() (в Python списки определяются с помощью квадратных скобок, внутри которых элементы разделены запятыми и могут содержать необязательную завершающую запятую. Например: [item1, item2, item3,]).

- -

Первый аргумент в обоих методах - маршрут (шаблон), который будет сопоставлен. В методе path() угловые скобки используются для определения частей URL-адреса, которые будут захвачены и переданы в функцию отображения (view) в качестве именованных аргументов. Функция re_path() использует гибкий подход к сопоставлению с шаблоном, известный как регулярное выражение. Мы поговорим об этом в следующей статье!

- -

Второй аргумент — это ещё одна функция, которая будет вызываться при сопоставлении шаблона. Обозначение views.book_detail указывает, что функция называется book_detail() и может быть обнаружена в модуле с именем views (т.е. внутри файла с именем views.py).

- -

Обработка запроса (views.py)

- -

Отображения (views) — это сердце веб-приложения, принимающего HTTP-запросы от веб-клиентов и возвращающего HTTP-ответы. Между этим они используют другие ресурсы фреймворка для доступа к базам данных, шаблонам визуализации и т. д.  

- -

В приведённом ниже примере показана минимальная функция представления index(), которая могла быть вызвана нашим сопоставителем URL-адресов в предыдущем разделе. Как и все функции отображения (view), она получает объект HttpRequest в качестве параметра (request) и возвращает объект HttpResponse. В этом случае мы ничего не делаем с запросом, и наш ответ просто возвращает жёстко запрограммированную строку. Мы покажем вам запрос, который делает что-то более интересное в следующем разделе.

- -
## filename: views.py (Django view functions)
-
-from django.http import HttpResponse
-
-def index(request):
-    # Получить HttpRequest — параметр запроса
-    # Выполнить операции, используя информацию из запроса.
-    # Вернуть HttpResponse
-    return HttpResponse('Hello from Django!')
-
- -
-

Заметка: Немного Python:

- -
    -
  • Модули Python это библиотеки функций, сохранённые в различных файлах, которые мы можем использовать в нашем коде. Здесь мы импортируем только объект HttpResponse из модуля django.http чтобы использовать его в нашем отображении (view): from django.http import HttpResponse . Также есть другие способы импортирования некоторых или всех объектов модуля.
  • -
  • Функции объявляются с помощью ключевого слова def, как показано выше, с именованными параметрами, перечисленными в скобках после имени функции; строка завершается двоеточием. Заметьте, что следующие строки содержат отступы.  Отступы важны, так как они определяют, какие строки кода находятся внутри конкретного блока (обязательные отступы — это ключевая особенность Python и одна из причин, почему код на Python так легко читать).
  • -
-
- - - -

Отображения (view) обычно содержатся в файле views.py.

- -

Определение данных модели (models.py)

- -

Веб-приложения Django обрабатывают и запрашивают данные через объекты Python, называемые моделями. Модели определяют структуру хранимых данных, включая типы полей и, возможно, их максимальный размер, значения по умолчанию, параметры списка выбора, текст справки для документации, текст меток для форм и т. д. Определение модели не зависит от используемой базы данных — ваши модели будут работать в любой из них. После того как вы выбрали базу данных, которую хотите использовать, вам не нужно напрямую обращатся к ней — вы просто пишете свою структуру модели и другой код, а Django выполняет всю «грязную работу» по обращению к базе данных за вас.

- -

В приведённом ниже фрагменте кода показана очень простая модель Django для объекта Team. Класс Team наследуется от класса models.Model. Он определяет имя команды и командный уровень в качестве полей символов и задаёт максимальное количество символов, которые могут быть сохранены для каждой записи. Team_level может быть одним из нескольких значений, поэтому мы определяем его как поле выбора и предоставляем сопоставление между отображаемыми вариантами и хранимыми данными вместе со значением по умолчанию.

- -
# filename: models.py
-
-from django.db import models
-
-class Team(models.Model):
-    team_name = models.CharField(max_length=40)
-
-    TEAM_LEVELS = (
-        ('U09', 'Under 09s'),
-        ('U10', 'Under 10s'),
-        ('U11', 'Under 11s'),
-        ...  #список других командных уровней
-    )
-    team_level = models.CharField(max_length=3,choices=TEAM_LEVELS,default='U11')
-
- -
-

Заметка: Немного Python:

- -
    -
  • Python поддерживает «объектно-ориентированное программирование», то есть стиль программирования, в котором мы организуем наш код в объекты, которые включают связанные данные и функции для работы с этими данными. Объекты также могут наследовать / расширять / выводить из других объектов, позволяя использовать одинаковое поведение между связанными объектами. В Python мы используем ключевое слово class, чтобы определить «скелет» для объекта. Мы можем создать несколько конкретных экземпляров типа объекта на основе модели в классе.
    -
    - Так, например, мы имеем класс Team, который происходит от класса Model. Это означает, что эта модель будет содержать все методы модели, но мы также можем дать ей специализированные возможности. В нашей модели мы определяем поля нашей базы данных, в которой будем хранить данные, присваивая им конкретные имена. Django использует эти определения, включая имена полей, для создания основной базы данных.
  • -
-
- -

Запросы данных (views.py)

- -

Модель Django предоставляет простой API запросов для поиска в базе данных. Поиск может осуществляться по нескольким полям одновременно, используя различные критерии (такие как exact («точный»), case-insensitive («без учёта регистра»), greater than («больше чем») и т. д.), и может поддерживать сложные выражения (например, вы можете указать поиск в командах U11, у которых есть имя команды, начинающееся с «Fr» или заканчивается на «al»).

- -

Фрагмент кода показывает функцию view (обработчик ресурсов) для отображения всех команд U09. Выделенная жирным строка показывет, как мы можем использовать модель API-запросов для того, чтобы отфильтровать все записи, где поле team_level в точности содержит текст 'U09' (обратите внимание, как эти критерии передаются функции filter() в качестве аргумента с именем поля и типом соответствия, разделённым двойным подчеркиванием: team_level__exact). 

- -
## filename: views.py
-
-from django.shortcuts import render
-from .models import Team
-
-def index(request):
-    list_teams = Team.objects.filter(team_level__exact="U09")
-    context = {'youngest_teams': list_teams}
-    return render(request, '/best/index.html', context)
-
- -
-
- -

Данная функция использует функцию render() для того, чтобы создать HttpResponse, который будет отправлен назад браузеру. Эта функция является ярлыком; она создаёт HTML-файл, комбинируя указанный HTML-шаблон и некоторые данные для вставки в шаблон (предоставляется в переменной с именем «context»). В следующем разделе мы  покажем как данные вставляются в шаблон для создания HTML-кода.

- -

Вывод данных (HTML-шаблоны)

- -

Системы шаблонов позволяют указать структуру выходного документа, используя заполнители для данных, которые будут вставлены при генерировании страницы. Шаблоны часто используются для создания HTML, но также могут создавать другие типы документов. Django «из коробки» поддерживает как собственную систему шаблонов, так и другую популярную библиотеку Python под названием Jinja2 (она также может быть использована для поддержки других систем, если это необходимо).

- -

Фрагмент кода показывает, как может выглядеть HTML-шаблон, вызванный функцией  render() из предыдущего раздела. Этот шаблон был написан с предположением, что во время отрисовки он будет иметь доступ к переменной списка, названной youngest_teams (содержащейся в контекстной переменной внутри функции render() выше). Внутри скелета HTML мы имеем выражение, которое сначала проверяет, существует ли переменная youngest_teams, а затем повторяет её в цикле for. При каждом повторе шаблон отображает значение team_name каждой команды в элементе {{htmlelement("li")}}.

- -
## filename: best/templates/best/index.html
-
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="utf-8">
-  <title>Home page</title>
-</head>
-<body>
-  {% if youngest_teams %}
-    <ul>
-      {% for team in youngest_teams %}
-        <li>\{\{ team.team_name \}\}</li>
-      {% endfor %}
-    </ul>
-  {% else %}
-    <p>No teams are available.</p>
-  {% endif %}
-</body>
-</html>
- -

Что ещё можно сделать?

- -

В предыдущих разделах показаны основные особенности, которые вы будете использовать почти в каждом веб-приложении: сопоставление URL-адресов, отображение, модели и шаблоны. Также Django предоставляет несколько других вещей:

- - - -

Резюме

- -

Поздравляем, вы завершили первый шаг в своем путешествии по Django! Теперь вы должны понимать основные преимущества Django, немного его истории, и примерно как может выглядеть каждая из основных частей приложения Django. Вы должны также изучить несколько вещей о языке программирования Python, включая синтаксис списков, функций и классов.

- -

Вы уже видели код на Django выше, но в отличие от клиентского кода вам нужно настроить среду разработки для её запуска. Это наш следующий шаг.

- -
{{NextMenu("Learn/Server-side/Django/development_environment", "Learn/Server-side/Django")}}
diff --git "a/files/ru/learn/server-side/django/\321\200\320\260\320\267\320\262\320\276\321\200\320\260\321\207\320\270\320\262\320\260\320\275\320\270\320\265/index.html" "b/files/ru/learn/server-side/django/\321\200\320\260\320\267\320\262\320\276\321\200\320\260\321\207\320\270\320\262\320\260\320\275\320\270\320\265/index.html" deleted file mode 100644 index 640527b63d..0000000000 --- "a/files/ru/learn/server-side/django/\321\200\320\260\320\267\320\262\320\276\321\200\320\260\321\207\320\270\320\262\320\260\320\275\320\270\320\265/index.html" +++ /dev/null @@ -1,680 +0,0 @@ ---- -title: 'Django Руководство часть 11: Разворачивание сайта на сервере' -slug: Learn/Server-side/Django/Разворачивание -tags: - - Веб-сервер - - Для начинающих - - Разворачивание на сервере - - Развёртывание Django -translation_of: Learn/Server-side/Django/Deployment ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/Server-side/Django/Testing", "Learn/Server-side/Django/web_application_security", "Learn/Server-side/Django")}}
- -

Теперь, когда вы создали (и протестировали) свой шикарный сайт LocalLibrary, у вас скорее всего, есть желание разместить его на публичном веб-сервере, чтобы он стал доступен через интернет персоналу  и посетителям библотеки. Данная статья дает общее представление о том, каким образом подойти к поиску хостинга для рамещения сайта, а также, что нужно сделать чтобы подготовить свой сайт к публикации.

- - - - - - - - - - - - -
Требования:Завершить изучение всех предыдущих частей руководства, включая Django Руководство часть 10:  Тестирование веб-приложений в Django.
Цель:Изучить, где и как вы можете развернуть приложение Django для публичного доступа.
- -

Обзор

- -

Даже когда разработка вашего сайта завершена (или "достаточно" завершена для начала публичного тестирования), то для публичного доступа вам надо его где-то разместить.

- -

До сего момента вы работали в каком-то рабочем окружении - чтобы получать отладочную и другую частную информацию, вы использовали веб-сервер Django в локальной сети при этом запускали сайт с (небезопасными) настройками разработки. Перед тем как разместить сайт публично, вы должны сделать следующее:

- - - -

Данное руководство предоставляет небольшой обзор выбора хостинга, приготовления сайта к публичному размещению, а также практический пример установки сайта LocalLibrary на облачный сервис Heroku.

- -

Что такое окружение развертывания?

- -

Окружение развертывания - это среда, которое предоставляет сервер, на котором вы будете размещать свой веб-сайт для публичного запуска и доступа. Данное окружение включает в себя:

- - - -
-

Примечание: У вас может быть потребность в обратном прокси, балансировщике загрузки и так далее.

-
- -

Сервер может быть вашим собственным с подключением к интернету по скоростному каналу, но более общим подходом является применение "облачных решений". Что действительно имеет значение, так это то, что ваш код запускается на некотором удаленном компьютере (возможно и "виртуальном"), в хостинговом дата-центре. Удаленный сервер обычно предоставляет определенный доступ к компьютерным ресурсам (процессору, оперативной памяти, памяти на жестких носителях и так далее) и соединение с интернетом за некоторую цену.

- -

Такой тип удаленного доступа к вычислительному/сетевому железу называется Инфраструктура как Сервис (Infrastructure as a Service - IaaS). Множество IaaS поставщиков предлагают услуги по предустановке какой-либо операционной системы, на которую вы можете установить необходимые для вашего рабочего окружения компоненты. Другие поставщики предлагают вам выбрать уже готовые полноценные рабочие окружения, возможно, включающие в себя Django и настроенный веб-сервер.

- -
-

Примечание: Готовые окружения могут сделать настройку вашего веб-сайта очень простой задачей, поскольку они имеют минимальную конфигурацию, однако, либо количество доступных опций может быть недостаточным, или они будут соответствовать устаревшей операционной системе. Часто, более предпочтительно установить необходимые компоненты самостоятельно, таким образом вы получите то, что вам необходимо, а в последующем, при обновлении системы, уже будете знать что нужно делать!

-
- -

Некоторые провайдеры поддерживают Django как часть своего предложения Платформа как Сервис (Platform as a Service - PaaS). При данном виде хостинга вам не нужно беспокоиться о большей части окружения (веб-сервере, сервере приложений, балансировщике загрузки), так как сама платформа берет это на себя (включая все моменты, касающиеся роста и развития вашего приложения). В данном случае развертывание приложения является достаточно простой задачей, - вам нужно сконцентрироваться только на вашем приложении, а не на инфраструктуре.

- -

Некоторые разработчики выбирают более гибкое решение, предоставляемое IaaS, в то время как другие предпочитают иметь наименьшие накладные расходы и простое масштабирование, предоставляемое PaaS. Когда вы только начинаете, то система типа PaaS является предпочтительной и это именно то, что мы будем использовать в данном руководстве.

- -
-

Примечание: Если вы выбираете хостинг с поддержкой Python/Django, то он должен иметь инструкцию по установке веб-сайта Django, учитывающую различные конфигурации веб-сервера, сервера приложений, обратного прокси и так далее (это не имеет значение, если вы выбрали PaaS). Например, существует множество инструкций "шаг-за-шагом" для различный конфигураций в Документации DigitalOcean по Django.

-
- -

Выбор хостинг провайдера

- -

Существует более 100 хорошо известных хостинг провайдеров, которые либо активно поддерживают, или работают с Django (их список можно увидеть в Django-дружественные хостинги). Данные поставщики предоставляют различные типы окружений (IaaS, PaaS), и различные уровни доступа к вычислительным и сетевым ресурсам, за разную цену.

- -

Некоторые вещи на которые надо обратить внимание при выборе хостинга:

- - - -

Хорошей новостью является то, что для того, чтобы начать существует достаточное количество компаний, которые предоставляют пробные "бесплатные" тарифы типа "evaluation" (для пробы), "developer" (разработка), или "hobbyist" (хобби). Всегда существуют ресурсы с ограниченым окружением, при использовании которых вам надо беспокоиться лишь о том, что они могут быть доступны лишь в течении определенного периода времени. Тем не менее, они являются отличным решением для тестирования сайтов с небольшим трафиком в реальном окружении, а также могут предоставлять простой доступ к платным ресурсам, в случае необходимости. Наиболее популярными провайдерами являются Heroku, Python Anywhere, Amazon Web Services, Microsoft Azure и так далее.

- -

Многие провайдеры имеют "basic" (базовый) тариф, предоставляющий достаточный уровень вычислительной мощности с небольшим количеством ограничений. Digital Ocean и Python Anywhere являются примерами провайдеров, которые предлагают относительно недорой базовый тариф (от $5 до $10USD в месяц).

- -
-

Примечание: Необходимо помнить, что цена не является единственным критерием выбора. Если ваш сайт успешен, то может так случиться, что масштабирование станет самым важным элементом вашего внимания при выборе услуг хостинга.

-
- -

Подготовка веб-сайта к публикации

- -

Скелет сайта был создан при помощи инструментов django-admin и manage.py, которые настроены таким образом, чтобы сделать разработку проще. Многие настройки файла проекта (определенных в settings.py) должны быть изменены перед публикацией сайта, либо из-за вопросов безопастности, либо производительности.

- -
-

Примечание: Общепринятым решением является иметь отдельный файл settings.py для публикации, который импортирует важные настройки из внешних файлов, или из переменных окружения. Доступ к данному файлу должен быть ограничен, даже если остальная часть исходного кода доступна в публичном репозитории.

-
- -

Критически важные настройки файла settings.py:

- - - -

Давайте изменим приложение LocalLibrary таким образом, чтобы читать SECRET_KEY и DEBUG из переменных окружения, если те определены, иначе использовать значения по умолчанию.

- -

Откройте /locallibrary/settings.py, закомментируйте исходное значение SECRET_KEY и добавьте новые строки, как указано ниже жирным. В течении разработки, никаких переменных окружения определено не было, таким образом будут использоваться значения по умолчанию (не имеет значения какой ключ вы используете в процессе разработки, поскольку при развертывании проекта вы будете использовать другой).

- -
# SECURITY WARNING: keep the secret key used in production secret!
-# SECRET_KEY = 'cg#p$g+j9tax!#a3cup@1$8obt2_+&k3q+pmu)5%asj6yjpkag'
-import os
-SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY', 'cg#p$g+j9tax!#a3cup@1$8obt2_+&k3q+pmu)5%asj6yjpkag')
-
- -

Затем закомментируйте строку с настройкой DEBUG, а затем, добавьте новую, указанную ниже.

- -
# SECURITY WARNING: don't run with debug turned on in production!
-# DEBUG = True
-DEBUG = bool( os.environ.get('DJANGO_DEBUG', True) )
-
- -

Значение DEBUG будет True по умолчанию и станет False, в том случае, если переменная окружения DJANGO_DEBUG будет проинициализирована пустой строкой, то есть, DJANGO_DEBUG=''.

- -
-

Примечание: Было бы более понятным, если бы мы могли просто установить и снять с  DJANGO_DEBUG непосредственно на True и False , напрямую, а не использовать «любую строку» или «пустую строку» (соответственно). К сожалению, значения переменных среды хранятся как строки Python и единственная строка, которая оценивается как False является пустой строкой (например, bool('')==False).

-
- -

Весь перечень настроек для разворачивания вашего сайта находится по ссылке Deployment checklist (Django docs). Кроме того, вы можете получить список настроек, выполнив в терминале команду:

- -
python3 manage.py check --deploy
-
- -

Пример: Установка LocalLibrary на Heroku

- -

Данный раздел предоставляет демонстрацию того, как установить LocalLibrary на Heroku PaaS cloud.

- -

Почему Heroku?

- -

Heroku - один из самых продолжительных и популярных облачных сервисов PaaS. Первоначально он поддерживал только приложения Ruby, но теперь его можно использовать для размещения приложений из многих сред программирования, включая Django!

- -

Мы выбираем для использования Heroku по нескольким причинам:

- - - -

Хотя Heroku идеально подходит для проведения этой демонстрации, она может быть не идеальна для вашего реального сайта. Heroku упрощает настройку и масштабирование за счет меньшей гибкости и, возможно, обойдется намного дороже, когда вы выходите из свободного уровня.

- -

Как работает Heroku?

- -

Heroku запускает сайты Django внутри одного, или более,  изолированых друг от друга "Dynos", которые являются виртуальными Unix-контейнерами, предоставляющими необходимое окружение для вашего приложения. Данные dynos полностью изолированы и имеют эфемерную файловую систему ("короткоживущая" файловая система, которая полностью очищается и обновляется каждый раз, когда dyno перезапускается). Единственной сущностью, которую предоставляет dynos по умолчанию, является приложение по конфигурации переменных. Heroku внутри себя применяет балансировщик загрузки для распределения веб-трафика среди всех "веб"-dynos. Поскольку dynos изолированы, Heroku может масштабировать приложение горизонтально, просто добавляя больше dynos (хотя, конечно, у вас может появиться необходимость расширить базу данных для обработки дополнительных соединений).

- -

Файловая система эфемерна, поэтому вы не можете напрямую установить необходимые для вашего приложения сервисы (то есть, базы данных, очереди, системы кэширования, хранения, сервисы электронной почты и так далее). Взамен этого, Heroku предоставляет сервисы, доступные как независимые "дополнения" ("add-ons") либо от самой Heroku, или от сторонних разработчиков. В тот момент когда ваше приложение запускается в системе, dynos получает доступ к сервисам, используя информацию, содержащуюся в переменных настройки вашего приложения.

- -

Для того, чтобы выполнить ваше приложение Heroku необходимо иметь возможность установить соответствующее окружение и зависимости, а также понимать как его (приложение) запустить. В случае приложений Django мы предоставляем соответствующую информацию в нескольких текстовых файлах:

- - - -

Разработчики Developers взаимодействуют с Heroku при помощи специального клиентского приложения/терминала, который сильно похож на bash-скрипт Unix. Оно позволяет вам загружать код, находящийся в git-репозитории, контроллировать выполняемые процессы, смотреть логи, устанавливать конфигурационные переменные и многое другое!

- -

Для того, чтобы заставить ваше приложение работать с Heroku, нам нужно разместить наше веб-приложение в git-репозитории, добавить, перечисленные ранее, файлы, подключить дополнение (add-on) базы данных и выполнить настройки для правильной работы со статическими файлами.

- -

Когда мы выполним все, что необходимо для нашего сайта мы можем создать аккаунт Heroku, получить доступ к клиенту Heroku и использовать его, для установки нашего веб-сайта.

- -
-

Примечание: Инструкции, перечисленные ниже, соответствуют процессу работы с Heroku во время написания данной статьи (английской версии - прим. перев.). Если Heroku значительно изменит этот процесс, вы можете воспользоваться соответствующим описанием: Heroku начало работы с Django.

-
- -

На этом завершается краткий обзор начала работы с Heroku (более подробное руководство Как работает Heroku).

- -

Создание репозитория приложения на Github

- -

Heroku тесно интегрирована с системой управления версиями исходного кода git, используя ее для загрузки / синхронизации любых изменений, которые вы вносите в живую систему. Он делает это, добавляя новый «удаленный» репозиторий heroku с именем heroku, указывающий на репозиторий для вашего источника в облаке Heroku. Во время разработки вы используете git для хранения изменений в вашем «master» репозитории. Когда вы хотите развернуть свой сайт, вы синхронизируете свои изменения в репозитории Heroku.

- -
-

Примечание: Если вы привыкли следовать хорошей практике разработки программного обеспечения, вы, вероятно, уже используете git или какую-либо другую систему SCM. Если у вас уже есть git-репозиторий, вы можете пропустить этот шаг.

-
- -

Существует множество способов работы с git, но одним из самых простых является создание учетной записи в Github, создание репозитория там, а затем синхронизация с ним локально:

- -
    -
  1. Посетите https://github.com/ и создайте аккаунт.
  2. -
  3. После входа в систему нажмите ссылку + в верхней панели инструментов и выберите Новый репозиторий.
  4. -
  5. Заполните все поля на этой форме. Хотя они не являются обязательными, они настоятельно рекомендуются. -
      -
    • Введите имя нового репозитория (например django_local_library), и комментарий к репозиторию (например "Local Library website written in Django".
    • -
    • Нажмите на кнопку Add .gitignore и в появившемся списке выберите Python.
    • -
    • Выберите подходящую вам лицензию из списка Add license. Если не знаете для чего это - оставьте как было.
    • -
    • -

      Установите галочку напротив Initialize this repository with a README.

      -
    • -
    -
  6. -
  7. Нажмите кнопку Create repository, тем самым создав ваш репозиторий.
  8. -
  9. Перейдите на страницу вашего репозитория. Там нажмите на зелёную кнопку "Clone or download". Скопируйте URL  из текстового поляиз появившегося диалогового окна (Это будет похоже на: https://github.com/<your_git_user_id>/django_local_library.git). Здесь <your_git_user_id> - это будет ваш id пользователя git.
  10. -
- -

Когда ваш репозиторий будет создан - загрузите его себе на компьтер, следуя инструкции, описанной ниже:

- -
    -
  1. Установите git себе на компьютер (Вы можете найти версию для своей платформы здесь).
  2. -
  3. Откройте командную строку (или терминал) и выполните в нём следующую команду, используя ссылку, которую вы получили с github: -
    git clone https://github.com/<your_git_user_id>/django_local_library.git
    -
    - Это создаст подпапку (с содержанием вашего репозитория и именем вашего репозитория) внутри папки, в котрой выполнялась команда.
  4. -
  5. Перейдите в эту папку: -
    cd django_local_library.git
    -
  6. -
- -

Последний шаг. Нужно скопировать ваше Django-приложение и добавить его файлы в новый репозиторий, используя git:

- -
    -
  1. Скопируйте ваше приложение в папку репозитория (все файлы с таким же уровнем, как у manage.py, БЕЗ папки проекта, в которой эти файлы находятся).
  2. -
  3. Откройте файл с расширением .gitignore в текстовом редакторе, вставьте в самый его конец строки, приведённые ниже, а затем сохраните (этот файл "говорит" о файлах, которые не должны быть  загружены в git по умолчанию). -
    # Text backup files
    -*.bak
    -
    -#Database
    -*.sqlite3
    -
  4. -
  5. -

    Откройте командную строку или терминал и используйте add команду с флагом -A. Эта комманда сохранит изменения в репозиторий:

    - -
    git add -A
    -
  6. -
  7. Используйте команду status,  что бы убедиться, что все файлы, которые вы собираетесь добавить верны (вы хотите включить исходные файлы, а не бинарные файлы, временные файлы и т. д.). В консоль выведется что то вроде этого: -
    > git status
    -On branch master
    -Your branch is up-to-date with 'origin/master'.
    -Changes to be committed:
    -  (use "git reset HEAD <file>..." to unstage)
    -
    -        modified:   .gitignore
    -        new file:   catalog/__init__.py
    -        ...
    -        new file:   catalog/migrations/0001_initial.py
    -        ...
    -        new file:   templates/registration/password_reset_form.html
    -
  8. -
  9. Теперь, зафиксируйте файлы в локальном репозитории: -
    git commit -m "First version of application moved into github"
    -
  10. -
  11. Синхронизируете свой локальный репозиторий с сайтом Github: -
    git push origin master
    -
  12. -
- -

Когда эти операции завершатся, вернитесь на страницу Github где вы создали свой репозиторий, обновите страницу, и убедитесь, что ваше приложение полностью загружено. При надобности обновить файлы на репозитории - повторите цикл ввода команд add/commit/push.

- -
-

Подсказка: Это хороший момент для создания резервной копии вашего «ванильного» проекта — в то время как некоторые изменения, которые мы собираемся сделать в следующих разделах, могут быть полезны для развертывания на любой платформе (или разработке), которые другие могут не использовать.

- -

Лучший способ сделать это - использовать git для управления вашими изменениями. С git вы можете не только вернуться к определенной старой версии, но и сохранить ее в отдельной «ветке» ваших производственных изменений, and cherry-pick - выбрать любые изменения для перемещения между ветвями производства и развития. Изучение Git будет стоить усилий, но это выходит за рамки данной темы. Самый простой способ сделать это - просто скопировать файлы в другое место. Используйте тот подход, который наилучшим образом соответствует вашим знаниям git!

-
- -

Обновить приложение для Heroku 

- -

В этой части говорится об изменениях, которые мы должны сделать на нашем приложении LocalLibrary, что бы оно работало на  Heroku. В то время как документация "начало работы с Heroku с инструкциями Django" предполагает, что вы будете использовать Heroku client для запуска локальной среды разработки, наши изменения здесь совместимы с существующим сервером разработки Django и способами работы, которые мы уже узнали.

- -

Procfile

- -

 Создайте файл с именем Procfile (без расширения) в корне нашего GitHub репозитории объявить типы процессов и точки входа приложения. Скопируйте в него следующий текст:

- -
web: gunicorn locallibrary.wsgi --log-file -
- -

«web:» сообщает Heroku, что это веб динамический и может быть отправлен HTTP-трафик. Процесс, который начнется в этом динамически, - это gunicorn, который является популярным сервером веб-приложений, который рекомендует Heroku. Мы запускаем Gunicorn, используя конфигурационную информацию в модуле locallibrary.wsgi (созданный с помощью нашего скелета приложения: /locallibrary/wsgi.py).

- -

Gunicorn

- -

Gunicorn рекомендуемый http сервер с Django на Heroku (Как указанов Procfile выше). Это чистый python http сервер для WSGI приложений  которые могут запускать множество параллельных python процессов в пределах одного динамического (посмотрите Deploying Python applications with Gunicorn для получения большей информации).

- -

Также нам не понадобится Gunicorn для обслушивания нашей LocalLibrary приложения в течение разработки, мы установим это так, чтобы он стал частью наших требований к Heroku для настройки на удаленном сервере.

- -

Установка Gunicorn локально в командной строке используя пакетный менеджер pip (которые мы установили когда настраивали среду разработки):

- -
pip3 install gunicorn
-
- -

Настройка Базы Данных

- -

Мы не можем использовать базу данных SQLite по умолчанию на Heroku, потому что она основана на файлах, и она будет удалена из эфемерной файловой системы каждый раз, когда приложение перезагружается (обычно один раз в день и каждый раз, когда изменяется приложение или его переменные конфигурации ).

- -

Механизм Heroku для обработки этой ситуации заключается в использовании надстройки базы данных и настройке веб-приложения с использованием информации из переменной конфигурации среды, установленной надстройкой. Существует множество опций базы данных, но мы будем использовать hobby уровень в базе данных postgres Heroku, поскольку это бесплатно, поддерживается Django и автоматически добавляется в наши новые приложения Heroku при использовании бесплатного уровня динамического плана для хобби.

- -

Информация о подключении базы данных предоставляется на web dyno, используя конфигурационную переменную с именем DATABASE_URL. Вместо того, чтобы жестко кодировать эту информацию в Django, Heroku рекомендует разработчикам использовать dj-database-url пакет для анализа DATABASE_URL переменную окружения и автоматически преобразовать ее в желаемый формат конфигурации Django. В дополнение к установке пакета dj-database-url нам также потребуется установить psycopg2, поскольку Django нуждается в этом, чтобы взаимодействовать с базами данных Postgres.

- -
dj-database-url (Django конфигурации базы данных из переменной окружения)
- -

Установите dj-database-url локально, чтобы он стал частью наших требований к настройке Heroku на удаленном сервере:

- -
$ pip3 install dj-database-url
-
- -
settings.py
- -

Откройте /locallibrary/settings.py и скопируйте следующую конфигурацию в нижнюю часть файла:

- -
# Heroku: Update database configuration from $DATABASE_URL.
-import dj_database_url
-db_from_env = dj_database_url.config(conn_max_age=500)
-DATABASES['default'].update(db_from_env)
- -
-

Заметка:

- -
    -
  • Мы все еще будем использовать SQLite во время разработки, поскольку DATABASE_URL переменная среды не будет установлена ​​на нашем компьютере разработки.
  • -
  • Значение conn_max_age=500 делает соединение постоянным, что намного эффективнее, чем воссоздавать соединение в каждом цикле запросов. Однако это необязательно и при необходимости можно удалить.
  • -
-
- -
psycopg2 (Python Postgres database support)
- -

Django нуждается в psycopg2 для работы с базами данных Postgres, и вам нужно будет добавить это в файл требований.txt для Heroku, чтобы установить это на удаленном сервере (как описано в разделе требований ниже).

- -

Django будет использовать нашу базу данных SQLite локально по умолчанию, поскольку переменная среды DATABASE_URL не задана в нашей локальной среде. Если вы хотите полностью перейти на Postgres и использовать нашу бесплатную базу данных Heroku для разработки и производства, то вы можете. Например, чтобы установить psycopg2 и его зависимости локально в системе на базе Linux, вы должны использовать следующие команды bash / terminal:

- -
sudo apt-get install python-pip python-dev libpq-dev postgresql postgresql-contrib
-pip3 install psycopg2
-
- -

Инструкции по установке для других платформ можно найти на веб-сайте psycopg2.

- -

Однако вам не нужно это делать - вам не нужно, чтобы PostGreSQL был активным на локальном компьютере, если вы передаете его в Heroku в качестве требования в файле требований.txt (см. Ниже).

- -

Обслуживание статических файлов в производстве

- -


- Во время разработки мы использовали Django и веб-сервер разработки Django для обслуживания наших статических файлов (CSS, JavaScript и т. Д.). В производственной среде вместо этого мы обычно обслуживаем статические файлы из сети доставки контента (CDN) или веб-сервера.

- -
-

Примечание. Обслуживание статических файлов через Django / веб-приложение неэффективно, потому что запросы должны проходить через ненужный дополнительный код (Django), а не обрабатываться непосредственно веб-сервером или полностью отдельным CDN. Хотя это не имеет значения для местного использования во время разработки, это будет иметь значительное влияние на производительность, если мы будем использовать тот же подход в производстве.

-
- -

Чтобы упростить размещение статических файлов отдельно от веб-приложения Django, Django предоставляет средство сбора данных для сбора этих файлов для развертывания (имеется переменная параметров, определяющая, где файлы должны собираться при запуске collectstatic). Шаблоны Django относятся к месту размещения статических файлов относительно переменной параметров (STATIC_URL), так что это можно изменить, если статические файлы перемещаются на другой хост / сервер.

- -

Соответствующими параметрами настройки являются:

- -

     STATIC_URL: это базовое расположение URL, из которого будут загружены статические файлы, например, на CDN. Это используется для переменной статического шаблона, доступ к которой осуществляется в нашем базовом шаблоне (см. Учебник по Django Part 5: Создание нашей домашней страницы).
-       STATIC_ROOT: Это абсолютный путь к каталогу, в котором инструмент «collectstatic» Django будет собирать любые статические файлы, упомянутые в наших шаблонах. После их сбора они затем могут быть загружены в группу, где бы файлы не размещались.
-       STATICFILES_DIRS: В этом списке перечислены дополнительные каталоги, в которых инструмент коллективного поиска Django должен искать статические файлы.

- -
settings.py
- -

Откройте /locallibrary/settings.py и скопируйте следующую конфигурацию в нижнюю часть файла. BASE_DIR уже должен быть определен в вашем файле (STATIC_URL, возможно, уже был определен в файле, когда он был создан. В то время как это не причинит вреда, вы также можете удалить дублируемую предыдущую ссылку).

- -
# Static files (CSS, JavaScript, Images)
-# https://docs.djangoproject.com/en/1.10/howto/static-files/
-
-# The absolute path to the directory where collectstatic will collect static files for deployment.
-STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
-
-# The URL to use when referring to static files (where they will be served from)
-STATIC_URL = '/static/'
-
- -

Фактически мы будем делать файл, используя библиотеку WhiteNoise, которую мы устанавливаем и настраиваем в следующем разделе.

- -

Для получения дополнительной информации см. Django и Static Assets (документы Heroku).

- -

WhiteNoise
- Существует множество способов обслуживания статических файлов на производстве (мы видели соответствующие настройки Django в предыдущих разделах). Heroku рекомендует использовать проект WhiteNoise для обслуживания статических активов непосредственно из Gunicorn в производстве.

- -
-

Заметка: Heroku автоматически вызывает collectstatic и готовит ваши статические файлы для использования WhiteNoise после того, как он загрузит ваше приложение. Посмотрите WhiteNoise документацию для объяснения того, как она работает, и почему реализация является относительно эффективным методом для обслуживания этих файлов.

-
- -

Шаги по настройке WhiteNoise для использования в проекте:

- -
WhiteNoise
- -

Установите WhiteNoise локально, используя следующую команду:

- -
$ pip3 install whitenoise
-
- -
settings.py
- -

Чтобы установить WhiteNoise в приложение Django, откройте /locallibrary/settings.py, найдите параметр MIDDLEWARE и добавьте WhiteNoiseMiddleware в верхней части списка, чуть ниже SecurityMiddleware:

- -
MIDDLEWARE = [
-    'django.middleware.security.SecurityMiddleware',
-    'whitenoise.middleware.WhiteNoiseMiddleware',
-    'django.contrib.sessions.middleware.SessionMiddleware',
-    'django.middleware.common.CommonMiddleware',
-    'django.middleware.csrf.CsrfViewMiddleware',
-    'django.contrib.auth.middleware.AuthenticationMiddleware',
-    'django.contrib.messages.middleware.MessageMiddleware',
-    'django.middleware.clickjacking.XFrameOptionsMiddleware',
-]
-
- -

При желании вы можете уменьшить размер статических файлов при их обслуживании (это более эффективно). Просто добавьте следующее в конец /locallibrary/settings.py:

- -
# Simplified static file serving.
-# https://warehouse.python.org/project/whitenoise/
-STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
-
- -

Requirements

- -

Требования Python вашего веб-приложения должны храниться в файле requirements.txt в корневом каталоге вашего репозитория. После этого Heroku автоматически установит их при восстановлении вашей среды. Вы можете создать этот файл с помощью pip в командной строке (запустите в корне repo):

- -
pip3 freeze > requirements.txt
- -

После установки всех разных зависимостей выше, файл requirements.txt должен иметь по меньшей мере эти перечисленные элементы (хотя номера версий могут отличаться). Удалите любые другие зависимости, не перечисленные ниже, если вы явно не добавили их для этого приложения.

- -
dj-database-url==0.4.1
-Django==1.10.2
-gunicorn==19.6.0
-psycopg2==2.6.2
-whitenoise==3.2.2
-
- -
-

Убедитесь, что строка  psycopg2, подобная приведенной выше, присутствует! Даже если вы не установили это локально, вы должны добавить это в requirements.txt.

-
- -

Среда выполнения

- -

Файл runtime.txt, если определён, говорит Heroku, какой язык программирования использовать. Создайте файл в корне репо и добавьте следующий текст:

- -
python-3.5.2
- -
-

Заметка: Heroku поддерживает только небольшое количество Python runtimes. (на момент написания статьи, в том числе и выше). Heroku будет использовать поддерживаемую среду выполнения независимо от значения, указанного в этом файле.

-
- -

Сохраните изменения в Github и перепроверьте

- -

Далее мы сохраним все наши изменения в Github. В терминале (whist внутри нашего репозитория) введите следующие команды:

- -
git add -A
-git commit -m "Added files and changes required for deployment to heroku"
-git push origin master
- -

Прежде чем продолжить, дайте возможность проверить сайт снова локально и убедиться, что это не повлияло ни на одно из наших изменений выше. Запустите веб-сервер разработки как обычно, а затем проверьте, работает ли сайт, как вы ожидаете в своем браузере.

- -
python3 manage.py runserver
- -

Теперь мы должны быть готовы начать развертывание LocalLibrary на Heroku.

- -

Получить аккаунт в heroku

- -

Чтобы начать использовать Heroku, вам сначала нужно создать учетную запись:

- - - -

Установка клиента

- -

Загрузите и установите клиент Heroku, следуя инструкциям Heroku здесь.

- -

После установки клиента вам будут дотупны команды. Например, чтобы получить справку о клиенте:

- -
heroku help
-
- -

Создание и загрузка веб-сайта

- -

Чтобы создать приложение, мы запускаем команду «create» в корневом каталоге нашего репозитория. Это создает git remote («указатель на удаленный репозиторий»), названный heroku в нашей локальной среде git.

- -
heroku create
- -
-

Заметка: Вы можете назвать удаленный, если хотите, указав значение после «create». Если вы этого не сделаете, вы получите случайное имя. Имя используется в URL-адресе по умолчанию.

-
- -

Затем мы можем подтолкнуть наше приложение в репозиторий heroku как показано ниже. Это позволит загрузить приложение, упаковать его в dyno, запустить collectstatic, и запустить сам сайт.

- -
git push heroku master
- -

Если нам повезет, приложение «заработает» на сайте, но оно не будет работать должным образом, потому что мы не настроили таблицы базы данных для использования нашим приложением. Для этого нам нужно использовать команду  heroku run и запустить "one off dyno" для выполнения операции переноса. Введите в терминал следующую команду:

- -
heroku run python manage.py migrate
- -

Мы также должны будем иметь возможность добавлять книги и авторов, поэтому давайте также создадим суперпользователя, снова используя одноразовый динамический режим:

- -
heroku run python manage.py createsuperuser
- -

Как только это будет завершено, мы можем посмотреть сайт. Он должен работать, хотя в нем еще нет книг. Чтобы открыть браузер на новом веб-сайте, используйте команду:

- -
heroku open
- -

Создайте несколько книг на сайте администратора и проверьте, работает ли сайт, как вы ожидаете.

- -

Управление аддонами

- -

Вы можете проверить дополнения в своем приложении, используя heroku addons команду. Это будет список всех аддонов, их ценовая категория и состояние.

- -
>heroku addons
-
-Add-on                                     Plan       Price  State
-─────────────────────────────────────────  ─────────  ─────  ───────
-heroku-postgresql (postgresql-flat-26536)  hobby-dev  free   created
- └─ as DATABASE
- -

Здесь мы видим, что у нас есть только одна надстройка, база данных postgres SQL. Это бесплатно и автоматически создается при создании приложения. Вы можете открыть веб-страницу, чтобы более подробно изучить надстройку базы данных (или любое другое дополнение), используя следующую команду:

- -
heroku addons:open heroku-postgresql
-
- -

Другие команды позволяют создавать, уничтожать, обновлять и понижать аддоны (используя аналогичный синтаксис для открытия). Для получения дополнительной информации см.  Managing Add-ons (Heroku docs).

- -

Настройка переменных конфигурации

- -

Вы можете проверить конфигурационные переменные для сайта, используя команду  heroku config. Ниже вы можете видеть, что у нас есть только одна переменная DATABASE_URL , используемая для настройки нашей базы данных.

- -
>heroku config
-
-=== locallibrary Config Vars
-DATABASE_URL: postgres://uzfnbcyxidzgrl:j2jkUFDF6OGGqxkgg7Hk3ilbZI@ec2-54-243-201-144.compute-1.amazonaws.com:5432/dbftm4qgh3kda3
- -

Если вы вспомните из раздела, посвященного  getting the website ready to publish, мы должны установить переменные среды для DJANGO_SECRET_KEY и DJANGO_DEBUG. Давайте сделаем это сейчас.

- -
-

Заметка: Секретный ключ должен быть действительно секретным! Один из способов генерации нового ключа - создать новый проект Django (django-admin startproject someprojectname) а затем получить ключ, который генерируется для вас в его settings.py.

-
- -

Мы устанавливаем  DJANGO_SECRET_KEY используя команду config:set (как показано ниже). Не забудьте использовать свой секретный ключ!

- -
>heroku config:set DJANGO_SECRET_KEY=eu09(ilk6@4sfdofb=b_2ht@vad*$ehh9-)3u_83+y%(+phh&=
-
-Setting DJANGO_SECRET_KEY and restarting locallibrary... done, v7
-DJANGO_SECRET_KEY: eu09(ilk6@4sfdofb=b_2ht@vad*$ehh9-)3u_83+y%(+phh
-
- -

Аналогично мы устанавливаем  DJANGO_DEBUG:

- -
>heroku config:set DJANGO_DEBUG=''
-
-Setting DJANGO_DEBUG and restarting locallibrary... done, v8
- -

Если вы посетите веб-сайт сейчас, вы получите ошибку "Bad request" , потому что в  ALLOWED_HOSTS надо внести параметры, если у вас DEBUG=False (в качестве меры безопасности). Откройте /locallibrary/settings.py и измените ALLOWED_HOSTS для включения вашего базового URL-адреса приложения (например, 'locallibrary1234.herokuapp.com') URL, который вы обычно используете на локальном сервере разработки.

- -
ALLOWED_HOSTS = ['<your app URL without the https:// prefix>.herokuapp.com','127.0.0.1']
-# For example:
-# ALLOWED_HOSTS = ['fathomless-scrubland-30645.herokuapp.com','127.0.0.1']
-
- -

Затем сохраните настройки и передайте их в репозиторий Github и в Heroku:

- -
git add -A
-git commit -m 'Update ALLOWED_HOSTS with site and development server URL'
-git push origin master
-git push heroku master
- -
-

После завершения обновления сайта на Heroku введите URL-адрес, который не существует (например,  /catalog/doesnotexist/). Раньше это отображало бы подробную страницу отладки, но теперь вы должны просто увидеть простую страницу «Не найдено».

-
- -

Отладка

- -

Клиент Heroku предоставляет несколько инструментов для отладки:

- -
heroku logs  # Show current logs
-heroku logs --tail # Show current logs and keep updating with any new results
-heroku config:set DEBUG_COLLECTSTATIC=1 # Add additional logging for collectstatic (this tool is run automatically during a build)
-heroku ps   #Display dyno status
-
- -

Если вам нужно больше информации, предоставленной здесь, вам нужно будет начать изучать Django Logging.

- - - -

Итоги

- -

Это конец этого руководства по настройке и развёртывании приложений Django, а также серия руководств по работе с Django. Надеемся, вы нашли их полезными. Вы можете проверить полностью проработанную версию по исходникам на Github.
- Следующий шаг - прочитать наши последние несколько статей, а затем завершить оценочную задачу.

- -

Смотрите также

- - - -

{{PreviousMenuNext("Learn/Server-side/Django/Testing", "Learn/Server-side/Django/web_application_security", "Learn/Server-side/Django")}}

- -

В этом модуле

- - diff --git "a/files/ru/learn/server-side/django/\321\201\320\265\321\201\321\201\320\270\320\270/index.html" "b/files/ru/learn/server-side/django/\321\201\320\265\321\201\321\201\320\270\320\270/index.html" deleted file mode 100644 index 5f7d492c72..0000000000 --- "a/files/ru/learn/server-side/django/\321\201\320\265\321\201\321\201\320\270\320\270/index.html" +++ /dev/null @@ -1,181 +0,0 @@ ---- -title: 'Руководство часть 7: Сессии' -slug: Learn/Server-side/Django/Сессии -tags: - - django - - Джанго - - Для начинающих - - Изучение - - Питон - - Руководство - - Серверная сторона - - Статья - - применение сессий - - сессии -translation_of: Learn/Server-side/Django/Sessions ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/Server-side/Django/Generic_views", "Learn/Server-side/Django/authentication_and_sessions", "Learn/Server-side/Django")}}
- -

Эта часть раширяет наш сайт LocalLibrary, добавляя счетчик посещений домашней страницы, реализованного при помощи сессий. Это относительно простой пример, но он демонстрирует то, как при помощи сессий реализовать анализ поведения анонимных пользователей на сайте.

- - - - - - - - - - - - -
Требования:Завершить изучение всех предыдущих разделов, включая Django Руководство Часть 6: Обобщенные отображения списков и детальной информации
Цель:Понимать как применять сессии.
- -

Обзор

- -

В предыдущих частях мы создали сайт LocalLibrary, который позволяет пользователям получать из каталога списки книг и авторов. На данный момент каждый посетитель сайта получает доступ к одним и тем же страницам и типам информации динамически сформированными из базы данных.

- -

В "настоящей" библиотеке вам хотелось бы предоставить пользователю индивидуальные услуги, которые зависят от его предпочтений и предыдущего опыта использования сайта, его настроек и тому подобное. Например, при очередном посещении сайта вы можете скрыть сообщения об ошибках для тех пользователей, которые их уже получали, или сохранить и учитывать пользовательские настройки (например, количество выводимых данных на странице как результат какого-либо поиска). 

- -

Сессии позволяют вам реализовать такой род функциональности, который позволит вам хранить и получать произвольные данные, полученные на основе индивидуального поведения пользователя на сайте.

- -

Что такое сессии?

- -

Все взаимодействия между браузерами и серверами осуществляются при помощи протокола HTTP, который не сохраняет свое состояние (stateless). Данный факт означает, что сообщения между клиентом и сервером являются полностью независимыми один от другого — то есть не существует какого-либо представления "последовательности", или поведения в зависимости от предыдущих сообщений. В результате, если вы хотите создать сайт который будет отслеживать взаимодействие с клиентом (браузером), вам нужно реализовать это самостоятельно.

- -

Сессии являются механизмом, который использует Django (да и весь остальной "Интернет") для отслеживания "состояния" между сайтом и каким-либо браузером. Сессии позволяют вам хранить произвольные данные браузера и получать их в тот момент, когда между данным браузером и сайтом устанавливается соединение. Данные получаются и сохраняются в сессии при помощи соответствующего "ключа".

- -

Django использует куки (cookie), которые содержат специальный идентификатор сессии, который выделяет среди остальных, каждый браузер и соответствующую сессию. Реальные данные сессии, по умолчанию, хранятся в базе данных сайта (это более безопасно, чем сохранять данные в куки, где они могут быть уязвими для злоумышленников). Однако, у вас есть возможность настроить Django так, чтобы сохранять данные сессий в других местах (кэше, файлах, "безопасных" куки). Но все же хранение по умолчанию является хорошей и безопасной возможностью.

- -

Подключение сессий

- -

Сессии стали доступны автоматически в тот момент, когда мы создали скелет сайта (во второй части руководства).

- -

Необходимые конфигурации выполняются в разделах INSTALLED_APPS и MIDDLEWARE файла проекта (locallibrary/locallibrary/settings.py), как показано ниже:

- -
INSTALLED_APPS = [
-    ...
-    'django.contrib.sessions',
-    ....
-
-MIDDLEWARE = [
-    ...
-    'django.contrib.sessions.middleware.SessionMiddleware',
-    ....
- -

Применение сессий

- -

Вы можете получить доступ к переменной session, в соответствующем отображении, через параметр request (HttpRequest передается как первый аргумент в каждое отображение). Переменная сессии является связью с определенным пользователем (или, если быть более точным, связью с определенным браузером, который определяется при помощи идентификатора (id) сессии, получаемого из куки браузера).

- -

Переменная (или поле) session является объектом-словарем, который служит для чтения и записи неограниченное число раз. С ним вы можете выполнять любые стандартные операции, включая очистку всех данных, проверку наличия ключа, циклы по данным и так далее. Большую часть времени вы будете тратить на  обычные "словарные" операции - получения и установки значений.

- -

Ниже представлены фрагменты кода, которые показывают вам как получать, задавать и удалять некоторые данные при помощи ключа "my_car", связанного с текущей сессией (браузером). 

- -
-

Примечание: Одной из самых грандиозных вещей в Django является то, что вам не надо думать о механизме, который связывает сессию с текущим запросом в отображении. Во фрагменте ниже, все что вам надо знать, это то, что  my_car связана с тем браузером, который отправил текущий запрос.

-
- -
# Получение значения сессии при помощи ключа(то есть, 'my_car').
-# Если такого ключа нет, то возникнет ошибка KeyError
-my_car = request.session['my_car']
-
-# Получение значения сессии. Если значения не существует,
-# то вернется значение по умолчанию ('mini')
-my_car = request.session.get('my_car', 'mini')
-
-# Передача значения в сессию
-request.session['my_car'] = 'mini'
-
-# Удаление значения из сессии
-del request.session['my_car']
-
- -

Данное API имеет другие методы, которые большей частью используются для управления куки, связанных с сессией.  Например, существуют методы проверки того, что куки поддерживаются клиентским браузером, другие методы служат для установки и проверки предельных дат жизни куки, а также для очистки просроченных сессий из хранилища. Подробное описание API вы можете найти в разделе Как использовать сессии (Django docs).

- -

Хранение данных сессии

- -

По умолчанию Django сохраняет данные сессии в базу данных и отправляет соответствующие куки клиенту только тогда, когда сессия была изменена, или удалена. Если вы обновляете какие-либо данные при помощи ключа сессии, как показано в предыдущем фрагменте, тогда вам не надо беспокоиться о процессе сохранения! Например:

- -
# Данное присваивание распознается как обновление сессии
-# и данные будут сохранены
-request.session['my_car'] = 'mini'
- -

Если вы обновлете информацию внутри данных сессии, тогда Django не распознает эти изменения и не выполнит сохранение данных (например, если вы изменили "wheels" внутри переменной "my_car", как показано ниже). В таких случаях вам надо явно указывать, что сессия была изменена.

- -
# Объект сессии модифицируется неявно.
-# Изменения НЕ БУДУТ сохранены!
-request.session['my_car']['wheels'] = 'alloy'
-
-# Явное указание, что данные изменены.
-# Сессия будет сохранена, куки обновлены (если необходимо).
-request.session.modified = True
-
- -
-

Примечание: Вы можете изменить поведение сессий таким образом, чтобы они записывали любое свое изменение в базу данных и отправляли куки, при каждом запросе, путем установки SESSION_SAVE_EVERY_REQUEST = True, в файле настроек проекта (locallibrary/locallibrary/settings.py).

-
- -

Простой пример — получение числа визитов

- -

В качестве примера из реального мира мы обновим нашу библиотеку так, чтобы сообщать пользователю количество совершенных им визитов главной страницы сайта LocalLibrary

- -

Откройте /locallibrary/catalog/views.py и добавьте изменения, выделенных жирным, ниже. 

- -
def index(request):
-    ...
-
-    num_authors=Author.objects.count()  # The 'all()' is implied by default.
-
-    # Number of visits to this view, as counted in the session variable.
-    num_visits=request.session.get('num_visits', 0)
-    request.session['num_visits'] = num_visits+1
-
-    # Render the HTML template index.html with the data in the context variable.
-    return render(
-        request,
-        'index.html',
-        context={'num_books':num_books,'num_instances':num_instances,'num_instances_available':num_instances_available,'num_authors':num_authors,
-            'num_visits':num_visits}, # num_visits appended
-    )
- -

В первую очередь мы получаем значение 'num_visits' из сессии, возвращая 0, если оно не было установлено ранее. Каждый раз при получении запроса, мы увеличиваем данное значение на единицу и сохраняем его обратно в сессии (до следующего посещения данной страницы пользователем). Затем переменная num_visits передается в шаблон через переменную контекста context.  

- -
-

Примечание: Можно проверить наличие поддержки куки в браузере (для примера, смотрите Как использовать сессии), или разработать наш UI таким образом, чтобы это не имело значения.

-
- -

Для показа значения переменной, из следующего фрагмента добавьте нижнюю строчку кода в ваш шаблон главной страницы сайта (/locallibrary/catalog/templates/index.html), в его нижний раздел "Dynamic content":

- -
<h2>Dynamic content</h2>
-
-<p>The library has the following record counts:</p>
-<ul>
-<li><strong>Books:</strong> \{{ num_books }}</li>
-<li><strong>Copies:</strong> \{{ num_instances }}</li>
-<li><strong>Copies available:</strong> \{{ num_instances_available }}</li>
-<li><strong>Authors:</strong> \{{ num_authors }}</li>
-</ul>
-
-<p>You have visited this page \{{ num_visits }}{% if num_visits == 1 %} time{% else %} times{% endif %}.</p>
-
- -

Сохраните ваши изменения и перезапустите сервер. Данное значение должно изменяться всякий раз, когда вы обновляете страницу.

- - - -

Итоги

- -

Вы узнали как применять сессии для улучшения взаимодейстсвие с анонимными пользователями. 

- -

В наших следующих статьях мы рассмотрим фреймворк аутентификации и авторизации (разрешение доступа, permission), и покажем вам как поддерживать пользовательские аккаунты.

- -

Смотрите также

- - - -

{{PreviousMenuNext("Learn/Server-side/Django/Generic_views", "Learn/Server-side/Django/Authentication", "Learn/Server-side/Django")}}

diff --git a/files/ru/learn/server-side/express_nodejs/tutorial_local_library_website/index.html b/files/ru/learn/server-side/express_nodejs/tutorial_local_library_website/index.html new file mode 100644 index 0000000000..c7e821248e --- /dev/null +++ b/files/ru/learn/server-side/express_nodejs/tutorial_local_library_website/index.html @@ -0,0 +1,73 @@ +--- +title: 'Учебник Express: сайт Local Library' +slug: Learn/Server-side/Express_Nodejs/Учебник_сайт_local_library +tags: + - Express + - Node + - nodejs + - Введение + - Для начинающих + - Серверная часть + - Учебник +translation_of: Learn/Server-side/Express_Nodejs/Tutorial_local_library_website +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Server-side/Express_Nodejs/development_environment", "Learn/Server-side/Express_Nodejs/skeleton_website", "Learn/Server-side/Express_Nodejs")}}
+ +

Первая статья в нашей серии практических уроков объясняет, что вы будете изучать, и предоставит обзор сайта "локальной библиотеки" ("local library"), над которым мы будем работать и развивать в последующих статьях.

+ + + + + + + + + + + + +
Необходимые знания:Прочтите Введение в Express. Для следования статьям вам также надо будет установить среду разработки Node
Задача:Представить пример приложения, используемого в этом учебнике, и позволить читателям понять, какие темы будут рассмотрены. 
+ +

Обзор

+ +

Добро пожаловать в учебник MDN «Local Library» Express (Node), в котором мы разрабатываем веб-сайт, который может использоваться для управления каталогом локальной библиотеки.

+ +
В этой серии обучающих статей вы будете:
+ + + +

Вы уже имеете знания о некоторых из этих тем и кратко касались других. К концу серии уроков вы должны знать достаточно, чтобы разрабатывать простые приложения Express самостоятельно.

+ +

Сайт LocalLibrary

+ +

LocalLibrary это название сайта который мы будем создавать и развивать в ходе прохождения этого курса уроков. Как и следовало ожидать, цель сайта - предоставить онлайн-каталог для небольшой локальной библиотеки, где пользователи могут просматривать доступные книги и управлять своими учётными записями.

+ +

Этот пример был тщательно подобран, потому что он может масштабироваться, чтобы отображать насколько можно много или мало записей, и может использоваться для демонстрации почти любой возможности Express. Что ещё более важно, это позволяет нам обеспечить управляемый путь через функциональность, которая вам понадобится на любом веб-сайте:

+ + + +

Несмотря на то, что это очень масштабируемый пример, он называется LocalLibrary, потому что мы надеемся показать минимальную информацию, которая поможет быстро начать работать с Express. В результате мы будем хранить информацию о книгах, копиях книг, авторов и другой ключевой информации. Однако, мы не будем хранить информацию о других предметах, которые может предоставить библиотека, или предоставить инфраструктуру, необходимую для поддержки нескольких сайтов библиотек или других функций "большой библиотеки".

+ +

Я застрял, где я могу посмотреть код?

+ +

По мере того, как вы работаете над учебником, мы предоставим вам соответствующие фрагменты кода для копирования и вставки в каждой точке, а также будет другой код, который, мы надеемся, вы расширите самостоятельно (с некоторыми рекомендациями).

+ +

Если вы застряли, вы можете найти полностью разработанную версию вебсайта на Github.

+ +

Резюме

+ +

Теперь, когда вы знаете немного больше о сайте LocalLIbrary и о том, что мы будем изучать, пришло время приступить к созданию скелета проекта, который будет использован в нашем сайте.

+ +

{{PreviousMenuNext("Learn/Server-side/Express_Nodejs/development_environment", "Learn/Server-side/Express_Nodejs/skeleton_website", "Learn/Server-side/Express_Nodejs")}}

diff --git "a/files/ru/learn/server-side/express_nodejs/\321\203\321\207\320\265\320\261\320\275\320\270\320\272_\321\201\320\260\320\271\321\202_local_library/index.html" "b/files/ru/learn/server-side/express_nodejs/\321\203\321\207\320\265\320\261\320\275\320\270\320\272_\321\201\320\260\320\271\321\202_local_library/index.html" deleted file mode 100644 index c7e821248e..0000000000 --- "a/files/ru/learn/server-side/express_nodejs/\321\203\321\207\320\265\320\261\320\275\320\270\320\272_\321\201\320\260\320\271\321\202_local_library/index.html" +++ /dev/null @@ -1,73 +0,0 @@ ---- -title: 'Учебник Express: сайт Local Library' -slug: Learn/Server-side/Express_Nodejs/Учебник_сайт_local_library -tags: - - Express - - Node - - nodejs - - Введение - - Для начинающих - - Серверная часть - - Учебник -translation_of: Learn/Server-side/Express_Nodejs/Tutorial_local_library_website ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/Server-side/Express_Nodejs/development_environment", "Learn/Server-side/Express_Nodejs/skeleton_website", "Learn/Server-side/Express_Nodejs")}}
- -

Первая статья в нашей серии практических уроков объясняет, что вы будете изучать, и предоставит обзор сайта "локальной библиотеки" ("local library"), над которым мы будем работать и развивать в последующих статьях.

- - - - - - - - - - - - -
Необходимые знания:Прочтите Введение в Express. Для следования статьям вам также надо будет установить среду разработки Node
Задача:Представить пример приложения, используемого в этом учебнике, и позволить читателям понять, какие темы будут рассмотрены. 
- -

Обзор

- -

Добро пожаловать в учебник MDN «Local Library» Express (Node), в котором мы разрабатываем веб-сайт, который может использоваться для управления каталогом локальной библиотеки.

- -
В этой серии обучающих статей вы будете:
- - - -

Вы уже имеете знания о некоторых из этих тем и кратко касались других. К концу серии уроков вы должны знать достаточно, чтобы разрабатывать простые приложения Express самостоятельно.

- -

Сайт LocalLibrary

- -

LocalLibrary это название сайта который мы будем создавать и развивать в ходе прохождения этого курса уроков. Как и следовало ожидать, цель сайта - предоставить онлайн-каталог для небольшой локальной библиотеки, где пользователи могут просматривать доступные книги и управлять своими учётными записями.

- -

Этот пример был тщательно подобран, потому что он может масштабироваться, чтобы отображать насколько можно много или мало записей, и может использоваться для демонстрации почти любой возможности Express. Что ещё более важно, это позволяет нам обеспечить управляемый путь через функциональность, которая вам понадобится на любом веб-сайте:

- - - -

Несмотря на то, что это очень масштабируемый пример, он называется LocalLibrary, потому что мы надеемся показать минимальную информацию, которая поможет быстро начать работать с Express. В результате мы будем хранить информацию о книгах, копиях книг, авторов и другой ключевой информации. Однако, мы не будем хранить информацию о других предметах, которые может предоставить библиотека, или предоставить инфраструктуру, необходимую для поддержки нескольких сайтов библиотек или других функций "большой библиотеки".

- -

Я застрял, где я могу посмотреть код?

- -

По мере того, как вы работаете над учебником, мы предоставим вам соответствующие фрагменты кода для копирования и вставки в каждой точке, а также будет другой код, который, мы надеемся, вы расширите самостоятельно (с некоторыми рекомендациями).

- -

Если вы застряли, вы можете найти полностью разработанную версию вебсайта на Github.

- -

Резюме

- -

Теперь, когда вы знаете немного больше о сайте LocalLIbrary и о том, что мы будем изучать, пришло время приступить к созданию скелета проекта, который будет использован в нашем сайте.

- -

{{PreviousMenuNext("Learn/Server-side/Express_Nodejs/development_environment", "Learn/Server-side/Express_Nodejs/skeleton_website", "Learn/Server-side/Express_Nodejs")}}

diff --git a/files/ru/learn/server-side/first_steps/website_security/index.html b/files/ru/learn/server-side/first_steps/website_security/index.html new file mode 100644 index 0000000000..6caa9b2aa2 --- /dev/null +++ b/files/ru/learn/server-side/first_steps/website_security/index.html @@ -0,0 +1,169 @@ +--- +title: Веб-безопасность +slug: Learn/Server-side/First_steps/Веб_Безопасность +translation_of: Learn/Server-side/First_steps/Website_security +--- +
{{LearnSidebar}}
+ +
{{PreviousMenu("Learn/Server-side/First_steps/Web_frameworks", "Learn/Server-side/First_steps")}}
+ +

Безопасность сайта требует бдительности во всех аспектах дизайна и использования сайта. Эта вводная статья не сделает из вас гуру безопасности веб-сайта, но она поможет вам понять, откуда приходят угрозы, и что вы можете сделать, чтобы укрепить свое веб-приложение против наиболее распространенных атак.

+ + + + + + + + + + + + +
Условия:Элементарная компьютерная грамотность
Цель:Понять самые распространенные угрозы безопасности веб-приложений. И что вы можете сделать, чтобы уменьшить риск взлома вашего сайта.
+ +

Что такое безопасность сайта?

+ +

Интернет опасное место! Мы регулярно слышим о том, что веб-сайты становятся недоступными из-за атак типа отказано в обслуживании, или отображение измененной (и часто поврежденной) информации на их страницах. В других случаях миллионы паролей, адресов электронной почты и данные кредитных карт становились общедоступными, подвергая пользователей веб-сайта личному смущению или к финансовым рискам.

+ +

Цель веб-безопасности заключается в предотвращении этих (или других) видов атак. Более формальным определением веб-безопасности является: способы защиты веб-сайтов от несанкционированного доступа, использования, изменения, уничтожения или нарушения работы.

+ +

Для эффективной безопасности веб-сайта необходимо уделять особое внимание к разработке всего веб-сайта: к вашему веб-приложению, конфигурации веб-сервера, при написании политик создания и обновления паролей, а так же кода на стороне клиента. Хотя все это звучит очень зловеще, хорошая новость заключается в том, что если вы используете веб-фреймворк для серверной части, то он почти наверняка обеспечит «по умолчанию» надежные и продуманные механизмы защиты от ряда наиболее распространенных атак. Другие атаки можно смягчить с помощью конфигурации вашего веб-сервера, например, включив HTTPS. Наконец, есть общедоступные инструменты для сканирования уязвимостей, которые могут помочь вам определить, если вы допустили какие-либо очевидные ошибки.

+ +

В оставшейся части этой статьи мы рассмотрим более подробную информацию о некоторых самых распространенных угрозах и о простых шагах, которые вы можете предпринять, чтобы защитить свой сайт.

+ +
+

Примечание: Это вводная статья, призванная помочь вам задуматься о безопасности веб-сайта, но она не является исчерпывающей.

+
+ +

Угрозы бесопасности сайта

+ +

В этом разделе перечислены лишь некоторые из наиболее распространенных угроз веб-сайта и способы их устранения. Читая, обратите внимание на то, насколько успешны угрозы, когда веб-приложение доверяет, либо недостаточно параноидально относится к данным, поступающим из браузера.

+ +

Межсайтовый скриптинг (XSS)

+ +

XSS (Cross-Site Scripting - Межсайтовый скриптинг) это термин, используемый для описания типа атак, которые позволяют злоумышленнику внедрять вредоносный код через веб-сайт в браузеры других пользователей. Поскольку внедренный код поступает в браузер с сайта, он является доверенным и может выполнять такие действия, как отправка авторизационного файла cookieпользователя злоумышленнику. Когда у злоумышленника есть файл cookie, он может войти на сайт, как если бы он был пользователем, и сделать все, что может пользователь, например, получить доступ к данным кредитной карты, просмотреть контактные данные или изменить пароли.

+ +
+

Примечание: Уязвимости XSS исторически встречались чаще, чем любые другие виды угроз безопасности.

+
+ +

Уязвимости XSS делятся на отраженные и хранимые, в зависимости от того, как сайт возвращает внедренный код в браузер.

+ + + +

SQL injection

+ +

Уязвимости SQL-инъекций позволяют злоумышленникам выполнять произвольный код SQL в базе данных, позволяя получать, изменять или удалять данные независимо от разрешений пользователя. Успешная инъекционная атака может подделать удостоверения, создать новые удостоверения с правами администратора, получить доступ ко всем данным на сервере или уничтожить / изменить данные, чтобы сделать их непригодными для использования.
+
+ Типы внедрения SQL включают внедрение SQL на основе ошибок, внедрение SQL на основе логических ошибок и внедрение SQL на основе времени.
+
+ Эта уязвимость присутствует, если пользовательский ввод, который передается в базовый оператор SQL, может изменить смысл оператора. Например, следующий код предназначен для перечисления всех пользователей с определенным именем (userName), которое было предоставлено из формы HTML:

+ +
statement = "SELECT * FROM users WHERE name = '" + userName + "';"
+ +

Если пользователь указывает реальное имя, оператор будет работать так, как задумано. Однако злонамеренный пользователь может полностью изменить поведение этого оператора SQL на новый оператор в следующем примере, просто указав текст полужирным шрифтом для userName.

+ +
SELECT * FROM users WHERE name = 'a';DROP TABLE users; SELECT * FROM userinfo WHERE 't' = 't';
+
+ +

Модифицированный оператор создает действительный оператор SQL, который удаляет таблицу пользователей и выбирает все данные из таблицы userinfo (которая раскрывает информацию о каждом пользователе). Это работает, потому что первая часть введенного текста (a ';) завершает исходное утверждение.
+
+ Чтобы избежать такого рода атак, вы должны убедиться, что любые пользовательские данные, которые передаются в запрос SQL, не могут изменить природу запроса. Один из способов сделать это - экранировать все символы пользовательского ввода, которые имеют особое значение в SQL.

+ +
+

Примечание. Инструкция SQL обрабатывает символ ' как начало и конец строкового литерала. Поместив обратную косую черту перед этим символом (\ '), мы экранируем символ и говорим SQL вместо этого трактовать его как символ (только часть строки).

+
+ +

В следующей инструкции мы экранируем символ '. Теперь SQL будет интерпретировать имя как всю строку, выделенную жирным шрифтом (это действительно очень странное имя, но безопасное).

+ +
SELECT * FROM users WHERE name = 'a\';DROP TABLE users; SELECT * FROM userinfo WHERE \'t\' = \'t';
+
+
+ +

Веб-фремворки будут часто заботиться о зарезервированных символах для вас. Django, например, гарантирует, что любые пользовательские данные, передаваемые в наборы запросов (модельные запросы), будут экранируются.

+ +
+

Примечание: этот раздел в значительной степени основан на информации из Wikipedia.

+
+ +

Подделка межсайтовых запросов (CSRF)

+ +

CSRF-атаки позволяют злоумышленнику выполнять действия, используя учетные данные другого пользователя, без его ведома или согласия.

+ +

Этот тип атаки лучше всего пояснить на примере. Джон - злоумышленник, который знает, что определенный сайт позволяет пользователям, вошедшим в систему, отправлять деньги на указанную учетную запись, используя HTTP-запрос POST, который включает имя учетной записи и сумму денег. Джон создает форму, которая включает в себя его банковские реквизиты и сумму денег в виде скрытых полей, и отправляет ее по электронной почте другим пользователям сайта (с кнопкой «Отправить», замаскированной под ссылку на сайт «быстрого обогащения»).

+ +

Если пользователь нажимает кнопку отправки, на сервер будет отправлен HTTP-запрос POST, содержащий сведения о транзакции и любые файлы cookie на стороне клиента, которые браузер связал с сайтом (добавление связанных файлов cookie сайта в запросы является нормальным поведением браузера). Сервер проверит файлы cookie и использует их, чтобы определить, вошел ли пользователь в систему и имеет ли разрешение на совершение транзакции.

+ +

В результате любой пользователь, который нажимает кнопку Отправить во время входа на торговый сайт, совершает транзакцию. Джон становится богатым.

+ +
+

Примечание: Уловка здесь в том, что Джону не нужен доступ к файлам cookie пользователя (или учетным данным). Браузер пользователя сохраняет эту информацию и автоматически включает ее во все запросы к соответствующему серверу.

+
+ +

Один из способов предотвратить этот тип атаки - запросить сервером запросы POST, содержащие секрет, созданный пользователем для конкретного сайта. Секрет будет предоставлен сервером при отправке веб-формы, используемой для переводов. Такой подход не позволяет Джону создать свою собственную форму, потому что он должен знать секрет, который сервер предоставляет пользователю. Даже если он узнает секрет и создаст форму для конкретного пользователя, он больше не сможет использовать ту же форму для атаки на каждого пользователя.

+ +

Веб-фреймворки часто включают такие механизмы предотвращения CSRF.

+ +

Прочие угрозы

+ +

Другие распространенные атаки / уязвимости включают:

+ + + +

Полный список угроз безопасности веб-сайтов см. Category: Web security exploits (Wikipedia) и Category: Attack (Open Web Application Security Project).

+ +

Несколько ключевых сообщений

+ +

Почти все эксплойты безопасности, описанные в предыдущих разделах, успешны, когда веб-приложение доверяет данным из браузера. Что бы вы ни делали для повышения безопасности своего веб-сайта, вы должны дезинфицировать все данные, исходящие от пользователей, прежде чем они будут отображаться в браузере, использоваться в запросах SQL или передаваться в вызов операционной системы или файловой системы.

+ +
+

Внимание! Самый важный урок, который вы можете извлечь о безопасности веб-сайтов: никогда не доверяйте данным из браузера. Это включает, помимо прочего, данные в параметрах URL-адресов запросов GET, запросов POST, заголовков HTTP и файлов cookie, а также файлов, загруженных пользователем. Всегда проверяйте и дезинфицируйте все входящие данные. Всегда предполагайте худшее!

+
+ +

Вы можете предпринять ряд других конкретных шагов:

+ + + +

Веб-фреймворки могут помочь смягчить многие из наиболее распространенных уязвимостей.

+ +

Резюме

+ +

В этой статье объясняется концепция веб-безопасности и некоторые из наиболее распространенных угроз, от которых ваш веб-сайт должен пытаться защититься. Самое главное, вы должны понимать, что веб-приложение не может доверять никаким данным из веб-браузера. Все пользовательские данные должны быть очищены перед отображением или использованием в SQL-запросах и вызовах файловой системы.

+ +

Этой статьей вы подошли к концу этого модуля, охватывающего ваши первые шаги в программировании на стороне сервера. Мы надеемся, что вам понравилось изучать эти фундаментальные концепции, и теперь вы готовы выбрать веб-платформу и начать программировать.

+ +

{{PreviousMenu("Learn/Server-side/First_steps/Web_frameworks", "Learn/Server-side/First_steps")}}

+ +

В этом модуле

+ + diff --git "a/files/ru/learn/server-side/first_steps/\320\262\320\265\320\261_\320\261\320\265\320\267\320\276\320\277\320\260\321\201\320\275\320\276\321\201\321\202\321\214/index.html" "b/files/ru/learn/server-side/first_steps/\320\262\320\265\320\261_\320\261\320\265\320\267\320\276\320\277\320\260\321\201\320\275\320\276\321\201\321\202\321\214/index.html" deleted file mode 100644 index 6caa9b2aa2..0000000000 --- "a/files/ru/learn/server-side/first_steps/\320\262\320\265\320\261_\320\261\320\265\320\267\320\276\320\277\320\260\321\201\320\275\320\276\321\201\321\202\321\214/index.html" +++ /dev/null @@ -1,169 +0,0 @@ ---- -title: Веб-безопасность -slug: Learn/Server-side/First_steps/Веб_Безопасность -translation_of: Learn/Server-side/First_steps/Website_security ---- -
{{LearnSidebar}}
- -
{{PreviousMenu("Learn/Server-side/First_steps/Web_frameworks", "Learn/Server-side/First_steps")}}
- -

Безопасность сайта требует бдительности во всех аспектах дизайна и использования сайта. Эта вводная статья не сделает из вас гуру безопасности веб-сайта, но она поможет вам понять, откуда приходят угрозы, и что вы можете сделать, чтобы укрепить свое веб-приложение против наиболее распространенных атак.

- - - - - - - - - - - - -
Условия:Элементарная компьютерная грамотность
Цель:Понять самые распространенные угрозы безопасности веб-приложений. И что вы можете сделать, чтобы уменьшить риск взлома вашего сайта.
- -

Что такое безопасность сайта?

- -

Интернет опасное место! Мы регулярно слышим о том, что веб-сайты становятся недоступными из-за атак типа отказано в обслуживании, или отображение измененной (и часто поврежденной) информации на их страницах. В других случаях миллионы паролей, адресов электронной почты и данные кредитных карт становились общедоступными, подвергая пользователей веб-сайта личному смущению или к финансовым рискам.

- -

Цель веб-безопасности заключается в предотвращении этих (или других) видов атак. Более формальным определением веб-безопасности является: способы защиты веб-сайтов от несанкционированного доступа, использования, изменения, уничтожения или нарушения работы.

- -

Для эффективной безопасности веб-сайта необходимо уделять особое внимание к разработке всего веб-сайта: к вашему веб-приложению, конфигурации веб-сервера, при написании политик создания и обновления паролей, а так же кода на стороне клиента. Хотя все это звучит очень зловеще, хорошая новость заключается в том, что если вы используете веб-фреймворк для серверной части, то он почти наверняка обеспечит «по умолчанию» надежные и продуманные механизмы защиты от ряда наиболее распространенных атак. Другие атаки можно смягчить с помощью конфигурации вашего веб-сервера, например, включив HTTPS. Наконец, есть общедоступные инструменты для сканирования уязвимостей, которые могут помочь вам определить, если вы допустили какие-либо очевидные ошибки.

- -

В оставшейся части этой статьи мы рассмотрим более подробную информацию о некоторых самых распространенных угрозах и о простых шагах, которые вы можете предпринять, чтобы защитить свой сайт.

- -
-

Примечание: Это вводная статья, призванная помочь вам задуматься о безопасности веб-сайта, но она не является исчерпывающей.

-
- -

Угрозы бесопасности сайта

- -

В этом разделе перечислены лишь некоторые из наиболее распространенных угроз веб-сайта и способы их устранения. Читая, обратите внимание на то, насколько успешны угрозы, когда веб-приложение доверяет, либо недостаточно параноидально относится к данным, поступающим из браузера.

- -

Межсайтовый скриптинг (XSS)

- -

XSS (Cross-Site Scripting - Межсайтовый скриптинг) это термин, используемый для описания типа атак, которые позволяют злоумышленнику внедрять вредоносный код через веб-сайт в браузеры других пользователей. Поскольку внедренный код поступает в браузер с сайта, он является доверенным и может выполнять такие действия, как отправка авторизационного файла cookieпользователя злоумышленнику. Когда у злоумышленника есть файл cookie, он может войти на сайт, как если бы он был пользователем, и сделать все, что может пользователь, например, получить доступ к данным кредитной карты, просмотреть контактные данные или изменить пароли.

- -
-

Примечание: Уязвимости XSS исторически встречались чаще, чем любые другие виды угроз безопасности.

-
- -

Уязвимости XSS делятся на отраженные и хранимые, в зависимости от того, как сайт возвращает внедренный код в браузер.

- - - -

SQL injection

- -

Уязвимости SQL-инъекций позволяют злоумышленникам выполнять произвольный код SQL в базе данных, позволяя получать, изменять или удалять данные независимо от разрешений пользователя. Успешная инъекционная атака может подделать удостоверения, создать новые удостоверения с правами администратора, получить доступ ко всем данным на сервере или уничтожить / изменить данные, чтобы сделать их непригодными для использования.
-
- Типы внедрения SQL включают внедрение SQL на основе ошибок, внедрение SQL на основе логических ошибок и внедрение SQL на основе времени.
-
- Эта уязвимость присутствует, если пользовательский ввод, который передается в базовый оператор SQL, может изменить смысл оператора. Например, следующий код предназначен для перечисления всех пользователей с определенным именем (userName), которое было предоставлено из формы HTML:

- -
statement = "SELECT * FROM users WHERE name = '" + userName + "';"
- -

Если пользователь указывает реальное имя, оператор будет работать так, как задумано. Однако злонамеренный пользователь может полностью изменить поведение этого оператора SQL на новый оператор в следующем примере, просто указав текст полужирным шрифтом для userName.

- -
SELECT * FROM users WHERE name = 'a';DROP TABLE users; SELECT * FROM userinfo WHERE 't' = 't';
-
- -

Модифицированный оператор создает действительный оператор SQL, который удаляет таблицу пользователей и выбирает все данные из таблицы userinfo (которая раскрывает информацию о каждом пользователе). Это работает, потому что первая часть введенного текста (a ';) завершает исходное утверждение.
-
- Чтобы избежать такого рода атак, вы должны убедиться, что любые пользовательские данные, которые передаются в запрос SQL, не могут изменить природу запроса. Один из способов сделать это - экранировать все символы пользовательского ввода, которые имеют особое значение в SQL.

- -
-

Примечание. Инструкция SQL обрабатывает символ ' как начало и конец строкового литерала. Поместив обратную косую черту перед этим символом (\ '), мы экранируем символ и говорим SQL вместо этого трактовать его как символ (только часть строки).

-
- -

В следующей инструкции мы экранируем символ '. Теперь SQL будет интерпретировать имя как всю строку, выделенную жирным шрифтом (это действительно очень странное имя, но безопасное).

- -
SELECT * FROM users WHERE name = 'a\';DROP TABLE users; SELECT * FROM userinfo WHERE \'t\' = \'t';
-
-
- -

Веб-фремворки будут часто заботиться о зарезервированных символах для вас. Django, например, гарантирует, что любые пользовательские данные, передаваемые в наборы запросов (модельные запросы), будут экранируются.

- -
-

Примечание: этот раздел в значительной степени основан на информации из Wikipedia.

-
- -

Подделка межсайтовых запросов (CSRF)

- -

CSRF-атаки позволяют злоумышленнику выполнять действия, используя учетные данные другого пользователя, без его ведома или согласия.

- -

Этот тип атаки лучше всего пояснить на примере. Джон - злоумышленник, который знает, что определенный сайт позволяет пользователям, вошедшим в систему, отправлять деньги на указанную учетную запись, используя HTTP-запрос POST, который включает имя учетной записи и сумму денег. Джон создает форму, которая включает в себя его банковские реквизиты и сумму денег в виде скрытых полей, и отправляет ее по электронной почте другим пользователям сайта (с кнопкой «Отправить», замаскированной под ссылку на сайт «быстрого обогащения»).

- -

Если пользователь нажимает кнопку отправки, на сервер будет отправлен HTTP-запрос POST, содержащий сведения о транзакции и любые файлы cookie на стороне клиента, которые браузер связал с сайтом (добавление связанных файлов cookie сайта в запросы является нормальным поведением браузера). Сервер проверит файлы cookie и использует их, чтобы определить, вошел ли пользователь в систему и имеет ли разрешение на совершение транзакции.

- -

В результате любой пользователь, который нажимает кнопку Отправить во время входа на торговый сайт, совершает транзакцию. Джон становится богатым.

- -
-

Примечание: Уловка здесь в том, что Джону не нужен доступ к файлам cookie пользователя (или учетным данным). Браузер пользователя сохраняет эту информацию и автоматически включает ее во все запросы к соответствующему серверу.

-
- -

Один из способов предотвратить этот тип атаки - запросить сервером запросы POST, содержащие секрет, созданный пользователем для конкретного сайта. Секрет будет предоставлен сервером при отправке веб-формы, используемой для переводов. Такой подход не позволяет Джону создать свою собственную форму, потому что он должен знать секрет, который сервер предоставляет пользователю. Даже если он узнает секрет и создаст форму для конкретного пользователя, он больше не сможет использовать ту же форму для атаки на каждого пользователя.

- -

Веб-фреймворки часто включают такие механизмы предотвращения CSRF.

- -

Прочие угрозы

- -

Другие распространенные атаки / уязвимости включают:

- - - -

Полный список угроз безопасности веб-сайтов см. Category: Web security exploits (Wikipedia) и Category: Attack (Open Web Application Security Project).

- -

Несколько ключевых сообщений

- -

Почти все эксплойты безопасности, описанные в предыдущих разделах, успешны, когда веб-приложение доверяет данным из браузера. Что бы вы ни делали для повышения безопасности своего веб-сайта, вы должны дезинфицировать все данные, исходящие от пользователей, прежде чем они будут отображаться в браузере, использоваться в запросах SQL или передаваться в вызов операционной системы или файловой системы.

- -
-

Внимание! Самый важный урок, который вы можете извлечь о безопасности веб-сайтов: никогда не доверяйте данным из браузера. Это включает, помимо прочего, данные в параметрах URL-адресов запросов GET, запросов POST, заголовков HTTP и файлов cookie, а также файлов, загруженных пользователем. Всегда проверяйте и дезинфицируйте все входящие данные. Всегда предполагайте худшее!

-
- -

Вы можете предпринять ряд других конкретных шагов:

- - - -

Веб-фреймворки могут помочь смягчить многие из наиболее распространенных уязвимостей.

- -

Резюме

- -

В этой статье объясняется концепция веб-безопасности и некоторые из наиболее распространенных угроз, от которых ваш веб-сайт должен пытаться защититься. Самое главное, вы должны понимать, что веб-приложение не может доверять никаким данным из веб-браузера. Все пользовательские данные должны быть очищены перед отображением или использованием в SQL-запросах и вызовах файловой системы.

- -

Этой статьей вы подошли к концу этого модуля, охватывающего ваши первые шаги в программировании на стороне сервера. Мы надеемся, что вам понравилось изучать эти фундаментальные концепции, и теперь вы готовы выбрать веб-платформу и начать программировать.

- -

{{PreviousMenu("Learn/Server-side/First_steps/Web_frameworks", "Learn/Server-side/First_steps")}}

- -

В этом модуле

- - diff --git a/files/ru/learn/tools_and_testing/client-side_javascript_frameworks/index.html b/files/ru/learn/tools_and_testing/client-side_javascript_frameworks/index.html new file mode 100644 index 0000000000..08fb977bb5 --- /dev/null +++ b/files/ru/learn/tools_and_testing/client-side_javascript_frameworks/index.html @@ -0,0 +1,137 @@ +--- +title: Понимание JavaScript-фреймворков для фронтенда +slug: Learn/Tools_and_testing/Фронтенд_JavaScript_фреймворки +translation_of: Learn/Tools_and_testing/Client-side_JavaScript_frameworks +--- +
{{LearnSidebar}}
+JavaScript-фреймворки являются неотъемлемой частью современной веб-разработки,
+ +
предоставляя разработчикам проверенные и протестированные
+ +
инструменты для создания масштабируемых и интерактивных веб-приложений. Многие
+ +
современные компании используют фреймворки для своих решений, поэтому многие задачи связанные с разработкой клиентской части веб-приложений теперь требуют опыта работы с ними.
+ +

Начинающему разработчику веб-интерфесов, может быть трудно понять, с чего начать изучение фреймворков - их выбор разнообразен, а новые появляются постоянно. В основном же они работают аналогичным образом, но делают некоторые вещи по-разному, также есть некоторые специфичные вещи, которые следует соблюдать при использовании фреймворков.

+ +

Этим набором статей мы постараемся дать вам удобную отправную точку, чтобы помочь вам начать изучать основы. Мы не стремимся научить вас всему, что вам нужно знать о React / ReactDOM, или Vue, или какой-то другой конкретной среде; Документация этих фреймворков отлично выполняют эту работу. Вместо этого мы хотим сделать шаг назад и сначала ответить на более фундаментальные вопросы, такие как:

+ + + +

После этого мы предоставим некоторые учебные пособия, охватывающие основы некоторых фреймворков, чтобы предоставить вам достаточно контекста, чтобы вы  могли начать углубляться в этой теме. Мы хотим, чтобы вы изучали фреймворки прагматично, не забывая о фундаментальных практиках веб-разработки, таких как, например, доступность.

+ +

Начните прямо сейчас с "Введение в фронтенд фрейворки"

+ +

Prerequisites

+ +

You should really learn the basics of the core web languages first before attempting to move on to learning client-side frameworks — HTML, CSS, and especially JavaScript.

+ +

Your code will be richer and more professional as a result, and you'll be able to troubleshoot problems with more confidence if you understand the fundamental web platform features that the frameworks are building on top of.

+ +

Introductory guides

+ +
+
1. Introduction to client-side frameworks
+
We begin our look at frameworks with a general overview of the area, looking at a brief history of JavaScript and frameworks, why frameworks exist and what they give us, how to start thinking about choosing a framework to learn, and what alternatives there are to client-side frameworks.
+
2. Framework main features
+
Each major JavaScript framework has a different approach to updating the DOM, handling browser events, and providing an enjoyable developer experience. This article will explore the main features of “the big 4” frameworks, looking at how frameworks tend to work from a high level, and the differences between them.
+
+ +

React tutorials

+ +
+

Note: React tutorials last tested in May 2020, with React/ReactDOM 16.13.1 and create-react-app 3.4.1.

+ +

If you need to check your code against our version, you can find a finished version of the sample React app code in our todo-react repository. For a running live version, see https://mdn.github.io/todo-react-build/.

+
+ +
+
1. Getting started with React
+
In this article we will say hello to React. We'll discover a little bit of detail about its background and use cases, set up a basic React toolchain on our local computer, and create and play with a simple starter app, learning a bit about how React works in the process.
+
2. Beginning our React todo list
+
Let's say that we’ve been tasked with creating a proof-of-concept in React – an app that allows users to add, edit, and delete tasks they want to work on, and also mark tasks as complete without deleting them. This article will walk you through putting the basic App component structure and styling in place, ready for individual component definition and interactivity, which we'll add later.
+
3. Componentizing our React app
+
At this point, our app is a monolith. Before we can make it do things, we need to break it apart into manageable, descriptive components. React doesn’t have any hard rules for what is and isn’t a component – that’s up to you! In this article we will show you a sensible way to break our app up into components.
+
4. React interactivity: Events and state
+
With our component plan worked out, it's now time to start updating our app from a completely static UI to one that actually allows us to interact and change things. In this article we'll do this, digging into events and state along the way.
+
5. React interactivity: Editing, filtering, conditional rendering
+
As we near the end of our React journey (for now at least), we'll add the finishing touches to the main areas of functionality in our Todo list app. This includes allowing you to edit existing tasks, and filtering the list of tasks between all, completed, and incomplete tasks. We'll look at conditional UI rendering along the way.
+
6. Accessibility in React
+
In our final tutorial article, we'll focus on (pun intended) accessibility, including focus management in React, which can improve usability and reduce confusion for both keyboard-only and screenreader users.
+
7. React resources
+
Our final article provides you with a list of React resources that you can use to go further in your learning.
+
+ +

Ember tutorials

+ +
+

Note: Ember tutorials last tested in May 2020, with Ember/Ember CLI version 3.18.0.

+ +

If you need to check your code against our version, you can find a finished version of the sample Ember app code in the ember-todomvc-tutorial repository. For a running live version, see https://nullvoxpopuli.github.io/ember-todomvc-tutorial/ (this also includes a few additional features not covered in the tutorial).

+
+ +
+
1. Getting started with Ember
+
In our first Ember article we will look at how Ember works and what it's useful for, install the Ember toolchain locally, create a sample app, and then do some initial setup to get it ready for development.
+
2. Ember app structure and componentization
+
In this article we'll get right on with planning out the structure of our TodoMVC Ember app, adding in the HTML for it, and then breaking that HTML structure into components.
+
3. Ember interactivity: Events, classes and state
+
At this point we'll start adding some interactivity to our app, providing the ability to add and display new todo items. Along the way, we'll look at using events in Ember, creating component classes to contain JavaScript code to control interactive features, and setting up a service to keep track of the data state of our app.
+
4. Ember Interactivity: Footer functionality, conditional rendering
+
Now it's time to start tackling the footer functionality in our app. Here we'll get the todo counter to update to show the correct number of todos still to complete, and correctly apply styling to completed todos (i.e. where the checkbox has been checked). We'll also wire up our "Clear completed" button. Along the way, we'll learn about using conditional rendering in our templates.
+
5. Routing in Ember
+
In this article we learn about routing, or URL-based filtering as it is sometimes referred to. We'll use it to provide a unique URL for each of the three todo views — "All", "Active", and "Completed".
+
6. Ember resources and troubleshooting
+
Our final Ember article provides you with a list of resources that you can use to go further in your learning, plus some useful troubleshooting and other information.
+
+ +

Vue tutorials

+ +
+

Note: Vue tutorials last tested in May 2020, with Vue 2.6.11.

+ +

If you need to check your code against our version, you can find a finished version of the sample Vue app code in our todo-vue repository. For a running live version, see https://mdn.github.io/todo-vue/dist/.

+
+ +
+
1. Getting started with Vue
+
Now let's introduce Vue, the third of our frameworks. In this article we'll look at a little bit of Vue background, learn how to install it and create a new project, study the high-level structure of the whole project and an individual component, see how to run the project locally, and get it prepared to start building our example.
+
2. Creating our first Vue component
+
Now it's time to dive deeper into Vue, and create our own custom component — we'll start by creating a component to represent each item in the todo list. Along the way, we'll learn about a few important concepts such as calling components inside other components, passing data to them via props, and saving data state.
+
3. Rendering a list of Vue components
+
At this point we've got a fully working component; we're now ready to add multiple ToDoItem components to our App. In this artcle we'll look at adding a set of todo item data to our App.vue component, which we'll then loop through and display inside ToDoItem components using the v-for directive.
+
4. Adding a new todo form: Vue events, methods, and models
+
We now have sample data in place, and a loop that takes each bit of data and renders it inside a ToDoItem in our app. What we really need next is the ability to allow our users to enter their own todo items into the app, and for that we'll need a text <input>, an event to fire when the data is submitted, a method to fire upon submission to add the data and rerender the list, and a model to control the data. This is what we'll cover in this article.
+
5. Styling Vue components with CSS
+
The time has finally come to make our app look a bit nicer. In this article we'll explore the different ways of styling Vue components with CSS.
+
6. Using Vue computed properties
+
In this article we'll add a counter that displays the number of completed todo items, using a feature of Vue called computed properties. These work similarly to methods, but only re-run when one of their dependencies changes.
+
7. Vue conditional rendering: editing existing todos
+
Now it is time to add one of the major parts of functionality that we're still missing — the ability to edit existing todo items. To do this, we will take advantage of Vue's conditional rendering capabilities — namely v-if and v-else — to allow us to toggle between the existing todo item view, and an edit view where you can update todo item labels. We'll also look at adding functionality to delete todo items.
+
8. Focus management with Vue refs
+
We are nearly done with Vue. The last bit of functionality to look at is focus management, or put another way, how we can improve our app's keyboard accessibility. We'll look at using Vue refs to handle this — an advanced feature that allows you to have direct access to the underlying DOM nodes below the virtual DOM, or direct access from one component to the internal DOM structure of a child component.
+
9. Vue resources
+
Now we'll round off our study of Vue by giving you a list of resources that you can use to go further in your learning, plus some other useful tips.
+
+ +

Which frameworks did we choose?

+ +

We are publishing our initial set of articles with guides focusing on three of the major frameworks out there — React/ReactDOM, Ember, and Vue. There is a variety of reasons for this:

+ + + +

We want to say this up front — we've not chosen the frameworks we are focusing on because we think they are the best, or because we endorse them in any way. We just think they score highly on the above criteria.

+ +

Note that we were hoping to have more frameworks included upon intial publication, but we decided to release the content and then add more framework guides later, rather than delay it longer. If your favourite framework is not represented in this content and you'd like to help change that, feel free to discuss it with us! Get in touch with us via Matrix, or Discourse, or drop us a mail on the mdn-admins list.

diff --git a/files/ru/learn/tools_and_testing/client-side_javascript_frameworks/react_getting_started/index.html b/files/ru/learn/tools_and_testing/client-side_javascript_frameworks/react_getting_started/index.html new file mode 100644 index 0000000000..9a898b282a --- /dev/null +++ b/files/ru/learn/tools_and_testing/client-side_javascript_frameworks/react_getting_started/index.html @@ -0,0 +1,462 @@ +--- +title: Начало работы с React +slug: Learn/Tools_and_testing/Фронтенд_JavaScript_фреймворки/React_getting_started +translation_of: >- + Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_getting_started +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Main_features","Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_todo_list_beginning", "Learn/Tools_and_testing/Client-side_JavaScript_frameworks")}}
+ +

В этой статье мы скажем привет React. Мы узнаем немного подробностей о его происхождении и сценариях использования, настроим базовый набор инструментов на нашем локальном компьютере, а также создадим и поиграем с простым приложением для начинающих, и в процессе узнаем немного о том, как React работает .

+ + + + + + + + + + + + +
Что нужно знать: +

HTML, CSS, и JavaScript, быть знакомым с терминалом/коммандной строкой.

+ +

React использует синтаксис HTML-in-JavaScript под названием JSX (JavaScript и XML). Знание HTML и JavaScript поможет вам изучить JSX и лучше определить, связаны ли ошибки в вашем приложении с JavaScript или с более специфической областью React.

+
Задача: +

Настроить локальную среду разработки React, создать стартовое приложение и понять основы его работы.

+
+ +

Привет Реакт

+ +

Как гласит официальный слоган, React - это библиотека для создания пользовательских интерфейсов. React не является фреймворком – он даже не рассчитан исключительно для web. Он используется для визуализации и в связке с другими библиотеками. Например, React Native можно использовать для создания мобильных приложений; React 360 можно использовать для создания приложений виртуальной реальности; помимо того есть и другие варианты.

+ +

Для создания веб-приложений разработчики используют React в тандеме с ReactDOM. React and ReactDOM часто обсуждаются в том же пространстве и используются для решения тех же проблем, что и другие настоящие фреймворки для веб-разработки. Когда мы ссылаемся на React как на «фреймворк», мы подразумеваем это разговорное понимание.

+ +

Основная цель React - минимизировать ошибки, возникающие при разработке пользовательских интерфейсов. Это достигается за счет использования компонентов - автономных логических фрагментов кода, которые описывают часть пользовательского интерфейса. А уже эти компоненты объединяются для создания полноценного пользовательского интерфейса. React абстрагирует большую часть работы по визуализации, оставляя вам возможность сосредоточиться на дизайне.

+ +

Когда использовать

+ +

В отличие от других платформ, рассматриваемых в этом модуле, React не обязывает к строгим правилам в отношении соглашений о коде или организации файлов. Это позволяет командам договариваться, что для них более подходит, и структурировать React проект соответствующим образом. React может отвечать за одну кнопку, несколько частей или же весь пользовательский интерфейс приложения.

+ +

Хотя React можно использовать для небольших частей интерфейса, «зайти» в него не так просто, как, к примеру, в jQuery, или даже во Vue. Куда легче это сделать создав всё приложения с помощью React.

+ +

Кроме того, такие преимущества React-приложения, как написание интерфейсов с помощью JSX, требуют процесса компиляции. Добавление на сайт компилятора Babel приводит к более медленному выполнению кода, поэтому такие инструменты обычно настраиваются для процесса сборки. Да, возможно, у React есть серьезные требования к инструментарию, но этому можно освоить.

+ +

В этой статье основное внимание будет уделено использованию React для создания всего пользовательского интерфейса с помощью create-react-app, предоставляемого Facebook.

+ +

Как React использует JavaScript?

+ +

React utilizes features of modern JavaScript for many of its patterns. Its biggest departure from JavaScript comes with the use of JSX syntax. JSX extends JavaScript's syntax so that HTML-like code can live alongside it. For example:

+ +
const heading = <h1>Mozilla Developer Network</h1>;
+ +

This heading constant is known as a JSX expression. React can use it to render that <h1> tag in our app.

+ +

Suppose we wanted to wrap our heading in a <header> tag, for semantic reasons? The JSX approach allows us to nest our elements within each other, just like we do with HTML:

+ +
const header = (
+  <header>
+    <h1>Mozilla Developer Network</h1>
+  </header>
+);
+ +
+

Note: The parentheses in the previous snippet aren't unique to JSX, and don’t have any effect on your application. They're a signal to you (and your computer) that the multiple lines of code inside are part of the same expression. You could just as well write the header expression like this:

+ +
const header = <header>
+    <h1>Mozilla Developer Network</h1>
+</header>
+ +

However, this looks kind of awkward, because the <header> tag that starts the expression is not indented to the same position as its corresponding closing tag.

+
+ +

Of course, your browser can't read JSX without help. When compiled (using a tool like Babel or Parcel), our header expression would look like this:

+ +
const header = React.createElement("header", null,
+  React.createElement("h1", null, "Mozilla Developer Network")
+);
+ +

It's possible to skip the compilation step and use React.createElement() to write your UI yourself. In doing this, however, you lose the declarative benefit of JSX, and your code becomes harder to read. Compilation is an extra step in the development process, but many developers in the React community think that the readability of JSX is worthwhile. Plus, popular tooling makes JSX-to-JavaScript compilation part of its setup process. You don't have to configure compilation yourself unless you want to.

+ +

Because JSX is a blend of HTML and JavaScript, some developers find it intuitive. Others say that its blended nature makes it confusing. Once you're comfortable with it, however, it will allow you build user interfaces more quickly and intuitively, and allow others to better understand your code base at a glance.

+ +

To read more about JSX, check out the React team's JSX In Depth article.

+ +

Настройка вашего первого React приложения

+ +

There are many ways to use React, but we're going to use the command-line interface (CLI) tool create-react-app, as mentioned earlier, which expedites the process of developing a React application by installing some packages and creating some files for you, handling the tooling described above.

+ +

It's possible to add React to a website without create-react-app by copying some <script> elements into an HTML file, but the create-react-app CLI is a common starting point for React applications. Using it will allow you spend more time building your app, and less time fussing with setup.

+ +

Requirements

+ +

In order to use create-react-app, you need to have Node.js installed. It's recommended that you use the long-term support (LTS) version. Node includes npm (the node package manager), and npx (the node package runner).

+ +

You may also use the Yarn package manager as an alternative, but we'll assume you are using npm in this set of tutorials. See Package management basics for more information on npm and yarn.

+ +

If you're using Windows, you will need to install some software to give you parity with Unix/macOS terminal in order to use the terminal commands mentioned in this tutorial. Gitbash (which comes as part of the git for Windows toolset) or Windows Subsystem for Linux (WSL) are both suitable. See Command line crash course for more information on these, and on terminal commands in general.

+ +

Also bear in mind that React and ReactDOM produce apps that only work on a fairly modern set of browsers — IE9+ by way of some polyfills. It is recommended that you use a modern browser like Firefox, Safari, or Chrome when working through these tutorials.

+ +

Also see the following for more information:

+ + + +

Initializing your app

+ +

create-react-app takes one argument: the name you'd like to give your app. create-react-app uses this name to make a new directory, then creates the necessary files inside it. Make sure you cd to the place you'd like your app to live on your hard drive, then run the following in your terminal:

+ +
npx create-react-app moz-todo-react
+ +

This creates a moz-todo-react directory, and does several things inside it:

+ + + +
+

Note: if you have the yarn package manager installed, create-react-app will default to using it instead of npm. If you have both package managers installed and explicitly want to use NPM, you can add the flag --use-npm when you run create-react-app:

+ +
npx create-react-app moz-todo-react --use-npm
+
+ +

create-react-app will display a number of messages in your terminal while it works; this is normal! This might take a few minutes, so now might be a good time to go make a cup of tea.

+ +

When the process is complete, cd into the moz-todo-react directory and run the command npm start. The scripts installed by create-react-app will start being served at a local server at localhost:3000, and open the app in a new browser tab. Your browser will display something like this:

+ +

Screenshot of Firefox MacOS, open to localhost:3000, showing the default create-react-app application

+ +

Application structure

+ +

create-react-app gives us everything we need to develop a React application. Its initial file structure looks like this:

+ +
moz-todo-react
+├── README.md
+├── node_modules
+├── package.json
+├── package-lock.json
+├── .gitignore
+├── public
+│   ├── favicon.ico
+│   ├── index.html
+│   └── manifest.json
+└── src
+    ├── App.css
+    ├── App.js
+    ├── App.test.js
+    ├── index.css
+    ├── index.js
+    ├── logo.svg
+    └── serviceWorker.js
+ +

The src directory is where we'll spend most of our time, as it's where the source code for our application lives.

+ +

The public directory contains files that will be read by your browser while you're developing the app; the most important of these is index.html. React injects your code into this file so that your browser can run it. There's some other markup that helps create-react-app function, so take care not to edit it unless you know what you're doing. You very much should change the text inside the <title> element in this file to reflect the title of your application. Accurate page titles are important for accessibility!

+ +

The public directory will also be published when you build and deploy a production version of your app. We won’t cover deployment in this tutorial, but you should be able to use a similar solution to that described in our Deploying our app tutorial.

+ +

The package.json file contains information about our project that Node.js/npm uses to keep it organized. This file is not unique to React applications; create-react-app merely populates it. You don't need to understand this file at all to complete this tutorial, however, if you'd like to learn more about it, you can read What is the file `package.json`? on NodeJS.org; we also talk about it in our Package management basics tutorial.

+ +

Изучаем наш первый React компонент — <App/>

+ +

In React, a component is a reusable module that renders a part of our app. These parts can be big or small, but they are usually clearly defined: they serve a single, obvious purpose.

+ +

Let's open src/App.js, since our browser is prompting us to edit it. This file contains our first component, App, and a few other lines of code:

+ +
import React from 'react';
+import logo from './logo.svg';
+import './App.css';
+
+function App() {
+  return (
+    <div className="App">
+      <header className="App-header">
+        <img src={logo} className="App-logo" alt="logo" />
+        <p>
+          Edit <code>src/App.js</code> and save to reload.
+        </p>
+        <a
+          className="App-link"
+          href="https://reactjs.org"
+          target="_blank"
+          rel="noopener noreferrer"
+        >
+          Learn React
+        </a>
+      </header>
+    </div>
+  );
+}
+export default App;
+ +

The App.js file consists of three main parts: some import statements at the top, the App component in the middle, and an export statement at the bottom. Most React components follow this pattern.

+ +

Import statements

+ +

The import statements at the top of the file allow App.js to use code that has been defined elsewhere. Let's look at these statements more closely.

+ +
import React from 'react';
+import logo from './logo.svg';
+import './App.css';
+ +

The first statement imports the React library itself. Because React turns the JSX we write into React.createElement(), all React components must import the React module. If you skip this step, your application will produce an error.

+ +

The second statement imports a logo from './logo.svg'. Note the ./ at the beginning of the path, and the .svg extension at the end — these tell us that the file is local and that it is not a JavaScript file. Indeed, the logo.svg file lives in our source directory.

+ +

We don't write a path or extension when importing the React module — this is not a local file; instead, it is listed as a dependency in our package.json file. Be careful of this distinction as you work through this lesson!

+ +

The third statement imports the CSS related to our App component. Note that there is no variable name and no from directive. This particular import syntax is not native to JavaScript module syntax – it comes from Webpack, the tool create-react-app uses to bundle all our JavaScript files together and serve them to the browser.

+ +

The App component

+ +

After the imports, we have a function named App. Whereas most of the JavaScript community prefers camel-case names like helloWorld, React components use pascal-case variable names, like HelloWorld, to make it clear that a given JSX element is a React component, and not a regular HTML tag. If you were to rename the App function to app, your browser would show you an error.

+ +

Let's look at App more closely.

+ +
function App() {
+  return (
+    <div className="App">
+      <header className="App-header">
+        <img src={logo} className="App-logo" alt="logo" />
+        <p>
+          Edit <code>src/App.js</code> and save to reload.
+        </p>
+        <a
+          className="App-link"
+          href="https://reactjs.org"
+          target="_blank"
+          rel="noopener noreferrer"
+        >
+          Learn React
+        </a>
+      </header>
+    </div>
+  );
+}
+ +

The App function returns a JSX expression. This expression defines what your browser ultimately renders to the DOM.

+ +

Some elements in the expression have attributes, which are written just like in HTML, following a pattern of attribute="value". On line 3, the opening <div> tag has a className attribute. This the same as the class attribute in HTML, but because JSX is JavaScript, we can't use the word class – it's reserved, meaning JavaScript already uses it for a specific purpose and it would cause problems here in our code. A few other HTML attributes are written differently in JSX than they are in HTML too, for the same kind of reason. We'll cover them as we encounter them.

+ +

Take a moment to change the <p> tag on line 6 so that it reads "Hello, world!", then save your file. You'll notice that this change is immediately rendered in the development server running at http://localhost:3000 in your browser. Now delete the <a> tag and save; the "Learn React" link will be gone.

+ +

Your App component should now look like this:

+ +
function App() {
+  return (
+    <div className="App">
+      <header className="App-header">
+        <img src={logo} className="App-logo" alt="logo" />
+        <p>
+          Hello, World!
+        </p>
+      </header>
+    </div>
+  );
+}
+ +

Export statements

+ +

At the very bottom of the App.js file, the statement export default App makes our App component available to other modules.

+ +

Interrogating the index

+ +

Let’s open src/index.js, because that's where the App component is being used. This file is the entry point for our app, and it initially looks like this:

+ +
import React from 'react';
+import ReactDOM from 'react-dom';
+import './index.css';
+import App from './App';
+import * as serviceWorker from './serviceWorker';
+
+ReactDOM.render(<App />, document.getElementById('root'));
+
+// If you want your app to work offline and load faster, you can change
+// unregister() to register() below. Note this comes with some pitfalls.
+// Learn more about service workers: https://bit.ly/CRA-PWA
+serviceWorker.unregister();
+ +

As with App.js, the file starts by importing all the JS modules and other assets it needs to run. src/index.css holds global styles that are applied to our whole app. We can also see our App component imported here; it is made available for import thanks to the export statement at the bottom of App.js.

+ +

Line 7 calls React’s ReactDOM.render() function with two arguments:

+ + + +

All of this tells React that we want to render our React application with the App component as the root, or first component.

+ +
+

Note: In JSX, React components and HTML elements must have closing slashes. Writing just <App> or just <img> will cause an error.

+
+ +

Service workers are interesting pieces of code that help application performance and allow features of your web applications to work offline, but they’re not in scope for this article. You can delete line 5, as well as lines 9 through 12.

+ +

Your final index.js file should look like this:

+ +
import React from 'react';
+import ReactDOM from 'react-dom';
+import './index.css';
+import App from './App';
+
+ReactDOM.render(<App />, document.getElementById('root'));
+ +

Переменные и свойства

+ +

Next, we'll use a few of our JavaScript skills to get a bit more comfortable editing components and working with data in React. We'll talk about how variables are used inside JSX, and introduce props, which are a way of passing data into a component (which can then be accessed using variables).

+ +

Variables in JSX

+ +

Back in App.js, let’s focus on line 9:

+ +
<img src={logo} className="App-logo" alt="logo" />
+ +

Here, the <img /> tag's src attribute value is in curly braces. This is how JSX recognizes variables. React will see {logo}, know you are referring to the logo import on line 2 of our app, then retrieve the logo file and render it.

+ +

Let's try making a variable of our own. Before the return statement of App, add const subject = 'React';. Your App component should now look like this:

+ +
function App() {
+  const subject = "React";
+  return (
+    <div className="App">
+      <header className="App-header">
+        <img src={logo} className="App-logo" alt="logo" />
+        <p>
+          Hello, World!
+        </p>
+      </header>
+    </div>
+  );
+}
+ +

Change line 8 to use our subject variable instead of the word "world", like this:

+ +
function App() {
+  const subject = "React";
+  return (
+    <div className="App">
+      <header className="App-header">
+        <img src={logo} className="App-logo" alt="logo" />
+        <p>
+          Hello, {subject}!
+        </p>
+      </header>
+    </div>
+  );
+}
+ +

When you save, your browser should display "Hello, React!" instead of "Hello, world!"

+ +

Variables are convenient, but the one we've just set doesn’t make great use of React's features. That's where props come in.

+ +

Component props

+ +

A prop is any data passed into a React component. Props are written inside component calls, and use the same syntax as HTML attributes — prop="value". Let’s open index.js and give our <App/> call its first prop.

+ +

Add a prop of subject to the <App/> component call, with a value of Clarice. When you are done, your code should look something like this:

+ +
ReactDOM.render(<App subject="Clarice" />, document.getElementById('root'));
+ +

Back in App.js, let's revisit the App function itself, which reads like this (with the return statement shortened for brevity):

+ +
function App() {
+  const subject = "React";
+  return (
+    // return statement
+  );
+}
+ +

Change the signature of the App function so that it accepts props as a parameter. Just like any other parameter, you can put props in a console.log() to read it out to your browser's console. Go ahead and do that after your subject constant but before the return statement, like so:

+ +
function App(props) {
+  const subject = "React";
+  console.log(props);
+  return (
+    // return statement
+  );
+}
+ +

Save your file and check your browser's JavaScript console. You should see something like this logged:

+ +
Object { subject: "Clarice" }
+ +

The object property subject corresponds to the subject prop we added to our <App /> component call, and the string Clarice corresponds to its value. Component props in React are always collected into objects in this fashion.

+ +

Now that subject is one of our props, let's utilize it in App.js. Change the subject constant so that, instead of defining it as the string React, you are reading the value of props.subject. You can also delete your console.log() if you want.

+ +
function App(props) {
+  const subject = props.subject;
+  return (
+    // return statement
+  );
+}
+ +

When you save, the the app should now greet you with "Hello, Clarice!". If you return to index.js, edit the value of subject, and save, your text will change.

+ +

Резюме

+ +

This brings us to the end of our initial look at React, including how to install it locally, creating a starter app, and how the basics work. In the next article we'll start building our first proper application — a todo list. Before we do that, however, let's recap some of the things we’ve learned.

+ +

In React:

+ + + +

{{PreviousMenuNext("Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Main_features","Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_todo_list_beginning", "Learn/Tools_and_testing/Client-side_JavaScript_frameworks")}}

+ +

В этом модуле

+ + diff --git a/files/ru/learn/tools_and_testing/github/index.html b/files/ru/learn/tools_and_testing/github/index.html new file mode 100644 index 0000000000..f78ac2a27c --- /dev/null +++ b/files/ru/learn/tools_and_testing/github/index.html @@ -0,0 +1,84 @@ +--- +title: Гит и ГитХаб +slug: Learn/Tools_and_testing/ГитХаб +tags: + - Веб + - Начинающий + - гит +translation_of: Learn/Tools_and_testing/GitHub +--- +
{{LearnSidebar}}
+ +

Все разработчики используют ту или иную систему контроля версий (СКВ, VCS), инструмент, позволяющий им взаимодействовать с другими разработчиками на проекте без угрозы того, что кто-то перезапишет чужую работу, а также вернуться к предыдущим версиям кода при обнаружении проблем позднее.

+ +

Самая популярная СКВ (по крайней мере, среди веб-разработчиков) являюся Гит (Git), а также ГитХаб (GItHub) - сайт, обеспечивающий размещение ваших репозиториев и включащий инструменты для работы с ними. Цели этого модуля - дать вам необходимые знания о каждой из упомянутых СКВ.

+ +

Обзор

+ +

СКВ являются основой для разработки программного обеспечения:

+ + + +

СКВ обеспечивают инструменты для решения всех вышеуказанных задач. Гит является примером СКВ, а ГитХаб - это сайт, обеспечивающий веб-интерфейс для работы с гит, а также множество полезных инструментов для работы с гит-репозиториями лично или в командах, такие как фиксация проблем с кодом, инструменты для проверки кода, инструменты для управления созданием продукта, например назначение задач и их статусов, и т.д.

+ +
+

Важно: ГИТ на самом деле - распределенная система контроля версий, это значит что полная копия репозитория, содержащая всю кодовую базу сохраняется на твой компьютер (и кого-либо еще). Ты вносишь изменения в свою копию и затем отправляешь эти изменения обратно на сервер, на котором администратор решит соединять ли твои измеения  с оригиналом. 

+
+ +

Подготовка

+ +

Для использования Git и GitHub тебе необходимо:

+ + + +

Что касается предварительных знаний, вам не нужно разбираться в веб-разработке, Git / GitHub или VCS, чтобы приступить к этому модулю. Тем не менее, рекомендуется, чтобы вы разбирались в состоавлении кода, могли его писать и читать, а также сохранили пару строчек кода в своих репозиториях!

+ +

Также желательно, чтобы у вас были некоторые базовые знания о терминале, например, перемещение между каталогами, создание файлов и изменение системного PATH.

+ +
+

Важно: Github не единственный сайт / инструментарий который ты можешь использовать с Git. Есть и альтернативы, такие как GitLab, которые ты можешь попробовать, а также ты моежшь попробовать настроить свой собственный сервер Git и использовать вместо GitHub. Мы в этом курсе останвились на GitHub, чтобы показать один из рабочих способов.

+
+ +

Guides

+ +

Note that the links below take you to resources on external sites. Eventually we will are aiming to have our own dedicated Git/GitHub course, but for now, these will help you get to grips with the subject in hand.

+ +
+
Hello World (from GitHub)
+
This is a good place to start — this practical guide gets you to jump right into using GitHub, learning the basics of Git such as creating repositories and branches, making commits, and opening and merging pull requests.
+
Git Handbook (from GitHub)
+
This Git Handbook goes into a little more depth, explaining what a VCS is, what a repository is, how the basic GitHub model works, Git commands and examples, and more.
+
Forking Projects (from GitHub)
+
Forking projects is essential when you want to contribute to someone else's code. This guide explains how.
+
About Pull Requests (from GitHub)
+
A useful guide to managing pull requests, the way that your suggested code changes are delivered to people's repositories for consideration.
+
Mastering issues (from GitHub)
+
Issues are like a forum for your GitHub project, where people can ask questions and report problems, and you can manage updates (for example assigning people to fix issues, clarifying the issue, letting people know things are fixed). This articles gives you what you need to know about issues.
+
+ +
+

Note: There is a lot more that you can do with Git and GitHub, but we feel that the above represents the minimum you need to know to start using Git effectively. As you get deeper into Git, you'll start to realise that it is easy to go wrong when you start using more complicated commands. Don't worry, even professional web developers find Git confusing sometimes, and often solve problems by searching for solutions on the web, or consulting sites like Flight rules for Git and Dangit, git!

+
+ +

See also

+ + diff --git "a/files/ru/learn/tools_and_testing/\320\263\320\270\321\202\321\205\320\260\320\261/index.html" "b/files/ru/learn/tools_and_testing/\320\263\320\270\321\202\321\205\320\260\320\261/index.html" deleted file mode 100644 index f78ac2a27c..0000000000 --- "a/files/ru/learn/tools_and_testing/\320\263\320\270\321\202\321\205\320\260\320\261/index.html" +++ /dev/null @@ -1,84 +0,0 @@ ---- -title: Гит и ГитХаб -slug: Learn/Tools_and_testing/ГитХаб -tags: - - Веб - - Начинающий - - гит -translation_of: Learn/Tools_and_testing/GitHub ---- -
{{LearnSidebar}}
- -

Все разработчики используют ту или иную систему контроля версий (СКВ, VCS), инструмент, позволяющий им взаимодействовать с другими разработчиками на проекте без угрозы того, что кто-то перезапишет чужую работу, а также вернуться к предыдущим версиям кода при обнаружении проблем позднее.

- -

Самая популярная СКВ (по крайней мере, среди веб-разработчиков) являюся Гит (Git), а также ГитХаб (GItHub) - сайт, обеспечивающий размещение ваших репозиториев и включащий инструменты для работы с ними. Цели этого модуля - дать вам необходимые знания о каждой из упомянутых СКВ.

- -

Обзор

- -

СКВ являются основой для разработки программного обеспечения:

- - - -

СКВ обеспечивают инструменты для решения всех вышеуказанных задач. Гит является примером СКВ, а ГитХаб - это сайт, обеспечивающий веб-интерфейс для работы с гит, а также множество полезных инструментов для работы с гит-репозиториями лично или в командах, такие как фиксация проблем с кодом, инструменты для проверки кода, инструменты для управления созданием продукта, например назначение задач и их статусов, и т.д.

- -
-

Важно: ГИТ на самом деле - распределенная система контроля версий, это значит что полная копия репозитория, содержащая всю кодовую базу сохраняется на твой компьютер (и кого-либо еще). Ты вносишь изменения в свою копию и затем отправляешь эти изменения обратно на сервер, на котором администратор решит соединять ли твои измеения  с оригиналом. 

-
- -

Подготовка

- -

Для использования Git и GitHub тебе необходимо:

- - - -

Что касается предварительных знаний, вам не нужно разбираться в веб-разработке, Git / GitHub или VCS, чтобы приступить к этому модулю. Тем не менее, рекомендуется, чтобы вы разбирались в состоавлении кода, могли его писать и читать, а также сохранили пару строчек кода в своих репозиториях!

- -

Также желательно, чтобы у вас были некоторые базовые знания о терминале, например, перемещение между каталогами, создание файлов и изменение системного PATH.

- -
-

Важно: Github не единственный сайт / инструментарий который ты можешь использовать с Git. Есть и альтернативы, такие как GitLab, которые ты можешь попробовать, а также ты моежшь попробовать настроить свой собственный сервер Git и использовать вместо GitHub. Мы в этом курсе останвились на GitHub, чтобы показать один из рабочих способов.

-
- -

Guides

- -

Note that the links below take you to resources on external sites. Eventually we will are aiming to have our own dedicated Git/GitHub course, but for now, these will help you get to grips with the subject in hand.

- -
-
Hello World (from GitHub)
-
This is a good place to start — this practical guide gets you to jump right into using GitHub, learning the basics of Git such as creating repositories and branches, making commits, and opening and merging pull requests.
-
Git Handbook (from GitHub)
-
This Git Handbook goes into a little more depth, explaining what a VCS is, what a repository is, how the basic GitHub model works, Git commands and examples, and more.
-
Forking Projects (from GitHub)
-
Forking projects is essential when you want to contribute to someone else's code. This guide explains how.
-
About Pull Requests (from GitHub)
-
A useful guide to managing pull requests, the way that your suggested code changes are delivered to people's repositories for consideration.
-
Mastering issues (from GitHub)
-
Issues are like a forum for your GitHub project, where people can ask questions and report problems, and you can manage updates (for example assigning people to fix issues, clarifying the issue, letting people know things are fixed). This articles gives you what you need to know about issues.
-
- -
-

Note: There is a lot more that you can do with Git and GitHub, but we feel that the above represents the minimum you need to know to start using Git effectively. As you get deeper into Git, you'll start to realise that it is easy to go wrong when you start using more complicated commands. Don't worry, even professional web developers find Git confusing sometimes, and often solve problems by searching for solutions on the web, or consulting sites like Flight rules for Git and Dangit, git!

-
- -

See also

- - diff --git "a/files/ru/learn/tools_and_testing/\321\204\321\200\320\276\320\275\321\202\320\265\320\275\320\264_javascript_\321\204\321\200\320\265\320\271\320\274\320\262\320\276\321\200\320\272\320\270/index.html" "b/files/ru/learn/tools_and_testing/\321\204\321\200\320\276\320\275\321\202\320\265\320\275\320\264_javascript_\321\204\321\200\320\265\320\271\320\274\320\262\320\276\321\200\320\272\320\270/index.html" deleted file mode 100644 index 08fb977bb5..0000000000 --- "a/files/ru/learn/tools_and_testing/\321\204\321\200\320\276\320\275\321\202\320\265\320\275\320\264_javascript_\321\204\321\200\320\265\320\271\320\274\320\262\320\276\321\200\320\272\320\270/index.html" +++ /dev/null @@ -1,137 +0,0 @@ ---- -title: Понимание JavaScript-фреймворков для фронтенда -slug: Learn/Tools_and_testing/Фронтенд_JavaScript_фреймворки -translation_of: Learn/Tools_and_testing/Client-side_JavaScript_frameworks ---- -
{{LearnSidebar}}
-JavaScript-фреймворки являются неотъемлемой частью современной веб-разработки,
- -
предоставляя разработчикам проверенные и протестированные
- -
инструменты для создания масштабируемых и интерактивных веб-приложений. Многие
- -
современные компании используют фреймворки для своих решений, поэтому многие задачи связанные с разработкой клиентской части веб-приложений теперь требуют опыта работы с ними.
- -

Начинающему разработчику веб-интерфесов, может быть трудно понять, с чего начать изучение фреймворков - их выбор разнообразен, а новые появляются постоянно. В основном же они работают аналогичным образом, но делают некоторые вещи по-разному, также есть некоторые специфичные вещи, которые следует соблюдать при использовании фреймворков.

- -

Этим набором статей мы постараемся дать вам удобную отправную точку, чтобы помочь вам начать изучать основы. Мы не стремимся научить вас всему, что вам нужно знать о React / ReactDOM, или Vue, или какой-то другой конкретной среде; Документация этих фреймворков отлично выполняют эту работу. Вместо этого мы хотим сделать шаг назад и сначала ответить на более фундаментальные вопросы, такие как:

- - - -

После этого мы предоставим некоторые учебные пособия, охватывающие основы некоторых фреймворков, чтобы предоставить вам достаточно контекста, чтобы вы  могли начать углубляться в этой теме. Мы хотим, чтобы вы изучали фреймворки прагматично, не забывая о фундаментальных практиках веб-разработки, таких как, например, доступность.

- -

Начните прямо сейчас с "Введение в фронтенд фрейворки"

- -

Prerequisites

- -

You should really learn the basics of the core web languages first before attempting to move on to learning client-side frameworks — HTML, CSS, and especially JavaScript.

- -

Your code will be richer and more professional as a result, and you'll be able to troubleshoot problems with more confidence if you understand the fundamental web platform features that the frameworks are building on top of.

- -

Introductory guides

- -
-
1. Introduction to client-side frameworks
-
We begin our look at frameworks with a general overview of the area, looking at a brief history of JavaScript and frameworks, why frameworks exist and what they give us, how to start thinking about choosing a framework to learn, and what alternatives there are to client-side frameworks.
-
2. Framework main features
-
Each major JavaScript framework has a different approach to updating the DOM, handling browser events, and providing an enjoyable developer experience. This article will explore the main features of “the big 4” frameworks, looking at how frameworks tend to work from a high level, and the differences between them.
-
- -

React tutorials

- -
-

Note: React tutorials last tested in May 2020, with React/ReactDOM 16.13.1 and create-react-app 3.4.1.

- -

If you need to check your code against our version, you can find a finished version of the sample React app code in our todo-react repository. For a running live version, see https://mdn.github.io/todo-react-build/.

-
- -
-
1. Getting started with React
-
In this article we will say hello to React. We'll discover a little bit of detail about its background and use cases, set up a basic React toolchain on our local computer, and create and play with a simple starter app, learning a bit about how React works in the process.
-
2. Beginning our React todo list
-
Let's say that we’ve been tasked with creating a proof-of-concept in React – an app that allows users to add, edit, and delete tasks they want to work on, and also mark tasks as complete without deleting them. This article will walk you through putting the basic App component structure and styling in place, ready for individual component definition and interactivity, which we'll add later.
-
3. Componentizing our React app
-
At this point, our app is a monolith. Before we can make it do things, we need to break it apart into manageable, descriptive components. React doesn’t have any hard rules for what is and isn’t a component – that’s up to you! In this article we will show you a sensible way to break our app up into components.
-
4. React interactivity: Events and state
-
With our component plan worked out, it's now time to start updating our app from a completely static UI to one that actually allows us to interact and change things. In this article we'll do this, digging into events and state along the way.
-
5. React interactivity: Editing, filtering, conditional rendering
-
As we near the end of our React journey (for now at least), we'll add the finishing touches to the main areas of functionality in our Todo list app. This includes allowing you to edit existing tasks, and filtering the list of tasks between all, completed, and incomplete tasks. We'll look at conditional UI rendering along the way.
-
6. Accessibility in React
-
In our final tutorial article, we'll focus on (pun intended) accessibility, including focus management in React, which can improve usability and reduce confusion for both keyboard-only and screenreader users.
-
7. React resources
-
Our final article provides you with a list of React resources that you can use to go further in your learning.
-
- -

Ember tutorials

- -
-

Note: Ember tutorials last tested in May 2020, with Ember/Ember CLI version 3.18.0.

- -

If you need to check your code against our version, you can find a finished version of the sample Ember app code in the ember-todomvc-tutorial repository. For a running live version, see https://nullvoxpopuli.github.io/ember-todomvc-tutorial/ (this also includes a few additional features not covered in the tutorial).

-
- -
-
1. Getting started with Ember
-
In our first Ember article we will look at how Ember works and what it's useful for, install the Ember toolchain locally, create a sample app, and then do some initial setup to get it ready for development.
-
2. Ember app structure and componentization
-
In this article we'll get right on with planning out the structure of our TodoMVC Ember app, adding in the HTML for it, and then breaking that HTML structure into components.
-
3. Ember interactivity: Events, classes and state
-
At this point we'll start adding some interactivity to our app, providing the ability to add and display new todo items. Along the way, we'll look at using events in Ember, creating component classes to contain JavaScript code to control interactive features, and setting up a service to keep track of the data state of our app.
-
4. Ember Interactivity: Footer functionality, conditional rendering
-
Now it's time to start tackling the footer functionality in our app. Here we'll get the todo counter to update to show the correct number of todos still to complete, and correctly apply styling to completed todos (i.e. where the checkbox has been checked). We'll also wire up our "Clear completed" button. Along the way, we'll learn about using conditional rendering in our templates.
-
5. Routing in Ember
-
In this article we learn about routing, or URL-based filtering as it is sometimes referred to. We'll use it to provide a unique URL for each of the three todo views — "All", "Active", and "Completed".
-
6. Ember resources and troubleshooting
-
Our final Ember article provides you with a list of resources that you can use to go further in your learning, plus some useful troubleshooting and other information.
-
- -

Vue tutorials

- -
-

Note: Vue tutorials last tested in May 2020, with Vue 2.6.11.

- -

If you need to check your code against our version, you can find a finished version of the sample Vue app code in our todo-vue repository. For a running live version, see https://mdn.github.io/todo-vue/dist/.

-
- -
-
1. Getting started with Vue
-
Now let's introduce Vue, the third of our frameworks. In this article we'll look at a little bit of Vue background, learn how to install it and create a new project, study the high-level structure of the whole project and an individual component, see how to run the project locally, and get it prepared to start building our example.
-
2. Creating our first Vue component
-
Now it's time to dive deeper into Vue, and create our own custom component — we'll start by creating a component to represent each item in the todo list. Along the way, we'll learn about a few important concepts such as calling components inside other components, passing data to them via props, and saving data state.
-
3. Rendering a list of Vue components
-
At this point we've got a fully working component; we're now ready to add multiple ToDoItem components to our App. In this artcle we'll look at adding a set of todo item data to our App.vue component, which we'll then loop through and display inside ToDoItem components using the v-for directive.
-
4. Adding a new todo form: Vue events, methods, and models
-
We now have sample data in place, and a loop that takes each bit of data and renders it inside a ToDoItem in our app. What we really need next is the ability to allow our users to enter their own todo items into the app, and for that we'll need a text <input>, an event to fire when the data is submitted, a method to fire upon submission to add the data and rerender the list, and a model to control the data. This is what we'll cover in this article.
-
5. Styling Vue components with CSS
-
The time has finally come to make our app look a bit nicer. In this article we'll explore the different ways of styling Vue components with CSS.
-
6. Using Vue computed properties
-
In this article we'll add a counter that displays the number of completed todo items, using a feature of Vue called computed properties. These work similarly to methods, but only re-run when one of their dependencies changes.
-
7. Vue conditional rendering: editing existing todos
-
Now it is time to add one of the major parts of functionality that we're still missing — the ability to edit existing todo items. To do this, we will take advantage of Vue's conditional rendering capabilities — namely v-if and v-else — to allow us to toggle between the existing todo item view, and an edit view where you can update todo item labels. We'll also look at adding functionality to delete todo items.
-
8. Focus management with Vue refs
-
We are nearly done with Vue. The last bit of functionality to look at is focus management, or put another way, how we can improve our app's keyboard accessibility. We'll look at using Vue refs to handle this — an advanced feature that allows you to have direct access to the underlying DOM nodes below the virtual DOM, or direct access from one component to the internal DOM structure of a child component.
-
9. Vue resources
-
Now we'll round off our study of Vue by giving you a list of resources that you can use to go further in your learning, plus some other useful tips.
-
- -

Which frameworks did we choose?

- -

We are publishing our initial set of articles with guides focusing on three of the major frameworks out there — React/ReactDOM, Ember, and Vue. There is a variety of reasons for this:

- - - -

We want to say this up front — we've not chosen the frameworks we are focusing on because we think they are the best, or because we endorse them in any way. We just think they score highly on the above criteria.

- -

Note that we were hoping to have more frameworks included upon intial publication, but we decided to release the content and then add more framework guides later, rather than delay it longer. If your favourite framework is not represented in this content and you'd like to help change that, feel free to discuss it with us! Get in touch with us via Matrix, or Discourse, or drop us a mail on the mdn-admins list.

diff --git "a/files/ru/learn/tools_and_testing/\321\204\321\200\320\276\320\275\321\202\320\265\320\275\320\264_javascript_\321\204\321\200\320\265\320\271\320\274\320\262\320\276\321\200\320\272\320\270/react_getting_started/index.html" "b/files/ru/learn/tools_and_testing/\321\204\321\200\320\276\320\275\321\202\320\265\320\275\320\264_javascript_\321\204\321\200\320\265\320\271\320\274\320\262\320\276\321\200\320\272\320\270/react_getting_started/index.html" deleted file mode 100644 index 9a898b282a..0000000000 --- "a/files/ru/learn/tools_and_testing/\321\204\321\200\320\276\320\275\321\202\320\265\320\275\320\264_javascript_\321\204\321\200\320\265\320\271\320\274\320\262\320\276\321\200\320\272\320\270/react_getting_started/index.html" +++ /dev/null @@ -1,462 +0,0 @@ ---- -title: Начало работы с React -slug: Learn/Tools_and_testing/Фронтенд_JavaScript_фреймворки/React_getting_started -translation_of: >- - Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_getting_started ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Main_features","Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_todo_list_beginning", "Learn/Tools_and_testing/Client-side_JavaScript_frameworks")}}
- -

В этой статье мы скажем привет React. Мы узнаем немного подробностей о его происхождении и сценариях использования, настроим базовый набор инструментов на нашем локальном компьютере, а также создадим и поиграем с простым приложением для начинающих, и в процессе узнаем немного о том, как React работает .

- - - - - - - - - - - - -
Что нужно знать: -

HTML, CSS, и JavaScript, быть знакомым с терминалом/коммандной строкой.

- -

React использует синтаксис HTML-in-JavaScript под названием JSX (JavaScript и XML). Знание HTML и JavaScript поможет вам изучить JSX и лучше определить, связаны ли ошибки в вашем приложении с JavaScript или с более специфической областью React.

-
Задача: -

Настроить локальную среду разработки React, создать стартовое приложение и понять основы его работы.

-
- -

Привет Реакт

- -

Как гласит официальный слоган, React - это библиотека для создания пользовательских интерфейсов. React не является фреймворком – он даже не рассчитан исключительно для web. Он используется для визуализации и в связке с другими библиотеками. Например, React Native можно использовать для создания мобильных приложений; React 360 можно использовать для создания приложений виртуальной реальности; помимо того есть и другие варианты.

- -

Для создания веб-приложений разработчики используют React в тандеме с ReactDOM. React and ReactDOM часто обсуждаются в том же пространстве и используются для решения тех же проблем, что и другие настоящие фреймворки для веб-разработки. Когда мы ссылаемся на React как на «фреймворк», мы подразумеваем это разговорное понимание.

- -

Основная цель React - минимизировать ошибки, возникающие при разработке пользовательских интерфейсов. Это достигается за счет использования компонентов - автономных логических фрагментов кода, которые описывают часть пользовательского интерфейса. А уже эти компоненты объединяются для создания полноценного пользовательского интерфейса. React абстрагирует большую часть работы по визуализации, оставляя вам возможность сосредоточиться на дизайне.

- -

Когда использовать

- -

В отличие от других платформ, рассматриваемых в этом модуле, React не обязывает к строгим правилам в отношении соглашений о коде или организации файлов. Это позволяет командам договариваться, что для них более подходит, и структурировать React проект соответствующим образом. React может отвечать за одну кнопку, несколько частей или же весь пользовательский интерфейс приложения.

- -

Хотя React можно использовать для небольших частей интерфейса, «зайти» в него не так просто, как, к примеру, в jQuery, или даже во Vue. Куда легче это сделать создав всё приложения с помощью React.

- -

Кроме того, такие преимущества React-приложения, как написание интерфейсов с помощью JSX, требуют процесса компиляции. Добавление на сайт компилятора Babel приводит к более медленному выполнению кода, поэтому такие инструменты обычно настраиваются для процесса сборки. Да, возможно, у React есть серьезные требования к инструментарию, но этому можно освоить.

- -

В этой статье основное внимание будет уделено использованию React для создания всего пользовательского интерфейса с помощью create-react-app, предоставляемого Facebook.

- -

Как React использует JavaScript?

- -

React utilizes features of modern JavaScript for many of its patterns. Its biggest departure from JavaScript comes with the use of JSX syntax. JSX extends JavaScript's syntax so that HTML-like code can live alongside it. For example:

- -
const heading = <h1>Mozilla Developer Network</h1>;
- -

This heading constant is known as a JSX expression. React can use it to render that <h1> tag in our app.

- -

Suppose we wanted to wrap our heading in a <header> tag, for semantic reasons? The JSX approach allows us to nest our elements within each other, just like we do with HTML:

- -
const header = (
-  <header>
-    <h1>Mozilla Developer Network</h1>
-  </header>
-);
- -
-

Note: The parentheses in the previous snippet aren't unique to JSX, and don’t have any effect on your application. They're a signal to you (and your computer) that the multiple lines of code inside are part of the same expression. You could just as well write the header expression like this:

- -
const header = <header>
-    <h1>Mozilla Developer Network</h1>
-</header>
- -

However, this looks kind of awkward, because the <header> tag that starts the expression is not indented to the same position as its corresponding closing tag.

-
- -

Of course, your browser can't read JSX without help. When compiled (using a tool like Babel or Parcel), our header expression would look like this:

- -
const header = React.createElement("header", null,
-  React.createElement("h1", null, "Mozilla Developer Network")
-);
- -

It's possible to skip the compilation step and use React.createElement() to write your UI yourself. In doing this, however, you lose the declarative benefit of JSX, and your code becomes harder to read. Compilation is an extra step in the development process, but many developers in the React community think that the readability of JSX is worthwhile. Plus, popular tooling makes JSX-to-JavaScript compilation part of its setup process. You don't have to configure compilation yourself unless you want to.

- -

Because JSX is a blend of HTML and JavaScript, some developers find it intuitive. Others say that its blended nature makes it confusing. Once you're comfortable with it, however, it will allow you build user interfaces more quickly and intuitively, and allow others to better understand your code base at a glance.

- -

To read more about JSX, check out the React team's JSX In Depth article.

- -

Настройка вашего первого React приложения

- -

There are many ways to use React, but we're going to use the command-line interface (CLI) tool create-react-app, as mentioned earlier, which expedites the process of developing a React application by installing some packages and creating some files for you, handling the tooling described above.

- -

It's possible to add React to a website without create-react-app by copying some <script> elements into an HTML file, but the create-react-app CLI is a common starting point for React applications. Using it will allow you spend more time building your app, and less time fussing with setup.

- -

Requirements

- -

In order to use create-react-app, you need to have Node.js installed. It's recommended that you use the long-term support (LTS) version. Node includes npm (the node package manager), and npx (the node package runner).

- -

You may also use the Yarn package manager as an alternative, but we'll assume you are using npm in this set of tutorials. See Package management basics for more information on npm and yarn.

- -

If you're using Windows, you will need to install some software to give you parity with Unix/macOS terminal in order to use the terminal commands mentioned in this tutorial. Gitbash (which comes as part of the git for Windows toolset) or Windows Subsystem for Linux (WSL) are both suitable. See Command line crash course for more information on these, and on terminal commands in general.

- -

Also bear in mind that React and ReactDOM produce apps that only work on a fairly modern set of browsers — IE9+ by way of some polyfills. It is recommended that you use a modern browser like Firefox, Safari, or Chrome when working through these tutorials.

- -

Also see the following for more information:

- - - -

Initializing your app

- -

create-react-app takes one argument: the name you'd like to give your app. create-react-app uses this name to make a new directory, then creates the necessary files inside it. Make sure you cd to the place you'd like your app to live on your hard drive, then run the following in your terminal:

- -
npx create-react-app moz-todo-react
- -

This creates a moz-todo-react directory, and does several things inside it:

- - - -
-

Note: if you have the yarn package manager installed, create-react-app will default to using it instead of npm. If you have both package managers installed and explicitly want to use NPM, you can add the flag --use-npm when you run create-react-app:

- -
npx create-react-app moz-todo-react --use-npm
-
- -

create-react-app will display a number of messages in your terminal while it works; this is normal! This might take a few minutes, so now might be a good time to go make a cup of tea.

- -

When the process is complete, cd into the moz-todo-react directory and run the command npm start. The scripts installed by create-react-app will start being served at a local server at localhost:3000, and open the app in a new browser tab. Your browser will display something like this:

- -

Screenshot of Firefox MacOS, open to localhost:3000, showing the default create-react-app application

- -

Application structure

- -

create-react-app gives us everything we need to develop a React application. Its initial file structure looks like this:

- -
moz-todo-react
-├── README.md
-├── node_modules
-├── package.json
-├── package-lock.json
-├── .gitignore
-├── public
-│   ├── favicon.ico
-│   ├── index.html
-│   └── manifest.json
-└── src
-    ├── App.css
-    ├── App.js
-    ├── App.test.js
-    ├── index.css
-    ├── index.js
-    ├── logo.svg
-    └── serviceWorker.js
- -

The src directory is where we'll spend most of our time, as it's where the source code for our application lives.

- -

The public directory contains files that will be read by your browser while you're developing the app; the most important of these is index.html. React injects your code into this file so that your browser can run it. There's some other markup that helps create-react-app function, so take care not to edit it unless you know what you're doing. You very much should change the text inside the <title> element in this file to reflect the title of your application. Accurate page titles are important for accessibility!

- -

The public directory will also be published when you build and deploy a production version of your app. We won’t cover deployment in this tutorial, but you should be able to use a similar solution to that described in our Deploying our app tutorial.

- -

The package.json file contains information about our project that Node.js/npm uses to keep it organized. This file is not unique to React applications; create-react-app merely populates it. You don't need to understand this file at all to complete this tutorial, however, if you'd like to learn more about it, you can read What is the file `package.json`? on NodeJS.org; we also talk about it in our Package management basics tutorial.

- -

Изучаем наш первый React компонент — <App/>

- -

In React, a component is a reusable module that renders a part of our app. These parts can be big or small, but they are usually clearly defined: they serve a single, obvious purpose.

- -

Let's open src/App.js, since our browser is prompting us to edit it. This file contains our first component, App, and a few other lines of code:

- -
import React from 'react';
-import logo from './logo.svg';
-import './App.css';
-
-function App() {
-  return (
-    <div className="App">
-      <header className="App-header">
-        <img src={logo} className="App-logo" alt="logo" />
-        <p>
-          Edit <code>src/App.js</code> and save to reload.
-        </p>
-        <a
-          className="App-link"
-          href="https://reactjs.org"
-          target="_blank"
-          rel="noopener noreferrer"
-        >
-          Learn React
-        </a>
-      </header>
-    </div>
-  );
-}
-export default App;
- -

The App.js file consists of three main parts: some import statements at the top, the App component in the middle, and an export statement at the bottom. Most React components follow this pattern.

- -

Import statements

- -

The import statements at the top of the file allow App.js to use code that has been defined elsewhere. Let's look at these statements more closely.

- -
import React from 'react';
-import logo from './logo.svg';
-import './App.css';
- -

The first statement imports the React library itself. Because React turns the JSX we write into React.createElement(), all React components must import the React module. If you skip this step, your application will produce an error.

- -

The second statement imports a logo from './logo.svg'. Note the ./ at the beginning of the path, and the .svg extension at the end — these tell us that the file is local and that it is not a JavaScript file. Indeed, the logo.svg file lives in our source directory.

- -

We don't write a path or extension when importing the React module — this is not a local file; instead, it is listed as a dependency in our package.json file. Be careful of this distinction as you work through this lesson!

- -

The third statement imports the CSS related to our App component. Note that there is no variable name and no from directive. This particular import syntax is not native to JavaScript module syntax – it comes from Webpack, the tool create-react-app uses to bundle all our JavaScript files together and serve them to the browser.

- -

The App component

- -

After the imports, we have a function named App. Whereas most of the JavaScript community prefers camel-case names like helloWorld, React components use pascal-case variable names, like HelloWorld, to make it clear that a given JSX element is a React component, and not a regular HTML tag. If you were to rename the App function to app, your browser would show you an error.

- -

Let's look at App more closely.

- -
function App() {
-  return (
-    <div className="App">
-      <header className="App-header">
-        <img src={logo} className="App-logo" alt="logo" />
-        <p>
-          Edit <code>src/App.js</code> and save to reload.
-        </p>
-        <a
-          className="App-link"
-          href="https://reactjs.org"
-          target="_blank"
-          rel="noopener noreferrer"
-        >
-          Learn React
-        </a>
-      </header>
-    </div>
-  );
-}
- -

The App function returns a JSX expression. This expression defines what your browser ultimately renders to the DOM.

- -

Some elements in the expression have attributes, which are written just like in HTML, following a pattern of attribute="value". On line 3, the opening <div> tag has a className attribute. This the same as the class attribute in HTML, but because JSX is JavaScript, we can't use the word class – it's reserved, meaning JavaScript already uses it for a specific purpose and it would cause problems here in our code. A few other HTML attributes are written differently in JSX than they are in HTML too, for the same kind of reason. We'll cover them as we encounter them.

- -

Take a moment to change the <p> tag on line 6 so that it reads "Hello, world!", then save your file. You'll notice that this change is immediately rendered in the development server running at http://localhost:3000 in your browser. Now delete the <a> tag and save; the "Learn React" link will be gone.

- -

Your App component should now look like this:

- -
function App() {
-  return (
-    <div className="App">
-      <header className="App-header">
-        <img src={logo} className="App-logo" alt="logo" />
-        <p>
-          Hello, World!
-        </p>
-      </header>
-    </div>
-  );
-}
- -

Export statements

- -

At the very bottom of the App.js file, the statement export default App makes our App component available to other modules.

- -

Interrogating the index

- -

Let’s open src/index.js, because that's where the App component is being used. This file is the entry point for our app, and it initially looks like this:

- -
import React from 'react';
-import ReactDOM from 'react-dom';
-import './index.css';
-import App from './App';
-import * as serviceWorker from './serviceWorker';
-
-ReactDOM.render(<App />, document.getElementById('root'));
-
-// If you want your app to work offline and load faster, you can change
-// unregister() to register() below. Note this comes with some pitfalls.
-// Learn more about service workers: https://bit.ly/CRA-PWA
-serviceWorker.unregister();
- -

As with App.js, the file starts by importing all the JS modules and other assets it needs to run. src/index.css holds global styles that are applied to our whole app. We can also see our App component imported here; it is made available for import thanks to the export statement at the bottom of App.js.

- -

Line 7 calls React’s ReactDOM.render() function with two arguments:

- - - -

All of this tells React that we want to render our React application with the App component as the root, or first component.

- -
-

Note: In JSX, React components and HTML elements must have closing slashes. Writing just <App> or just <img> will cause an error.

-
- -

Service workers are interesting pieces of code that help application performance and allow features of your web applications to work offline, but they’re not in scope for this article. You can delete line 5, as well as lines 9 through 12.

- -

Your final index.js file should look like this:

- -
import React from 'react';
-import ReactDOM from 'react-dom';
-import './index.css';
-import App from './App';
-
-ReactDOM.render(<App />, document.getElementById('root'));
- -

Переменные и свойства

- -

Next, we'll use a few of our JavaScript skills to get a bit more comfortable editing components and working with data in React. We'll talk about how variables are used inside JSX, and introduce props, which are a way of passing data into a component (which can then be accessed using variables).

- -

Variables in JSX

- -

Back in App.js, let’s focus on line 9:

- -
<img src={logo} className="App-logo" alt="logo" />
- -

Here, the <img /> tag's src attribute value is in curly braces. This is how JSX recognizes variables. React will see {logo}, know you are referring to the logo import on line 2 of our app, then retrieve the logo file and render it.

- -

Let's try making a variable of our own. Before the return statement of App, add const subject = 'React';. Your App component should now look like this:

- -
function App() {
-  const subject = "React";
-  return (
-    <div className="App">
-      <header className="App-header">
-        <img src={logo} className="App-logo" alt="logo" />
-        <p>
-          Hello, World!
-        </p>
-      </header>
-    </div>
-  );
-}
- -

Change line 8 to use our subject variable instead of the word "world", like this:

- -
function App() {
-  const subject = "React";
-  return (
-    <div className="App">
-      <header className="App-header">
-        <img src={logo} className="App-logo" alt="logo" />
-        <p>
-          Hello, {subject}!
-        </p>
-      </header>
-    </div>
-  );
-}
- -

When you save, your browser should display "Hello, React!" instead of "Hello, world!"

- -

Variables are convenient, but the one we've just set doesn’t make great use of React's features. That's where props come in.

- -

Component props

- -

A prop is any data passed into a React component. Props are written inside component calls, and use the same syntax as HTML attributes — prop="value". Let’s open index.js and give our <App/> call its first prop.

- -

Add a prop of subject to the <App/> component call, with a value of Clarice. When you are done, your code should look something like this:

- -
ReactDOM.render(<App subject="Clarice" />, document.getElementById('root'));
- -

Back in App.js, let's revisit the App function itself, which reads like this (with the return statement shortened for brevity):

- -
function App() {
-  const subject = "React";
-  return (
-    // return statement
-  );
-}
- -

Change the signature of the App function so that it accepts props as a parameter. Just like any other parameter, you can put props in a console.log() to read it out to your browser's console. Go ahead and do that after your subject constant but before the return statement, like so:

- -
function App(props) {
-  const subject = "React";
-  console.log(props);
-  return (
-    // return statement
-  );
-}
- -

Save your file and check your browser's JavaScript console. You should see something like this logged:

- -
Object { subject: "Clarice" }
- -

The object property subject corresponds to the subject prop we added to our <App /> component call, and the string Clarice corresponds to its value. Component props in React are always collected into objects in this fashion.

- -

Now that subject is one of our props, let's utilize it in App.js. Change the subject constant so that, instead of defining it as the string React, you are reading the value of props.subject. You can also delete your console.log() if you want.

- -
function App(props) {
-  const subject = props.subject;
-  return (
-    // return statement
-  );
-}
- -

When you save, the the app should now greet you with "Hello, Clarice!". If you return to index.js, edit the value of subject, and save, your text will change.

- -

Резюме

- -

This brings us to the end of our initial look at React, including how to install it locally, creating a starter app, and how the basics work. In the next article we'll start building our first proper application — a todo list. Before we do that, however, let's recap some of the things we’ve learned.

- -

In React:

- - - -

{{PreviousMenuNext("Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Main_features","Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_todo_list_beginning", "Learn/Tools_and_testing/Client-side_JavaScript_frameworks")}}

- -

В этом модуле

- - diff --git a/files/ru/learn/understanding_domain_names/index.html b/files/ru/learn/understanding_domain_names/index.html deleted file mode 100644 index fb561cf8ea..0000000000 --- a/files/ru/learn/understanding_domain_names/index.html +++ /dev/null @@ -1,155 +0,0 @@ ---- -title: Что такое доменные имена -slug: Learn/Understanding_domain_names -tags: - - DNS - - вводная - - домен - - доменное имя - - начальный уровень -translation_of: Learn/Common_questions/What_is_a_domain_name ---- -
-

В этом материале мы обсудим доменные имена: что это такое, как они формируются и как зарегистрировать домен для себя.

-
- - - - - - - - - - - - -
Необходимые знания:Вы должны знать как работает Интернет и понимать устройтво устройство URL.
Цель:Вы узнаете, что такое доменные имена, как они работают и почему они важны.
- -

Summary

- -

Доменные имена - ключевая составляющая инфраструктуры Интернета. Они предоставляют человеко-читаемые адреса веб-серверов, доступных в Интернете.

- -

Каждый компьютер подключен к Интернету и может быть доступен через публичный {{Glossary("IP")}}-адрес, который состоит из 32 бит для IPv4 адреса (такие адреса обычно записываются в виде четырёх чисел от 0 до 255, разделённых точками (напр., 173.194.121.32) или 128 bit для IPv6 адреса (они обычно записываются в виде 8 групп по 4 шеснадцетиричных чисел, разделенных двоеточиями (напр, 2027:0da8:8b73:0000:0000:8a2e:0370:1337). Компьютеры могут легко обрабатывать эти адреса , но у живых людей уходит слишком много времени на использование таких адресов. IP-адреса также сложно запоминаются и часто меняются со временем. Для решения этой проблемы в Интернете используются человеко-читаемые адреса, называемые доменными именами.

- -

Активно изучаем

- -

В данный момент нет обучающего курса . Но вы можете помочь составить его.

- -

Глубокое погружение

- -

Структура доменных имён

- -

Доменное имя имеет простую структуру, состояющую из нескольких частей (частей может быть бесконечное количество, но на практике число уровней обычно невелико), разделенных точками и читаемых справа налево:

- -

Anatomy of the MDN domain name

- -

Каждая из этих частей предоставляет специфическую информацию о доменном имени.

- -
-
{{Glossary("TLD")}} (Корневой домен).
-
Корневой домен сообщает наиболее общую информацию. Корневой домен говорит пользователям наиболее общую информацию о службе, доступной по доменному имени. Наиболее общие корневые домены (.com, .org, .net) не требуют от веб-службы соответствия строгим критериям, но некоторые корневые домены имеют и более строгие политики. Например, локальные корневые домены, такие как .us, .fr, или .sh, могут требовать, чтобы услуги по данному адресу предоставлялись на национальном языке или физически размещались на территории страны.
-
Домены
-
Домены - это то, что следует за корневыми доменами. Домен может представлять собой что угодно, от одного знака до целого предложения. Домен сразу за корневым доменом также называют "доменом второго уровня". Доменное имя может включать неограниченное количество доменов, нет никакого ограничения только на 3 домена в составе доменного имени. Например, www.inf.ed.ac.uk - это корректное доменное имя. Тот, кто контролирует "верхнюю" часть доменного имени (например, mozilla.org), тот может создавать доменные имена более "низких" уровней (часто называемые, "поддоменами") (например, developer.mozilla.org).
-
- -

Покупка доменного имени

- -

Кто владеет доменным именем?

- -

Вы не можете “купить доменное имя”. Вы платите за право использовать доменное имя в течение одного или нескольких лет. Вы можете продлить это право и ваше продление будет иметь безусловный приоритет над заявками на домен от других желающих. Но вы никогда не владете доменным именем.

- -

Компании, называемые регистраторами, ведут реестры доменных имён, которые содержат техническую и административную информацию, связывающую вас и ваш домен.

- -
-

Примечание: Для некоторых доменных имён регистратор может отсутстовать, реестр может не вестись. Например, все домены в зоне .fire используются компанией Amazon только в собственных нуждах.

-
- -

Как найти свободное доменное имя

- -

Для того, чтобы определить, свободно или нет желаемое доменное имя, сделайте следующее,

- - - -
$ whois mozilla.org
-Domain Name:MOZILLA.ORG
-Domain ID: D1409563-LROR
-Creation Date: 1998-01-24T05:00:00Z
-Updated Date: 2013-12-08T01:16:57Z
-Registry Expiry Date: 2015-01-23T05:00:00Z
-Sponsoring Registrar:MarkMonitor Inc. (R37-LROR)
-Sponsoring Registrar IANA ID: 292
-WHOIS Server:
-Referral URL:
-Domain Status: clientDeleteProhibited
-Domain Status: clientTransferProhibited
-Domain Status: clientUpdateProhibited
-Registrant ID:mmr-33684
-Registrant Name:DNS Admin
-Registrant Organization:Mozilla Foundation
-Registrant Street: 650 Castro St Ste 300
-Registrant City:Mountain View
-Registrant State/Province:CA
-Registrant Postal Code:94041
-Registrant Country:US
-Registrant Phone:+1.6509030800
-
- -

Как вы видите, нельзя зарегистрировать доменное имя mozilla.org потому что Mozilla Foundation уже зарегистрировало его.

- -

Теперь давайте посмотрим, можно ли зарегистрировать доменное имя afunkydomainname.org:

- -
$ whois afunkydomainname.org
-NOT FOUND
-
- -

Как вы видите, домен не существует в базе данных whois (на момент написания этой статьи), соответственно, его можно зарегистрировать.

- -

Как получить доменное имя

- -

Процедура довольно проста:

- -
    -
  1. Перейдите на веб-сайт регистратора доменных имён.
  2. -
  3. Обычно там есть кнопка "Зарегистрировать домен" или что-то подобное. Нажмите её.
  4. -
  5. Заполните форму требуемыми данными. Убедитесь, что вы не опечатались в названии доменного имени. Потому что, если вы оплатите его, то будет уже поздно исправлять ошибку!
  6. -
  7. Регистратор сообщит вам, когда доменное имя будет корректно зарегистрировано. Через несколько часов все DNS-сервера обновятся и ваш домен начнёт работать.
  8. -
- -
-

Примечание: В процессе регистрации регистратор доменов спросит вас ваш реальный домашний или рабочий адрес. Обязательно заполните его корректно, потому что многие национальные регистраторы могут отменить регистрацию домена, если был указан ошибочный адрес.

-
- -

Обновление DNS

- -

Базы данных DNS хранятся на каждом DNS-сервере по всему миру и эти серверы обращаются за обновлениями к нескольким серверам, называемым “authoritative name server” или “корневой DNS-сервер”. Когда ваш регистратор создаёт или обновляет информацию о зарегистрированном домене, она должна обновиться во всех DNS-базах. Каждый DNS-сервер хранит информацию о домене фиксированное количество времени, а затем автоматически обновляет её (DNS-сервер запрашивает корневой сервер снова). Соответственно, обновление баз занимает какое-то время, пока информация о новых или измененных доменах распространяется по Интернету.

- -
-

Примечание: Это время часто называется время распространения. Тем не менее эта задержка не означает, что за это время доменное имя обновит само себя на всех серверах сверху донизу. Очень часто DNS-сервер, запрашиваемый вашим компьютером не знает конкретного домена и запрашивает о нём корневые DNS-сервера по мере требования.

-
- -

Как работает DNS-запрос?

- -

Как мы уже увидели, когда вы хотите, чтобы веб-страница отобразилась в вашем браузере, легче напечатать доменное имя, чем IP-адрес. Давайте разберем весь процесс:

- -
    -
  1. Напечатайте mozilla.org в адресной строке вашего браузера.
  2. -
  3. Ваш браузер спросит ваш компьютер, знает ли он уже, какому IP-адресу соответствует этот домен (используя локальный DNS-кэш). Если имя есть в кэше, оно транслируется в IP-адрес и браузер направляется к необходимому серверу. И всё.
  4. -
  5. Если же ваш компьютер не знает, какой IP-адрес соответствует доменному имени mozilla.org, он запрашивает DNS-сервер, чья задача - сообщить вашему компьютеру какой IP-адрес соответствует запрошенному доменному имени.
  6. -
  7. Теперь ваш компьютер знает соответствие и может взаимодействовать с сервером.
  8. -
- -

Explanation of the steps needed to obtain the result to a DNS request

- -

Следующие шаги

- -

Итак, мы поговорили о процессах и архитектуре. Время двигаться дальше.

- - diff --git a/files/ru/learn/understanding_links_on_the_web/index.html b/files/ru/learn/understanding_links_on_the_web/index.html deleted file mode 100644 index 63a22eb949..0000000000 --- a/files/ru/learn/understanding_links_on_the_web/index.html +++ /dev/null @@ -1,102 +0,0 @@ ---- -title: Разбираемся с веб ссылками -slug: Learn/Understanding_links_on_the_web -tags: - - Навигация - - инфраструктура - - начальный уровень -translation_of: Learn/Common_questions/What_are_hyperlinks ---- -
-

В данной статье мы узнаем, что такое ссылки и почему они важны.

-
- - - - - - - - - - - - -
Предварительно:Вы должны знать как работает интернет и иметь представление о разнице между веб-страницей, веб-сайтом, веб-сервером и поисковой системой.
Цель:Изучить, что такое веб-ссылки и почему они важны.
- -

Коротко

- -

Гиперссылки, в народе ссылки, являются фундаментальной основой Веба. Чтобы объяснить, что такое ссылки, мы должны обратиться к основам Веб-архитектуры. 

- -

В 1989 году Тим Бернерс-Ли (Tim Berners-Lee), создатель Веба, говорил о трёх китах, на которых стоит Веб:

- -
    -
  1. {{Glossary("URL")}}, система адресов, которая отслеживает веб-документы. 
  2. -
  3. {{Glossary("HTTP")}}, транспортный протокол, помогающий найти документы по заданным URL
  4. -
  5. {{Glossary("HTML")}}, формат документа, позволяющий встраивать гиперссылки
  6. -
- -

Как вы видите, все в Вебе крутится вокруг документов и способах обеспечения доступа к ним. Первоначальная цель Веба заключалась в предоставлении легкого инструмента доступа к текстовым документам, их чтения и навигации по ним. С тех пор Веб эволюционировал в инструмент обеспечения доступа к изображениям, видео и бинарным данным, но все эти улучшения врядли были бы возможны без тех самых трёх китов, о которых говорил Тим. 

- -

До Веба было весьма сложно получить доступ к документам и перемещаться от одного к другому. Став понятными для пользователя, URL'ы уже сделали жизнь гораздо проще, но нам довольно сложно было печатать длинный URL каждый раз, когда мы хотели получить документ. Вот тут то гиперссылки и совершили революцию. Ссылка может связать любой текст с URL, так что пользователь может моментально достигнуть цели всего лишь активируя ссылку.

- -

По умолчанию голубого цвета и подчёркнутые, ссылки выделяются из общего текста. Кликните на ссылку, чтобы активировать ее, или, если вы используете клавиатуру, перейдите на ссылку при помощи Tab и нажмите Enter.

- -

Example of a basic display and effect of a link in a web page

- -

Ссылки стали прорывом, который сделал Веб таким полезным и популярным. В остальной части этой статьи мы обсудим различные типы ссылок и их важность в современном Веб-дизайне. 

- -

Активно изучаем

- -

В данном разделе нет контента. Please, consider contributing.

- -

Глубокое погружение

- -

Как мы определили, ссылка это строка, которая связана с URL. Мы используем ссылки, чтобы с легкостью перепрыгивать с одного документа на другой. Здесь существуют некоторые нюансы, которые важно рассмотреть: 

- -

Типы ссылок

- -
-
Внутренняя ссылка
-
Ссылка между двумя веб-страницами, принадлежащими к одному веб-сайту. Без внутренных ссылок нет такого понятия как веб-сайт (конечно, если это не одностраничный сайт).
-
Внешняя ссылка
-
Ссылка с вашей веб-страницы на чью-либо другую веб-страницу. Без внешних ссылок не будет Веба, так как Веб  это сеть веб-страниц. Используйте внешние ссылки для того, чтобы предоставить информацию помимо той, что вы поддерживаете на вашем сайте. 
-
Входящие ссылки
-
Ссылка с чьей-либо веб-страницы на ваш сайт. Это внешняя ссылка наоборот. Имейте в виду, что вам не обязательно отвечать тем же кому-то, кто ссылается на ваш сайт.
-
- -

Когда вы создаёте веб-сайт, фокусируйтесь на внутренних ссылках, так как они делают ваш сайт возможным и удобным для использования. Найдите нужный баланс между большим и недостаточным количеством ссылок. Мы поговорим о дизайне навигации сайта в другой статье, но в качестве правила, каждый раз когда вы создаете веб-страницу, убедитесь, что хотя бы одна из ваших страниц ссылается на неё. С другой стороны, если на вашем сайте более чем десять страниц, добиваться того, чтобы каждая страница ссылалась друг на друга, может быть весьма контрпродуктивно. 

- -

Когда вы начинаете, вам не имеет смысла сильно волноваться о наличии внешних и входящих ссылок, но они важны, если вы хотите, чтобы поисковые системы находили ваш сайт. (См. более детальное объяснение ниже.)

- -

Якоря (Anchors)

- -

В большинстве случаев ссылки связывают две страницы вместе. Якоря (Anchors) же связывают две области одного документа. Когда вы следуете по ссылке указывающей на якорь, ваш браузер переходит с одной части текущего документа на другую, вместо загрузки нового документа. Хотя вы создаёте и используете якоря точно так же, как любые другие ссылки. 

- -

Example of a basic display and effect of an anchor in a web page

- -

Ссылки и поисковые системы

- -

Ссылки важны как для ваших пользователей, так и для поисковых систем. Каждый раз когда поисковые движки проверяют страницу, они индексируют сайт следуя по доступным ссылкам. Поисковые движки не только следуют по ссылкам, чтобы обнаружить разные страницы сайта, но также используют текст ссылки, чтобы определить поисковый запрос, который позволит найти страницу. 

- -

Итак, ссылки влияют на готовность поисковых систем сослаться на ваш сайт. Проблема в том, что активность поисковых систем сложно оценить. Компании обычно хотят, чтобы их сайты выводились первыми в результатах поиска, и многочисленные поиски решений дают нам понять, по крайней мере, следующее:

- - - -

SEO (поисковая оптимизация) - это комплекс мер для "поднятия" позиции сайтов в поисковой выдаче. Оптимизация использования ссылок на сайте является одной из ключевых в SEO.

- - - -

Следующие шаги

- -

Так что теперь, конечно, Вы захотите создать несколько веб-страниц со ссылками!

- - diff --git a/files/ru/learn/understanding_urls/index.html b/files/ru/learn/understanding_urls/index.html deleted file mode 100644 index 41fe5182c7..0000000000 --- a/files/ru/learn/understanding_urls/index.html +++ /dev/null @@ -1,161 +0,0 @@ ---- -title: Что такое URL-адрес? -slug: Learn/Understanding_URLs -tags: - - URL - - Адрес - - Порт - - Ресурс - - Якорь - - домен - - протокол -translation_of: Learn/Common_questions/What_is_a_URL ---- -
-

Данная статья описывает Единый локатор ресурсов или Uniform Resource Locators (URLs), объясняет, что это такое, и опиcывает его структуру. 

-
- - - - - - - - - - - - -
Предварительно:Вам нужно узнать как работает интернет, что такое Веб сервер and что лежит в основе веб ссылок .
Цель:Вы узнаете, что такое URL и как они работают в вебе.
- -

Введение

- -

Наряду с понятиями гипертекста и протокола HTTP, понятие URL является одной из основных концепций Всемирной паутины. Это механизм, используемый браузерами для получения любого опубликованного во Всемирной сети ресурса.

- -

URL обозначает Uniform Resource Locator. URL это лишь адрес, который выдан уникальному ресурсу в интернете. В теории, каждый корректный URL ведет на уникальный ресурс. Такими ресурсами могут быть HTML-страница, CSS-файл, изображение и т.д. На практике, существуют некоторые исключения, когда, например, URL ведет на ресурс, который больше не существует или который был перемещён. Поскольку ресурс, доступный по URL, а также сам URL обрабатываются веб-сервером, его владелец должен внимательно следить за размещаемыми ресурсами и связанными с ними URL.

- -

Активное обучение

- -

Активного обучения пока не существует. Пожайлуста подумайте, возможно Вы сможете внести свой вклад.

- -

Подробная информация

- -

Основы: анатомия URL

- -

Вот несколько примеров URL:

- -
https://developer.mozilla.org
-https://developer.mozilla.org/ru/docs/Learn/
-https://developer.mozilla.org/ru/search?q=URL
- -

Каждый из этих URLs могут быть напечатаны в адресной строке браузера, чтобы заставить его загрузить связанную страницу (ресурс).

- -

URL состоит из различных частей, некоторые из которых являются обязательными, а некоторые - факультативными. Рассмотрим наиболее важные части на примере:

- -
http://www.example.com:80/path/to/myfile.html?key1=value1&key2=value2#SomewhereInTheDocument
- -
-
Protocol
-
http:// это протокол. Он отображает, какой протокол браузер должен использовать. Обычно это HTTP-протокол или его безопасная версия - HTTPS. Интернет требует эти 2 протокола, но браузеры часто могут использовать и другие протоколы, например mailto: (чтобы открыть почтовый клиент) или ftp: для запуска передачи файлов, так что не стоит удивляться, если вы вдруг увидите другие протоколы.
-
Domaine Name
-
www.example.com это доменное имя. Оно означает, какой веб-сервер должен быть запрошен. В качестве альтернативы может быть использован и {{Glossary("IP address", "IP-адрес")}}, но это делается редко, поскольку запоминать IP сложнее, и это не популярно в интернете.
-
Port
-
:80 это порт. Он отображает технический параметр, используемый для доступа к ресурсам на веб-сервере. Обычно подразумевается, что веб-сервер использует стандартные порты HTTP-протокола (80 для HTTP и 443 для HTTPS) для доступа к своим ресурсам. В любом случае, порт - это факультативная составная часть URL.
-
Path to the file
-
/path/to/myfile.html это адрес ресурса на веб-сервере. В прошлом, адрес отображал местоположение реального файла в реальной директории на веб-сервере. В наши дни это чаще всего абстракция, позволяющая обрабатывать адреса и отображать тот или иной контент из баз данных.
-
Parameters
-
?key1=value1&key2=value2 это дополнительные параметры, которые браузер сообщает веб-серверу. Эти параметры - список пар ключ/значение, которые разделены символом &. Веб-сервер может использовать эти параметры для исполнения дополнительных команд перед тем как отдать ресурс. Каждый веб-сервер имеет свои собственные правила обработки этих параметров и узнать их можно, только спросив владельца сервера.
-
Anchor
-
#SomewhereInTheDocument это якорь на другую часть того же самого ресурса. Якорь представляет собой вид "закладки" внутри ресурса, которая переадресовывает браузер на "заложенную" часть ресурса. В HTML-документе, например, браузер может переместиться в точку, где установлен якорь; в видео- или аудио-документе браузер может перейти к времени, на которое ссылается якорь. Важно отметить, что часть URL после #, которая также известна как идентификатор фрагмента, никогда не посылается на сервер вместе с запросом.
-
- -

{{Note('Есть и другие составные части и правила, касающиеся URL, но обычно они не используются ни пользователями, ни разработчика. Поэтому не стоит о них беспокоиться, вам не обязательно их знать, чтобы формировать работоспособные URL.')}}

- -

Вам стоит представлять URL как обычный почтовый адрес: протокол обозначает почтовый транспорт, который вы собираетесь использовать,доменное имя - это город, порт - это почтовый индекс; адрес - это номер дома;параметры представляют собой дополнительную информацию, как, например, номер квартиры; и, наконец, якорь представляет собой конкретного получателя, которому вы адресуете своё письмо.

- -

Как использовать URL

- -

Каждый URL может быть напечатан напрямую в адресной строке браузера, чтобы сразу получить запрошенный ресурс. Но это только вершина айсберга!

- -

Язык {{Glossary("HTML")}} — который будет обсуждать позже — позволяет активно использовать URL для:

- - - -
-

Примечание: При указании URL-адресов для загрузки ресурсов как части страницы (например, при использовании <script>, <audio>, <img>, <video>, и т.д.), следует использовать только URL-адреса HTTP и HTTPS. Использование FTP, например, не особенно безопасно и больше не поддерживается многими браузерами.

-
- -

Другие технологии, такие как {{Glossary("CSS")}} или {{Glossary("JavaScript")}}, также активно используют URL, так что это реально основа веба.

- -

Абсолютные и относительные URL

- -

Все, что мы изучали выше - это абсолютные URL. Но так же существуют и относительные URL. Изучим их.

- -

Обязательные части URL во многом зависят от контекста, в котором используется URL. В адресной строке браузера URL не имеет никакого контекста, так что приходится вводить полный (или абсолютный) URL, такие как мы рассматривали выше. Обычно вам не требуется вводить протокол (браузер подставляет HTTP по умолчанию) и порт (который нужен только в том случае, если сервер использует нестандартный порт), но остальные части URL всё равно необходимы.

- -

Когда URL используется в документе, например в HTML-странице, ситуация отличается. Потому что браузер уже знает URL текущего документа и он может использовать эти сведения для дополнения недостающих частей любого адреса, указанного в документе. Простейший пример относительного URL - указание только адресной части URL. А если адрес в URL начинается с символа "/", браузер запросит ресурс от корня сервера, без отсылки к контексту текущего документа.

- -

Разберем это на примерах.

- -

Примеры абсолютных URL

- -
-
Полный URL (такой же, как обсуждали в начале статьи)
-
-
https://developer.mozilla.org/ru/docs/Learn
-
-
Скрыт протокол
-
-
//developer.mozilla.org/ru/docs/Learn
- -

В этом случае браузер использует тот же протокол, что использовался для загрузки текущего документа.

-
-
Скрыт домен
-
-
/ru/docs/Learn
- -

Это наиболее частый пример использования аболютного URL в HTML-документе. Браузер использует тот же протокол и то же доменное имя, как у текущего документа. Примечание: не возможно скрыть домен, не скрывая при этом протокол, только вместе.

-
-
- -

Примеры относительных URL

- -

Для лучшего понимания следующих примеров, давайте договоримся, что мы обращаемся к URL из документа, который опубликован по адресу: https://developer.mozilla.org/ru/docs/Learn

- -
-
Дочерние ресурсы
-
-
Skills/Infrastructure/Understanding_URLs
-
-
-
Поскольку URL не начинается с  /, браузер сделает попытку найти документ в поддиректории относительно текущего документа. В данном примере будет запрошен этот URL: https://developer.mozilla.org/ru/docs/Learn/Skills/Infrastructure/Understanding_URLs
-
Назад по дереву папок
-
-
../CSS/display
- -

В этом случае, мы используем команду ../  — унаследованную из файловой системы UNIX — чтобы сказать браузеру, что он должен подняться на 1 директорию вверх. Соответственно, здесь мы хотим открыть URL: https://developer.mozilla.org/ru/docs/Learn/../CSS/display, который может быть упрощен до вида: https://developer.mozilla.org/ru/docs/CSS/display

-
-
- -

Семантические URL

- -

Помимо своего технического значения, URL представляют собой человеко-читаемые записи о местоположении документов на веб-ресурсе. Они могут быть запомнены и любой может ввести их в адресную строку своего браузера. Веб создавался для людей и распространённой практикой является принцип записи URL, который называется  семантические URL.  Семантические URL используют в своём составе слова, значение которых может быть понято любым человеком, даже тем, кто не разбирается в технических нюансах.

- -

Семантика, разумеется, плохо распознаётся компьютерами. Вы наверняка видели URL, которые выглядят как куча случайных символов. Но у семантических URL есть много преимуществ:

- - - -

Следующие шаги

- - diff --git "a/files/ru/learn/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/accessibility_troubleshooting/index.html" "b/files/ru/learn/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/accessibility_troubleshooting/index.html" deleted file mode 100644 index d47abae869..0000000000 --- "a/files/ru/learn/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/accessibility_troubleshooting/index.html" +++ /dev/null @@ -1,101 +0,0 @@ ---- -title: Устранение проблем доступности -slug: Learn/Доступность/Accessibility_troubleshooting -translation_of: Learn/Accessibility/Accessibility_troubleshooting ---- -
{{LearnSidebar}}
- -
{{PreviousMenu("Learn/Accessibility/Mobile", "Learn/Accessibility")}}
- -

In the assessment for this module, we present to you a simple site with a number of accessibility issues that you need to diagnose and fix.

- - - - - - - - - - - - -
Prerequisites:Basic computer literacy, a basic understanding of HTML, CSS, and JavaScript, an understanding of the previous articles in the course.
Objective:To test basic knowledge of accessibility fundamentals.
- -

Starting point

- -

To get this assessment started, you should go and grab the ZIP containing the files that comprise the example. Decompress the contents into a new directory somewhere on your local computer.

- -

The finished assessment site should look like so:

- -

- -

You will see some differences/issues with the display of the starting state of the assessment — this is mainly due to the differences in the markup, which in turn cause some styling issues as the CSS is not applied properly. Don't worry — you'll be fixing these problems in the upcoming sections!

- -

Project brief

- -

For this project, you are presented with a fictional nature site displaying a "factual" article about bears. As it stands, it has a number of accessibility issues — your task is to explore the existing site and fix them to the best of your abilities, answering the questions given below.

- -

Color

- -

The text is difficult to read because of the current color scheme. Can you do a test of the current color contrast (text/background), report the results of the test, and then fix it by changing the assigned colors?

- -

Semantic HTML

- -
    -
  1. The content is still not very accessible — report on what happens when you try to navigate it using a screenreader.
  2. -
  3. Can you update the article text to make it easier for screenreader users to navigate?
  4. -
  5. The navigation menu part of the site (wrapped in <div class="nav"></div>) could be made more accessible by putting it in a proper HTML5 semantic element. Which one should it be updated to? Make the update.
  6. -
- -
-

Note: You'll need to update the CSS rule selectors that style the tags to their proper equivalents for the semantic headings. Once you add paragraph elements, you'll notice the styling looking better.

-
- -

The images

- -

The images are currently inaccessible to screenreader users. Can you fix this?

- -

The audio player

- -
    -
  1. The <audio> player isn't accessible to hearing impaired (deaf) people — can you add some kind of accessible alternative for these users?
  2. -
  3. The <audio> player isn't accessible to those using older browsers that don't support HTML5 audio. How can you allow them to still access the audio?
  4. -
- -

The forms

- -
    -
  1. The <input> element in the search form at the top could do with a label, but we don't want to add a visible text label that would potentially spoil the design and isn't really needed by sighted users. How can you add a label that is only accessible to screenreaders?
  2. -
  3. The two <input> elements in the comment form have visible text labels, but they are not unambiguously associated with their labels — how do you achieve this? Note that you'll need to update some of the CSS rule as well.
  4. -
- -

The show/hide comment control

- -

The show/hide comment control button is not current keyboard-accessible. Can you make it keyboard accessible, both in terms of focusing it using the tab key, and activating it using the return key?

- -

The table

- -

The data table is not currently very accessible — it is hard for screenreader users to associate data rows and columns together, and the table also has no kind of summary to make it clear what it shows. Can you add some features to your HTML to fix this problem?

- -

Other considerations?

- -

Can you list two more ideas for improvements that would make the website more accessible?

- -

Assessment

- -

If you are following this assessment as part of an organized course, you should be able to give your work to your teacher/mentor for marking. If you are self-learning, then you can get the marking guide fairly easily by asking on the discussion thread for this exercise, or in the #mdn IRC channel on Mozilla IRC. Try the exercise first — there is nothing to be gained by cheating!

- -

{{PreviousMenu("Learn/Accessibility/Mobile", "Learn/Accessibility")}}

- -

В этом модуле

- - diff --git "a/files/ru/learn/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/css_and_javascript/index.html" "b/files/ru/learn/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/css_and_javascript/index.html" deleted file mode 100644 index 31ed1cb106..0000000000 --- "a/files/ru/learn/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/css_and_javascript/index.html" +++ /dev/null @@ -1,357 +0,0 @@ ---- -title: CSS и JavaScript доступность - лучшие практики -slug: Learn/Доступность/CSS_and_JavaScript -tags: - - CSS - - JavaScript -translation_of: Learn/Accessibility/CSS_and_JavaScript ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/Accessibility/HTML","Learn/Accessibility/WAI-ARIA_basics", "Learn/Accessibility")}}
- -

CSS и JavaScript, при правильном использовании, появляется возможность получить доступный web - опыт ... или же они могут значительно навредить доступности если не правильно используются. Это статья в общих очертаниях описывает рекомендации по использованию CSS и JavaScript , это является лучшей практикой, поэтому следует учитывать для обеспечения того, чтобы даже сложное содержание было максимально доступным

- - - - - - - - - - - - -
необходимые условия:Базовая компьютерная грамотность, базовое понимание HTML, CSS, и JavaScript, и понимать (что такое доступность) what accessibility is.
Цели:Приобрести хорошую осведомленность при использовании CSS и JavaScript в ваших web документах для максимального увелечения доступности и (not detract from it)-(привет я не понял как переводится эти слова так что помогите если понимаете).
- -

CSS и JavaScript доступны?

- -

CSS и JavaScript не имеют такого же непосредственного значения для доступности как HTML, но они остаются способными для помощи или для повреждения доступности, в зависимости от того как их использовать. Другими словами, важно чтобы вы рассмотрели некоторые рекомендации для лучшей практики,чтобы убедится, что CSS JavaScript не разрушат доступность ваших документов.

- -

CSS

- -

Let's start off by looking at CSS.

- -

Correct semantics and user expectation

- -

It is possible to use CSS to make any HTML element look like anything, but this doesn't mean that you should. As we frequently mentioned in our HTML: A good basis for accessibility article, you should use the appropriate semantic element for the job, whenever possible. If you don't, it can cause confusion and usability issues for everyone, but particularly users with disabilities. Using correct semantics has a lot to do with user expectations — elements look and behave in certain ways, according to their functionality, and these common conventions are expected by users.

- -

As an example, a screen reader user can't navigate a page via heading elements if the developer hasn't appropriately used heading elements to markup the content. By the same token, a heading loses its visual purpose if you style it so it doesn't look like a heading.

- -

The rule of thumb is that you can update the styling of a page feature to fit in your design, but don't change it so much that it no longer looks or behaves as expected. The following sections summarize the main HTML features to consider.

- -

"Standard" text content structure

- -

Headings, paragraphs, lists — the core text content of your page:

- -
<h1>Heading</h1>
-
-<p>Paragraph</p>
-
-<ul>
-  <li>My list</li>
-  <li>has two items.</li>
-</ul>
- -

Some typical CSS might look like this:

- -
h1 {
-  font-size: 5rem;
-}
-
-p, li {
-  line-height: 1.5;
-  font-size: 1.6rem;
-}
- -

You should:

- - - -

See HTML text fundamentals and Styling text for more information.

- -

Emphasised text

- -

Inline markup that confers specific emphasis to the text that it wraps:

- -
<p>The water is <em>very hot</em>.</p>
-
-<p>Water droplets collecting on surfaces is called <strong>condensation</strong>.</p>
- -

You might want to add some simple coloring to your emphasised text:

- -
strong, em {
-  color: #a60000;
-}
- -

You will however rarely need to style emphasis elements in any significant way. The standard conventions of bold and italic text are very recognisable, and changing the style can cause confusion. For more on emphasis, see Emphasis and importance.

- -

Abbreviations

- -

An element that allows an abbreviation, acronym, or initialization to be associated with its expansion:

- -
<p>Web content is marked up using <abbr title="Hypertext Markup Language">HTML</abbr>.</p>
- -

Again, you might want to style it in some simple way:

- -
abbr {
-  color: #a60000;
-}
- -

The recognised styling convention for abbreviations is a dotted underline, and it is unwise to significantly deviate from this. For more on abbreviations, see Abbreviations.

- - - -

Hyperlinks — the way you get to new places on the web:

- -
<p>Visit the <a href="https://www.mozilla.org">Mozilla homepage</a>.</p>
- -

Some very simple link styling is shown below:

- -
a {
-  color: #ff0000;
-}
-
-a:hover, a:visited, a:focus {
-  color: #a60000;
-  text-decoration: none;
-}
-
-a:active {
-  color: #000000;
-  background-color: #a60000;
-}
- -

The standard link conventions are underlined and a different color (default: blue) in their standard state, another color variation when the link has previously been visited (default: purple), and yet another color when the link is activated (default: red). In addition, the mouse pointer changes to a pointer icon when links are moused over, and the link receives a highlight when focused (e.g. via tabbing) or activated. The following image shows the highlight in both Firefox (a dotted outline) and Chrome (a blue outline):

- -

- -

- -

You can be creative with link styles, as long as you keep giving users feedback when they interact with the links. Something should definitely happen when states change, and you shouldn't get rid of the pointer cursor or the outline — both are very important accessibility aids for those using keyboard controls.

- -

Form elements

- -

Elements to allow users to input data into websites:

- -
<div>
-  <label for="name">Enter your name</label>
-  <input type="text" id="name" name="name">
-</div>
- -

You can see some good example CSS in our form-css.html example (see it live also).

- -

Most of the CSS you'll write for forms will be for sizing the elements, lining up labels and inputs, and getting them looking neat and tidy.

- -

You shouldn't however deviate too much from the expected visual feedback form elements receive when they are focused, which is basically the same as links (see above). You could style form focus/hover states to make this behaviour more consistent across browsers or fit in better with your page design, but don't get rid of it altogether — again, people rely on these clues to help them know what is going on.

- -

Tables

- -

Tables for presenting tabular data.

- -

You can see a good, simple example of table HTML and CSS in our table-css.html example (see it live also).

- -

Table CSS generally serves to make the table fit better into your design and look less ugly. It is a good idea to make sure the table headers stand out (normally using bold), and use zebra striping to make different rows easier to parse.

- -

Color and color contrast

- -

When choosing a color scheme for your website, make sure that the text (foreground) color contrasts well with the background color. Your design might look cool, but it is no good if people with visual impairments like color blindness can't read your content.

- -

There is an easy way to check whether your contrast is large enough to not cause problems. There are a number of contrast checking tools online that you can enter your foreground and background colors into, to check them. For example WebAIM's Color Contrast Checker is simple to use, and provides an explanation of what you need to conform to the WCAG criteria around color contrast.

- -
-

Note: A high contrast ratio will also allow anyone using a smartphone or tablet with a glossy screen to better read pages when in a bright environment, such as sunlight.

-
- -

Another tip is to not rely on color alone for signposts/information, as this will be no good for those who can't see the color. Instead of marking required form fields in red, for example, mark them with an asterisk and in red.

- -

Hiding things

- -

There are many instances where a visual design will require that not all content is shown at once. For example, in our Tabbed info box example (see source code) we have three panels of information, but we are positioning them on top of one another and providing tabs that can be clicked to show each one (it is also keyboard accessible — you can alternatively use Tab and Enter/Return to select them).

- -

- -

Screen reader users don't care about any of this — they are happy with the content as long as the source order makes sense, and they can get to it all. Absolute positioning (as used in this example) is generally seen as one of the best mechanisms of hiding content for visual effect, because it doesn't stop screen readers from getting to it.

- -

On the other hand, you shouldn't use {{cssxref("visibility")}}:hidden or {{cssxref("display")}}:none, because they do hide content from screen readers. Unless of course, there is a good reason why you want this content to be hidden from screen readers.

- -
-

Note: Invisible Content Just for Screen Reader Users has a lot more useful detail surrounding this topic.

-
- -

Accept that users can override styles

- -

Accept that users can override your styles

- -

It is possible for users to override your styles with their own custom styles, for example:

- - - -

Users might do this for a variety of reasons. A visually impaired user might want to make the text bigger on all websites they visit, or a user with severe color deficiency might want to put all websites in high contrast colors that are easy for them to see. Whatever the need, you should be comfortable with this, and make your designs flexible enough so that such changes will work in your design. As an example, you might want to make sure your main content area can handle bigger text (maybe it will start to scroll to allow it all to be seen), and won't just hide it, or break completely.

- -

JavaScript

- -

JavaScript can also break accessibility, depending on how it is used.

- -

Modern JavaScript is a powerful language, and we can do so much with it these days, from simple content and UI updates to fully-fledged 2D and 3D games. There is no rule that says all content has to be 100% accessible to all people — you just need to do what you can, and make your apps as accessible as possible.

- -

Simple content and functionality is arguably easy to make accessible — for example text, images, tables, forms and push button that activate functions. As we looked at in our HTML: A good basis for accessibility article, the key considerations are:

- - - -

We also looked at an example of how to use JavaScript to build in functionality where it is missing — see Building keyboard accessibility back in. This is not ideal — really you should just use the right element for the right job — but it shows that it is possible in situations where for some reason you can't control the markup that is used. Another way to improve accessibility for non-semantic JavaScript-powered widgets is to use WAI-ARIA to provide extra semantics for screen reader users. The next article will also cover this in detail.

- -

Complex functionality like 3D games are not so easy to make accessible — a complex 3D game created using WebGL will be rendered on a {{htmlelement("canvas")}} element, which has no facility at this time to provide text alternatives or other information for severely visually impaired users to make use of. It is arguable that such a game doesn't really have this group of people as a part of its main target audience, and it would be unreasonable to expect you to make it 100% accessible to blind people, however you could implement keyboard controls so it is usable by non-mouse users, and make the color scheme contrasting enough to be usable by those with color deficiencies.

- -

The problem with too much JavaScript

- -

The problem often comes when people rely on JavaScript too much. Sometimes you'll see a website where everything has been done with JavaScript — the HTML has been generated by JavaScript, the CSS has been generated by JavaScript, etc. This has all kinds of accessibility and other issues associated with it, so it is not advised.

- -

As well as using the right element for the right job, you should also make sure you are using the right technology for the right job! Think carefully about whether you need that shiny JavaScript-powered 3D information box, or whether plain old text would do. Think carefully about whether you need a complex non-standard form widget, or whether a text input would do. And don't generate all your HTML content using JavaScript if at all possible.

- -

Keeping it unobtrusive

- -

You should keep unobtrusive JavaScript in mind when creating your content. The idea of unobtrusive JavaScript is that it should be used wherever possible to enhance functionality, not build it in entirely — basic functions should ideally work without JavaScript, although it is appreciated that this is not always an option. But again, a large part of it is using built-in browser functionality where possible.

- -

Good example uses of unobtrusive JavaScript include:

- - - -

As an example, we've written a quick and dirty client-side form validation example — see form-validation.html (also see the demo live). Here you'll see a simple form; when you try to submit the form with one or both fields left empty, the submit fails, and an error message box appears to tell you what is wrong.

- -

This kind of form validation is unobtrusive — you can still use the form absolutely fine without the JavaScript being available, and any sensible form implementation will have server-side validation active as well, because it is too easy for malicious users to bypass client-side validation (for example, by turning JavaScript off in the browser). The client-side validation is still really useful for reporting errors — users can know about mistakes they make instantly, rather than having to wait for a round trip to the server and a page reload. This is a definite usability advantage.

- -
-

Note: Server-side validation has not been implemented in this simple demo.

-
- -

We've made this form validation pretty accessible too. We've used {{htmlelement("label")}} elements to make sure the form labels are unambiguously linked to their inputs, so screen readers can read them out alongside:

- -
<label for="name">Enter your name:</label>
-<input type="text" name="name" id="name">
- -

We only do the validation when the form is submitted — this is so that we don't update the UI too often and potentially confuse screen reader (and possibly other) users:

- -
form.onsubmit = validate;
-
-function validate(e) {
-  errorList.innerHTML = '';
-  for(var i = 0; i < formItems.length; i++) {
-    var testItem = formItems[i];
-    if(testItem.input.value === '') {
-      errorField.style.left = '360px';
-      createLink(testItem);
-    }
-  }
-
-  if(errorList.innerHTML !== '') {
-    e.preventDefault();
-  }
-}
- -
-

Note: In this example, we are hiding and showing the error message box using absolute positioning rather than another method such as visibility or display, because it doesn't interfere with the screen reader being able to read content from it.

-
- -

Real form validation would be much more complex than this — you'd want to check that the entered name actually looks like a name, the entered age is actually a number and is realistic (e.g. not a minus number, or four digits). Here we've just implemented a simple check that a value has been filled in to each input field (if(testItem.input.value === '')).

- -

When the validation has been performed, if the tests pass then the form is submitted. If there are errors (if(errorList.innerHTML !== '')) then we stop the form submitting (using preventDefault()), and display any error messages that have been created (see below). This mechanism means that the errors will only be shown if there are errors, which is better for usability.

- -

For each input that doesn't have a value filled in when the form is submitted, we create a list item with a link and insert it in the errorList.

- -
function createLink(testItem) {
-  var listItem = document.createElement('li');
-  var anchor = document.createElement('a');
-  anchor.textContent = testItem.input.name + ' field is empty: fill in your ' + testItem.input.name + '.';
-  anchor.href = '#' + testItem.input.name;
-  anchor.onclick = function() {
-    testItem.input.focus();
-  };
-  listItem.appendChild(anchor);
-  errorList.appendChild(listItem);
-}
- -

Each link serves a dual purpose — it tells you what the error is, plus you can click on it/activate it to jump straight to the input element in question and correct your entry.

- -
-

Note: The focus() part of this example is a bit tricky. Chrome and Edge (and newer versions of IE) will focus the element when the link is clicked, without needing the onclick/focus() block. Safari will only highlight the form element with the link on its own, so needs the onclick/focus() block to actually focus it. Firefox doesn't focus the inputs properly at all in this context, so Firefox users can't take advantage of this at present (although everything else works fine). The Firefox issue should be fixed soon — work is being done to give Firefox behaviour parity with other browsers (see {{bug(277178)}}).

-
- -

In addition, the errorField is placed at the top of the source order (although it is positioned differently in the UI using CSS), meaning that users can find out exactly what's wrong with their form submissions and get to the input elements in question by going back up to the start of the page.

- -

As a final note, we have used some WAI-ARIA attributes in our demo to help solve accessibility problems caused by areas of content constantly updating without a page reload (screen readers won't pick this up or alert users to it by default):

- -
<div class="errors" role="alert" aria-relevant="all">
-  <ul>
-  </ul>
-</div>
- -

We will explain these attributes in our next article, which covers WAI-ARIA in much more detail.

- -
-

Note: Some of you will probably be thinking about that fact that HTML5 forms have built-in validation mechanisms like the required, min/minlength, and max/maxlength attributes (see the {{htmlelement("input")}} element reference for more information). We didn't end up using these in the demo because cross-browser support for them is patchy (for example IE10 and above only, no Safari support).

-
- -
-

Note: WebAIM's Usable and Accessible Form Validation and Error Recovery provides some further useful information about accessible form validation.

-
- -

Other JavaScript accessibility concerns

- -

There are other things to be aware of when implementing JavaScript and thinking about accessibility. We will add more as we find them.

- -

mouse-specific events

- -

As you will be aware, most user interactions are implemented in client-side JavaScript using event handlers, which allow us to run functions in response to certain events happening. Some events can have accessibility issues. The main example you'll come across is mouse-specific events like mouseover, mouseout, dblclick, etc. Functionality that runs in response to these events will not be accessible using other mechanisms, like keyboard controls.

- -

To mitigate such problems, you should double up these events with similar events that can be activated by other means (so-called device-independent event handlers) — focus and blur would provide accessibility for keyboard users.

- -

Let's look at an example that highlights when this could be useful. Maybe we want to provide a thumbnail image that shows a larger version of the image when it is moused over or focused (like you'd see on an e-commerce product catalog.)

- -

We've made a very simple example, which you can find at mouse-and-keyboard-events.html (see also the source code). The code features two functions that show and hide the zoomed-in image; these are run by the following lines that set them as event handlers:

- -
imgThumb.onmouseover = showImg;
-imgThumb.onmouseout = hideImg;
-
-imgThumb.onfocus = showImg;
-imgThumb.onblur = hideImg;
- -

The first two lines run the functions when the mouse pointer hovers over and stops hovering over the thumbnail, respectively. This won't allow us to access the zoomed view by keyboard though — to allow that, we've included the last two lines, which run the functions when the image is focused and blurred (when focus stops). This can be done by tabbing over the image, because we've included tabindex="0" on it.

- -

The click event is interesting — it sounds mouse-dependent, but most browsers will activate onclick event handlers after Enter/Return is pressed on a link or form element that has focus, or when such an element is tapped on a touchscreen device. This doesn't work by default however when you allow a non-default-focusable event to have focus using tabindex — in such cases you need to detect specifically when that exact key is pressed (see Building keyboard accessibility back in).

- -

Summary

- -

We hope this article has given you a good amount of detail and understanding about the accessibility issues surrounding CSS and JavaScript use on web pages.

- -

Next up, WAI-ARIA!

- -
{{PreviousMenuNext("Learn/Accessibility/HTML","Learn/Accessibility/WAI-ARIA_basics", "Learn/Accessibility")}}
- -
-

В этом модуле

- - -
diff --git "a/files/ru/learn/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/html/index.html" "b/files/ru/learn/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/html/index.html" deleted file mode 100644 index 64c19fd4d6..0000000000 --- "a/files/ru/learn/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/html/index.html" +++ /dev/null @@ -1,537 +0,0 @@ ---- -title: 'HTML: Хорошая основа для доступности' -slug: Learn/Доступность/HTML -tags: - - HTML - - a11y - - Клавиатура - - Кнопки - - Начинающий - - Семантика - - Ссылки - - Формы - - вспомагательные технологии - - доступность -translation_of: Learn/Accessibility/HTML ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/Accessibility/What_is_Accessibility","Learn/Accessibility/CSS_and_JavaScript", "Learn/Accessibility")}}
- -

Большая часть содержимого интернета может быть сделана доступной просто благодаря использованию правильных HTML элементов по назначению. В этой статье подробно рассмотрено как HTML может быть использован для обеспечения максимальной доступности.

- - - - - - - - - - - - -
Необходимые знания:Базовая компьютерная грамотность, базовое понимание HTML (смотрите Введение в HTML), и понимания, что такое доступность.
Цель: -

Познакомиться с тем, какие особенности HTML способствуют доступности, и как использовать их на ваших веб-страницах должным образом.

-
- -

HTML и доступность

- -

По мере изучения HTML: чтения статей, просмотра примеров и т.д., вы заметите одну общую тему — важность использования семантического HTML (иногда называемого POSH (Plain Old Semantic HTML), или «старый добрый семантический HTML»). Это означает использование HTML элементов по назначению насколько это возможно.

- -

Вы спросите, почему это так важно?  В конце концов, можно использовать комбинацию CSS и JavaScript, чтобы заставить почти любой HTML элемент вести себя так, как вы захотите. Например, кнопка для воспроизведения видео на вашем сайте может быть обозначена вот так:

- -
<div>Воспроизвести видео</div>
- -

Но, как вы увидите далее, в данном случае намного логичнее использовать правильный элемент:

- -
<button>Воспроизвести видео</button>
- -

HTML элементы <button> не только имеют соответствующие кнопке стили по-умолчанию (которые вы скорее всего захотите переписать), они также имеют встроенную доступность с клавиатуры: между ними можно передвигаться с помощью кнопки Tab и активировать, используя Enter.

- -

Вёрстка с помощью семантического HTML не займёт больше времени, чем с помощью не семантического (плохого) HTML, если делать это последовательно с самого начала проекта, и это также имеет другие преимущества помимо доступности:

- -
    -
  1. Легче разрабатывать — как сказано выше, вы получаете функционал «из коробки», плюс проще для восприятия.
  2. -
  3. Лучше для мобильных — семантический HTML легче по размеру, чем не семантический спаггети-код, и его легче сделать адаптивным.
  4. -
  5. Хорошо для SEO — поисковики уделяют больше внимания ключевым словам внутри заголовков, ссылок и т.д., чем ключевым словам, помещённым в не семантический <div> и т.д., поэтому клиентам будет проще найти ваш сайт.
  6. -
- -

Давайте рассмотрим доступный HTML более детально.

- -
-

Примечание: Желательно, чтобы у вас был установлен скринридер, чтобы вы могли тестировать примеры, приведённые ниже. Посмотрите наше Руководство по скринридерам для более подробной информации.

-
- -

Хорошая семантика

- -

Мы уже говорили о важности хорошей семантики, и почему нам стоит использовать HTML элементы по назначению. Это нельзя игнорировать, поскольку это одно из основных мест, где ломается доступность из-за плохой семантики, если должным образом не уделять внимания.

- -

В интернете люди делают очень странные вещи с HTML разметкой. Некоторые злоупотребляют HTML, используя устаревшие практики, которые не были полностью забыты, а некоторые просто не знают. В любом случае, вам стоит заменить по возможности плохой код, где бы вы его не увидели.

- -

У вас не всегда есть возможность избавиться от плохой вёрстки: ваши страницы могут быть сгенерированы каким-нибудь фреймворком на стороне сервера, над которым у вас нет полного контроля, или на страницах есть сторонний контент (такой как рекламные баннеры), которые вы также не контролируете.

- -

Цель не «всё или ничего», однако — каждое улучшение, которое вам под силу сделать, поможет обеспечить доступность.

- -

Текстовый контент

- -

Одно из самых лучших вспомогательных средств доступности для пользователя скринридера — хорошая структура заголовков, параграфов, список и т.д. Пример хорошей семантики может выглядеть так:

- -
<h1>Мой заголовок</h1>
-
-<p>Это первый раздел моей страницы.</p>
-
-<p>Я добавлю ещё один параграф тут.</p>
-
-<ol>
-  <li>Это</li>
-  <li>список для</li>
-  <li>чтения</li>
-</ol>
-
-<h2>Мой подзаголовок</h2>
-
-<p>Это первый подраздел моей страницы. Я бы хотела, чтобы люди могли найти этот контент!</p>
-
-<h2>Мой второй подзаголовок</h2>
-
-<p>Это второй подраздел. Думаю, он намного интереснее, чем предыдущий.</p>
- -

Мы подготовили версию с длинными текстом, чтобы вы попробовали со скринридером (смотрите good-semantics.html). Если вы попробуете поперемещаться, то увидите, как легко ориентироваться на странице:

- -
    -
  1. Скринридер озвучивает каждый заголовок по мере перемещения, оповещая вас, что является заголовком, а что параграфом. 
  2. -
  3. Он останавливается после каждого элемента, позволяя вам переместиться в любое другое место, которое вам надо.
  4. -
  5. Во многих скринридерах Вы можете перемещаться к следующему/предыдущему заголовкам.
  6. -
  7. Во многих скринридерах Вы также можете вызвать список всех заголовков, который можно использовать как содержание, чтобы найти определённую информацию. 
  8. -
- -

Иногда люди используют презентационные элементы HTML и перенос строки, чтобы написать заголовки или параграфы:

- -
<font size="7">Мой заголовок</font>
-<br><br>
-Это первый раздел моей страницы.
-<br><br>
-Я добавлю ещё один параграф тут.
-<br><br>
-1. Это
-<br><br>
-2. список для
-<br><br>
-3. чтения
-<br><br>
-<font size="5">Мой подзаголовок</font>
-<br><br>
-Это первый подраздел моей страницы. Я бы хотела, чтобы люди могли найти этот контент!
-<br><br>
-<font size="5">Мой второй подзаголовок</font>
-<br><br>
-Это второй подраздел. Думаю, он намного интереснее, чем предыдущий.
- -

Если вы попробуете полную версию с помощью скринридера (смотрите bad-semantics.html), вам не слишком это понравится: скринридеру нечего использовать как ориентир, поэтому вы не сможете получить содержание, а вся страница для скринридера — это один большой блок, поэтому он озвучит всё за один раз, без остановок. 

- -

Есть и другие проблемы, помимо доступности — сложнее стилизовать контент, используя CSS, или манипулировать им с помощью JavaScript, например, потому что  там нет элементов, которые можно использовать как селекторы.

- -

Использование понятного языка

- -

Язык, который вы используете, также может влиять на доступность. В целом, лучше использовать понятный язык, который не слишком сложный, и который не использует ненужные жаргоны и сленг. Это помогает не только людям с когнитивными или другими нарушениями, но и читателям, для которых текст написан не на родном языке, молодым людям... на самом деле всем! Кроме этого, стоит избегать использование языка и символов, которые не могут быть чётко озвучено скринридером. Например:

- - - -

Вёрстка

- -

В старые недобрые времена, люди верстали с помощью HTML-таблиц: использовали различные табличные ячейки для размещения шапки, подвала, боковую панель, колонку с основным контентом и т.д. Это плохая идея, потому что скринридер, скорее всего, выдаст непонятную озвучку, особенно, если раскладка сложная и имеет много вложенных таблиц.

- -

Посмотрите пример табличной вёрстки, открыв table-layout.html, которая выглядит примерно так:

- -
<table width="1200">
-      <!-- main heading row -->
-      <tr id="heading">
-        <td colspan="6">
-
-          <h1 align="center">Шапка</h1>
-
-        </td>
-      </tr>
-      <!-- nav menu row  -->
-      <tr id="nav" bgcolor="#ffffff">
-        <td width="200">
-          <a href="#" align="center">Главная</a>
-        </td>
-        <td width="200">
-          <a href="#" align="center">Наша команда</a>
-        </td>
-        <td width="200">
-          <a href="#" align="center">Проекты</a>
-        </td>
-        <td width="200">
-          <a href="#" align="center">Контакты</a>
-        </td>
-        <td width="300">
-          <form width="300">
-            <input type="search" name="q" placeholder="Поиск" width="300">
-          </form>
-        </td>
-        <td width="100">
-          <button width="100">Вперёд!</button>
-        </td>
-      </tr>
-      <!-- spacer row -->
-      <tr id="spacer" height="10">
-        <td>
-
-        </td>
-      </tr>
-      <!-- main content and aside row -->
-      <tr id="main">
-        <td id="content" colspan="4" bgcolor="#ffffff">
-
-          <!-- основной контент -->
-        </td>
-        <td id="aside" colspan="2" bgcolor="#ff80ff" valign="top">
-          <h2>Связанный контент</h2>
-
-          <!-- второстепенный контент -->
-
-        </td>
-      </tr>
-      <!-- spacer row -->
-      <tr id="spacer" height="10">
-        <td>
-
-        </td>
-      </tr>
-      <!-- footer row -->
-      <tr id="footer" bgcolor="#ffffff">
-        <td colspan="6">
-          <p>© 2050 никто. Все права защищены.</p>
-        </td>
-      </tr>
-    </table>
- -

Если вы попробуете поперемещаться с помощью скринридера, вероятно, он скажет вам, что перед вами таблица (хотя некоторые скринридеры могу различать табличную вёрстку от таблиц данных). После этого, скорее всего (в зависимости от того, какой скринридер вы используете), вам придётся переместиться в таблицу как в объект, посмотрев каждый элемент по отдельности, затем выйти из таблицы, чтобы продолжить перемещение по контенту.

- -

Табличная вёрстка — пережиток прошлого, который имел смысл, когда поддержка CSS не была сильно распространена среди браузеров, но она создаёт путаницу среди пользователей скринридеров, и плоха по многим другим причинам (злоупотребление таблицами, пожалуй, требует больше разметки, делает дизайн менее гибким). Не делайте так!

- -

Вы можете проверить эти утверждения, сравнив предыдущий опыт с более современной структурой веб-сайта, которая выглядит так:

- -
<header>
-  <h1>Шапка</h1>
-</header>
-
-<nav>
-  <!-- основная навигация -->
-</nav>
-
-<!-- Основной контент нашей страницы -->
-<main>
-
-  <!-- На ней есть статьи -->
-  <article>
-    <h2>Заголовок статьи</h2>
-
-    <!-- сама статья -->
-  </article>
-
-  <aside>
-    <h2>Связанный контент</h2>
-
-    <!-- второстепенный контент -->
-  </aside>
-
-</main>
-
-<!-- А здесь наш основной подвал, который используется на всех страницах нашего сайта -->
-
-<footer>
-  <!-- здесь содержимое подвала -->
-</footer>
- -

Если вы попробуете нашу более современную структуру с помощью скринридера, вы увидите, что разметка больше не сбивает с толку скринридер. Она также более компактная с точки зрения размера кода, что означает, его легче поддерживать, а пользователям меньше скачивать (особенно для тех, у кого медленный интенет).

- -

На что ещё стоит обратить внимание при вёрстке — это использование семантических HTML5 элементов, которые можно увидеть в примере выше (смотрите секционирование содержания): вы можно верстать, используя только вложенные {{htmlelement("div")}} элементы, но лучше использовать соответствующие секционные элементы, чтобы обернуть вашу основную навигацию ({{htmlelement("nav")}}), футер ({{htmlelement("footer")}}), повторяющийся контент ({{htmlelement("article")}}) и т.д. Эти элементы предоставляют дополнительную семантику для скринридеров (и других инструментов), чтобы давать пользователю дополнительную информацию о контенте, по которому они перемещаются (смотрите статью Screen Reader Support for new HTML5 Section Elements для представления поддержки этих элементов с помощью скринридеров).

- -
-

Примечание: Помимо того, что ваш контент имеет семантическую и красивую разметку, он должен иметь логический порядок в его исходном коде — позже вы всегда можете разместить элементы там, где хотите, с помощью CSS, но располагать элементы в правильном порядке нужно в самом начале, чтобы то, что зачитывает пользователям скринридер, имело смысл.

-
- -

Элементы интерфейса

- -

Под элементами интерфейса мы подразумеваем основные элементы веб-страниц, с которыми взаимодействует пользователь, в основном это кнопки, ссылки и элементы форм. В этом разделе мы рассмотрим основные проблемы доступности, которые стоит учитывать при создании таких элементов. В следующих статьях про WAI-ARIA и мультимедиа мы рассмотрим другие аспекты доступности пользовательского интерфейса.

- -

Одним из ключевых аспектов доступуности элементов интерфейса является то, что браузеры по-умолчанию позволяют управлять ими с помощью клавиатуры. Вы можете проверить это, открыв в новой вкладке native-keyboard-accessibility.html (смотрите исходный код). Попробуйте понажимать клавишу Tab, после нескольких нажатий вы заметите, что фокус перемещается по всем фокусируемым элементам. Сфокусированные элеметы подсвечиваются браузерными стилями по-умолчанию (в зависимости от браузера они немного разные), чтобы можно было понять, какой элемент в фокусе.

- -

- -

Вы можете нажать Enter, чтобы перейти по сфокусированной ссылке или нажать кнопку (мы добавили немного JavaScript, чтобы кнопки выводили окно с сообщением), или начать печатать в текстовом поле (другие элементы формы имеют разное управление, например, у элемента {{htmlelement("select")}} можно отобразить опции и переключаться между ними, используя клавиши-стрелки вверх и вниз).

- -
-

Примечание: Различные браузеры могут иметь разное управление с клавиатуры. Для более подробной информации смотрите Using native keyboard accessibility.

-
- -

Такое поведение вы получаете сразу по-умолчанию, просто используя правильные элементы, например:

- -
<h1>Ссылки</h1>
-
-<p>Это ссылка ведёт на сайт <a href="https://www.mozilla.org">Mozilla</a>.</p>
-
-<p>Другая ссылка на <a href="https://developer.mozilla.org">Mozilla Developer Network</a>.</p>
-
-<h2>Кнопки</h2>
-
-<p>
-  <button data-message="Это из первой кнопки">Нажми меня!</button>
-  <button data-message="Это из второй кнопки">Меня тоже нажми!</button>
-  <button data-message="Это из третьей кнопки">И меня!</button>
-</p>
-
-<h2>Форма</h2>
-
-<form>
-  <div>
-    <label for="name">Укажите ваше имя:</label>
-    <input type="text" id="name" name="name">
-  </div>
-  <div>
-    <label for="age">Укажите ваш возраст:</label>
-    <input type="text" id="age" name="age">
-  </div>
-  <div>
-    <label for="mood">Выберите ваше настроение:</label>
-    <select id="mood" name="mood">
-      <option>Счастливый</option>
-      <option>Грустный</option>
-      <option>Злой</option>
-      <option>Обеспокоенный</option>
-    </select>
-  </div>
-</form>
- -

Это предполагает использование соответствующим образом ссылок, кнопок, элементов форм и меток (включая элемент {{htmlelement("label")}} для элементов форм).

- -

Однако, опять же, люди иногда делают странные вещи с HTML. Например, иногда вы видите кнопки, размеченные с помощью элемента {{htmlelement("div")}}:

- -
<div data-message="Это из первой кнопки">Нажми меня!</div>
-<div data-message="Это из второй кнопки">Меня тоже нажми!</div>
-<div data-message="Это из третьей кнопки">И меня!</div>
- -

Такой код не советуется использовать: вы сразу же теряете нативную доступность с клавиатуры, которая у вас была бы, если просто использовать элемент {{htmlelement("button")}}, к тому же {{htmlelement("div")}} по-умолчанию не имеет кнопочных стилей.

- -

Добавление доступности с клавиатуры

- -

Для добавления доступности с клавиатуры несоответствующим элементам придётся немного поработать (вы можете посмотреть пример, открыв  fake-div-buttons.html, а также исходный код). Мы дали нашим поддельным <div>-кнопкам возможность фокусироваться (в том числе через Tab), указав аттрибут tabindex="0":

- -
<div data-message="Это из первой кнопки" tabindex="0">Кликни меня!</div>
-<div data-message="Это из второй кнопки" tabindex="0">Меня тоже кликни!</div>
-<div data-message="Это из третьей кнопки" tabindex="0">И меня!</div>
- -

Аттрибут {{htmlattrxref("tabindex")}} в первую очередь предназначен для того, чтобы менять порядок фокусируемых элементов в последовательной навигации (указанный в виде положительного целого числа). Это почти всегда — плохая идея, которая может вызвать большую путаницу. Используйте его, если он правда необходим, например, если визуальный порядок сильно отличается от исходного, и вы хотите более логичную последовательную навигацию. Есть два варианта значений tabindex:

- - - -

Хотя дополнение, которые мы сделали, позволяет нам перемещаться по кнопкам с помощью Tab, оно не позволяет нам активировать их кнопкой Enter. Для этого нам необходимо добавить хитрый кусочек JavaScript:

- -
document.onkeydown = function(e) {
-  if(e.keyCode === 13) { // Кнопка Enter
-    document.activeElement.click();
-  }
-};
- -

Мы навешиваем обработчик событий на document для обнаружения нажатий с клавиатуры. Далее, через свойство объекта события keyCode, проверяем, какая кнопка была нажата. Если код клавиши совпадает с кодом клавиши Enter, мы выполняем функцию, которая хранится в обработчике кнопки onclick, используя document.activeElement.click(). activeElement возвращает текущий сфокусированный элемент.

- -

Слишком много дополнительной мороки с добавлением такой функциональности. И обязательно будут ещё проблемы. Лучше просто сразу использовать правильные элементы по назначению.

- -

Содержательные текстовые метки

- -

Текстовые метки (описания) для элементов интерфейса полезны всем пользователям, но их правильное описание — особенно важно для пользователей с ограниченными способностями.

- -

Вы должны следить за тем, чтобы кнопки и ссылки имели понятные и уникальные текстовые описания. Не используйте фразу «Кликните здесь», потому что пользователи скринридеров иногда вызывают список кнопок и элементов форм. В примере ниже можно увидеть такой список, вызванный из VoiceOver на Mac.

- -

- -

Удостоверьтесь, что описания вне контекста имеют смысл, так же как и в контексте параграфа, в котором они содержаться. Например, вот хороший текст для ссылки:

- -
<p>Киты очень классные существа. <a href="whales.html">Узнай больше о китах</a>.</p>
- -

а это плохой текст для ссылки:

- -
<p>Киты очень классные существа. Чтобы узнать больше о китах, <a href="whales.html">нажмите здесь</a>.</p>
- -
-

Примечание: Более подробно о создании ссылок и лучших практиках можно почитать в статье «Создание ссылок». Также посмотреть на примеры хороших и плохих ссылок можно на good-links.html и bad-links.html

-
- -

Описания форм также важны для понимания, что нужно вводить в каждое текстовое поле. Следующий пример кажется достаточно разумным:

- -
Укажите ваше имя: <input type="text" id="name" name="name">
- -

Однако, это не совсем удобно для пользователей с ограниченными возможностями. В примере нет ничего, что могло бы однозначно связать описание текстового поля с самим текстовым полем, и чётко указать, как его заполнить, если вы не можете видеть. Если бы вы воспользовались скринридером, скорее всего он озвучил описание примерно как «редактировать текст».

- -

Следующий пример намного лучше:

- -
<div>
-  <label for="name">Укажите ваше имя:</label>
-  <input type="text" id="name" name="name">
-</div>
- -

С такой разметкой описание будет явно связано с текстовым полем, и будет звучать как «Укажите ваше имя: редактировать текст».

- -

- -

Как бонус, в большинстве браузеров привязка описания к полю ввода означает, что вы можете щелкнуть по описанию, чтобы выбрать/активировать элемент формы. Это облегчает нажатие на элемент формы из-за увеличенной зоны нажатия.

- -
-

Примечание: Посмотреть на хорошие и плохие пример форм можно на good-form.html и bad-form.html.

-
- -

Доступные таблицы

- -

Обычные таблицы с данными можно сверстать очень простой разметкой, например:

- -
<table>
-  <tr>
-    <td>Имя</td>
-    <td>Возраст</td>
-    <td>Пол</td>
-  </tr>
-  <tr>
-    <td>Гавриил</td>
-    <td>13</td>
-    <td>Мужской</td>
-  </tr>
-  <tr>
-    <td>Эвелина</td>
-    <td>8</td>
-    <td>Женский</td>
-  </tr>
-  <tr>
-    <td>Фрида</td>
-    <td>5</td>
-    <td>Женский</td>
-  </tr>
-</table>
- -

Но есть проблемы — пользователи скринридера никак не смогут связать вместе строки или столбцы в группу данных. Чтобы это сделать, нужно знать какие из строк являются заголовками, и озаглавливают ли они строки, столбцы и т.д. Для таблицы выше это можно определить только визуально (попробуйте сами на примере, открыв bad-table.html).

- -

Теперь посмотрим на пример таблицы с панк-группами, где можно увидеть несколько вспомогательных средств:

- - - -
-

Примечание: Более подробную информацию о доступных таблицах можно узнать в статье HTML-таблицы: продвинутые возможности и доступность.

-
- -

Альтернативный текст

- -

В то время как текстовый контент доступен по-умолчанию, этого нельзя сказать о мультимедийном контенте — изображения/видео-контент не может быть просмотрен людьми с нарушениями зрения, а аудио контент не может быть услышан людьми с нарушениями слуха. Мы подробно рассмотрим видео и аудио контент в статье о доступности мультимедиа позже, но в этой статье мы рассмотрим доступность для простого элемента {{htmlelement("img")}}.

- -

У нас есть простой пример, accessible-image.html, который содержит четыре копии одного и того же изображения:

- -
<img src="dinosaur.png">
-
-<img src="dinosaur.png"
-     alt="Красный тираннозавр Рекс: стоящий как человек двуногий динозавр, с маленькими передними лапами и большой головой с большим количеством острых зубов.">
-
-<img src="dinosaur.png"
-     alt="Красный тираннозавр Рекс: стоящий как человек двуногий динозавр, с маленькими передними лапами и большой головой с большим количеством острых зубов."
-     title="Красный динозавр Mozilla">
-
-
-<img src="dinosaur.png" aria-labelledby="dino-label">
-
-<p id="dino-label">Красный тираннозавр Рекс Mozilla: стоящий как человек двуногий динозавр, с маленькими передними лапами и большой головой с большим количеством острых зубов.</p>
-
- -

Первое изображение, когда оно просматривается программой чтения с экрана, не очень помогает пользователю — например, VoiceOver озвучивает его как «/dinosaur.png, image». Он озвучивает имя файла, чтобы попытаться помочь. В этом примере пользователь, по крайней мере, будет знать, что это какой-то динозавр, но часто файлы могут загружаться с программно-генерируемыми именами (например, с цифровой камеры), и эти имена файлов, скорее всего, не обеспечат контекста для содержимого изображения.

- -
-

Примечание: Вот почему вы никогда не должны включать текстовое содержимое в изображение — скринридеры просто не могут получить к нему доступ.Есть и другие недостатки — вы не можете выбрать его и скопировать/вставить. Просто не делайте этого!

-
- -

Когда скринридер встретит второе изображение, он озвучит аттрибут alt полностью: «Красный тираннозавр Рекс: стоящий как человек двуногий динозавр, с маленькими передними лапами и большой головой с большим количеством острых зубов».

- -

Это подчёркивает важность не только использования содержательных файловых имён в случаях отсутствия, так называемого, альтернативного текста, но также важность предоставления альтернативного текста в аттрибуте alt, где это возможно. Заметьте, что содержание аттрибута alt должно всегда предоставлять прямое представление изображения и то, что оно визуально передаёт. Любые личные знания или дополнительное описание не должны быть включены, так как это не принесёт пользы людям, которые не видели изображение ранее.

- -

Также стоит учитывать, имеют ли изображения значение внутри вашего контента, или они исключительно для украшения без смысла. Если они декоративные, лучше оставить значение аттрибута alt пустым (смотрите «Пустые аттрибуты alt») или просто вставить их как фон с помощью CSS.

- -
-

Примечание: Для более подробной информации об изображениях и лучших практиках читайте «Изображения в HTML» и «Адаптивные изображения».

-
- -

Если вы всё же хотите предоставить дополнительную контекстуальную информацию, поместите её в тексте рядом с изображением или внутри аттрибута title, как показано ниже. В этом случае большинство скринридеров озвучат альтернативный текст, аттрибут title и имя файла. Дополнительно, при наведении мышкой браузеры отобразят текст из аттрибута title как всплывающую подсказку.

- -

- -

Давайте взглянем на четвёртый способ:

- -
<img src="dinosaur.png" aria-labelledby="dino-label">
-
-<p id="dino-label">Красный тираннозавр Mozilla ... </p>
- -

В этом случае мы вообще не используем аттрибут alt. Вместо этого мы представили наше описание изображения как обычный параграф, указали id, и потом использовали аттрибут aria-labelledby, сославшись на тот id. Это вынуждает скринридеры использовать параграф как альтернативный текст/описание изображения. Это особенно удобно, если вы хотите использовать один текст как описание для нескольких изображений, что невозомжно с помощью аттрибута alt.

- -
-

Примечание: aria-labelledby — часть спецификации WAI-ARIA, которая позволяет разработчиками добавлять, где требуется, дополнительную семантику разметке для улучшения доступности при использовании скринридеров. Чтобы узнать больше о том, как это работает, читайте статью «Основы WAI-ARIA».

-
- -

Другие механизмы альтернативного текста

- -

У изображений есть ещё один механизм для предоставления описательного текста. Например, есть аттрибут longdesc, который предназначен для указания отдельной веб-страницы, содержащей расширенное описание изображения:

- -
<img src="dinosaur.png" longdesc="dino-info.html">
- -

Звучит, как хорошая идея, особенно для такой инфографики как диаграммы с большим количеством информации, которую, в качестве альтернативы, можно представить в виде доступной таблицы с данными (смотрите предыдущий раздел). Однако, longdesc нестабильно поддерживается скринридерами, и контент полностью недоступен пользователям, которые не используют скринридеры. Пожалуй, намного лучше будет вставить длинное описание на страницу вместе с изображением, или указать обычную ссылку.

- -

HTML5 содержит два новых элемента — {{htmlelement("figure")}} и {{htmlelement("figcaption")}}, которые, как предполагается, должны связывать какую-любо фигуру (всё что угодно, необязательно изображение) с заголовком фигуры:

- -
<figure>
-  <img src="dinosaur.png" alt="Тираннозавр организации Mozilla">
-  <figcaption>Красный тираннозавр Рекс: стоящий как человек двуногий динозавр, с маленькими передними лапами и большой головой с большим количеством острых зубов.</figcaption>
-</figure>
- -

К сожалению, большинство скринридеров, кажется, пока ещё не умеют связывать заголовки фигур с  самими фигурами, но такая структура элементов удобна для CSS стилизации, к тому же, она предоставляет способ расположить описание рядом с изображением в исходнике.

- -

Пустые аттрибуты alt

- -
<h3>
-  <img src="article-icon.png" alt="">
-  Тираннозавр Рекс: король динозвров
-</h3>
- -

Бывает, что  в дизайне страницы присутствуют изображения, но они исполняют декоративную роль. В примере выше вы можете заметить, что у изображения пустой аттрибут alt — это сделано, чтобы скринридер опознал изображение, но не стал озвучивать её описание (вместо этого, он бы озвучил её как «изображение», или аналогично).

- -

Причина, по которой стоит использовать пустой аттрибут alt, вместо того, чтобы просто его не указывать в том, что большинство скринридеров объявят весь URL-адрес изображения, если не указан alt. В пример выше изображение используется как украшение для связанного с ним заголовка. В таких случаях и случаях, когда изображение является украшением и не имеет ценное содержание, вы должны использовать пустой аттрибут alt. Другой вариант — использовать aria роль role="presentation". Это также предотвратит озвучивание скринридером альтернативного текста.

- -
-

Примечание: По возможности для отображения декоративных изображений вы должны использовать CSS.

-
- -

Заключение

- -

Теперь вы должны хорошо разбираться в написании доступного HTML для большинства случаев. Наша статья про основы WAI-ARIA также заполнит пробелы в знаниях, но эта статья посвящена основам. Далее мы рассмотрим CSS и JavaScript, и как хорошое или плохое их использование влияет на доступность. 

- -

{{PreviousMenuNext("Learn/Accessibility/What_is_Accessibility","Learn/Accessibility/CSS_and_JavaScript", "Learn/Accessibility")}}

- - - -

В этом модуле

- - diff --git "a/files/ru/learn/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/index.html" "b/files/ru/learn/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/index.html" deleted file mode 100644 index 422bead1d7..0000000000 --- "a/files/ru/learn/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/index.html" +++ /dev/null @@ -1,55 +0,0 @@ ---- -title: Доступность -slug: Learn/Доступность -tags: - - CSS - - HTML - - JavaScript - - Удобство - - доступность -translation_of: Learn/Accessibility ---- -
{{LearnSidebar}}
- -

Изучение HTML, CSS, и JavaScript полезно, если вы хотите стать веб-разработчиком, но ваши знания должны быть глубже обычного использования технологий — вы должны быть ответственны и максимизировать доступность ваших веб-приложений, не лишая никого возможности их использования. Чтобы достигнуть этого, вы можете следовать общепринятым лучшим практикам (которые демонстрируются в статьях посвященных HTML, CSS и JavaScript), проводить кросс-браузерное тестирование и обращать внимание на доступность с самого начала. В этом модуле мы рассмотрим эту тему в деталях.

- -

Прежде чем начать

- -

Чтобы разобраться с большей частью материалов этого модуля, хорошей идеей будет проходить одновременно один или несколько из модулей других тем (HTML, CSS или JavaScript), или, что ещё лучше, пройти соответствующие части данного модуля во время изучения этих технологий.

- -
-

Примечание: Если вы работаете на компьютере/планшете/другом устройстве, на котором у вас нет возможности создавать файлы, вы можете попробовать большую часть примеров кода в онлайн программах, таких как JSBin или Thimble.

-
- -

Справочники

- -
-
Что такое доступность?
-
Данная статья открывает модуль, в котором рассматривается, что такое доступность на самом деле — она включает в себя группы людей, которые нам нужно учитывать и почему, какие инструменты используют разные пользователи для взаимодействия с вебом, и как мы можем сделать доступность частью нашего рабочего процесса веб-разработки.
-
HTML: Хорошая основа для доступности
-
Большая часть содержимого интернета может быть сделана доступной просто благодаря использованию HTML элементов по назначению. В этой статье подробно рассмотрено как HTML может быть использован для обеспечения максимальной доступности.
-
Лучшие практики CSS и JavaScript для обеспечения доступности
-
CSS и JavaScript, при правильном использовании, также имеют потенциал для обеспечения доступности, но при неправильном использовании они могут существенно ухудшить доступность. Эта статья раскрывает некоторые из лучших практик CSS и JavaScript которые должны помочь сделать даже очень сложное содержимое как можно более доступным.
-
Основы WAI-ARIA
-
Web Accessibility Initiative - Accessible Rich Internet Applications — это технологический стандарт для предоставления возможности полноценного использования Интернета людьми с физическими ограничениями.
- Исходя из предыдущей статьи, иногда создание сложных элементов управления пользовательским интерфейсом, которые включают в себя не семантический HTML и динамический контент, обновляемый с помощью JavaScript, может быть затруднено. WAI-ARIA — это технология, которая может помочь в решении таких проблем, добавляя дополнительную семантику, которую браузеры и вспомогательные технологии могут распознавать и использовать, чтобы пользователи знали, что происходит. Здесь мы покажем, как использовать его на базовом уровне для улучшения доступности.
-
Доступный мультимедиа контент
-
Другая категория контента, которая может создавать проблемы с доступностью, это мультимедиа — видео, аудио и изображения, которые должны быть предоставлены с надлежащей текстовой альтернативой, чтобы их могли понять с помощью вспомогательных технологий и их пользователи. В этой статье показано, как это можно сделать.
-
Доступность на мобильных устройствах
-
Поскольку веб-доступ на мобильных устройствах является настолько популярным, и на популярных платформах, таких как iOS и Android, есть полноценные средства обеспечения доступности, важно учитывать доступность вашего веб-контента для этих платформ. В этой статье рассматриваются соображения доступности для мобильных устройств.
-
- -

Проверка знаний

- -
-
Найди недочеты в доступности
-
В этом блоке представлен достаточно простой сайт, в котором, однако, есть множество недочетов в доступности. Необходимо найти их и починить.
-
- -

Также советуем посмотреть

- - diff --git "a/files/ru/learn/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/mobile/index.html" "b/files/ru/learn/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/mobile/index.html" deleted file mode 100644 index bbdc7f0e1d..0000000000 --- "a/files/ru/learn/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/mobile/index.html" +++ /dev/null @@ -1,304 +0,0 @@ ---- -title: Мобильная доступность -slug: Learn/Доступность/Mobile -tags: - - Mobile -translation_of: Learn/Accessibility/Mobile ---- -
-
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/Accessibility/Multimedia","Learn/Accessibility/Accessibility_troubleshooting", "Learn/Accessibility")}}
- -

With web access on mobile devices being so popular, and popular platforms such as iOS and Android having fully fledged accessibility tools, it is important to consider the accessibility of your web content on these platforms. This article looks at mobile-specific accessibility considerations.

- - - - - - - - - - - - -
Prerequisites:Basic computer literacy, a basic understanding of HTML, CSS, and JavaScript, and an understanding of the previous articles in the course.
Objective:To understand what problems exist with accessibility on mobile devices, and how to overcome them.
- -

Accessibility on mobile devices

- -

The state of accessibility — and support for web standards in general — is good in modern mobile devices. Long gone are the days when mobile devices ran completely different web technologies to desktop browsers, forcing developers to use browser sniffing and serve them completely separate sites (although quite a few companies still detect usage of mobile devices and serve them a separate mobile domain).

- -

These days, mobile devices in general can handle "full fat" websites, and the main platforms even have screenreaders built in to enable visually impaired users to use them successfully. Modern mobile browsers tend to have good support for WAI-ARIA, too.

- -

To make a website accessible and usable on mobile, you just need to follow general good web design and accessibility best practices.

- -

There are some exceptions that need special consideration for mobile; the main ones are:

- -
    -
  • Control mechanisms — Make sure interface controls such as buttons are accessible on mobiles (i.e., mainly touchscreen), as well as desktops/laptops (mainly mouse/keyboard).
  • -
  • User input — Make user input requirements as painless as possible on mobile (e.g., in forms, keep typing to a minimum).
  • -
  • Responsive design — Make sure layouts work on mobile, conserve image download sizes, and think about provision of images for high-resolution screens.
  • -
- -

Summary of screenreader testing on Android and iOS

- -

The most common mobile platforms have fully functional screenreaders. These function in much the same way as desktop screenreaders, except they are largely operated using touch gestures rather than key combinations.

- -

Let's look at the main two: TalkBack on Android and VoiceOver on iOS.

- -

Android TalkBack

- -

The TalkBack screenreader is built into the Android operating system.

- -

To turn it on, select Settings > Accessibility > TalkBack, and then press the slider switch to turn it on. Follow any additional on-screen prompts that you are presented with.

- -

Note: Older versions of TalkBack are turned on in slightly different ways.

- -

When TalkBack is turned on, your Android device's basic controls will be a bit different. For example:

- -
    -
  1. Single-tapping an app will select it, and the device will read out what the app is.
  2. -
  3. Swiping left and right will move between apps, or buttons/controls if you are in a control bar. The device will read out each option.
  4. -
  5. Double-tapping anywhere will open the app/select the option.
  6. -
  7. You can also "explore by touch" — hold your finger down on the screen and drag it around, and your device will read out the different apps/items you move across.
  8. -
- -

If you want to turn TalkBack off:

- -
    -
  1. Navigate to your Settings app using the above gestures.
  2. -
  3. Navigate to Accessibility > TalkBack.
  4. -
  5. Navigate to the slider switch and activate it to turn it off.
  6. -
- -

Note: You can get to your homescreen at any time by swiping up and left in a smooth motion. If you have more than one homescreen, you can move between them by swiping two fingers left and right.

- -

For a more complete list of TalkBack gestures, see Use TalkBack gestures.

- -

Unlocking the phone

- -

When TalkBack is turned on, unlocking the phone is a bit different.

- -

You can do a two-finger swipe up from the bottom of the lock screen. If you've set a passcode or pattern for unlocking your device, you will then be taken to the relevant entry screen to enter it.

- -

You can also explore by touch to find the Unlock button at the bottom middle of the screen, and then double-tap.

- -

Global and local menus

- -

TalkBack allows you to access global and local context menus, wherever you have navigated to on the device. The former provides global options relating to the device as a whole, and the latter provides options relating just to the current app/screen you are in.

- -

To get to these menus:

- -
    -
  1. Access the global menu by quickly swiping down, and then right.
  2. -
  3. Access the local menu by quickly swiping up, and then right.
  4. -
  5. Swipe left and right to cycle between the different options.
  6. -
  7. Once you've selected the option you want, double-click to choose that option.
  8. -
- -

For details on all the options available under the global and local context menus, see Use global and local context menus.

- -

Browsing web pages

- -

You can use the local context menu while in a web browser to find options to navigate web pages using just the headings, form controls, or links, or navigate line by line, etc.

- -

For example, with TalkBack turned on:

- -
    -
  1. Open your web browser.
  2. -
  3. Activate the URL bar.
  4. -
  5. Enter a web page that has a bunch of headings on it, such as the front page of bbc.co.uk. To enter the text of the URL: -
      -
    • Select the URL bar by swiping left/right till you get to it, and then double-tapping.
    • -
    • Hold your finger down on the virtual keyboard until you get the character you want, and then release your finger to type it. Repeat for each character.
    • -
    • Once you've finished, find the Enter key and press it.
    • -
    -
  6. -
  7. Swipe left and right to move between different items on the page.
  8. -
  9. Swipe up and right with a smooth motion to enter the local content menu.
  10. -
  11. Swipe right until you find the "Headings and Landmarks" option.
  12. -
  13. Double-tap to select it. Now you'll be able to swipe left and right to move between headings and ARIA landmarks.
  14. -
  15. To go back to the default mode, enter the local context menu again by swiping up and right, select "Default", and then double-tap to activate.
  16. -
- -

Note: See Get started on Android with TalkBack for more complete documentation.

- -

iOS VoiceOver

- -

A mobile version of VoiceOver is built into the iOS operating system.

- -

To turn it on, go to Your Settings app and select General > Accessibility > VoiceOver. Press the VoiceOver slider to enable it (you'll also see a number of other options related to VoiceOver on this page).

- -

Once VoiceOver is enabled, the iOS's basic control gestures will be a bit different:

- -
    -
  1. A single tap will cause the item you tap on to be selected; your device will speak the item you've tapped on.
  2. -
  3. You can also navigate the items on the screen by swiping left and right to move between them, or by sliding your finger around on the screen to move between different items (when you find the item you want, you can remove your finger to select it).
  4. -
  5. To activate the selected item (e.g., open a selected app), double-tap anywhere on the screen.
  6. -
  7. Swipe with three fingers to scroll through a page.
  8. -
  9. Tap with two fingers to perform a context-relevant action — for example, taking a photo while in the camera app.
  10. -
- -

To turn it off again, navigate back to Settings > General > Accessibility > VoiceOver using the above gestures, and toggle the VoiceOver slider back to off.

- -

Unlock phone

- -

To unlock the phone, you need to press the home button (or swipe) as normal. If you have a passcode set, you can select each number by swiping/sliding (as explained above) and then double-tapping to enter each number when you've found the right one.

- -

Using the Rotor

- -

When VoiceOver is turned on, you have a navigation feature called the Rotor available to you, which allows you to quickly choose from a number of common useful options. To use it:

- -
    -
  1. Twist two fingers around on the screen like you are turning a dial. Each option will be read aloud as you twist further around. You can go back and forth to cycle through the options.
  2. -
  3. Once you've found the option you want: -
      -
    • Release your fingers to select it.
    • -
    • If it is an option you can iterate the value of (such as Volume or Speaking Rate), you can do a swipe up or down to increase or decrease the value of the selected item.
    • -
    -
  4. -
- -

The options available under the Rotor are context-sensitive — they will differ depending on what app or view you are in (see below for an example).

- -

Browsing web pages

- -

Let's have a go at web browsing with VoiceOver:

- -
    -
  1. Open your web browser.
  2. -
  3. Activate the URL bar.
  4. -
  5. Enter a web page that has a bunch of headings on it, such as the front page of bbc.co.uk. To enter the text of the URL: -
      -
    • Select the URL bar by swiping left/right until you get to it, and then double-tapping.
    • -
    • For each character, hold your finger down on the virtual keyboard until you get the character you want, and then release your finger to select it. Double-tap to type it.
    • -
    • Once you've finished, find the Enter key and press it.
    • -
    -
  6. -
  7. Swipe left and right to move between items on the page. You can double-tap an item to select it (e.g., follow a link).
  8. -
  9. By default, the selected Rotor option will be Speaking Rate; you can currently swipe up and down to increase or decrease the speaking rate.
  10. -
  11. Now turn two fingers around the screen like a dial to show the rotor and move between its options. Here are a few examples of the options available: -
      -
    • Speaking Rate: Change the speaking rate.
    • -
    • Containers: Move between different semantic containers on the page.
    • -
    • Headings: Move between headings on the page.
    • -
    • Links: Move between links on the page.
    • -
    • Form Controls: Move between form controls on the page.
    • -
    • Language: Move between different translations, if they are available.
    • -
    -
  12. -
  13. Select Headings. Now you'll be able to swipe up and down to move between headings on the page.
  14. -
- -

Note: For a more complete reference covering the VoiceOver gestures available and other hints on accessibility testing on iOS, see Test Accessibility on Your Device with VoiceOver.

- -

Control mechanisms

- -

In our CSS and JavaScript accessibility article, we looked at the idea of events that are specific to a certain type of control mechanism (see Mouse-specific events). To recap, these cause accessibility issues because other control mechanisms can't activate the associated functionality.

- -

As an example, the click event is good in terms of accessibility — an associated event handler can be invoked by clicking the element the handler is set on, tabbing to it and pressing Enter/Return, or tapping it on a touchscreen device. Try our simple-button-example.html example (see it running live) to see what we mean.

- -

Alternatively, mouse-specific events such as mousedown and mouseup create problems — their event handlers cannot be invoked using non-mouse controls.

- -

If you try to control our simple-box-drag.html (see example live) example with keyboard or touch, you'll see the problem. This occurs because we are using code such as the following:

- -
div.onmousedown = function() {
-  initialBoxX = div.offsetLeft;
-  initialBoxY = div.offsetTop;
-  movePanel();
-}
-
-document.onmouseup = stopMove;
- -

To enable other forms of control, you need to use different, yet equivalent events — for example, touch events work on touchscreen devices:

- -
div.ontouchstart = function(e) {
-  initialBoxX = div.offsetLeft;
-  initialBoxY = div.offsetTop;
-  positionHandler(e);
-  movePanel();
-}
-
-panel.ontouchend = stopMove;
- -

We've provided a simple example that shows how to use the mouse and touch events together — see multi-control-box-drag.html (see the example live also).

- -

Note: You can also see fully functional examples showing how to implement different control mechanisms at Implementing game control mechanisms.

- -

Responsive design

- -

Responsive design is the practice of making your layouts and other features of your apps dynamically change depending on factors such as screen size and resolution, so they are usable and accessible to users of different device types.

- -

In particular, the most common problems that need to be addressed for mobile are:

- -
    -
  • Suitability of layouts for mobile devices. A multi-column layout won't work as well on a narrow screen, for example, and the text size may need to be increased so it is legible. Such issues can be solved by creating a responsive layout using technologies such as media queriesviewport, and flexbox.
  • -
  • Conserving image sizes downloaded. In general, small screen devices won't need images that are as large as their desktop counterparts, and they are more likely to be on slow network connections. Therefore, it is wise to serve smaller images to narrow screen devices as appropriate. You can handle this using responsive image techniques.
  • -
  • Thinking about high resolutions. Many mobile devices have high-resolution screens, and therefore need higher-resolution images so that the display can continue to look crisp and sharp. Again, you can serve images as appropriate using responsive image techniques. In addition, many image requirements can be fulfilled using the SVG vector images format, which is well-supported across browsers today. SVG has a small file size and will stay sharp regardless of whatever size is being displayed  (see Adding vector graphics to the web for more details).
  • -
- -

Note: We won't provide a full discussion of responsive design techniques here, as they are covered in other places around MDN (see above links).

- -

Specific mobile considerations

- -

There are other important issues to consider when making sites more accessible on mobile. We have listed a couple here, but we will add more when we think of them.

- -

Not disabling zoom

- -

Using viewport, it is possible to disable zoom, using code like this in your {{htmlelement("head")}}:

- -
<meta name="viewport" content="user-scalable=no">
- -

You should never do this if at all possible — many people rely on zoom to be able to see the content of your website, so taking this functionality away is a really bad idea. There are certain situations where zooming might break the UI; in such cases, if you feel that you absolutely need to disable zoom, you should provide some other kind of equivalent, such as a control for increasing the text size in a way that doesn't break your UI.

- -

Keeping menus accessible

- -

Because the screen is so much narrower on mobile devices, it is very common to use media queries and other technologies to make the navigation menu shrink down to a tiny icon at the top of the display — which can be pressed to reveal the menu only if it's needed — when the site is viewed on mobile. This is commonly represented by a "three horizontal lines" icon, and the design pattern is consequently known as a "hamburger menu".

- -

When implementing such a menu, you need to make sure that the control to reveal it is accessible by appropriate control mechanisms (normally touch for mobile), as discussed in {{anch("Control mechanisms")}} above, and that the rest of the page is moved out of the way or hidden in some way while the menu is being accessed, to avoid confusion with navigating it.

- -

Click here for a good hamburger menu example.

- -

User input

- -

On mobile devices, inputting data tends to be more annoying for users than the equivalent experience on desktop computers. It is more convenient to type text into form inputs using a desktop or laptop keyboard than a touchscreen virtual keyboard or a tiny mobile physical keyboard.

- -

For this reason, it is worth trying to minimize the amount of typing needed. As an example, instead of getting users to fill out their job title each time using a regular text input, you could instead offer a {{htmlelement("select")}} menu containing the most common options (which also helps with consistency in data entry), and offer an "Other" option that displays a text field to type any outliers into. You can see a simple example of this idea in action in common-job-types.html (see the common jobs example live).

- -

It is also worth considering the use of HTML5 form input types such as date on mobile platforms as they handle them well — both Android and iOS, for example, display usable widgets that fit well with the device experience. See html5-form-examples.html for some examples (see the HTML5 form examples live) — try loading these and manipulating them on mobile devices. For example:

- -
    -
  • Types numbertel, and email display suitable virtual keyboards for entering numbers/telephone numbers.
  • -
  • Types time and date display suitable pickers for selecting times and dates.
  • -
- -

If you want to provide a different solution for desktops, you could always serve different markup to your mobile devices using feature detection. See input types for raw information on detecting different input types, and also check out our feature detection article for much more information.

- -

Summary

- -

In this article we have provided you with some details about common mobile accessibility-specific issues and how to overcome them. We also took you through usage of the most common screenreaders to aid you in accessibility testing.

- -

See also

- - - -
{{PreviousMenuNext("Learn/Accessibility/Multimedia","Learn/Accessibility/Accessibility_troubleshooting", "Learn/Accessibility")}}
- -
-

В этом модуле

- - -
-
diff --git "a/files/ru/learn/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/multimedia/index.html" "b/files/ru/learn/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/multimedia/index.html" deleted file mode 100644 index e07550ba5e..0000000000 --- "a/files/ru/learn/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/multimedia/index.html" +++ /dev/null @@ -1,360 +0,0 @@ ---- -title: Доступность мультимедиа -slug: Learn/Доступность/Multimedia -tags: - - JavaScript -translation_of: Learn/Accessibility/Multimedia ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/Accessibility/WAI-ARIA_basics","Learn/Accessibility/Mobile", "Learn/Accessibility")}}
- -

Another category of content that can create accessibility problems is multimedia — video, audio, and image content need to be given proper textual alternatives so they can be understood by assistive technologies and their users. This article shows how.

- - - - - - - - - - - - -
Prerequisites:Basic computer literacy, a basic understanding of HTML, CSS, and JavaScript, an understanding of what accessibility is.
Objective:To understand the accessibility issues behind multimedia, and how to overcome them.
- -

Multimedia and accessibility

- -

So far in this module we have looked at a variety of content and what needs to be done to ensure its accessibility, ranging from simple text content to data tables, images, native controls such as form elements and buttons, and even more complex markup structures (with WAI-ARIA attributes).

- -

This article on the other hand looks at another general class of content that arguably isn't as easy to ensure accessibility for — multimedia. Images, videos, {{htmlelement("canvas")}} elements, Flash movies, etc., aren't as easily understood by screenreaders or navigated by the keyboard, and we need to give them a helping hand.

- -

But don't despair — here we will help you navigate through the techniques available for making multimedia more accessible.

- -

Simple images

- -

We already covered simple text alternatives for HTML images in our HTML: A good basis for accessibility article — you can refer back to there for the full details. In short, you should ensure that where possible visual content has an alternative text available for screenreaders to pick up and read to their users.

- -

For example:

- -
<img src="dinosaur.png"
-     alt="A red Tyrannosaurus Rex: A two legged dinosaur standing upright like a human, with small arms, and a large head with lots of sharp teeth.">
-
- -

Accessible audio and video controls

- -

Implementing controls for web-based audio/video shouldn't be a problem, right? Let's investigate.

- -

The problem with native HTML5 controls

- -

HTML5 video and audio instances even come with a set of inbuilt controls that allow you to control the media straight out of the box. For example (see native-controls.html source code and live):

- -
<audio controls>
-  <source src="viper.mp3" type="audio/mp3">
-  <source src="viper.ogg" type="audio/ogg">
-  <p>Your browser doesn't support HTML5 audio. Here is a <a href="viper.mp3">link to the audio</a> instead.</p>
-</audio>
-
-<br>
-
-<video controls>
-  <source src="rabbit320.mp4" type="video/mp4">
-  <source src="rabbit320.webm" type="video/webm">
-  <p>Your browser doesn't support HTML5 video. Here is a <a href="rabbit320.mp4">link to the video</a> instead.</p>
-</video>
- -

The controls attribute provides play/pause buttons, seek bar, etc. — the basic controls you'd expect from a media player. It looks like so in Firefox and Chrome:

- -

Screenshot of Video Controls in Firefox

- -

Screenshot of Video Controls in Chrome

- -

However, there are problems with these controls:

- - - -

To remedy this, we can create our own custom controls. Let's look at how.

- -

Creating custom audio and video controls

- -

HTML5 video and audio share an API — HTML Media Element — which allows you to map custom functionality to buttons and other controls — both of which you define yourself.

- -

Let's take the video example from above and add custom controls to them.

- -

Basic setup

- -

First, grab a copy of our custom-controls-start.html, custom-controls.css, rabbit320.mp4, and rabbit320.webm files and save them in a new directory on your hard drive.

- -

Create a new file called main.js and save it in the same directory.

- -

First of all, let's look at the HTML for the video player, in the HTML:

- -
<section class="player">
-  <video controls>
-    <source src="rabbit320.mp4" type="video/mp4">
-    <source src="rabbit320.webm" type="video/webm">
-    <p>Your browser doesn't support HTML5 video. Here is a <a href="rabbit320.mp4">link to the video</a> instead.</p>
-  </video>
-
-  <div class="controls">
-    <button class="playpause">Play</button>
-    <button class="stop">Stop</button>
-    <button class="rwd">Rwd</button>
-    <button class="fwd">Fwd</button>
-    <div class="time">00:00</div>
-  </div>
-</section>
- -

JavaScript basic setup

- -

We've inserted some simple control buttons below our video. These controls of course won't do anything by default; to add functionality, we will use JavaScript.

- -

We will first need to store references to each of the controls — add the following to the top of your JavaScript file:

- -
var playPauseBtn = document.querySelector('.playpause');
-var stopBtn = document.querySelector('.stop');
-var rwdBtn = document.querySelector('.rwd');
-var fwdBtn = document.querySelector('.fwd');
-var timeLabel = document.querySelector('.time');
- -

Next, we need to grab a reference to the video/audio player itself — add this line below the previous lines:

- -
var player = document.querySelector('video');
- -

This holds a reference to a {{domxref("HTMLMediaElement")}} object, which has several useful properties and methods available on it that can be used to wire up functionality to our buttons.

- -

Before moving onto creating our button functionality, let's remove the native controls so they don't get in the way of our custom controls. Add the following, again at the bottom of your JavaScript:

- -
player.removeAttribute('controls');
- -

Doing it this way round rather than just not including the controls attribute in the first place has the advantage that if our JavaScript fails for any reason, the user still has some controls available.

- -

Wiring up our buttons

- -

First, let's set up the play/pause button. We can get this to toggle between play and pause with a simple conditional function, like the following. Add it to your code, at the bottom:

- -
playPauseBtn.onclick = function() {
-  if(player.paused) {
-    player.play();
-    playPauseBtn.textContent = 'Pause';
-  } else {
-    player.pause();
-    playPauseBtn.textContent = 'Play';
-  }
-};
- -

Next, add this code to the bottom, which controls the stop button:

- -
stopBtn.onclick = function() {
-  player.pause();
-  player.currentTime = 0;
-  playPauseBtn.textContent = 'Play';
-};
- -

There is no stop() function available on {{domxref("HTMLMediaElement")}}s, so instead we pause() it, and at the same time set the currentTime to 0.

- -

Next, our rewind and fast forward buttons — add the following blocks to the bottom of your code:

- -
rwdBtn.onclick = function() {
-  player.currentTime -= 3;
-};
-
-fwdBtn.onclick = function() {
-  player.currentTime += 3;
-  if(player.currentTime >= player.duration || player.paused) {
-    player.pause();
-    player.currentTime = 0;
-    playPauseBtn.textContent = 'Play';
-  }
-};
- -

These are very simple, just adding or subtracting 3 seconds to the currentTime each time they are clicked. In a real video player, you'd probably want a more elaborate seeking bar, or similar.

- -

Note that we also check to see if the currentTime is more than the total media duration, or if the media is not playing, when the Fwd button is pressed. If either conditions are true, we simply stop the video, to avoid the user interface going wrong if they attempt to fast forward when the video is not playing, or fast forward past the end of the video.

- -

Last of all, add the following to the end of the code, to control the time elapsed display:

- -
player.ontimeupdate = function() {
-  var minutes = Math.floor(player.currentTime / 60);
-  var seconds = Math.floor(player.currentTime - minutes * 60);
-  var minuteValue;
-  var secondValue;
-
-  if (minutes<10) {
-    minuteValue = "0" + minutes;
-  } else {
-    minuteValue = minutes;
-  }
-
-  if (seconds<10) {
-    secondValue = "0" + seconds;
-  } else {
-    secondValue = seconds;
-  }
-
-  mediaTime = minuteValue + ":" + secondValue;
-  timeLabel.textContent = mediaTime;
-};
- -

Each time the time updates (once per second), we fire this function. It works out the number of minutes and seconds from the given currentTime value that is just in seconds, adds a leading 0 if either the minute or second value is less than 10, and then create the display readout and adds it to the time label.

- -

Further reading

- -

This gives you a basic idea of how to add custom player functionality to video/audio player instances. For more information on how to add more complex features to video/audio players, including Flash fallbacks for older browsers, see:

- - - -

We've also created an advanced example to show how you could create an object-oriented system that finds every video and audio player on the page (no matter how many there are) and adds our custom controls to it. See custom-controls-oojs (also see the source code).

- -

Audio transcripts

- -

To provide deaf people with access to audio content, you really need to create text transcripts. These can either be included on the same page as the audio in some way, or included on a separate page and linked to.

- -

In terms of actually creating the transcript, your options are:

- - - -

As with most things in life, you tend to get what you pay for; different services will vary in accuracy and time taken to produce the transcript. If you pay a reputable company or AI service to do the transcription, you will probably get it done rapidly and to a high quality. If you don't want to pay for it, you are likely to get it done at a lower quality, and/or slowly.

- -

It is not OK to publish an audio resource but promise to publish the transcript later on — such promises often aren't kept, which will erode trust between you and your users. If the audio you are presenting is something like a face to face meeting or live spoken performance, it would be acceptable to take notes during the performance, publish them in full along with the audio, then seek help in cleaning up the notes afterwards.

- -

Transcript examples

- -

If you use an automated service, then you'll probably have to use the user interface that the tool provides. For example, take a look at Audio Transcription Sample 1 and choose More > Transcript.

- -

If you are creating your own user interface to present your audio and associated transcript, you can do it however you like, but it might make sense to include it in a showable/hideable panel; see our audio-transcript-ui example (also see the source code).

- -

Audio descriptions

- -

On occasions where there are visuals accompanying your audio, you'll need to provide audio descriptions of some kind to describe that extra content.

- -

In many cases this will simply take the form of video, in which case you can implement captions using the techniques described in the next section of the article.

- -

However, there are some edge cases. You might for example have an audio recording of a meeting that refers to an accompanying resource such as a spreadsheet or chart. In such cases, you should make sure that the resources are provided along with the audio + transcript, and specifically link to them in the places where they are referred to in the transcript. This of course will help all users, not just people who are deaf.

- -
-

Note: An audio transcript will in general help multiple user groups. As well as giving deaf users access to the information contained in the audio, think about a user with a low bandwidth connection, who would find downloading the audio inconvenient. Think also about a user in a noisy environment like a pub or bar, who is trying to access the information but can't hear it over the noise.

-
- -

Video text tracks

- -

To make video accessible for deaf, blind, or even other groups of users (such as those on low bandwidth, or who don't understand the language the video is recorded in), you need to include text tracks along with your video content.

- -
-

Note: text tracks are also useful for potentially any user, not just those with disabilities. for example, some users may not be able to hear the audio because they are in noisy environments (like a crowded bar when a sports game is being shown) or might not want to disturb others if they are in a quiet place (like a library.)

-
- -

This is not a new concept — television services have had closed captioning available for quite a long time:

- -

Frame from an old-timey cartoon with closed captioning "Good work, Goldie. Keep it up!"

- -

Whereas many countries offer English films with subtitles written in their own native languages, and different language subtitles are often available on DVDs, for example

- -

An English film with German subtitles "Emo, warum erkennst du nicht die Schonheit dieses Ortes?"

- -

There are different types of text track with different purposes. The main ones you'll come across are:

- - - -

Implementing HTML5 video text tracks

- -

Text tracks for displaying with HTML5 video need to be written in WebVTT, a text format containing multiple strings of text along with metadata such as what time in the video you want each text string to be displayed, and even limited styling/positioning information. These text strings are called cues.

- -

A typical WebVTT file will look something like this:

- -
WEBVTT
-
-1
-00:00:22.230 --> 00:00:24.606
-This is the first subtitle.
-
-2
-00:00:30.739 --> 00:00:34.074
-This is the second.
-
-  ...
- -

To get this displayed along with the HTML media playback, you need to:

- - - -

Here's an example:

- -
<video controls>
-    <source src="example.mp4" type="video/mp4">
-    <source src="example.webm" type="video/webm">
-    <track kind="subtitles" src="subtitles_en.vtt" srclang="en">
-</video>
- -

This will result in a video that has subtitles displayed, kind of like this:

- -

Video player with standard controls such as play, stop, volume, and captions on and off. The video playing shows a scene of a man holding a spear-like weapon, and a caption reads "Esta hoja tiene pasado oscuro."

- -

For more details, please read Adding captions and subtitles to HTML5 video. You can find the example that goes along with this article on Github, written by Ian Devlin (see the source code too.) This example uses some JavaScript to allow users to choose between different subtitles. Note that to turn the subtitles on, you need to press the "CC" button and select an option — English, Deutsch, or Español.

- -
-

Note: Text tracks and transcriptions also help you with {{glossary("SEO")}}, since search engines especially thrive on text. Text tracks even allow search engines to link directly to a spot partway through the video.

-
- -

Other multimedia content

- -

The above sections don't cover all types of multimedia content that you might want to put on a web page. You might also need to deal with games, animations, slideshows, embedded video, and content created using other available technologies such as:

- - - -

For such content, you need to deal with accessibility concerns on a case by case basis. In some cases it is not so bad, for example:

- - - -

However, other multimedia is not so easy to make accessible. If for example you are dealing with an immersive 3D game or virtual reality app, it really is quite difficult to provide text alternatives for such an experience, and you might argue that blind users are not really in the target audience bracket for such apps.

- -

You can however make sure that such an app has good enough color contrast and clear presentation so it is perceivable to those with low vision/color blindness, and also make it keyboard accessible. Remember that accessibility is about doing as much as you can, rather than striving for 100% accessibility all the time, which is often impossible.

- -

Summary

- -

This chapter has provided a summary of accessibility concerns for multimedia content, along with some practical solutions.

- -

{{PreviousMenuNext("Learn/Accessibility/WAI-ARIA_basics","Learn/Accessibility/Mobile", "Learn/Accessibility")}}

- -

 

- -

В этом модуле

- - - -

 

diff --git "a/files/ru/learn/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/wai-aria_basics/index.html" "b/files/ru/learn/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/wai-aria_basics/index.html" deleted file mode 100644 index d04c4fd483..0000000000 --- "a/files/ru/learn/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/wai-aria_basics/index.html" +++ /dev/null @@ -1,416 +0,0 @@ ---- -title: Основы WAI-ARIA -slug: Learn/Доступность/WAI-ARIA_basics -tags: - - JavaScript -translation_of: Learn/Accessibility/WAI-ARIA_basics ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/Accessibility/CSS_and_JavaScript","Learn/Accessibility/Multimedia", "Learn/Accessibility")}}
- -

Исходя из предыдущей статьи, иногда создание сложных элементов UI, которые включают в себя неcемантичный HTML и динамически обновляемый с помощью JavaScript контент, может быть затруднено. WAI-ARIA - это технология, которая может помочь в решении таких проблем, добавляя дополнительную разметку, которую браузеры и вспомогательные технологии могут распознавать и использовать, чтобы пользователи знали, что происходит. В этой статье мы покажем, как использовать эту технологию на базовом уровне для улучшения доступности.

- - - - - - - - - - - - -
Необходимые знания:Базовая компьютерная грамотность, базовое понимание HTML, CSS и JavaScript, понимание предыдущей статьи курса.
Цель:Ознакомиться с WAI-ARIA и узнать, как эту технологию можно использовать для включения полезной дополнительной семантики в целях повышения доступности.
- -

Что такое WAI-ARIA?

- -

Давайте начнем с рассмотрения того, что такое WAI-ARIA и чем она может быть полезна.

- -

Новый набор проблем

- -

С тех пор как веб-приложения стали более сложными и динамичными, появились новые специальные возможности и проблемы.

- -

Например, HTML5 ввел ряд семантических элементов, чтобы определить общую разметку страниц ( <nav><footer>и т.д.). До того как они были доступны, разработчики просто использовали <div> с идентификаторами или классами, например <div class="nav">, но это создавало проблемы, так как не было никакого простого способа найти определенный раздел страницы программным способом.

- -

Первоначальным решением было добавить одну или несколько скрытых ссылок вверху страницы для ссылки на навигацию (или на что-то еще), например:

- -
<a href="#hidden" class="hidden">Skip to navigation</a>
- -

Но это все еще не очень точно, и может использоваться только тогда, когда программа чтения с экрана читает сверху страницы.

- -

В качестве другого примера, в приложения стали использовать сложные элементы управления, такие как поля выбора даты, ползунки для выбора значений и т.д. HTML5 предоставляет специальные типы ввода для отображения таких элементов управления:

- -
<input type="date">
-<input type="range">
- -

Они не очень хорошо поддерживаются в разных браузерах, и их очень сложно стилизовать, что делает их не очень полезными для интеграции с дизайном сайтов. В результате разработчики нередко используют библиотеки JavaScript, которые генерируют такие элементы управления, как последовательность вложенных <div>элементов или ячеек таблиц с именами классов, которые затем стилизуются с помощью CSS и управляют с помощью JavaScript.

- -

The problem here is that visually they work, but screenreaders can't make any sense of what they are at all, and their users just get told that they can see a jumble of elements with no semantics to describe what they mean.

- -

Enter WAI-ARIA

- -

WAI-ARIA is a specification written by the W3C, defining a set of additional HTML attributes that can be applied to elements to provide additional semantics and improve accessibility wherever it is lacking. There are three main features defined in the spec:

- - - -

An important point about WAI-ARIA attributes is that they don't affect anything about the web page, except for the information exposed by the browser's accessibility APIs (where screenreaders get their information from). WAI-ARIA doesn't affect webpage structure, the DOM, etc., although the attributes can be useful for selecting elements by CSS.

- -
-

Note: You can find a useful list of all the ARIA roles and their uses, with links to futher information, in the WAI-ARIA spec — see Definition of Roles.

- -

The spec also contains a list of all the properties and states, with links to further information — see Definitions of States and Properties (all aria-* attributes).

-
- -

Where is WAI-ARIA supported?

- -

This is not an easy question to answer. It is difficult to find a conclusive resource that states what features of WAI-ARIA are supported, and where, because:

- -
    -
  1. There are a lot of features in the WAI-ARIA spec.
  2. -
  3. There are many combinations of operating system, browser, and screenreader to consider.
  4. -
- -

This last point is key — To use a screenreader in the first place, your operating system needs to run browsers that have the necessary accessibility APIs in place to expose the information screenreaders need to do their job. Most popular OSes have one or two browsers in place that screenreaders can work with. The Paciello Group has a fairly up-to-date post that provides data for this — see Rough Guide: browsers, operating systems and screen reader support updated.

- -

Next, you need to worry about whether the browsers in question support ARIA features and expose them via their APIs, but also whether screenreaders recognise that information and present it to their users in a useful way.

- -
    -
  1. Browser support is generally quite good — at the time of writing, caniuse.com stated that global browser support for WAI-ARIA was around 88%.
  2. -
  3. Screenreader support for ARIA features isn't quite at this level, but the most popular screenreaders are getting there. You can get an idea of support levels by looking at Powermapper's WAI-ARIA Screen reader compatibility article.
  4. -
- -

In this article, we won't attempt to cover every WAI-ARIA feature, and its exact support details. Instead, we will cover the most critical WAI-ARIA features for you to know about; if we don't mention any support details, you can assume that the feature is well-supported. We will clearly mention any exceptions to this.

- -
-

Note: Some JavaScript libraries support WAI-ARIA, meaning that when they generate UI features like complex form controls, they add ARIA attributes to improve the accessibility of those features. If you are looking for a 3rd party JavaScript solution for rapid UI development, you should definitely consider the accessibility of its UI widgets as an important factor when making your choice. Good examples are jQuery UI (see About jQuery UI: Deep accessibility support), ExtJS, and Dojo/Dijit.

-
- -

When should you use WAI-ARIA?

- -

We talked about some of the problems that prompted WAI-ARIA to be created earlier on, but essentially, there are four main areas that WAI-ARIA is useful in:

- -
    -
  1. Signposts/Landmarks: ARIA's role attribute values can act as landmarks that either replicate the semantics of HTML5 elements (e.g. {{htmlelement("nav")}}), or go beyond HTML5 semantics to provide signposts to different functional areas, e.g search, tabgroup, tab, listbox, etc.
  2. -
  3. Dynamic content updates: Screenreaders tend to have difficulty with reporting constantly changing content; with ARIA we can use aria-live to inform screenreader users when an area of content is updated, e.g. via XMLHttpRequest, or DOM APIs.
  4. -
  5. Enhancing keyboard accessibility: There are built-in HTML elements that have native keyboard accessibility; when other elements are used along with JavaScript to simulate similar interactions, keyboard accessibility and screenreader reporting suffers as a result. Where this is unavoidable, WAI-ARIA provides a means to allow other elements to receive focus (using tabindex).
  6. -
  7. Accessibility of non-semantic controls: When a series of nested <div>s along with CSS/JavaScript is used to create a complex UI-feature, or a native control is greatly enhanced/changed via JavaScript, accessibility can suffer — screenreader users will find it difficult to work out what the feature does if there are no semantics or other clues. In these situations, ARIA can help to provide what's missing with a combination of roles like button, listbox, or tabgroup, and properties like aria-required or aria-posinset to provide further clues as to functionality.
  8. -
- -

One thing to remember though — you should only use WAI-ARIA when you need to! Ideally, you should always use native HTML features to provide the semantics required by screenreaders to tell their users what is going on. Sometimes this isn't possible, either because you have limited control over the code, or because you are creating something complex that doesn't have an easy HTML element to implement it. In such cases, WAI-ARIA can be a valuable accessibility enhancing tool.

- -

But again, only use it when necessary!

- -
-

Note: Also, try to make sure you test your site with a variety of real users — non-disabled people, people using screenreaders, people using keyboard navigation, etc. They will have better insights than you about how well it works.

-
- -

Practical WAI-ARIA implementations

- -

In the next section we'll look at the four areas in more detail, along with practical examples. Before you continue, you should get a screenreader testing setup put in place, so you can test some of the examples as you go through.

- -

See our section on testing screenreaders for more information.

- -

Signposts/Landmarks

- -

WAI-ARIA adds the role attribute to browsers, which allows you to add extra semantic value to elements on your site wherever they are needed. The first major area in which this is useful is providing information for screenreaders so that their users can find common page elements. Let's look at an example — our website-no-roles example (see it live) has the following structure:

- -
<header>
-  <h1>...</h1>
-  <nav>
-    <ul>...</ul>
-    <form>
-      <!-- search form  -->
-    </form>
-  </nav>
-</header>
-
-<main>
-  <article>...</article>
-  <aside>...</aside>
-</main>
-
-<footer>...</footer>
- -

If you try testing the example with a screenreader in a modern browser, you'll already get some useful information. For example, VoiceOver gives you the following:

- - - -

If you go to VoiceOver's landmarks menu (accessed using VoiceOver key + U and then using the cursor keys to cycle through the menu choices), you'll see that most of the elements are nicely listed so they can be accessed quickly.

- -

- -

However, we could do better here. the search form is a really important landmark that people will want to find, but it is not listed in the landmarks menu or treated like a notable landmark, beyond the actual input being called out as a search input (<input type="search">). In addition, some older browsers (most notably IE8) don't recognise the semantics of the HTML5 elements.

- -

Let's improve it by the use of some ARIA features. First, we'll add some role attributes to our HTML structure. You can try taking a copy of our original files (see index.html and style.css), or navigating to our website-aria-roles example (see it live), which has a structure like this:

- -
<header>
-  <h1>...</h1>
-  <nav role="navigation">
-    <ul>...</ul>
-    <form role="search">
-      <!-- search form  -->
-    </form>
-  </nav>
-</header>
-
-<main>
-  <article role="article">...</article>
-  <aside role="complementary">...</aside>
-</main>
-
-<footer>...</footer>
- -

We've also given you a bonus feature in this example — the {{htmlelement("input")}} element has been given the attribute aria-label, which gives it a descriptive label to be read out by a screenreader, even though we haven't included a {{htmlelement("label")}} element. In cases like these, this is very useful — a search form like this one is a very common, easily recognised feature, and adding a visual label would spoil the page design.

- -
<input type="search" name="q" placeholder="Search query" aria-label="Search through site content">
- -

Now if we use VoiceOver to look at this example, we get some improvements:

- - - -

Beyond this, the site is more likely to be accessible to users of older browsers such as IE8; it is worth including ARIA roles for that purpose. And if for some reason your site is built using just <div>s, you should definitely include the ARIA roles to provide these much needed semantics!

- -

The improved semantics of the search form have shown what is made possible when ARIA goes beyond the semantics available in HTML5. You'll see a lot more about these semantics and the power of ARIA properties/attributes below, especially in the {{anch("Accessibility of non-semantic controls")}} section. For now though, let's look at how ARIA can help with dynamic content updates.

- -

Dynamic content updates

- -

Content loaded into the DOM can be easily accessed using a screenreader, from textual content to alternative text attached to images. Traditional static websites with largely text content are therefore easy to make accessible for people with visual impairments.

- -

The problem is that modern web apps are often not just static text — they tend to have a lot of dynamically updating content, i.e. content that updates without the entire page reloading via a mechanism like XMLHttpRequest, Fetch, or DOM APIs. These are sometimes referred to as live regions.

- -

Let's look at a quick example — see aria-no-live.html (also see it running live). In this example we have a simple random quote box:

- -
<section>
-  <h1>Random quote</h1>
-  <blockquote>
-    <p></p>
-  </blockquote>
-</section>
- -

Our JavaScript loads a JSON file via XMLHttpRequest containing a series of random quotes and their authors. Once that is done, we start up a setInterval() loop that loads a new random quote into the quote box every 10 seconds:

- -
var intervalID = window.setInterval(showQuote, 10000);
- -

This works OK, but it is not good for accessibility — the content update is not detected by screenreaders, so their users would not know what is going on. This is a fairly trivial example, but just imagine if you were creating a complex UI with lots of constantly updating content, like a chat room, or a strategy game UI, or a live updating shopping cart display — it would be impossible to use the app in any effective way without some kind of way of alerting the user to the updates.

- -

WAI-ARIA fortunately provides a useful mechanism to provide these alerts — the aria-live property. Applying this to an element causes screenreaders to read out the content that is updated. How urgently the content is read out depends on the attribute value:

- - - -

We'd like you to take a copy of aria-no-live.html and quotes.json, and update your <section> tag as follows:

- -
<section aria-live="assertive">
- -

This will cause a screenreader to read out the content as it is updated.

- -
-

Note: Most browsers will throw a security exception if you try to do an XMLHttpRequest call from a file:// URL, e.g. if you just load the file by loading it directly into the browser (via double clicking, etc.). To get it to run, you will need to upload it to a web server, for example using GitHub, or a local web server like Python's SimpleHTTPServer.

-
- -

There is an additional consideration here — only the bit of text that updates is read out. It might be nice if we always read out the heading too, so the user can remember what is being read out. To do this, we can add the aria-atomic property to the section. Update your <section> tag again, like so:

- -
<section aria-live="assertive" aria-atomic="true">
- -

The aria-atomic="true" attribute tells screenreaders to read out the entire element contents as one atomic unit, not just the bits that were updated.

- -
-

Note: You can see the finished example at aria-live.html (see it running live).

-
- -
-

Note: The aria-relevant property is also quite useful for controlling what gets read out when a live region is updated. You can for example only get content additions or removals read out.

-
- -

Enhancing keyboard accessibility

- -

As discussed in a few other places in the module, one of the key strengths of HTML with respect to accessibility is the built-in keyboard accessibility of features such as buttons, form controls, and links. Generally, you are able to use the tab key to move between controls, the Enter/Return key to select or activate controls, and occasionally other controls as needed (for example the up and down cursor to move between options in a <select> box).

- -

However, sometimes you will end up having to write code that either uses non-semantic elements as buttons (or other types of control), or uses focusable controls for not quite the right purpose. You might be trying to fix some bad code you've inherited, or you might be building some kind of complex widget that requires it.

- -

In terms of making non-focusable code focusable, WAI-ARIA extends the tabindex attribute with some new values:

- - - -

We discussed this in more detail and showed a typical implementation back in our HTML accessibility article — see Building keyboard accessibility back in.

- -

Accessibility of non-semantic controls

- -

This follows on from the previous section — when a series of nested <div>s along with CSS/JavaScript is used to create a complex UI-feature, or a native control is greatly enhanced/changed via JavaScript, not only can keyboard accessibility suffer, but screenreader users will find it difficult to work out what the feature does if there are no semantics or other clues. In such situations, ARIA can help to provide those missing semantics.

- -

Form validation and error alerts

- -

First of all, let's revisit the form example we first looked at in our CSS and JavaScript accessibility article (read Keeping it unobtrusive for a full recap). At the end of this section we showed that we have included some ARIA attributes on the error message box that appears when there are validation errors when you try to submit the form:

- -
<div class="errors" role="alert" aria-relevant="all">
-  <ul>
-  </ul>
-</div>
- - - -

We could go further with our ARIA usage, and provide some more validation help. How about indicating whether fields are required in the first place, and what range the age should be?

- -
    -
  1. At this point, take a copy of our form-validation.html and validation.js files, and save them in a local directory.
  2. -
  3. Open them both in a text editor and have a look at how the code works.
  4. -
  5. First of all, add a paragraph just above the opening <form> tag, like the one below, and mark both the form <label>s with an asterisk. This is normally how we mark required fields for sighted users. -
    <p>Fields marked with an asterisk (*) are required.</p>
    -
  6. -
  7. This makes visual sense, but it isn't as easy to understand for screenreader users. Fortunately, WAI-ARIA provides the aria-required attribute to give screenreaders hints that they should tell users that form inputs need to be filled in. Update the <input> elements like so: -
    <input type="text" name="name" id="name" aria-required="true">
    -
    -<input type="number" name="age" id="age" aria-required="true">
    -
  8. -
  9. If you save the example now and test it with a screenreader, you should hear something like "Enter your name star, required, edit text".
  10. -
  11. It might also be useful if we give screenreader users and sighted users an idea of what the age value should be. This is often presented as a tooltip, or placeholder inside the form field perhaps. WAI-ARIA does include aria-valuemin and aria-valuemax properties to specify min and max values, but these currently don't seem very well supported; a better supported feature is the HTML5 placeholder attribute, which can contain a message that is shown in the input when no value is entered, and is read out by a number of screenreaders. Update your number input like this: -
    <input type="number" name="age" id="age" placeholder="Enter 1 to 150" aria-required="true">
    -
  12. -
- -
-

Note: You can see the finished example live at form-validation-updated.html.

-
- -

WAI-ARIA also enables some advanced form labelling techniques, beyond the classic {{htmlelement("label")}} element. We already talked about using the aria-label property to provide a label where we don't want the label to be visible to sighted users (see the {{anch("Signposts/Landmarks")}} section, above). There are some other labelling techniques that use other properties such as aria-labelledby if you want to designate a non-<label> element as a label or label multiple form inputs with the same label, and aria-describedby, if you want to associate other information with a form input and have it read out as well. See WebAIM's Advanced Form Labeling article for more details.

- -

There are many other useful properties and states too, for indicating the status of form elements. For example, aria-disabled="true" can be used to indicate that a form field is disabled. Many browsers will just skip past disabled form fields, and they won't even be read out by screenreaders, but in some cases they will be perceived, so it is a good idea to include this attribute to let the screenreader know that a disabled input is in fact disabled.

- -

If the disabled state of an input is likely to change, then it is also a good idea to indicate when it happens, and what the result is. For example, in our form-validation-checkbox-disabled.html demo there is a checkbox that when checked, enables another form input to allow further information be entered. We've set up a hidden live region:

- -
<p class="hidden-alert" aria-live="assertive"></p>
- -

which is hidden from view using absolute positioning. When this is checked/unchecked, we update the text inside the hidden live region to tell screenreader users what the result of checking this checkbox is, as well as updating the aria-disabled state, and some visual indicators too:

- -
function toggleMusician(bool) {
-  var instruItem = formItems[formItems.length-1];
-  if(bool) {
-    instruItem.input.disabled = false;
-    instruItem.label.style.color = '#000';
-    instruItem.input.setAttribute('aria-disabled', 'false');
-    hiddenAlert.textContent = 'Instruments played field now enabled; use it to tell us what you play.';
-  } else {
-    instruItem.input.disabled = true;
-    instruItem.label.style.color = '#999';
-    instruItem.input.setAttribute('aria-disabled', 'true');
-    instruItem.input.removeAttribute('aria-label');
-    hiddenAlert.textContent = 'Instruments played field now disabled.';
-  }
-}
- -

Describing non-semantic buttons as buttons

- -

A few times in this course already, we've mentioned the native accessibilty of (and the accessibility issues behind using other elements to fake) buttons, links, or form elements (see UI controls in the HTML accessibility article, and {{anch("Enhancing keyboard accessibility")}}, above). Basically, you can add keyboard accessibility back in without too much trouble in many cases, using tabindex and a bit of JavaScript.

- -

But what about screenreaders? They still won't see the elements as buttons. If we test our fake-div-buttons.html example in a screenreader, our fake buttons will be reported using phrases like "Click me!, group", which is obviously confusing.

- -

We can fix this using a WAI-ARIA role. Make a local copy of fake-div-buttons.html, and add role="button" to each button <div>, for example:

- -
<div data-message="This is from the first button" tabindex="0" role="button">Click me!</div>
- -

Now when you try this using a screenreader, you'll have buttons be reported using phrases like "Click me!, button" — much better.

- -
-

Note: Don't forget however that using the correct semantic element where possible is always better. If you want to create a button, and can use a {{htmlelement("button")}} element, you should use a {{htmlelement("button")}} element!

-
- -

Guiding users through complex widgets

- -

There are a whole host of other roles that can identify non-semantic element structures as common UI features that go beyond what's available in standard HTML, for example combobox, slider, tabpanel, tree. You can see a number of userful examples in the Deque university code library, to give you an idea of how such controls can be made accessible.

- -

Let's go through an example of our own. We'll return to our simple absolutely-positioned tabbed interface (see Hiding things in our CSS and JavaScript accessibility article), which you can find at Tabbed info box example (see source code).

- -

This example as-is works fine in terms of keyboard accessibility — you can happily tab between the different tabs and select them to show the tab contents. It is also fairly accessible too — you can scroll through the content and use the headings to navigate , even if you can't see what is happening on screen. It is however not that obvious what the content is — a screenreader currently reports the content as a list of links, and some content with three headings. It doesn't give you any idea of what the relationship is between the content. Giving the user more clues as to the structure of the content is always good.

- -

To improve things, we've created a new version of the example called aria-tabbed-info-box.html (see it running live). We've updated the structure of the tabbed interface like so:

- -
<ul role="tablist">
-  <li class="active" role="tab" aria-selected="true" aria-setsize="3" aria-posinset="1" tabindex="0">Tab 1</li>
-  <li role="tab" aria-selected="false" aria-setsize="3" aria-posinset="2" tabindex="0">Tab 2</li>
-  <li role="tab" aria-selected="false" aria-setsize="3" aria-posinset="3" tabindex="0">Tab 3</li>
-</ul>
-<div class="panels">
-  <article class="active-panel" role="tabpanel" aria-hidden="false">
-    ...
-  </article>
-  <article role="tabpanel" aria-hidden="true">
-    ...
-  </article>
-  <article role="tabpanel" aria-hidden="true">
-    ...
-  </article>
-</div>
- -
-

Note: The most striking change here is that we've removed the links that were originally present in the example, and just used the list items as the tabs — this was done because it makes things less confusing for screenreader users (the links don't really take you anywhere; they just change the view), and it allows the setsize/position in set features to work better — when these were put on the links, the browser kept reporting "1 of 1" all the time, not "1 of 3", "2 of 3", etc.

-
- -

The new features are as follows:

- - - -

In our tests, this new structure did serve to improve things overall. The tabs are now recognised as tabs (e.g. "tab" is spoken by the screenreader), the selected tab is indicated by "selected" being read out with the tab name, and the screenreader also tells you which tab number you are currently on. In addition, because of the aria-hidden settings (only the non-hidden tab ever has aria-hidden="false" set), the non-hidden content is the only one you can navigate down to, meaning the selected content is easier to find.

- -
-

Note: If there is anything you explicitly don't want screen readers to read out, you can give them the aria-hidden="true"  attribute.

-
- -

Summary

- -

This article has by no means covered all that's available in WAI-ARIA, but it should have given you enough information to understand how to use it, and know some of the most common patterns you will encounter that require it.

- -

See also

- - - -

{{PreviousMenuNext("Learn/Accessibility/CSS_and_JavaScript","Learn/Accessibility/Multimedia", "Learn/Accessibility")}}

- -

В этом модуле

- - diff --git "a/files/ru/learn/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/what_is_accessibility/index.html" "b/files/ru/learn/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/what_is_accessibility/index.html" deleted file mode 100644 index 1a6e11f73e..0000000000 --- "a/files/ru/learn/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/what_is_accessibility/index.html" +++ /dev/null @@ -1,210 +0,0 @@ ---- -title: Что такое доступность? -slug: Learn/Доступность/What_is_accessibility -tags: - - CSS - - HTML - - JavaScript - - Изучение - - Клавиатура - - Написание скриптов - - Начинающий - - Программные средства - - Статья - - Считыватель экрана - - вспомогательная технология - - доступность -translation_of: Learn/Accessibility/What_is_accessibility ---- -
{{LearnSidebar}}
- -
{{NextMenu("Learn/Accessibility/HTML", "Learn/Accessibility")}}
- -

Данная статья открывает модуль, в котором рассматривается, что такое доступность на самом деле — она включает в себя группы людей, которые нам нужно учитывать и почему, какие инструменты используют разные пользователи для взаимодействия с вебом, и как мы можем сделать доступность частью нашего рабочего процесса веб-разработки.

- - - - - - - - - - - - -
Необходимые знания:Базовая компьютерная грамотность, базовое понимание HTML и CSS.
Цель:Узнать, что такое доступность, и как она влияет на вас как на веб-разработчика.
- -

Итак, что такое доступность?

- -

Доступность — это практика, позволяющая использовать ваши сайты как можно большему числу людей. Мы традиционно думаем об этом как о доступности для людей с ограниченными возможностями, но на самом деле, в это число входят и другие группы пользователей, которые используют мобильные устройства либо имеют медленное сетевое соединение.

- -

Вы также можете думать о доступности как о способе предоставления равных прав и одинаковых возможностей, независимо от способностей или обстоятельств. Точно так же, как не правильно лишать человека права посещать разнообразные места, только потому что он перемещается в инвалидном кресле (общественные здания в наши дни обычно имеют пандусы для инвалидных колясок или лифты), так и не правильно исключать кого-либо из веб-пространства из-за того, что у них слабое зрение или они используют мобильный телефон. Мы все разные, но все мы люди, и поэтому имеем одинаковые (человеческие) права.

- -

Помимо того, что доступность это просто хороший тон, она также регулируется законодательством в некоторых странах и может поспособствовать открытию важных рынков, которые в противном случае не смогут использовать ваши услуги, покупать ваши продукты и т. д.

- -

Доступность и опыт её применения принесут пользу всем:

- - - -

Какие виды ограниченных возможностей мы рассматриваем?

- -

Люди с ограниченными возможностями так же разнообразны, как и люди без них, так и своими недостатками. Ключевой урок заключается в том, чтобы думать за пределами вашего собственного компьютера и того, как вы используете Интернет, и начать изучать как его используют другие — вы не ваши пользователи. Ниже разъясняются основные виды инвалидности, а также любые специализированные инструменты, которые  используются для доступа к веб-контенту (известные как вспомогательные технологии).

- -
-

Примечание: в информационном бюллетене Всемирной организации здравоохранения по вопросам Инвалидности и Здоровья говорится, что "Более 1 миллиарда людей, около 15% населения мира, имеют какую-либо форму инвалидности" и "От 110 до 190 миллионов взрослых испытывают значительные трудности в функционировании."

-
- -

Люди с нарушениями зрения

- -

Сюда относятся люди со слепотой, слабым зрением, дальтонизмом и другие. Многие из этих людей используют экранные лупы (либо физические лупы, либо программные возможности масштабирования — большинство браузеров и операционных систем в наши дни имеют возможности масштабирования), а некоторые будут использовать программы чтения с экрана, то есть программное обеспечение, которое читает цифровой текст вслух:

- - - -

Хорошая идея ознакомиться с экранными дикторами; вы можете настроить экранный считыватель и поиграть с ним, чтобы получить представление о том, как это работает. Более подробную информацию об их использовании см. в руководстве по кросс-браузерному тестированию. Видео ниже предоставляет краткий пример взаимодействия с экранными читателями.

- -

{{EmbedYouTube("IK97XMibEws")}}

- -

 

- -

Что касается статистики: по оценкам Всемирной Организации Здравоохранения: "285 миллионов человек во всем мире страдают нарушениями зрения: 39 миллионов слепы и 246 имеют слабовидение." (см. Нарушения зрения и слепота). Это большая и значительная группа пользователей, которые просто упущены, потому что ваш сайт не закодирован должным образом — почти такой же размер, как и население Соединенных Штатов Америки.

- -

Люди с нарушениями слуха

- -

Эта группа людей либо имеет низкий уровень слуха, либо вообще не слышит. Люди с нарушениями слуха используют ATs (см. Вспомогательные устройства для людей с нарушениями слуха, голоса, речи или языка), но на самом деле нет специальных ATs, специфичных для использования на компьютере или в интернете.

- -

Однако существуют специальные техники, которые следует учитывать для предоставления текстовых альтернатив аудиоконтенту, который люди смогут читать, от простых текстовых транскриптов до текстовых дорожек (т.е. подписей), которые могут отображаться вместе с видео. Об этом будет рассказано в статье позже.

- -

Люди с нарушениями слуха представляют значительную базу пользователей — "360 миллионов человек в мире страдают от инвалидизирующей потери слуха", — говорится в информационном бюллетене Всемирной Организации Здравоохранения о Глухоте и потере слуха.

- -

Люди с ограниченными физическими возможностями 

- -

Это группа людей, которые имеют инвалидность в отношении движения, которая может включать в себя чисто физические проблемы (такие как потеря конечности или паралич), или неврологические/генетические расстройства, которые приводят к слабости или потере контроля в конечностях. Некоторые люди могут испытывать трудности с выполнением точных движений рук, необходимых для использования мыши, в то время как другие могут быть более серьезно затронуты, возможно, значительно парализованы до такой степени, что им нужно использовать указатель головы для взаимодействия с компьютером.

- -

Этот вид инвалидности также может быть результатом старости, а не какой-либо конкретной травмы или состояния, а также может быть результатом аппаратных ограничений — у некоторых пользователей может не быть мыши.

- -

Управление элементами с помощью клавиатуры является обычным требованием, которое влияет на процесс веб-разработки — мы обсудим доступ с клавиатруы в последующих статьях модуля. Хорошая идея, чтобы попробовать пользоваться веб-сайтами, только с помощью клавиатуры, чтобы увидеть, что из этого выйдет и как это работает. Например, можно ли использовать клавишу Tab для перемещения между различными элементами управления веб-формы? Вы можете найти больше деталей об использовании клавиатуры в нашей секции Cross browser testing Using native keyboard accessibility.

- -

С точки зрения статистики, значительное количество людей имеют нарушения мобильности. Центры США по контролю и профилактике заболеваний Инвалидности и Функционирования (Неинституционализированные взрослые в возрасте 18 лет и старше) сообщают, что в США "Процент взрослых с любым физическим нарушением функционирования: 16,1%".

- -

Люди с когнитивными нарушениями

- -

Вероятно, самый широкий спектр инвалидности можно увидеть в этой категории — когнитивные нарушения в широком смысле могут относиться к инвалидности от психических заболеваний до трудностей в обучении, трудности в понимании и концентрации, такие как СДВГ (синдром дефицита внимания и гиперактивности), людям аутистического спектра, людям с шизофренией, и множество других типов нарушений. Такие недостатки могут повлиять на многие детали повседневной жизни из-за проблем с памятью, решением, пониманием, вниманием и т. д.

- -

Наиболее распространенные способы, вызванные когнитивными нарушениями, которые могут повлиять на использование веб-сайта — трудности с пониманием того, как выполнить задачу; вспомнить, как сделать что-то, что было ранее выполнено; повышенное разочарование в запутанных рабочих процессах или непоследовательных макетах/навигации/других функциях страницы.

- -

В отличие от других проблем доступности интернета, невозможно назначить быстрые исправления для многих проблем доступности, связанных с когнитивными нарушениями; лучшее решение, которое у вас есть — это проектировать веб-сайты таким образом, чтобы они были логичными, последовательными и удобными для использования настолько, насколько это возможно. Например, убедитесь, что:

- - - -

Это не "методы доступности" как таковые — это хорошая практика проектирования. Они принесут пользу всем, кто использует ваши сайты, и должны быть стандартной частью вашей работы.

- -

С точки зрения статистики, опять же цифры значительны. Отчет Корнелльского университета О состоянии инвалидности за 2014 год (PDF, 511 КБ)(en) показывает, что в 2014 году 4,5% людей в США в возрасте 21-64 лет имели ту или иную форму когнитивной инвалидности.

- -
-

Примечание: Страница о когнитивных расстройствах на WebAIM обепечивает полезное распространение этих идей, и это, безусловно, стоит прочитать.

-
- -

Реализация доступности в проекте

- -

Распространенный миф о доступности заключается в том, что доступность является дорогостоящим "дополнением" для реализации проекта. Этот миф на самом деле может быть правдой, если:

- - - -

Если вы рассматриваете доступность с самого начала проекта, то стоимость создания доступного контента должна быть весьма небольшой.

- -

При планировании проекта учитывайте тестирование доступности в своём режиме тестирования, как при тестировании любого другого важного сегмента целевой аудитории (например, настольный или мобильный браузер). Тестируйте на ранних этапах и часто, выполняя автоматические тесты, чтобы выявить программно обнаруживаемые отсутствующие функции (такие как отсутствующий альтернативный текст изображения или неправильная ссылка — см. Element relationships and context), и тестируйте с некоторыми нетрудоспособными групами пользователей, чтобы увидеть, насколько хорошо для них работают более сложные функции сайта. Например:

- - - -

Вы можете и должны хранить заметку о потенциальных проблемных местах в контенте, которые будут нуждаться в доработке, чтобы сделать их доступыми, убедитесь, что они тщательно протестированы, и подумайте о решениях/альтернативах. Текстовый контент (как вы увидите в следующей статье) довольно прост, но как насчет вашего мультимедийного контента, и красивой 3D-графики? Вы должны смотреть на свой бюджет проекта и реально думать о том, какие решения у вас есть, чтобы сделать такой контент доступным? Вы можете заплатить за расшифровку всего вашего мультимедийного контента, это может быть дорогостоящим, но будет сделано.

- -

Кроме того, будьте реалистами. "100% доступность" является недостижимым идеалом — вы всегда столкнетесь с каким-то случаем, который приводёт к тому, что определенный пользователь найдёт определенный контент трудным в использовании, но вы должны сделать столько, сколько сможете. Если вы планируете использовать трехмерную круговую диаграмму, созданную с помощью WebGL, вы можете включить таблицу данных в качестве доступного альтернативного представления данных. Или, вы можете просто включить таблицу и избавиться от 3D круговой диаграммы-таблица доступна для всех, быстрее кодировать, меньше ресурсов процессора, и проще в обслуживании.

- -

С другой стороны, если вы работаете на веб-сайте галереи с интересным трехмерным искусством, было бы неразумно ожидать, что каждое произведение искусства будет идеально доступно для людей с нарушениями зрения, учитывая, что это полностью визуальная среда.

- -

Чтобы показать, что вы заботитесь о доступности и думали о ней, опубликуйте на своем сайте заявление о доступности, в котором подробно излагается, какова ваша политика в отношении доступности, и какие шаги вы предприняли для обеспечения доступности сайта. Если кто-то жалуется, что у вашего сайта есть проблема с доступностью, начните с ним диалог, проявите сочувствие и примите разумные меры, чтобы попытаться устранить проблему.

- -
-

Note: В нашей статье «Об общих проблемах доступности» рассматриваются особенности доступности, которые необходимо протестировать более подробно.

-
- -

Подведём итоги:

- - - -

Руководство по доступности и закон

- -

Существует множество чеклистов и наборов руководств, на которых можно основываться при тестировании доступности, которые на первый взгляд могут показаться ошеломляющими. Наш совет — ознакомиться с основными областями, о которых вам необходимо позаботиться, а также понять структуры руководящих принципов, которые наиболее актуальны для вас.

- - - -

Поэтому, хотя WCAG представляет собой набор руководств, в вашей стране, вероятно, будут приняты законы, регулирующие доступность веба или, по крайней мере, доступность обществественных услуг (которые могут включать в себя веб-сайты, телевидение, физические пространства и т.д.). Это хорошая идея — узнать, каковы ваши законы. Если вы не предпримете никаких усилий, чтобы проверить, что ваш контент доступен, у вас могут возникнуть проблемы с законом, если люди с ограниченными возможностями жалуются на это.

- -

Это звучит серьезно, но на самом деле вам просто нужно рассматривать доступность в качестве основного приоритета вашей практики веб-разработки, как описано выше. В случае сомнений обратитесь за советом к квалифицированному юристу. Мы не собираемся предлагать больше советов, чем эти, потому что мы не юристы.

- -

Специальные API доступа

- -

Веб-браузеры используют специальные API доступа (предоставляемые базовой операционной системой)  которые предоставляют информацию, полезную для вспомогательных технологий (AT). AT обычно используют семантическую информацию, поэтому эта информация не включает такие вещи, как информация о стилях или JavaScript. Эта информация структурирована в дереве информации, которое называется деревом доступности.

- -

Различные операционные системы имеют разные API доступа:

- - - -

Там, где нативная семантическая информация, предоставляемая элементами HTML в ваших веб-приложениях, падает, вы можете дополнить ее функциями из спецификации WAI-ARIA, которые добавляют семантическую информацию в дерево доступности для улучшения доступности. Вы можете узнать больше о WAI-ARIA в нашей статье основы WAI-ARIA.

- -

Заключение

- -

Эта статья должна была дать вам полезный обзор специальных возможностей, показать, почему это так важно, и посмотреть, как вы можете вписать его в свой рабочий процесс. Теперь у вас также должна быть жажда узнать о деталях реализации, которые помогут сделать сайты доступными, и мы начнем с этого в следующем разделе, рассматривая, почему HTML является хорошей основой для доступности.

- -

{{NextMenu("Learn/Accessibility/HTML", "Learn/Accessibility")}}

- -

В этом модуле

- - diff --git "a/files/ru/learn/\320\272\320\260\320\272_\321\201\320\264\320\265\320\273\320\260\321\202\321\214_\320\262\320\272\320\273\320\260\320\264/index.html" "b/files/ru/learn/\320\272\320\260\320\272_\321\201\320\264\320\265\320\273\320\260\321\202\321\214_\320\262\320\272\320\273\320\260\320\264/index.html" deleted file mode 100644 index caed3b7970..0000000000 --- "a/files/ru/learn/\320\272\320\260\320\272_\321\201\320\264\320\265\320\273\320\260\321\202\321\214_\320\262\320\272\320\273\320\260\320\264/index.html" +++ /dev/null @@ -1,85 +0,0 @@ ---- -title: Как сделать вклад в Обучающую Зону MDN -slug: Learn/Как_сделать_вклад -tags: - - Вклад - - Документация - - Новичку - - Новичок - - Обучение - - Правила - - Руководство -translation_of: Learn/How_to_contribute ---- -
{{LearnSidebar}}
- -

Оказались ли вы здесь впервые или в результате глубокого поиска, вас, вероятно, привело сюда желание помочь Обучающей Зоне MDN. И это отличная новость!

- -

На этой странице вы найдёте всё необходимое для того, чтобы помочь улучшить обучающий контент MDN. Здесь есть много вещей, которые вы можете сделать, в зависимости от того, сколько времени у вас есть и кем вы являетесь новичком, веб-разработчиком или учителем.

- -
-

Руководство по написанию новой статьи в обучающем пространстве можно посмотреть на странице How to write an article to help people learn about the Web.

-
- -

Найдите конкретные задачи

- -

Для организации своих задач участники сообщества используют Trello board. Там вы можете найти конкретные задачи проекта, ожидающие выполнения. Если вы хотите использовать её, просто создайте Trello аккаунт и напишите Chris Mills, чтобы он дал доступ к записи на доску.

- -

Принятие участия - это также отличный способ повеселиться, одновременно изучая новое. Если вы запутались или у вас есть вопросы, не стесняйтесь написать нам в наш список рассылки или IRC канал (подробности указаны внизу этой страницы). Chris Mills заведует Обучающей Зоной — вы также можете попробовать написать ему напрямую.

- -

В следующих разделах описаны некоторые идеи касательно задач, которыми вы могли бы заняться.

- -

Я новичок

- -

Это круто! Новички очень важны для создания и предоставления отзывов об материалах для обучения. Ваш уникальный взгляд представителя целевой аудитории данных статей может сделать вас бесценным участником нашей команды. В самом деле, если вы "застряли" в процессе изучения какой-либо темы по одной из наших статей, или находите эту статью в некотором роде запутанной, вы можете либо исправить её сами, либо сообщить об этой проблеме нам, чтобы мы позаботились о её исправлении.

- -

Вот как, например, вы можете помочь:

- -
-
Добавьте теги к нашим статьям (5 мин)
-
Добавление тегов к контенту MDN - один из самых легких способов внести свой вклад. Помощь в этом направлении очень ценна, поскольку теги широко применяются в MDN, чтобы вписать информацию в контекст. Начать можно с просмотра списков словарных и обучающих статей.
-
Прочитайте и проверьте статью в словаре (5 мин)
-
Нам очень важен ваш взгляд, как начинающего, на наш контент. Если вы считаете, что статья в словаре слишком сложна, значит, её необходимо улучшить. Не стесняйтесь вносить любые необходимые, на ваш взгляд, изменения. Если вам кажется, что у вас недостаточно навыков, чтобы самостоятельно отредактировать статью, можете сообщить нам о ней в нашем списке рассылки.
-
Напишите новую статью для словаря (20 минут)
-
Это самый эффективный способ узнать что-то новое. Выберите понятие, которое вам хотелось бы изучить, и в процессе изучения пишите о нем статью для словаря. Объяснить какую-либо вещь другим - отличный способ закрепить знание в голове, и разобраться самому, при этом помогая другим. Everybody wins!
-
Прочитайте и проверьте обучающую статью (2 часа)
-
Эта задача очень похожа на проверку статей в словаре (см. выше), она лишь занимает больше времени, поскольку обычно такие статьи значительно длиннее.
-
- -

Я веб-разработчик

- -

Фантастика! Ваши технические навыки - именно то, что помогает нам убедиться в технической точности контента для новичков. Поскольку данная конкретная часть MDN посвящена обучению Вебу, постарайтесь делать ваши объяснения максимально простыми, но не чересчур простыми, они не должны стать бесполезны. Понятность важнее, чем чрезмерная точность.

- -
-
Прочитайте и проверьте статью в словаре (5 мин)
-
Нам важно, чтобы вы, как веб-разработчик, убедились в том, что наш контент технически точен, но при этом не слишком сложен. Не стесняйтесь делать любые изменения, которые вам покажутся нужными. Если вы хотите обсудить контент до того, как приступать к редактированию, напишите нам в список рассылки или IRC канал.
-
Напишите новую статью для словаря (20 минут)
-
Разъяснение технического жаргона - хороший способ научиться быть одновременно технически точным и простым. Новички будут вам за это благодарны. У нас есть много терминов без определений, которые нуждаются в вашем внимании. Выберите один и приступайте!
-
Прочитайте и проверьте обучающую статью (2 часа)
-
Это тоже самое, что и проверка статьи в словаре (см.выше), но занимает больше времени, поскольку обычно такие статьи значительно длиннее.
-
Напишите новую обучающую статью (4 часа или больше)
-
MDN не хватает ясных и доходчивых статей об использовании веб-технологий (HTML, CSS, JavaScript, и т.д). Кроме того, у нас есть старый контент, который нуждается в редактуре и изменениях. Доведите ваши умения до предела, чтобы сделать веб-технологии пригодными для использования даже начинающими.
-
Создайте упражнения, примеры кода или интерактивные обучающие инструменты (? часов)
-
Все наши обучающие статьи требуют материалов, как мы это называем, "активного обучения", так как эффективнее всего люди учатся, выполняя что-либо самостоятельно. Под такого рода материалами подразумеваются упражнения или интерактивный контент, которые помогают пользователю применять и оперировать понятиями, описанными в статье. Существует множество способов создания контента активного обучения, от написания образцов кода с помощью JSFiddle или подобных инструментов, до построения fully hackable интерактивного контента в Thimble. Раскройте ваш творческий потенциал!
-
- -

Я учитель

- -

У MDN долгая история совершенствования в техническом плане, но нам не хватает глубины понимания того, как лучше обучать новичков. Именно на этом этапе мы нуждаемся в вас, как в преподавателях и педагогах. Вы можете помочь нам гарантировать, что наши материалы обеспечивают хороший, практикоориентированный образовательный путь для наших читателей.

- -
-
Прочитайте и проверьте статью в словаре (15 мин)
-
Просмотрите словарную статью и не стесняйтесь вносить любые необходимые, на ваш взгляд, изменения. Если вы хотели бы обсудить контент перед тем, как редактировать, напишите нам в наш список рассылки или IRC канал.
-
Напишите новую статью для словаря (1 час)
-
Новички очень нуждаются в ясных, простых определениях терминов и базовом обзоре понятий в словаре. Ваш педагогический опыт может помочь нам создать превосходные словарные статьи; у нас есть множество терминов без определений, которые нуждаются в вашем внимании. Выбирайте один из них и приступайте.
-
Добавьте илллюстрации и/или схемы в статью (1 час)
-
Как вам, наверное, известно, иллюстрации - бесценная часть любого обучающего материала. Зачастую именно их нам не хватает на MDN, и ваши навыки могут улучшить ситуацию в данной области. Посмотрите список статей, у которых отсутствует иллюстративный материал, и выберите одну, к которой вам бы хотелось создать графику.
-
Прочитайте и проверьте обучающую статью (2 часа)
-
Это тоже самое, что и проверка статьи в словаре (см.выше), но занимает больше времени, поскольку обычно такие статьи значительно длиннее.
-
Напишите новую обучающую статью (4 часа)
-
Нам нужны простые, доходчивые статьи о Web экосистеме и прочих практических темах в связанных областях. Поскольку данные обучающие статьи должны быть скорее образовательными, чем охватывать целиком всю имеющуюся информацию, ваш опыт касательно того, что именно нужно осветить и как, будет очень ценен.
-
Создайте упражнения, викторины или интерактивные обучающие инструменты (? часа)
-
Все наши обучающие статьи требуют материалов "активного обучения", то есть упражнений или интерактивного контента, которые помогают пользователю углубиться и научиться использовать концепции, описанные в статье. В этой области вы можете сделать многое, от создания викторин до построения fully hackable интерактивного контента с Thimble. Раскройте вашу творческую сторону!
-
Создайте пути обучения (? часа)
-
Чтобы предоставить прогрессивные и доступные для понимания руководства, нам необходимо объединять контент в пути. Это способ собрать существующий контент и выяснить, чего в нем недостает для написания обучающей статьи.
-
diff --git "a/files/ru/learn/\321\204\321\200\320\276\320\275\321\202\320\265\320\275\320\264_\321\200\320\260\320\267\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272/index.html" "b/files/ru/learn/\321\204\321\200\320\276\320\275\321\202\320\265\320\275\320\264_\321\200\320\260\320\267\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272/index.html" deleted file mode 100644 index c219d6a069..0000000000 --- "a/files/ru/learn/\321\204\321\200\320\276\320\275\321\202\320\265\320\275\320\264_\321\200\320\260\320\267\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272/index.html" +++ /dev/null @@ -1,195 +0,0 @@ ---- -title: Фронтенд разработчик -slug: Learn/Фронтенд_разработчик -tags: - - Начинающий - - Стандарты веб-разработки - - Фронт-енд -translation_of: Learn/Front-end_web_developer ---- -

{{learnsidebar}}
-
- Добро пожаловать на курс обучения Фронтенд разработчика!
-
- Здесь мы предлагаем вам структурированный курс, который научит вас всему, что вам необходимо знать, чтобы стать фронтенд разработчиком. Изучение в рекомендуемом порядке каждого раздела позволит получить новые навыки, или улучшить имеющиеся. Также в каждом разделе вы найдете упражнения и тесты. Прежде чем переходить к следующей теме обязательно проверьте себя.

- -

Основные темы:

- -

В курсе рассматриваются темы:

- - - -

Различные разделы предназначены для проработки по порядку, но каждый из них также самодостаточен. Если вы, к примеру, уже хорошо знакомы с HTML, то можете перейти к разделу CSS.

- -

Необходимые условия

- -

Вам не нужно никаких предварительных знаний, чтобы начать этот курс. Всё, что вам необходимо – это компьютер, который может работать с современными браузерами, интернет соединение и готовность учиться.
-
- Если вы не уверены, подходит ли вам фронтент разработка и/или вы хотите получить подробное представление, то прежде чем начинать полный курс, вам следует сначала изучить наш раздел Начало работы с веб модулем.

- -

Получить помощь

- -

Мы постарались сделать изучение фронтенд разработки настолько комфортным, насколько это возможно. Вероятно, вы всё равно рано или поздно попадёте в безвыходное положение, когда что-то будет непонятно или какой-то код не будет работать.

- -

Не беспокойтесь. Мы все иногда застреваем, и начинающие, и профессиональные веб-разработчики. Статья Обучение и получение помощи предоставит вам серию советов и подсказок для поиска информации и помощи самому себе. Если вы всё ещё в замешательстве, задайте вопрос по возникшей проблеме на нашем Форуме.

- -

Давайте начнём,

- -

Удачи!

- -

Путь обучения

- -

Начало работы

- -

Время изучения: 1–2 часа

- -

Необходимые условия

- -

Ничего, кроме базовой компьютерной грамотности.

- -

Как понять, что я могу двигаться дальше?

- -

В этой части курса нет оценок, но обязательно убедитесь, что вы ничего здесь не пропустили — важно всё настроить и подготовиться к выполнению упражнений в дальнейшем.

- -

Основные руководства

- - - -

Семантика и структура с HTML

- -

Время завершения: 35–50 часов

- -

Необходимые условия

- -

Ничего, кроме базовой компьютерной грамотности и базовой среды разработки веб-приложений.

- -

Как понять, что я могу двигаться дальше?

- -

Оценки в каждом модуле предназначены для проверки ваших знаний по предмету - завершение каждого из них докажет, что вы можете перейти к следующему модулю.

- -

Основные модули

- - - -

Стилизация и размещение с помощью CSS

- -

Время завершения: 90–120 часов

- -

Необходимые условия

- -

Рекомендуется иметь базовые знания HTML перед началом изучения CSS. Сначала вы должны изучить Введение в HTML.

- -

Как понять, что я могу двигаться дальше?

- -

Оценки в каждом модуле предназначены для проверки ваших знаний по предмету - завершение каждого из них докажет, что вы можете перейти к следующему модулю.

- -

Основные модули

- - - -

Дополнительные ресурсы

- - - -

Интерактивность с JavaScript

- -

Время завершения: 135–185 часов

- -

Необходимые условия

- -

Рекомендуется иметь базовые знания HTML перед началом изучения JavaScript. Сначала вы должны изучить Введение в HTML.

- -

Как понять, что я могу двигаться дальше?

- -

Оценки в каждом модуле предназначены для проверки ваших знаний по предмету - завершение каждого из них докажет, что вы можете перейти к следующему модулю.

- -

Основные модули

- - - -

Веб формы — Работаем с данными пользователя

- -

Время завершения: 40–50 часов

- -

Необходимые условия

- -

Для эффективного использования форм требуется знание HTML, CSS и JavaScript. Они сложны и поэтому рассматриваются отдельно.

- -

Как понять, что я могу двигаться дальше?

- -

Упражнения и оценки в каждом модуле предназначены для проверки ваших знаний по предмету - завершение каждого из них докажет, что вы можете перейти к следующему модулю.

- -

Основные модули

- - - -

Заставляем веб работать для всех

- -

Время завершения: 60–75 часов

- -

Необходимые условия

- -

Рекомендуется ознакомиться с HTML, CSS и JavaScript перед началом работы с этим разделом - многие из техник и лучших практик используются в нескольких технологиях.

- -

Как понять, что я могу двигаться дальше?

- -

Упражнения и оценки в каждом модуле предназначены для проверки ваших знаний по предмету - завершение каждого из них докажет, что вы можете перейти к следующему модулю.

- -

Основные модули

- - - -

Современные инструменты

- -

Время завершения: 55–90 часов

- -

Необходимые условия

- -

Рекомендуется ознакомиться с HTML, CSS и JavaScript перед началом работы с этим разделом, так как обсуждаемые инструменты работают со многими из этих технологий.

- -

Как понять, что я могу двигаться дальше?

- -

В этом наборе модулей нет специальных статей для оценки, но учебные примеры в конце 2-го и 3-го модулей хорошо подготовят вас к пониманию основ современного инструментария.

- -

Основные модули

- - diff --git "a/files/ru/learn/\321\207\321\202\320\276_\321\202\320\260\320\272\320\276\320\265_\320\262\320\265\320\261_\321\201\320\265\321\200\320\262\320\265\321\200/index.html" "b/files/ru/learn/\321\207\321\202\320\276_\321\202\320\260\320\272\320\276\320\265_\320\262\320\265\320\261_\321\201\320\265\321\200\320\262\320\265\321\200/index.html" deleted file mode 100644 index efdc287ba9..0000000000 --- "a/files/ru/learn/\321\207\321\202\320\276_\321\202\320\260\320\272\320\276\320\265_\320\262\320\265\320\261_\321\201\320\265\321\200\320\262\320\265\321\200/index.html" +++ /dev/null @@ -1,128 +0,0 @@ ---- -title: Что такое веб-сервер -slug: Learn/Что_такое_веб_сервер -tags: - - Веб-сервер - - Динамический сайт - - Новичок - - Статический сайт -translation_of: Learn/Common_questions/What_is_a_web_server ---- -
-

В этой статье мы узнаем, что из себя представляют веб-серверы, как они работают, и почему они так важны.

-
- - - - - - - - - - - - -
Необходимые
- знания:
Вы должны уже знать, как работает Интернет и понимать разницу между страницей, сайтом, сервером и поисковой системой.
Цель: -

Вы узнаете, что такое веб-сервер и получите общее представление о том, как он работает.

-
- -

Введение

- -

Понятие «веб-сервер» может относиться как к аппаратной начинке, так и к программному обеспечению. Или даже к обеим частям, работающим совместно.

- -
    -
  1. С точки зрения "железа", «веб-сервер» — это компьютер, который хранит файлы сайта (HTML-документы, CSS-стили, JavaScript-файлы, картинки и другие) и доставляет их на устройство конечного пользователя (веб-браузер и т.д.). Он подключен к сети Интернет и может быть доступен через доменное имя, подобное mozilla.org.
  2. -
  3. С точки зрения ПО, веб-сервер включает в себя несколько компонентов, которые контролируют доступ веб-пользователей к размещенным на сервере файлам, как минимум — это HTTP-сервер. HTTP-сервер — это часть ПО, которая понимает {{Glossary("URL","URL’ы ")}} (веб-адреса) и {{Glossary("HTTP")}} (протокол, который ваш браузер использует для просмотра веб-страниц).
  4. -
- -

На самом базовом уровне, когда браузеру нужен файл, размещенный на веб-сервере, браузер запрашивает его через HTTP-протокол. Когда запрос достигает нужного веб-сервера ("железо"), сервер HTTP (ПО) принимает запрос, находит запрашиваемый документ (если нет, то сообщает об ошибке 404) и отправляет обратно, также через HTTP.

- -

Basic representation of a client/server connection through HTTP

- -

Чтобы опубликовать веб-сайт, необходим либо статический, либо динамический веб-сервер.

- -

Статический веб-сервер, или стек, состоит из компьютера ("железо") с сервером HTTP (ПО). Мы называем это «статикой», потому что сервер посылает размещенные файлы в браузер «как есть».

- -

Динамический веб-сервер состоит из статического веб-сервера и дополнительного программного обеспечения, чаще всего сервера приложения и базы данных. Мы называем его «динамическим», потому что сервер приложений изменяет исходные файлы перед отправкой в ваш браузер по HTTP.

- -

Например, для получения итоговой страницы, которую вы просматриваете в браузере, сервер приложений может заполнить HTML-шаблон данными из базы данных. Такие сайты, как MDN или Википедия, состоят из тысяч веб-страниц, но они не являются реальными HTML документами — лишь несколько HTML-шаблонов и гигантские базы данных. Эта структура упрощает и ускоряет сопровождение веб-приложений и доставку контента.

- -

Активное изучение

- -

Активное изучение пока не доступно. Пожалуйста, рассмотрите возможность внести свой вклад.

- -

Погружаемся глубже

- -

Чтобы загрузить веб-страницу, как мы уже говорили, ваш браузер отправляет запрос к веб-серверу, который приступает к поиску запрашиваемого файла в своем собственном пространстве памяти. Найдя файл, сервер считывает его, обрабатывает как ему это необходимо, и отсылает в браузер. Давайте рассмотрим эти шаги более подробно.

- -

Хостинг файлов

- -

Прежде всего, веб-сервер должен содержать файлы веб-сайта, а именно все HTML-документы и связанные с ними ресурсы, включая изображения, CSS-стили, JavaScript-файлы, шрифты и видео.

- -

Технически, вы можете разместить все эти файлы на своем компьютере, но гораздо удобнее хранить их на выделенном веб-сервере, который:

- - - -

По всем этим причинам поиск хорошего хостинг-провайдера является ключевой частью создания вашего сайта. Рассмотрите многочисленные предложения компаний и выберите то, что соответствует вашим потребностям и бюджету (предложения варьируются от бесплатных до тысяч долларов в месяц). Вы можете найти подробности в этой статье.

- -

Как только вы решили проблему с хостингом, вам понадобится только загрузить свои файлы на ваш веб-сервер.

- -

Связь по HTTP

- -

Во-вторых, веб-сервер обеспечивает поддержку {{Glossary("HTTP")}} (англ. Hypertext Transfer Protocol - гипертекстовый транспортный протокол). Как следует из названия, HTTP указывает, как передавать гипертекст (т.е. связанные веб-документы) между двумя компьютерами.

- -

Протокол представляет собой набор правил для связи между двумя компьютерами. HTTP является текстовым протоколом без сохранения состояния.

- -
-
Текстовый
-
Все команды являются простым человекочитаемым текстом.
-
Не сохраняет состояние
-
Ни клиент, ни сервер не помнят о предыдущих соединениях. Например, опираясь только на HTTP, сервер не сможет вспомнить введенный вами пароль или на каком шаге транзакции вы находитесь. Для таких задач, вам потребуется сервер приложения. (Мы остановимся на этих технологиях в следующих статьях.)
-
- -

HTTP задает строгие правила взаимодействия клиента и сервера. Мы рассмотрим сам протокол HTTP в технической статье немного позднее. Пока достаточно знать об этих правилах:

- - - -

The MDN 404 page as an example of such error pageНа веб-сервере HTTP-сервер отвечает за обработку входящих запросов и ответ на них.

- -
    -
  1. При получении запроса, HTTP-сервер сначала проверяет, существует ли ресурс по данному URL.
  2. -
  3. Если это так, веб-сервер отправляет содержимое файла обратно в браузер. Если нет, сервер приложения генерирует необходимый ресурс.
  4. -
  5. Если ничто из этого не возможно, веб-сервер возвращает сообщение об ошибке в браузер, чаще всего “404 Not Found”. (Это ошибка настолько распространена, что многие веб-дизайнеры тратят большое количество времени на разработку 404 страниц об ошибках.)
  6. -
- -

Статический и Динамический контент

- -

Грубо говоря, сервер может отдавать статическое или динамическое содержимое. «Статическое» означает «отдается как есть». Статические веб-сайты делаются проще всего, поэтому мы предлагаем вам сделать свой первый сайт статическим.

- -

«Динамическое» означает, что сервер обрабатывает данные или даже генерирует их на лету из базы данных. Это обеспечивает большую гибкость, но технически сложнее в реализации и обслуживании, из-за чего процесс создания сайта очень сильно усложняется.

- -

Возьмем для примера страницу, которую вы сейчас читаете. На веб-сервере, где она хостится, есть сервер приложения, который извлекает содержимое статьи из базы данных, форматирует его, добавляет в HTML-шаблоны и отправляет вам результат. В нашем случае, сервер приложения называется Kuma, написан он на языке программирования Python (используя фреймворк Django). Команда Mozilla создала Kuma для конкретных нужд MDN, но есть множество подобных приложений, построенных совершенно на других технологиях.

- -

Существует так много серверов приложений, что довольно трудно предложить какой-то один. Некоторые серверы приложений заточены под определенные категории веб-сайтов, такие как блоги, вики-страницы или интернет-магазины; другие, называемые {{Glossary("CMS", "CMSs")}} (системы управления контентом), более универсальны. Если вы создаете динамический сайт, потратьте немного времени на выбор инструмента, который соответствует вашим потребностям. Если вы не хотите изучать веб-программирование (хотя это увлекательно само по себе!), то вам не нужно создавать свой собственный сервер приложения. Это будет изобретением очередного велосипеда.

- -

Следующие шаги

- -

Теперь, когда вы познакомились с веб-серверами, вы можете:

- - - -
- -
diff --git a/files/ru/mdn/at_ten/index.html b/files/ru/mdn/at_ten/index.html new file mode 100644 index 0000000000..bbbdcccd01 --- /dev/null +++ b/files/ru/mdn/at_ten/index.html @@ -0,0 +1,39 @@ +--- +title: 10-летие MDN +slug: MDN_at_ten +tags: + - MDN +translation_of: MDN_at_ten +--- +
Празднуем 10-летие документирования Web.
+ +
+
+

История MDN

+ +

В начале 2005 года небольшая группа идеалистов поставила цель создать новый, свободный и поддерживаемый сообществом интернет-ресурс для всех web-разработчиков. Их прекрасная и смелая идея переросла в Mozilla Developer Network — главный ресурс для всех открытых web-технологий. Десять лет спустя наше мировое сообщество стало больше чем когда-либо, и вместе мы продолжаем создавать документацию, примеры кода и обучающие ресурсы для всех открытых веб-технологий, включая CSS, HTML и JavaScript и всего остального, что делает открытый Web ещё лучше.

+ +

Узнать большеabout the history

+ + +

Участвие в MDN

+ +

В течение десяти лет сообщество MDN создавала документацию для открытого Web'а. От исправления простых опечаток до написания целых сайтов и совершенно новых API. Каждому есть что предложить, и этот вклад не является слишком большим или слишком маленьким. У нас есть более 90 000 страниц контента, которые были написаны или переведены членами нашего выдающегося сообщества Mozillians. Вы можете стать одним из них.

+ +

Узнать большеabout contributing

+ +

 

+ +

 

+
+ +
{{TenthCampaignQuote}}
+ +

Содержание

+ +
    +
  1. 10-летие MDN
  2. +
  3. История MDN
  4. +
  5. Участие в MDN
  6. +
+
diff --git a/files/ru/mdn/contribute/creating_and_editing_pages/index.html b/files/ru/mdn/contribute/creating_and_editing_pages/index.html deleted file mode 100644 index 9b6d34eff9..0000000000 --- a/files/ru/mdn/contribute/creating_and_editing_pages/index.html +++ /dev/null @@ -1,182 +0,0 @@ ---- -title: Как создавать и редактировать страницы -slug: MDN/Contribute/Creating_and_editing_pages -tags: - - MDN основы - - Гайд - - Как - - Новичок - - Стартовая -translation_of: MDN/Contribute/Howto/Create_and_edit_pages ---- -
{{MDNSidebar}}
- -

Данная статья предоставляет новым контрибьюторам основную информацию о процессе создания и редактирования страниц.

- -

Редактирование уже существующей страницы

- -

Чтобы редактировать страницу:

- -
    -
  1. Кликните на кнопку Редактировать в правом верхнем углу страницы.
  2. -
  3. Затем страница перезагрузится, и вы увидите редактор, в котором можно добавлять или удалять информацию напрямую.
  4. -
  5. Добавляйте параграфы, удаляйте текст, вставляйте заголовки и используйте другие основные фунцкии, которые нужны для написания и редактирования.
  6. -
- -

Смотрите руководства Редактор UI элементов в Руководстве по MDN редактору, чтобы получить больше информации об использовании встроенных MDN редакторах.

- -

Предварительный просмотр изменений

- -

Чтобы посмотреть, как ваши изменения будут выглядеть:

- - - -

Будьте аккуратны! Предварительный просмотр не сохраняет ваши изменения. Не закрывайте вкладку с редактором, пока не сохраните свою работу.

- -

Комментарий к ревизии

- -

После предварительного просмотра своих изменений вы захотите сохранить свою ревизию. Перед тем, как сохранить, посмотрите на текстовый блок с комментарием к ревизии, находящийся внизу страницы и оставляющий комментарий для того, чтобы объяснить другим контрибьторам, зачем вы сделали изменения. Например, вы могли добавить новую секцию, изменить текст, чтобы сделать терминологию более упорядоченной, переписать параграф для лучшего объяснения или удалить определённую информацию, так как она просто лишняя.

- -

Содержание

- -

В секции "В этой статье" находится список ссылок к заголовкам на странице. Вы можете изменить содержание, изменив заголовки. Также вы можете просто убрать данную секцию или увеличить количество ссылок, поменяв в секции "Редактировать описание" значение пункта "Оглавление".

- -

Метки статьи (теги)

- -

Вы можете добавлять или удалять теги, описывающие содержание и назначение страницы, в самом низу страницы редактирования. Смотрите Стандартные метки статей в MDN, чтобы получить больше информации о тегах.

- -

Требуется проверка?

- -

Если ваши изменения нуждаются в проверке экспертом или просто опытным контрибьютором, то, пожалуйста, оставьте заявку на техническую (для кода, API или технологий) и/или на редакционную (качества написания, грамматики или содержимого) проверку, убедитесь, что поставили галочки в нужных вам полях перед тем, как сохранить.

- -

Прикрепить файлы

- -

Если вы хотите прикрепить файлы к существующей странице или добавить иллюстрацию для объяснения, это может быть сделано внизу страницы. При загрузке изображения, пожалуйста, убедитесь, что используете инструменты оптимизации, чтобы сделать файл маленьким, а загрузку возможной. Это улучшает время загрузки страницы и помогает производительности MDN в целом. Вы можете использовать свой любимый инструмент, если он у вас есть. Иначе, мы предлагаем TinyPNG - удобный Веб инструмент.

- -

 Публикация, отмена или дальнейшие изменения

- -

Когда вы закончили редактирование и довольны изменениями, опубликуйте свою работу и комментарии, кликнув на зелёную кнопку Опубликовать в правом верхнем или нижнем углу страницы. Если же вы хотите продолжить вносить изменения, нажмите Сохранить и продолжить редактирование, это опубликует ваши изменения, однако оставит вас во вкладке с редактором.

- -

Если вы изменили своё мнение, вы можете отменить изменения, нажав на красную кнопку Отменить. Изменения, которые вы хотите отменить, будут навсегда отменены.

- -

Нажатие клавиши Enter в поле ввода комментария к ревизии то же самое, что нажатие кнопку Сохранить и продолжить редактирование.

- -
-

Если при попытке сохранить изменения, они были не приняты как некорректные, но вы считаете, что правки полностью приемлемы для MDN, обратитесь к администрации MDN за помощью.

-
- -

Получение прав на создание страниц

- -

По причинам безопасности недавно созданные аккаунты не имеют права добавлять новые страницы. Если вы попытаетесь сделать это, то увидите страницу с инструкцией, как создать страницу. Есть два варианта:

- - - -

Создание новой страницы

- -

Сразу же, как только вы получили право создавать страницы, вы может начать добавлять их.

- -

Если вы не знаете, где разместить новую статью, не беспокойтесь. Вставьте её, куда угодно: мы найдём её и переместим туда, где ей лучше всего быть, или используем её в уже существующем контенте. Также не волнуйтесь о том, чтобы статья выглядела идеально. У нас есть гномы-помощники, которые помогают сделать вашу статью понятнее и привлекательнее.

- -

Есть несколько способов создать страницу:

- - - -

Ссылка на отсутствующую страницу

- -

Как и в большинстве вики, возможно такое, что есть ссылка, ведущая на страницу, которой ещё нет. Например, автор мог написать список участников API перед тем, как создать страницы для этих участников. На MDN ссылки на несуществующие страницы обычно отображаются красным цветом.

- -

Чтобы создать отсутствующую страницу:

- -
    -
  1. Войдите в MDN аккаунт с правами на создание страниц. Если вы не зайдёте, тогда при переходе на ссылку на отсутсвующую страницу будет выводиться ошибка 404 (страница не найдена).
  2. -
  3. Кликните на ссылку на отсутсвующую страницу. Если у вас есть соответсвующие права, тогда перед вами откроется MDN Редактор (Editor) UI для создания страницы.
  4. -
  5. Напишите содержание страницы и сохраните её.
  6. -
- -

Новая страница без ссылки

- -

Чтобы создать новую страницу без ссылки с другой страницы, введите имя несуществующей страницы в адресной строке вашего браузера. Например, если вы введёте:

- -
https://developer.mozilla.org/ru/docs/FooBar
-
- -

MDN создаст новую страницу с заголовком "FooBar" и открытым редактором для добавления контента. Вернитесь к разделу Редактирование уже существующей страницы в этой статье, чтобы узнать, как работать в редакторе.

- -

Чтобы создать новую страницу без ссылки с другой страницы:

- -
    -
  1. Войдите в аккаунт с правами на создание страниц.
  2. -
  3. Введите следующий текст в адресную строку своего браузера:
  4. -
- -
https://developer.mozilla.org/ru/docs/new
-
- -

MDN создаст страницу с местом для заголовка и откроет редактор, чтобы добавить содержимое. Вернитесь к разделу Редактирование уже существующей страницы в этой статье, чтобы узнать больше о редакторе.

- -

Подстраница уже имеющейся страницы

- -

Чтобы создать подстраницу:

- -
    -
  1. На "родительской" странице (parent page) нажмите кнопку Дополнительно (значок шестерёнки в правом верхнем углу страницы) и выберите Новая подстатья.
  2. -
  3. Откроется редактор для создания документа.
  4. -
  5. Добавьте заголовок в поле Заголовок.
  6. -
  7. Если нужно, измените Slug поле. Например, если заголовок длинный и короткий URL смотрится лучше. Это поле по умолчанию заполняет редактор, заменяя в заголовке пробелы нижними подчёркиваниями и изменяя только последнюю часть URL.
  8. -
  9. В поле Оглавление выберите уровни заголовков, которые нужно отобразить. Если же оглавление не нужно, можно выбрать "Нет содержимого".
  10. -
  11. Напишите статью в редакторе и сохраните изменения. Вернитесь к разделу Редактирование уже существующей страницы в этой статье, чтобы узнать больше о редакторе.
  12. -
- -

Клонирование уже имеющейся страницы

- -

Если уже есть страница, формат и структуру которой вы хотите использовать для создание собственной, то вы можете просто склонировать эту страницу, а затем изменить её содержимое.

- -
    -
  1. На оригинальной странице нажмите на кнопку Дополнительно и выберите Клонировать эту статью. Откроется редактор для создания нового документа. 
  2. -
  3. Измените Заголовок страницы в соответствии с контентом. Поле Slug обновится автоматически, как только вы измените Заголовок.
  4. -
  5. Измените путь в поле Slug, если нужно вставить документ в другое место в иерархии документа. В большинстве случаев это не нужно. Клонированная страница чаще всего схожа по контенту с оригиналом, поэтому желательно, чтобы она была в том же месте.
  6. -
  7. В поле Оглавление выберите уровни заголовков для содержания. Или выберите "Нет содержимого", если это не нужно.
  8. -
  9. Напишите статью и сохраните изменения. Вернитесь к разделу Редактирование уже существующей страницы в этой статье, чтобы узнать больше о редакторе.
  10. -
- -

Ссылка из уже имеющейся страницы

- -

Это в какой-то степени гибрид. Вы можете создать ссылку на другую страницу, затем нажать на ссылку, которую вы только что создали, чтобы добавить новую страницу:

- -
    -
  1. Введите имя новой страницы, где угодно, чтобы это был текст на существующей странице. 
  2. -
  3. Выделите это новое имя и нажмите на значок ссылки ()  в панеле инструментов редактора. Окно "Обновить ссылку" откроется с выделенным текстом в поле "Ссылка на".
  4. -
  5. "/ru/docs/" вставлена по умолчанию в начале URL. Введите имя страницы после "/ru/docs/". Название страницы необязательно должно совпадать с текстом ссылки. 
  6. -
  7. Нажмите OK, чтобы создать и вставить ссылку.
  8. -
- -

Если страницы ещё не существует, то ссылка будет красного цвета. Если же страница уже есть, то ссылка будет синего цвета. Если вы хотите создать новую страницу, но заголовок уже занят, проверьте, возможно вы можете помочь редактировать и улучшить эту страницу. С другой стороны придумайте уникальное имя для своей страницы и сделайте ссылку для неё. Посмотрите также Руководство по оформлению материалов MDN.

- -

Обновление содержимого страницы

- -

MDN поддерживает KumaScript макросы и интеграцию контента с других страниц, иногда кэширования страниц может быть затруднено по соображениям производительности. Страницы строятся из своих исходных мест, и их сборка может кэшироваться для дальнейших запросов. С этого момента макросы (шаблоны) или интеграции (используют макрос Page) не будут реагировать на дальнейшие изменения самих макросов, их выходных данных или контента интегрированных материалов.

- - - -

См. также

- - diff --git a/files/ru/mdn/contribute/howto/add_or_update_browser_compatibility_data/index.html b/files/ru/mdn/contribute/howto/add_or_update_browser_compatibility_data/index.html new file mode 100644 index 0000000000..5b31ce215e --- /dev/null +++ b/files/ru/mdn/contribute/howto/add_or_update_browser_compatibility_data/index.html @@ -0,0 +1,34 @@ +--- +title: Как добавить или обновить данные о браузерной совместимости +slug: MDN/Contribute/Howto/Добавить_или_обновить_данные_о_браузерной_совместимости +tags: + - MDN Meta + - Руководство +translation_of: MDN/Contribute/Howto/Add_or_update_browser_compatibility_data +--- +
{{MDNSidebar}}{{IncludeSubnav("/ru/docs/MDN")}}
+ +

Если вы знаете информацию о браузерной совместимости с веб-функциями — или вы хотите помочь и можете провести некоторые исследования или эксперименты — вы можете помочь обновить MDN База данных о браузерной совместимости (BCD).

+ +
+
Где это нужно сделать?
+
+

Есть несколько способов как вы можете улучшить информацию о браузерной совместимости на MDN:

+ +
    +
  • Добавить данные о веб-функциях, ещё не включённых в BCD репозиторий
  • +
  • Обновить существующие данные новой информацией на основе либо изменениях в новых версиях браузеров, исправления ошибок в существующих данных, либо обновления о данных функциях
  • +
  • Отправить pull request по адресу BCD проблемы на Github.
  • +
+
+
Что вам нужно знать, чтобы выполнить задачу?
+
+
    +
  • Знакомство с Github
  • +
  • Знакомство с JSON
  • +
  • Информация о чём-либо или возможность проверить совместимость функций веб-стандартов в различных браузерах. Вы также можете конвертировать "старые" таблицы совместимости в формат JSON.
  • +
+
+
Какие шаги нужно сделать, чтобы выполнить задачу?
+
Подробнее о том как обновить JSON файлы в BCD репозитории на Github, смотри нашу статью таблицы совместимости. Для списка проблем по которым конкретно ищется помощь ищите  Github проблемы с тегом "Help Wanted".
+
diff --git a/files/ru/mdn/contribute/howto/create_an_interactive_exercise_to_help_learning_the_web/index.html b/files/ru/mdn/contribute/howto/create_an_interactive_exercise_to_help_learning_the_web/index.html new file mode 100644 index 0000000000..5488b77d10 --- /dev/null +++ b/files/ru/mdn/contribute/howto/create_an_interactive_exercise_to_help_learning_the_web/index.html @@ -0,0 +1,184 @@ +--- +title: Как создать интерактивное обучающее упражнение +slug: >- + MDN/Contribute/Howto/Создай_интерактивное_упражнение_для_помощи_в_изучении_веба +translation_of: MDN/Contribute/Howto/Create_an_interactive_exercise_to_help_learning_the_web +--- +
{{MDNSidebar}}
+ +
{{IncludeSubnav("/en-US/docs/MDN")}}
+ +

При изучении веба, важно полагаться на активном обучающем контенте. Такой контент создан для помощи в изучении чего-либо проактивно. Это может быть упражнения, живые взламываемые примеры, задачи к исполнению, оценки и т.д. Вкратце, всё что может помочь кому-либо в активном понимании чего-либо.

+ +

Нет прямого способа для создания такого контента. Например существует много сторонних инструментов которые помогут в создании живых примеров (см: JSFiddle, CodePen, Dabblet, и т.д.) которые вы можете ссылаться из MDN статей. Если вы хотите создать более продвинутые упражнения, то можете воспользоваться Thimble из проекта WebMaker.

+ +

На данный момент MDN не имеет лёгкого инструмента для пометки автора такого контента. Однако, если вы являетесь программистом, то можете возпользоваться текущими MDN функциями для создания своего активного обучающего контента. Читайте далее для того чтобы узнать как это сделать.

+ +

MDN live samples

+ +

MDN has a very cool feature called live samples. It's a mechanism that turns any HTML, CSS, and JavaScript code inside an MDN page into its executed equivalent. Before using it, you should read over Using the live sample system, which is our complete documentation for building them. While they're easy to do, there are quirks and tricks you'll learn along the way.

+ +

What is interesting is that it's really easy to tweak that feature to use it in order to embed any kind of tool or utility you want into an MDN page.

+ +

Hidden code

+ +

The first way to use a code sample to create active learning content is to edit the page where you want to add your content. Use the Live Sample feature to create your content as you wish. Don't bother with the code complexity you could write; just create what you need. Once your content is ready, just switch to the editor code view and surround your code with a simple {{HTMLElement('div')}} element with the class hidden. By doing so, your code won't be displayed but your live sample remains accessible and displayable.

+ +

Let's see a simple example:

+ +
+

Click on the following square to randomly change its color or just type a hexadecimal code color

+ + +{{EmbedLiveSample('hidden_code_example', 120, 120)}}
+ +

If you take a look at that page HTML code with the MDN editor, you'll see the exact following HTML code:

+ +
<div class="moreinfo">
+<p>Click on the following square to randomly change its color or just type an hexadecimal code color</p>
+
+<div class="hidden">
+<h4 id="hidden_code_example">hidden code example</h4>
+
+<h5 id="HTML">HTML</h5>
+
+<pre class="brush: html">
+&lt;div class="square"&gt;
+  #&lt;input class="color"&gt;
+&lt;/div&gt;</pre>
+
+<h5 id="CSS">CSS</h5>
+
+<pre class="brush: css">
+body {
+  padding: 10px;
+  margin : 0;
+}
+
+.square {
+  width  : 80px;
+  height : 80px;
+  padding: 10px;
+  background-color: black;
+  color: white;
+  text-align: center;
+}
+
+.color {
+  width: 60px;
+  text-transform: uppercase;
+}
+</pre>
+
+<h5 id="JS">JS</h5>
+
+<pre class="brush: js">
+function setColor(color) {
+  document.querySelector('.square').style.backgroundColor = '#' + color;
+  document.querySelector('.color').value = color;
+}
+
+function getRandomColor() {
+  var color = Math.floor(Math.random() * 16777215);
+  return color.toString(16);
+}
+
+function getInputColor() {
+  var value = document.querySelector('.color').value;
+  var color = Number('0x' + color);
+  if (color === +color) {
+    return color.toString(16);
+  }
+  return value;
+}
+
+document.addEventListener('click', function () {
+  setColor(getRandomColor());
+});
+
+document.addEventListener('keyup', function () {
+  setColor(getInputColor());
+});
+</pre>
+</div>
+
+\{{EmbedLiveSample('hidden_code_example', 120, 120)}}
+</div>
+ +

You can see a more advance example of such a tweak on the Canvas API page.

+ +

Code from outside the page

+ +

The previous example is okay if you want to embed basic active learning content. However, if you want to deal with complex code, it can become a bit awkward to deal with that hidden class wrapper.

+ +

So another option is to write the code of your learning content on an MDN page and then embed it into another page. To do this we can use the {{TemplateLink("EmbedDistLiveSample")}} macro instead of the {{TemplateLink("EmbedLiveSample")}} macro.

+ +

Let's how that sample looks when configured as if it were being embedded from a remote origin:

+ +
+

Click on the following square to randomly change its color or just type a hexadecimal code color

+{{EmbedLiveSample('The_example', 120, 120, '', 'MDN/Contribute/Howto/Create_an_interactive_exercise_to_help_learning_the_web/distant_example')}}
+ +

This time, if you take a look at that page's HTML using the MDN editor, you'll see no hidden code. If you want to see the code, just go to the page that hosts it.

+ +

You can see a more advanced example of this usage in our HTML Form tutorial, which uses this technique to allow experimentation with forms.

diff --git a/files/ru/mdn/contribute/howto/create_an_mdn_account/index.html b/files/ru/mdn/contribute/howto/create_an_mdn_account/index.html deleted file mode 100644 index 99857a600a..0000000000 --- a/files/ru/mdn/contribute/howto/create_an_mdn_account/index.html +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: Как создать MDN аккаунт -slug: MDN/Contribute/Howto/Create_an_MDN_account -tags: - - Документация - - Начинающий - - Руководство -translation_of: MDN/Contribute/Howto/Create_an_MDN_account ---- -
{{MDNSidebar}}
- -

Чтобы вносить любые изменения в контент на MDN, вам будет нужен MDN профиль (для чтения и поиска сайту он не нужен). Данное руководство поможет вам создать ваш MDN профиль.

- -
-
Дл чего MDN нужен адрес моей электронной почты?
-
-Адрес вашей электронной почты используется для восстановления аккаунта. Иногда адрес может понадобиться администраторам MDN, чтобы написать вам по вопросам, связанным с вашим аккаунтом либо с вашей активностью на данном сайте.
-
-Кроме того, вы можете дополнительно подписаться на уведомления (например, when specific pages are changed) и сообщения (например, если вы решите присоединиться к нашей команде бета-тестирования, то сможете получать по электронной почте сведения о новых возможностях сайта, которые нужно протестировать).
-
-Адрес вашей электронной почты никогда не будет показан на MDN и будет использоваться только согласно нашей политике конфиденциальности.
- -
Если вы вошли в MDN через аккаунт GitHub, и вы используете режим "noreply" в настройках почтового адреса на GitHub, вы не получите сообщений (включая оповещения от страниц, на которые вы подписаны) от MDN.
-
-
- -
    -
  1. В верхней части каждой страницы MDN есть кнопка с надписью Войти. Наведите курсор мыши на неё (или нажмите на неё, если вы на мобильном устройстве), чтобы отобразить список сервисов, которые мы поддерживаем для регистрации в MDN.
  2. -
  3. Выберите аккаунт для того, чтобы Войти в систему. Сейчас доступны GitHub и Google. Обратите внимание, что если вы выберете GitHub, то ссылка на ваш GitHub-профиль будет отображаться на публичной странице вашего профиля MDN.
  4. -
  5. Следуйте инструкциям, чтобы подключить выбранную учетную запись к MDN (например, форма для входа через GitHub будет выглядеть как на картинке ниже).
  6. -
  7. После того, как служба аутентификации вернет вас на сайт MDN, вам будет предложено ввести имя пользователя MDN и адрес электронной почты. Ваше имя пользователя будет отображаться публично, чтобы при вкладе в развитие сообщества было видно ваше авторство. Не используйте свой адрес электронной почты в качестве имени пользователя.
  8. -
  9. Нажмите Создать мой профиль MDN.
  10. -
  11. Если адрес электронной почты, указанный в шаге 4, не то же самый, который вы используете на выбранном для аутентификации сервисе, то проверьте свою электронную почту и нажмите на ссылку в письме с подтверждением, которое мы выслали вам.
  12. -
- -

Это всё! Теперь у вас есть аккаунт MDN, и вы можете сразу начать  редактировать контент сообщества!

- -

Нажмите на своё имя в верхней части любой страницы MDN, чтобы увидеть свой профиль. В профиле нажмите Редактировать, если хотите внести изменения или дополнения.

- -
-

Новые имена пользователей не могут содержать пробелы или символ"@". Выбирая имя, помните, что оно будет отображаться публично, чтобы было видно, что именно вы проделали ту или иную работу.

-
diff --git a/files/ru/mdn/contribute/howto/create_and_edit_pages/index.html b/files/ru/mdn/contribute/howto/create_and_edit_pages/index.html new file mode 100644 index 0000000000..9b6d34eff9 --- /dev/null +++ b/files/ru/mdn/contribute/howto/create_and_edit_pages/index.html @@ -0,0 +1,182 @@ +--- +title: Как создавать и редактировать страницы +slug: MDN/Contribute/Creating_and_editing_pages +tags: + - MDN основы + - Гайд + - Как + - Новичок + - Стартовая +translation_of: MDN/Contribute/Howto/Create_and_edit_pages +--- +
{{MDNSidebar}}
+ +

Данная статья предоставляет новым контрибьюторам основную информацию о процессе создания и редактирования страниц.

+ +

Редактирование уже существующей страницы

+ +

Чтобы редактировать страницу:

+ +
    +
  1. Кликните на кнопку Редактировать в правом верхнем углу страницы.
  2. +
  3. Затем страница перезагрузится, и вы увидите редактор, в котором можно добавлять или удалять информацию напрямую.
  4. +
  5. Добавляйте параграфы, удаляйте текст, вставляйте заголовки и используйте другие основные фунцкии, которые нужны для написания и редактирования.
  6. +
+ +

Смотрите руководства Редактор UI элементов в Руководстве по MDN редактору, чтобы получить больше информации об использовании встроенных MDN редакторах.

+ +

Предварительный просмотр изменений

+ +

Чтобы посмотреть, как ваши изменения будут выглядеть:

+ + + +

Будьте аккуратны! Предварительный просмотр не сохраняет ваши изменения. Не закрывайте вкладку с редактором, пока не сохраните свою работу.

+ +

Комментарий к ревизии

+ +

После предварительного просмотра своих изменений вы захотите сохранить свою ревизию. Перед тем, как сохранить, посмотрите на текстовый блок с комментарием к ревизии, находящийся внизу страницы и оставляющий комментарий для того, чтобы объяснить другим контрибьторам, зачем вы сделали изменения. Например, вы могли добавить новую секцию, изменить текст, чтобы сделать терминологию более упорядоченной, переписать параграф для лучшего объяснения или удалить определённую информацию, так как она просто лишняя.

+ +

Содержание

+ +

В секции "В этой статье" находится список ссылок к заголовкам на странице. Вы можете изменить содержание, изменив заголовки. Также вы можете просто убрать данную секцию или увеличить количество ссылок, поменяв в секции "Редактировать описание" значение пункта "Оглавление".

+ +

Метки статьи (теги)

+ +

Вы можете добавлять или удалять теги, описывающие содержание и назначение страницы, в самом низу страницы редактирования. Смотрите Стандартные метки статей в MDN, чтобы получить больше информации о тегах.

+ +

Требуется проверка?

+ +

Если ваши изменения нуждаются в проверке экспертом или просто опытным контрибьютором, то, пожалуйста, оставьте заявку на техническую (для кода, API или технологий) и/или на редакционную (качества написания, грамматики или содержимого) проверку, убедитесь, что поставили галочки в нужных вам полях перед тем, как сохранить.

+ +

Прикрепить файлы

+ +

Если вы хотите прикрепить файлы к существующей странице или добавить иллюстрацию для объяснения, это может быть сделано внизу страницы. При загрузке изображения, пожалуйста, убедитесь, что используете инструменты оптимизации, чтобы сделать файл маленьким, а загрузку возможной. Это улучшает время загрузки страницы и помогает производительности MDN в целом. Вы можете использовать свой любимый инструмент, если он у вас есть. Иначе, мы предлагаем TinyPNG - удобный Веб инструмент.

+ +

 Публикация, отмена или дальнейшие изменения

+ +

Когда вы закончили редактирование и довольны изменениями, опубликуйте свою работу и комментарии, кликнув на зелёную кнопку Опубликовать в правом верхнем или нижнем углу страницы. Если же вы хотите продолжить вносить изменения, нажмите Сохранить и продолжить редактирование, это опубликует ваши изменения, однако оставит вас во вкладке с редактором.

+ +

Если вы изменили своё мнение, вы можете отменить изменения, нажав на красную кнопку Отменить. Изменения, которые вы хотите отменить, будут навсегда отменены.

+ +

Нажатие клавиши Enter в поле ввода комментария к ревизии то же самое, что нажатие кнопку Сохранить и продолжить редактирование.

+ +
+

Если при попытке сохранить изменения, они были не приняты как некорректные, но вы считаете, что правки полностью приемлемы для MDN, обратитесь к администрации MDN за помощью.

+
+ +

Получение прав на создание страниц

+ +

По причинам безопасности недавно созданные аккаунты не имеют права добавлять новые страницы. Если вы попытаетесь сделать это, то увидите страницу с инструкцией, как создать страницу. Есть два варианта:

+ + + +

Создание новой страницы

+ +

Сразу же, как только вы получили право создавать страницы, вы может начать добавлять их.

+ +

Если вы не знаете, где разместить новую статью, не беспокойтесь. Вставьте её, куда угодно: мы найдём её и переместим туда, где ей лучше всего быть, или используем её в уже существующем контенте. Также не волнуйтесь о том, чтобы статья выглядела идеально. У нас есть гномы-помощники, которые помогают сделать вашу статью понятнее и привлекательнее.

+ +

Есть несколько способов создать страницу:

+ + + +

Ссылка на отсутствующую страницу

+ +

Как и в большинстве вики, возможно такое, что есть ссылка, ведущая на страницу, которой ещё нет. Например, автор мог написать список участников API перед тем, как создать страницы для этих участников. На MDN ссылки на несуществующие страницы обычно отображаются красным цветом.

+ +

Чтобы создать отсутствующую страницу:

+ +
    +
  1. Войдите в MDN аккаунт с правами на создание страниц. Если вы не зайдёте, тогда при переходе на ссылку на отсутсвующую страницу будет выводиться ошибка 404 (страница не найдена).
  2. +
  3. Кликните на ссылку на отсутсвующую страницу. Если у вас есть соответсвующие права, тогда перед вами откроется MDN Редактор (Editor) UI для создания страницы.
  4. +
  5. Напишите содержание страницы и сохраните её.
  6. +
+ +

Новая страница без ссылки

+ +

Чтобы создать новую страницу без ссылки с другой страницы, введите имя несуществующей страницы в адресной строке вашего браузера. Например, если вы введёте:

+ +
https://developer.mozilla.org/ru/docs/FooBar
+
+ +

MDN создаст новую страницу с заголовком "FooBar" и открытым редактором для добавления контента. Вернитесь к разделу Редактирование уже существующей страницы в этой статье, чтобы узнать, как работать в редакторе.

+ +

Чтобы создать новую страницу без ссылки с другой страницы:

+ +
    +
  1. Войдите в аккаунт с правами на создание страниц.
  2. +
  3. Введите следующий текст в адресную строку своего браузера:
  4. +
+ +
https://developer.mozilla.org/ru/docs/new
+
+ +

MDN создаст страницу с местом для заголовка и откроет редактор, чтобы добавить содержимое. Вернитесь к разделу Редактирование уже существующей страницы в этой статье, чтобы узнать больше о редакторе.

+ +

Подстраница уже имеющейся страницы

+ +

Чтобы создать подстраницу:

+ +
    +
  1. На "родительской" странице (parent page) нажмите кнопку Дополнительно (значок шестерёнки в правом верхнем углу страницы) и выберите Новая подстатья.
  2. +
  3. Откроется редактор для создания документа.
  4. +
  5. Добавьте заголовок в поле Заголовок.
  6. +
  7. Если нужно, измените Slug поле. Например, если заголовок длинный и короткий URL смотрится лучше. Это поле по умолчанию заполняет редактор, заменяя в заголовке пробелы нижними подчёркиваниями и изменяя только последнюю часть URL.
  8. +
  9. В поле Оглавление выберите уровни заголовков, которые нужно отобразить. Если же оглавление не нужно, можно выбрать "Нет содержимого".
  10. +
  11. Напишите статью в редакторе и сохраните изменения. Вернитесь к разделу Редактирование уже существующей страницы в этой статье, чтобы узнать больше о редакторе.
  12. +
+ +

Клонирование уже имеющейся страницы

+ +

Если уже есть страница, формат и структуру которой вы хотите использовать для создание собственной, то вы можете просто склонировать эту страницу, а затем изменить её содержимое.

+ +
    +
  1. На оригинальной странице нажмите на кнопку Дополнительно и выберите Клонировать эту статью. Откроется редактор для создания нового документа. 
  2. +
  3. Измените Заголовок страницы в соответствии с контентом. Поле Slug обновится автоматически, как только вы измените Заголовок.
  4. +
  5. Измените путь в поле Slug, если нужно вставить документ в другое место в иерархии документа. В большинстве случаев это не нужно. Клонированная страница чаще всего схожа по контенту с оригиналом, поэтому желательно, чтобы она была в том же месте.
  6. +
  7. В поле Оглавление выберите уровни заголовков для содержания. Или выберите "Нет содержимого", если это не нужно.
  8. +
  9. Напишите статью и сохраните изменения. Вернитесь к разделу Редактирование уже существующей страницы в этой статье, чтобы узнать больше о редакторе.
  10. +
+ +

Ссылка из уже имеющейся страницы

+ +

Это в какой-то степени гибрид. Вы можете создать ссылку на другую страницу, затем нажать на ссылку, которую вы только что создали, чтобы добавить новую страницу:

+ +
    +
  1. Введите имя новой страницы, где угодно, чтобы это был текст на существующей странице. 
  2. +
  3. Выделите это новое имя и нажмите на значок ссылки ()  в панеле инструментов редактора. Окно "Обновить ссылку" откроется с выделенным текстом в поле "Ссылка на".
  4. +
  5. "/ru/docs/" вставлена по умолчанию в начале URL. Введите имя страницы после "/ru/docs/". Название страницы необязательно должно совпадать с текстом ссылки. 
  6. +
  7. Нажмите OK, чтобы создать и вставить ссылку.
  8. +
+ +

Если страницы ещё не существует, то ссылка будет красного цвета. Если же страница уже есть, то ссылка будет синего цвета. Если вы хотите создать новую страницу, но заголовок уже занят, проверьте, возможно вы можете помочь редактировать и улучшить эту страницу. С другой стороны придумайте уникальное имя для своей страницы и сделайте ссылку для неё. Посмотрите также Руководство по оформлению материалов MDN.

+ +

Обновление содержимого страницы

+ +

MDN поддерживает KumaScript макросы и интеграцию контента с других страниц, иногда кэширования страниц может быть затруднено по соображениям производительности. Страницы строятся из своих исходных мест, и их сборка может кэшироваться для дальнейших запросов. С этого момента макросы (шаблоны) или интеграции (используют макрос Page) не будут реагировать на дальнейшие изменения самих макросов, их выходных данных или контента интегрированных материалов.

+ + + +

См. также

+ + diff --git a/files/ru/mdn/contribute/howto/do_a_technical_review/index.html b/files/ru/mdn/contribute/howto/do_a_technical_review/index.html deleted file mode 100644 index ba395e2669..0000000000 --- a/files/ru/mdn/contribute/howto/do_a_technical_review/index.html +++ /dev/null @@ -1,57 +0,0 @@ ---- -title: Как сделать технический обзор -slug: MDN/Contribute/Howto/Do_a_technical_review -tags: - - Guide - - Howto - - MDN Meta - - Как сделать - - Руководство -translation_of: MDN/Contribute/Howto/Do_a_technical_review ---- -
{{MDNSidebar}}
- -

Технический обзор заключается в рассмотрении технической точности и полноты статьи и её корректировки, если это необходимо. Если автор статьи хочет, чтобы кто-нибудь ещё проверил техническое содержание статьи, то он ставит пометку "Технический обзор" при редактировании. Часто автор связывается с определённым инженером для выполнения технического обзора, но кто-либо с техническими знаниями и опытом в теме также может сделать это.

- -

Эта статья описывает, как выполнить технический обзор, тем самым гарантируя точность содержания MDN.

- -
-
В чём задача?
-
Обзор и исправление статей на техническую точность и полноту.
-
Где это необходимо сделать?
-
В конкретных статьях, которые отмечены как требующие технического обзора.
-
Что Вы должны знать, чтобы выполнить задачу?
-
-
    -
  • Экспертные знания в теме, которую Вы обозреваете.
  • -
  • Возможность редактирования статьи на MDN.
  • -
-
-
Какие действия нужно выполнить, чтобы сделать это?
-
-
    -
  1. Выберите статью для обзора: -
      -
    1. Перейдите к списку страниц, которые нуждаются в техническом обзоре. В этом списке перечислены все страницы, для которых был запрошен технический обзор.
    2. -
    3. Выберите страницу, с темой которой Вы очень хорошо знакомы.
    4. -
    5. Нажмите на ссылку статьи, чтобы загрузить страницу.
    6. -
    -
  2. -
  3. Прочитайте статью, обращая пристально внимание на технические детали: Верна ли статья? Чего-то не хватает? Не стесняйтесь переключаться на другую статью, если выбранная не устраивает Вас.
  4. -
  5. Если ошибок нет, то Вам не нужно редактировать статью, чтобы отметить её как просмотренную. Посмотрите на окно "быстрого обзора" в левой боковой панели страницы:
    -
    - Выберите флажок Технический и нажмите Обзор завершен.
  6. -
  7. Если Вы нашли ошибки, которые нужно исправить: -
      -
    1. Нажмите кнопку Редактировать в верхней части страницы; она переместит Вас в редактор MDN.
    2. -
    3. Исправьте неверную техническую информацию и добавьте важную информацию, которая отсутствует.
    4. -
    5. Введите Комментарий к ревизии в нижней части статьи, который описывает, что Вы сделали, например, "Технический обзор закончен". Если Вы исправляли информацию, добавьте это в Ваш комментарий, например, "Технический обзор: исправлено описание параметров".
    6. -
    7. Отмените флажок Технический под Требуется проверка?.
    8. -
    9. Нажмите кнопку Сохранить изменения.
    10. -
    -
  8. -
-
-
- -

Поздравляем! Вы только что завершили свой первый технический обзор! Спасибо вам за вашу помощь! 

diff --git a/files/ru/mdn/contribute/howto/do_an_editorial_review/index.html b/files/ru/mdn/contribute/howto/do_an_editorial_review/index.html deleted file mode 100644 index eab3b47fde..0000000000 --- a/files/ru/mdn/contribute/howto/do_an_editorial_review/index.html +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: Как сделать редакционный обзор -slug: MDN/Contribute/Howto/Do_an_editorial_review -tags: - - Guide - - Howto - - MDN Meta - - Как сделать - - Руководство -translation_of: MDN/Contribute/Howto/Do_an_editorial_review ---- -
{{MDNSidebar}}

Редакционный обзор заключается в исправлении опечаток и орфографических, грамматических, оборотных или текстовых ошибок в статье. Не все участники обладают лингвистическими навыками, но, благодаря их знаниям, появляются чрезвычайно полезные статьи, которые нуждаются в техническом редактировании и исправлении; это делается в редакционном обзоре.

- -

Эта статья описывает выполнение редакционного обзора для поддержания точности содержания MDN.

- -
-
В чём задача?
-
Техническое редактирование и исправление статей, которые отмечены как требующие редакционного обзора.
-
Где это необходимо сделать?
-
В конкретных статьях, которые отмечены как требующие редакционного обзора.
-
Что Вы должны знать, чтобы выполнить задачу?
-
Вы должны иметь хорошие грамматические и орфографические навыки в русском языке.
-
Какие действия нужно выполнить, чтобы сделать это?
-
-
    -
  1. Выберите статью для обзора: -
      -
    1. Перейдите к списку страниц, которые нуждаются в редакционном обзоре.  В этом списке перечислены все страницы, для которых был запрошен редакционный обзор.
    2. -
    3. Выберите страницу.
    4. -
    5. Нажмите на ссылку статьи, чтобы загрузить страницу.
    6. -
    -
  2. -
  3. Прочитайте статью, обращая пристальное внимание на опечатки и орфографические, грамматические или оборотные ошибки. Не стесняйтесь переключаться на другую статью, если выбранная не устраивает Вас.
  4. -
  5. Если ошибок нет, то Вам не нужно редактировать статью, чтобы отметить её как прошедшую корректуру. Посмотрите на окно "быстрого обзора" в левой боковой панели страницы:
    -
    - Выберите флажок Редакционный и нажмите Обзор завершен.
  6. -
  7. Если Вы нашли ошибки, которые нужно исправить: -
      -
    1. Нажмите кнопку Редактировать в верхней части страницы; она переместит Вас в редактор MDN.
    2. -
    3. Исправьте все опечатки и орфографические, грамматические или оборотные ошибки, которые Вы видите.
    4. -
    5. Введите Комментарий ревизии в нижней части статьи; что-то вроде 'Редакционный обзор: исправлены опечатки, грамматика и орфография'.
    6. -
    7. Снимите флажок Редакционный под Требуется проверка?.
    8. -
    9. Нажмите кнопку Сохранить изменения.
    10. -
    -
  8. -
- -
-

Из-за соображений производительности Ваши правки могут не сразу появиться на странице.

-
-
-
diff --git "a/files/ru/mdn/contribute/howto/\320\264\320\276\320\261\320\260\320\262\320\270\321\202\321\214_\320\270\320\273\320\270_\320\276\320\261\320\275\320\276\320\262\320\270\321\202\321\214_\320\264\320\260\320\275\320\275\321\213\320\265_\320\276_\320\261\321\200\320\260\321\203\320\267\320\265\321\200\320\275\320\276\320\271_\321\201\320\276\320\262\320\274\320\265\321\201\321\202\320\270\320\274\320\276\321\201\321\202\320\270/index.html" "b/files/ru/mdn/contribute/howto/\320\264\320\276\320\261\320\260\320\262\320\270\321\202\321\214_\320\270\320\273\320\270_\320\276\320\261\320\275\320\276\320\262\320\270\321\202\321\214_\320\264\320\260\320\275\320\275\321\213\320\265_\320\276_\320\261\321\200\320\260\321\203\320\267\320\265\321\200\320\275\320\276\320\271_\321\201\320\276\320\262\320\274\320\265\321\201\321\202\320\270\320\274\320\276\321\201\321\202\320\270/index.html" deleted file mode 100644 index 5b31ce215e..0000000000 --- "a/files/ru/mdn/contribute/howto/\320\264\320\276\320\261\320\260\320\262\320\270\321\202\321\214_\320\270\320\273\320\270_\320\276\320\261\320\275\320\276\320\262\320\270\321\202\321\214_\320\264\320\260\320\275\320\275\321\213\320\265_\320\276_\320\261\321\200\320\260\321\203\320\267\320\265\321\200\320\275\320\276\320\271_\321\201\320\276\320\262\320\274\320\265\321\201\321\202\320\270\320\274\320\276\321\201\321\202\320\270/index.html" +++ /dev/null @@ -1,34 +0,0 @@ ---- -title: Как добавить или обновить данные о браузерной совместимости -slug: MDN/Contribute/Howto/Добавить_или_обновить_данные_о_браузерной_совместимости -tags: - - MDN Meta - - Руководство -translation_of: MDN/Contribute/Howto/Add_or_update_browser_compatibility_data ---- -
{{MDNSidebar}}{{IncludeSubnav("/ru/docs/MDN")}}
- -

Если вы знаете информацию о браузерной совместимости с веб-функциями — или вы хотите помочь и можете провести некоторые исследования или эксперименты — вы можете помочь обновить MDN База данных о браузерной совместимости (BCD).

- -
-
Где это нужно сделать?
-
-

Есть несколько способов как вы можете улучшить информацию о браузерной совместимости на MDN:

- -
    -
  • Добавить данные о веб-функциях, ещё не включённых в BCD репозиторий
  • -
  • Обновить существующие данные новой информацией на основе либо изменениях в новых версиях браузеров, исправления ошибок в существующих данных, либо обновления о данных функциях
  • -
  • Отправить pull request по адресу BCD проблемы на Github.
  • -
-
-
Что вам нужно знать, чтобы выполнить задачу?
-
-
    -
  • Знакомство с Github
  • -
  • Знакомство с JSON
  • -
  • Информация о чём-либо или возможность проверить совместимость функций веб-стандартов в различных браузерах. Вы также можете конвертировать "старые" таблицы совместимости в формат JSON.
  • -
-
-
Какие шаги нужно сделать, чтобы выполнить задачу?
-
Подробнее о том как обновить JSON файлы в BCD репозитории на Github, смотри нашу статью таблицы совместимости. Для списка проблем по которым конкретно ищется помощь ищите  Github проблемы с тегом "Help Wanted".
-
diff --git "a/files/ru/mdn/contribute/howto/\320\272\320\260\320\272_\320\276\320\277\321\202\320\270\320\274\320\270\320\267\320\270\321\200\320\276\320\262\320\260\321\202\321\214_\321\201\321\202\321\200\320\260\320\275\320\270\321\206\321\213/index.html" "b/files/ru/mdn/contribute/howto/\320\272\320\260\320\272_\320\276\320\277\321\202\320\270\320\274\320\270\320\267\320\270\321\200\320\276\320\262\320\260\321\202\321\214_\321\201\321\202\321\200\320\260\320\275\320\270\321\206\321\213/index.html" deleted file mode 100644 index 26d5101d9d..0000000000 --- "a/files/ru/mdn/contribute/howto/\320\272\320\260\320\272_\320\276\320\277\321\202\320\270\320\274\320\270\320\267\320\270\321\200\320\276\320\262\320\260\321\202\321\214_\321\201\321\202\321\200\320\260\320\275\320\270\321\206\321\213/index.html" +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: Как оптимизировать страницы -slug: MDN/Contribute/Howto/Как_оптимизировать_страницы -translation_of: MDN/Contribute/Howto/Set_the_summary_for_a_page ---- -
{{MDNSidebar}}

Вы можете заняться оптимизацией любой страницы на MDN, для поисковой оптимизации страницы, вы можете выбрать любую страницу: пусть то будет Лендинговая страница или подсказки. Это должен быть текст, который связан по смыслу с контентом страницы. Все слова должны быть уникальными и не должны встречаться в тексте.

- -

 

- -
-
Что необходимо сделать?
-
Выделить ключевые слова и написать оптимизированную (SEO) статью .
-
Где это нужно сделать?
-
На любых страницах, которые еще не оптимизированы, либо на страницах, которые не достаточно хорошо оптимизированы.
-
Необходимые знания и навыки для выполнения этого задания?
-
Навыки использования MDN редактора; владение Английским языком на уровне - native; умение писать SEO-статьи.
-
Что необходимо для этого сделать?
-
-
    -
  1. Выбрать страницу, на которой необходимо провести оптимизацию: -
      -
    1. На этой странице MDN выберите раздел, в котором вы сильны (например, HTML):
      -
    2. -
    3. На этой странице, нажмите СТРАНИЦЫ (Pages) в разделе Резюме (Summary). В этом разделе вы увидите индекс всех страниц. Так же вы увидите ссылки на страницы (слева), а тэги и SEO - статьи справа:
      -
    4. -
    5. Выберите страницу, которую необходимо оптимизировать:
      -
    6. -
    7. Кликните на ссылку, чтобы перейти на эту страницу.
    8. -
    -
  2. -
  3. Нажмите кнопку Правка (Edit), чтобы открыть MDN редактор.
  4. -
  5. Составьте одно - два предложения в качестве SEO-статьи. При необходимости отредактируйте уже существующую статью.
  6. -
  7. Выберите текст, который будет использован в качестве SEO.
  8. -
  9. На панели инструментов выберите виджет Styles. Выберите SEO Summary. (В исходном коде страницы будет создано {{HTMLElement("span")}} элемент с class="seoSummary" вокруг выделенного текста.)
    -
  10. -
  11. Сохраните свои изменения, желательно с комментариями. Для облегчения понимания ваших трудов другим участникам.
  12. -
-
-
- -

 

diff --git "a/files/ru/mdn/contribute/howto/\320\274\320\265\321\202\320\272\320\270_javascript_\321\201\321\202\321\200\320\260\320\275\320\270\321\206/index.html" "b/files/ru/mdn/contribute/howto/\320\274\320\265\321\202\320\272\320\270_javascript_\321\201\321\202\321\200\320\260\320\275\320\270\321\206/index.html" deleted file mode 100644 index 0c0ed4eca9..0000000000 --- "a/files/ru/mdn/contribute/howto/\320\274\320\265\321\202\320\272\320\270_javascript_\321\201\321\202\321\200\320\260\320\275\320\270\321\206/index.html" +++ /dev/null @@ -1,74 +0,0 @@ ---- -title: Как пометить страницы JavaScript -slug: MDN/Contribute/Howto/Метки_JavaScript_страниц -tags: - - Guide - - Howto - - JavaScript - - MDN Meta -translation_of: MDN/Contribute/Howto/Tag_JavaScript_pages ---- -
{{MDNSidebar}}

Маркировка состоит из добавления метаданных на страницы, чтобы связанный контент можно было сгруппировать, например, в инструменте поиска.

- -
-
Где это нужно сделать?
-
Внутри определенных JavaScript-страниц без тегов
-
Что вам нужно знать, чтобы выполнить эту задачу?
-
Базовые знания JavaScript, например, знание метода или свойства.
-
Каковы шаги для этого?
-
-
    -
  1. Выберите одну из страниц в списке, указанном выше.
  2. -
  3. Нажмите ссылку на статью, чтобы загрузить страницу.
  4. -
  5. После загрузки страницы, нажмите кнопку EDIT рядом с нее названием; это перенесет вас в редактор MDN.
  6. -
  7. Как минимум тег JavaScript нужно добавить. Так же здесь список возможных тегов для добавления: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    ТегКакие страницы использовать
    Methodметоды
    Propertyсвойства
    prototypeпрототипы
    Object type nameметоды объекта; например String.fromCharCode должен иметь тег String
    ECMAScript6 и Experimentalвозможности (фичи) которые были добавлены в новой версии ECMAScript
    Deprecatedустаревшие функции (использование которых не рекомендуется, но поддерживается)
    Obsoleteустаревшие функции (которые больше не поддерживаются в современных браузерах)
    othersСм. Стандарты тегов MDN для других возможных меток
    -
  8. -
  9. Сохранить с комментарием.
  10. -
  11. Готово!
  12. -
-
-
- -

 

diff --git "a/files/ru/mdn/contribute/howto/\321\201\320\276\320\267\320\264\320\260\320\271_\320\270\320\275\321\202\320\265\321\200\320\260\320\272\321\202\320\270\320\262\320\275\320\276\320\265_\321\203\320\277\321\200\320\260\320\266\320\275\320\265\320\275\320\270\320\265_\320\264\320\273\321\217_\320\277\320\276\320\274\320\276\321\211\320\270_\320\262_\320\270\320\267\321\203\321\207\320\265\320\275\320\270\320\270_\320\262\320\265\320\261\320\260/index.html" "b/files/ru/mdn/contribute/howto/\321\201\320\276\320\267\320\264\320\260\320\271_\320\270\320\275\321\202\320\265\321\200\320\260\320\272\321\202\320\270\320\262\320\275\320\276\320\265_\321\203\320\277\321\200\320\260\320\266\320\275\320\265\320\275\320\270\320\265_\320\264\320\273\321\217_\320\277\320\276\320\274\320\276\321\211\320\270_\320\262_\320\270\320\267\321\203\321\207\320\265\320\275\320\270\320\270_\320\262\320\265\320\261\320\260/index.html" deleted file mode 100644 index 5488b77d10..0000000000 --- "a/files/ru/mdn/contribute/howto/\321\201\320\276\320\267\320\264\320\260\320\271_\320\270\320\275\321\202\320\265\321\200\320\260\320\272\321\202\320\270\320\262\320\275\320\276\320\265_\321\203\320\277\321\200\320\260\320\266\320\275\320\265\320\275\320\270\320\265_\320\264\320\273\321\217_\320\277\320\276\320\274\320\276\321\211\320\270_\320\262_\320\270\320\267\321\203\321\207\320\265\320\275\320\270\320\270_\320\262\320\265\320\261\320\260/index.html" +++ /dev/null @@ -1,184 +0,0 @@ ---- -title: Как создать интерактивное обучающее упражнение -slug: >- - MDN/Contribute/Howto/Создай_интерактивное_упражнение_для_помощи_в_изучении_веба -translation_of: MDN/Contribute/Howto/Create_an_interactive_exercise_to_help_learning_the_web ---- -
{{MDNSidebar}}
- -
{{IncludeSubnav("/en-US/docs/MDN")}}
- -

При изучении веба, важно полагаться на активном обучающем контенте. Такой контент создан для помощи в изучении чего-либо проактивно. Это может быть упражнения, живые взламываемые примеры, задачи к исполнению, оценки и т.д. Вкратце, всё что может помочь кому-либо в активном понимании чего-либо.

- -

Нет прямого способа для создания такого контента. Например существует много сторонних инструментов которые помогут в создании живых примеров (см: JSFiddle, CodePen, Dabblet, и т.д.) которые вы можете ссылаться из MDN статей. Если вы хотите создать более продвинутые упражнения, то можете воспользоваться Thimble из проекта WebMaker.

- -

На данный момент MDN не имеет лёгкого инструмента для пометки автора такого контента. Однако, если вы являетесь программистом, то можете возпользоваться текущими MDN функциями для создания своего активного обучающего контента. Читайте далее для того чтобы узнать как это сделать.

- -

MDN live samples

- -

MDN has a very cool feature called live samples. It's a mechanism that turns any HTML, CSS, and JavaScript code inside an MDN page into its executed equivalent. Before using it, you should read over Using the live sample system, which is our complete documentation for building them. While they're easy to do, there are quirks and tricks you'll learn along the way.

- -

What is interesting is that it's really easy to tweak that feature to use it in order to embed any kind of tool or utility you want into an MDN page.

- -

Hidden code

- -

The first way to use a code sample to create active learning content is to edit the page where you want to add your content. Use the Live Sample feature to create your content as you wish. Don't bother with the code complexity you could write; just create what you need. Once your content is ready, just switch to the editor code view and surround your code with a simple {{HTMLElement('div')}} element with the class hidden. By doing so, your code won't be displayed but your live sample remains accessible and displayable.

- -

Let's see a simple example:

- -
-

Click on the following square to randomly change its color or just type a hexadecimal code color

- - -{{EmbedLiveSample('hidden_code_example', 120, 120)}}
- -

If you take a look at that page HTML code with the MDN editor, you'll see the exact following HTML code:

- -
<div class="moreinfo">
-<p>Click on the following square to randomly change its color or just type an hexadecimal code color</p>
-
-<div class="hidden">
-<h4 id="hidden_code_example">hidden code example</h4>
-
-<h5 id="HTML">HTML</h5>
-
-<pre class="brush: html">
-&lt;div class="square"&gt;
-  #&lt;input class="color"&gt;
-&lt;/div&gt;</pre>
-
-<h5 id="CSS">CSS</h5>
-
-<pre class="brush: css">
-body {
-  padding: 10px;
-  margin : 0;
-}
-
-.square {
-  width  : 80px;
-  height : 80px;
-  padding: 10px;
-  background-color: black;
-  color: white;
-  text-align: center;
-}
-
-.color {
-  width: 60px;
-  text-transform: uppercase;
-}
-</pre>
-
-<h5 id="JS">JS</h5>
-
-<pre class="brush: js">
-function setColor(color) {
-  document.querySelector('.square').style.backgroundColor = '#' + color;
-  document.querySelector('.color').value = color;
-}
-
-function getRandomColor() {
-  var color = Math.floor(Math.random() * 16777215);
-  return color.toString(16);
-}
-
-function getInputColor() {
-  var value = document.querySelector('.color').value;
-  var color = Number('0x' + color);
-  if (color === +color) {
-    return color.toString(16);
-  }
-  return value;
-}
-
-document.addEventListener('click', function () {
-  setColor(getRandomColor());
-});
-
-document.addEventListener('keyup', function () {
-  setColor(getInputColor());
-});
-</pre>
-</div>
-
-\{{EmbedLiveSample('hidden_code_example', 120, 120)}}
-</div>
- -

You can see a more advance example of such a tweak on the Canvas API page.

- -

Code from outside the page

- -

The previous example is okay if you want to embed basic active learning content. However, if you want to deal with complex code, it can become a bit awkward to deal with that hidden class wrapper.

- -

So another option is to write the code of your learning content on an MDN page and then embed it into another page. To do this we can use the {{TemplateLink("EmbedDistLiveSample")}} macro instead of the {{TemplateLink("EmbedLiveSample")}} macro.

- -

Let's how that sample looks when configured as if it were being embedded from a remote origin:

- -
-

Click on the following square to randomly change its color or just type a hexadecimal code color

-{{EmbedLiveSample('The_example', 120, 120, '', 'MDN/Contribute/Howto/Create_an_interactive_exercise_to_help_learning_the_web/distant_example')}}
- -

This time, if you take a look at that page's HTML using the MDN editor, you'll see no hidden code. If you want to see the code, just go to the page that hosts it.

- -

You can see a more advanced example of this usage in our HTML Form tutorial, which uses this technique to allow experimentation with forms.

diff --git a/files/ru/mdn/contribute/processes/index.html b/files/ru/mdn/contribute/processes/index.html new file mode 100644 index 0000000000..4c6bdda462 --- /dev/null +++ b/files/ru/mdn/contribute/processes/index.html @@ -0,0 +1,14 @@ +--- +title: Процессы документирования +slug: MDN/Contribute/Процессы +tags: + - Landing + - MDN Meta + - Процессы +translation_of: MDN/Contribute/Processes +--- +
{{MDNSidebar}}
{{IncludeSubnav("/en-US/docs/MDN")}}
+ +

Проектная документация МДН необъятна; существует огромное количество технологий, реализуемые при помощи сотен участников со всего мира. Чтобы помочь нам навести порядок в этом хаосе, имеются стандартные процессы при работе с конкретными документационно-связанными задачами. Здесь вы найдете руководства к этим процессам.

+ +

{{LandingPageListSubPages()}}

diff --git "a/files/ru/mdn/contribute/\320\277\321\200\320\276\321\206\320\265\321\201\321\201\321\213/index.html" "b/files/ru/mdn/contribute/\320\277\321\200\320\276\321\206\320\265\321\201\321\201\321\213/index.html" deleted file mode 100644 index 4c6bdda462..0000000000 --- "a/files/ru/mdn/contribute/\320\277\321\200\320\276\321\206\320\265\321\201\321\201\321\213/index.html" +++ /dev/null @@ -1,14 +0,0 @@ ---- -title: Процессы документирования -slug: MDN/Contribute/Процессы -tags: - - Landing - - MDN Meta - - Процессы -translation_of: MDN/Contribute/Processes ---- -
{{MDNSidebar}}
{{IncludeSubnav("/en-US/docs/MDN")}}
- -

Проектная документация МДН необъятна; существует огромное количество технологий, реализуемые при помощи сотен участников со всего мира. Чтобы помочь нам навести порядок в этом хаосе, имеются стандартные процессы при работе с конкретными документационно-связанными задачами. Здесь вы найдете руководства к этим процессам.

- -

{{LandingPageListSubPages()}}

diff --git a/files/ru/mdn/editor/basics/index.html b/files/ru/mdn/editor/basics/index.html deleted file mode 100644 index 10b5d91eb9..0000000000 --- a/files/ru/mdn/editor/basics/index.html +++ /dev/null @@ -1,62 +0,0 @@ ---- -title: Редактор UI элементов -slug: MDN/Editor/Basics -translation_of: MDN/Editor/Basics ---- -
{{MDNSidebar}}
- -

Встроенный WYSIWYG редактор на MDN разработан так, чтобы максимально упростить создание, редактирование и улучшение статей и других страниц практически на всем сайте. Окно редактора, как показано ниже, состоит из восьми блоков.
- Это руководство предоставляет информацию о каждом разделе, чтобы вы знали, как использовать все возможности нашего редактора.

- -
-

Note: Мы постоянно работаем над улучшением MDN, так что может наступить такой момент, когда эта документация и скриншоты к ней окажутся немного устаревшими. Чтобы идти в ногу со временем - мы будем периодически обновлять документацию.

-
- -

Edit page with en/ru labels

- -

Интерфейс редактора содержит следующие разделы, как показано выше. Нажмите на ссылку ниже чтобы прочесть о конкретном разделе.

- - - -

Поле редактирования

- -

Поле редактирования - это, конечно же. место где вы вводите текст.

- -

Нажатие правой кнопки мыши (ПКМ) в поле редактирования показывает дополнительные опции, в зависимости от контекста. Нажатие ПКМ на таблице, например, предлагает опции для работы с таблицами, а на списке, соответственно, опции для работы со списками. По умолчанию редактор использует свое собственное контекстное меню в поле редактирования. Чтобы открыть стандартное браузерное контекстное меню, при нажатии ПКМ зажмите Shift или Control (Command на Mac OS X).

- -

Во время работы в окне редактирования вы можете использовать специальные сочетания клавиш.

- -

Примечание

- -

После того как вы закончили свою работу, настоятельно рекомендуется добавлять к своим изменениям примечание. Оно будет показано в истории изменений к этой странице, а также в обзорной панели изменений (Revision Dashboard). Это поможет объяснить и донести смысл ваших изменений до тех, кто может просматривать их позже. Чтобы добавить свое примечание, просто заполните это поле перед нажатием на кнопку Сохранить/Опубликовать.

- -

Вот несколько причин почему это полезно:

- - - -

Запрос проверки

- -

MDN сообщество использует проверки (reviews) для того чтобы следить за качеством контента и улучшать его. Это работает с помощью переключения флажка у нужного пункта. Вы можете узнать больше о технической проверке (technical review) и редакционной проверке (editorial review) в руководствах "Как сделать".

- -

Для запроса проверки статьи, над которой вы работали, переключите флажок возле нужного пункта. Техническую проверку следует запрашивать каждый раз, когда вы вносите изменения в технические детали работы чего-либо. Редакционная же проверка хороший выбор когда вы хотите посторонней оценки стиля или качества вашего текста.

- -

Несмотря на то что эти опции добавляют вашу работу в соответсвующие списки (needing technical review или needing editorial review), это не означает что она будет проверена немедленно. Для технической проверки хорошей идеей будет прямо обратиться к специалистам в этой области (см. subject-matter expert). Для редакционной проверки вы можете написать на форуме MDN (см. MDN discussion forum) с просьбой проверить вашу работу.

- -

Будьте внимательны, убедитесь что установили нужные флажки перед нажатием кнопки Сохранить/Опубликовать.

- -

 

- -

{{EditorGuideQuicklinks}}

diff --git a/files/ru/mdn/editor/basics/page_controls/index.html b/files/ru/mdn/editor/basics/page_controls/index.html deleted file mode 100644 index 3f49c886b4..0000000000 --- a/files/ru/mdn/editor/basics/page_controls/index.html +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Элементы управления страницей в редакторе MDN -slug: MDN/Editor/Basics/Page_controls -tags: - - Beginner - - Guide - - editor -translation_of: MDN/Editor/Basics/Page_controls ---- -
{{MDNSidebar}}
- -

Элементы управления состоят из кнопок, затрагивающих страницу в целом. Они расположены наверху и внизу страницы, для удобства прокрутки страницы. Здесь расположены четыре кнопки:

- -
-

Если вы пытаетесь сохранить вашу работу и ваши изменения отклоняются как некорректные, но вы уверены, что ваш контент подходит для MDN,  вам следует связаться с командой редакторов для разрешения проблемы.

-
- -
-
Сохранить и продолжить редактирование
-
Эта кнопка сохраняет и публикует страницу, не закрывая редактор. Это позволяет периодически сохранять вашу работу, оставляя запись в истории. Благодаря этому вы сможете при необходимости откатить изменения, или приостановить работу и продолжить в удобное время. Эта функция недоступна при создании новых страниц. Смотрите также раздел о примечании, чтобы узнать как оставить комментарий к вашим изменениям и зачем это делать. 
-
Опубликовать
-
Эта кнопка сохраняет и публикует изменения, а также закрывает редактор и возвращает вас на страницу в обычном режиме.
-
Предварительный просмотр
-
Эта кнопка открывает новую вкладку или окно, в котором показано как будут выглядить ваши изменения после публикации. Это подразумевает, что все ваши макросы и шаблоны будут показаны как уже обработанные. Обратите внимание, что ваша работа не будет сохранена при использовании этой опции. Эта возомжность позволяет вам проверить, до того как вы сделали свои изменения публичными, не допустили ли вы ошибок в своих шаблонах, макросах, или при оформлении текста. Если вы столкнулись с ошибками выполнения скриптов, смотрите Troubleshooting scripting error while previewing a page.
-
-
-

Внимание: В настоящее время некоторые шамблоны и макросы не выполняются корректно при предварительном просмотре, оставляя страницу без части контента (таких как боковые меню), и, следовательно, частично искажая страницу. Кроме того, если SCAYT включен (и если страница содержит определенные рабочие макросы или шаблоны), режим предварительного просмотра может выдавать ошибку выполнения скриптов.

-
-
-
Отменить
-
Эта кнопка отменяет все ваши несохраненные изменения. Вы будете возвращены на страницу в обычном режиме чтения.
-
-
-

Warning: Occasionally Discard can malfunction and start acting more like a partial "discard," undoing many of your changes without exiting the editor. If this happens to you, you should save, exit, and re-enter the editor.

-
-
-
diff --git a/files/ru/mdn/editor/basics/toolbar/index.html b/files/ru/mdn/editor/basics/toolbar/index.html deleted file mode 100644 index 8a01621158..0000000000 --- a/files/ru/mdn/editor/basics/toolbar/index.html +++ /dev/null @@ -1,256 +0,0 @@ ---- -title: Панель инструментов редактора MDN -slug: MDN/Editor/Basics/Toolbar -tags: - - Beginner - - editor -translation_of: MDN/Editor/Basics/Toolbar ---- -
{{MDNSidebar}}
- -

Панель инструментов редактора предоставляет вам возможность менять внешний вид и структуру документов во время работы. Эта статья описывает назначение кнопок в панели инструментов.  

- -

На панели расположено три ряда. На первых двух - кнопки, а на третьем HTML контекст, который показывает вам какой элемент вы редактируете в данный момент. На скриншоте ниже, например, редактирование происходит в {{htmlelement("p")}} элементе. 

- -

Screenshot of the toolbar, with labels for the button groupsКнопки на панели инструментов разделены на девять групп. Давайте взглянем на все. Мы будем изучать кнопки в каждой группе по порядку, слева направо.

- - - -

Документ

- -

Кнопки из этой группы используются для управления на уровне всего документа.

- -
-
Source
-
Кнопка Source позволяет переключаться между редактированием в режиме WYSIWYG и редактированием разметки HTML. Мы просим вас избегать редактирования разметки, т.к. в таком случае очень легко неправильно оформить статью или вовсе столкнуться с ошибками. Правда в настоящее время у редактора могут встречаться некоторые причуды в работе, из-за которых сделать некоторые вещи не удастся, не отредактировав разметку напрямую. Смотрите Режим разметки в редакторе MDN чтобы более подробно изучить этот режим и понять что в разметке писать можно, а чего писать не следует.
-
Publish
-
То же что и кнопка Опубликовать.
-
- -
-

Примечание: Если вы пытаетесь сохранить вашу работу и ваши изменения отклоняются как некорректные, но вы уверены, что ваш контент подходит для MDN, вам следует связаться с командой редакторов для разрешения проблемы.

-
- -
-
Preview
-
Аналог кнопки Предварительный просмотр.
-
- -

Правка

- -

Функции этих кнопок очень схожи с соответствующими из меню Правка в любом другом редакторе.

- -
-
Paste / Вставить
-
Вставить контент из буфера обмена в поле редактора.
-
Paste as plain text / Вставить как обычный текст
-
Открывает диалоговое окно в которое вы можете вставить текст. Этот текст будет отделен от всего лишнего, так что вы не вставите случайно текст с лишними стилями или ссылками. После вставки текста, вы можете его отредактировать, если нужно, а затем, кликнув на кнопку OK, вставить на страницу.
-
-
-

Примечание: Обратите внимание, что во время вставки контента в редактор, если вы копировали стилизованный контент (например, скопированный с другого сайта  код  с подсветкой синтаксиса),  вы можете случайно вставить вместе с ним стили или посторонние классы. Пожалуйста, будьте внимательны и не допускайте этого. Проверяйте свои изменения в режиме разметки, если требуется, чтобы удалить лишние стили и классы (или позаботьтесь об этом заранее, воспользовавшись кнопкой "Paste as plain text").

-
-
-
Undo
-
Отменить последнее изменение.
-
Redo
-
Применить последнее отмененное изменение.
-
- -

Работа с текстом

- -
-
Find / Найти
-
Открывает диалоговое окно Find and Replace в режиме "Find", который позволяет найти в вашем документе определенную строку.
-
Replace / Заменить
-
Открывает диалоговое окно Find and Replace в режиме "Replace", с помощью которого можно найти нужную строку и заменить на новую.
-
- -

Кнопки Find и Replace открывают одно и то же диалоговое окно, которое имеет несколько опций для поиска и, опционально, замены текста.

- -
-
Spell Checker / Проверка правописания
-
Эта кнопка открывает меню с несколькими пунктами: -
-
Enable SCAYT/Disable SCAYT
-
Включает или отключает Spell Check As You Type (SCAYT)
-
Options
-
Если SCAYT включен, этот пункт открывает диалоговое окно SCAYT во вкладке с опциями для настройки SCAYT.
-
Languages
-
Если SCAYT включен, этот пункт открывает диалоговое окно SCAYT во вкладке "Languages", где вы можете выбрать язык для проверки правописания.
-
Dictionaries
-
Если SCAYT включен, этот пункт открывает диалоговое окно SCAYT во вкладке "Dictionaries", где вы можете сами выбрать словарь, который SCAYT будет использовать.
-
About SCAYT
-
Если SCAYT включен, этот пункт открывает диалоговое окно SCAYT во вкладке "About", в которой написано о SCAYT.
-
Check Spelling
-
Этот пункт открывает диалоговое окно Spell Checker, в котором вы можете проверить правописание в пакетном режиме (batch mode) для всего документа. Вы можете воспользоваться вкладкой Grammar для проверки грамматических ошибок, или воспользоваться вкладкой Thesaurus для поиска синонимов для слов в документе.
-
-
-
- -

Вид

- -

Эта группа позволяет настроить вид отображения интерфейса редактора. 

- -
-
Maximize
-
Эта кнопка разворачивает интерфейс редактора (то есть панель инструментов и поле редактирования) во всё окно браузера, предоставляя вам как можно больше места для работы.
-
Show blocks
-
Эта кнопка отображает контуры вокруг блочных элементов в вашем документе. Это может быть удобным для проверки структуры документа без необходимости заглядывать в разметку.
-
- -

Строковые стили

- -

Строковые стили содержат распространенные стили, которые могут вам пригодиться при оформлении текста.

- -
-
Bold
-
Переключает жирный стиль текста, создавая при этом в разметке элемент {{htmlelement("strong")}}.
-
Italic
-
Переключает курсив. Создает {{htmlelement("em")}} элемент.
-
Underline
-
Переключает нижнее подчеркивание. Создает {{htmlelement("u")}} элемент.
-
Strike through
-
Переключает перечеркивание. Создает {{htmlelement("s")}} элемент.
-
Subscript
-
Переключает нижний индекс. Создает {{htmlelement("sub")}} элемент.
-
Superscript
-
Переключает верхний индекс. Создает {{htmlelement("sup")}} элемент. Заметьте, что такой строковый стиль не используется на MDN, так что вам вряд ли когда-нибудь пригодится эта кнопка.
-
Remove format
-
Удаляет текущий строковый стиль в выделенном тексте.
-
Code
-
Переключает стиль для кода. Создает {{htmlelement("code")}} элемент. Это используется для представления в тексте имен переменных, функций, объектов, файлов и т.п.
-
- -

Работа со ссылками

- -

Данная группа предоставляет инструменты для работы со ссылками.

- -
-
Link
-
Создает новую ссылку. При нажатии вызывается окно создания ссылки, работа с которым подробна описана в Ссылки с помощью панели инструментов.
-
Unlink
-
Удаляет ссылку в месте, где расположен курсор.
-
Anchor
-
Создает якорь в месте, где расположен курсор. Заметьте, что вам не нужно создавать якорь для заголовков, редактор автоматически создает {{htmlattrxref("id")}} для каждого заголовка, заменяя пробелы в названии на нижние подчеркивания. Например, заголовок этой секции имеет id, значение которого Работа_со_ссылками.
-
Create a redirect
-
Встраивает переадресацию на другую страницу. Смотрите Создание переадресаций для подробной информации.
-
- -

Специальные стили

- -

Кнопка Styles - это выпадающее меню, предлагающее на выбор специальные стили форматирования текста.

- -

Блочные стили

- -
-
None
-
Удаляет стиль с выбранного блока.
-
Note box
-
Создает блок с примечание, как показано ниже. Вы должны всегда начинать примечание со слова "Примечание:" жирными буквами.
-
- -
-

Примечание: Это поле с примечанием.

-
- -
-
Warning box
-
Создает блок с предупреждением, как показано ниже. Блок должен всегда начинаться со слова "Внимание:" жирными буквами.
-
- -
-

Внимание: Это поле с предупреждением.

-
- -
-
Two columns
-
Делает выделенный текст или блок двухколоночным на браузерах, которые это поддерживают.
-
Three columns
-
Делает выделенный текст или блок трехколоночным на браузерах, которые это поддерживают.
-
Syntax box
-
Создает поле для синтаксиса, как показано ниже. Это создает {{htmlelement("pre")}}. Вы можете также использовать кнопку "PRE".
-
-
Это поле для синтаксиса
-
-
Hidden when reading
-
Создает блок, который видно только в режиме редактирования. Это не то же, что и HTML-комментарий, который виден только в режиме разметки.
-
- -

Строковые стили

- -
-
SEO summary
-
Этот специальный стиль используется чтобы выделить предложение или два, которые будут использованы как краткое описание для поисковой оптимизации. Он также используется макросами для автоматического создания посадочных страниц. Если вы не воспользуетесь этим стилем, MDN автоматически использует первый абзац вашей статьи. Но иногда это не самый лучший вариант и лучше воспользоваться предложенным стилем.
-
- -

Блоки

- -

Эта группа включает опции для прочих стилей блоков. Некоторые из них относятся к стандартному HTML, а другие - уникальны, т.к. относятся к Kuma.

- -
-
Blockquote
-
Вставляет блок для цитаты. Пожалуйста, не используйте это. Блоки с цитатами не являются частью нашего стайлгайда, и эта кнопка будет удалена в ближайшем будущем.
-
Preformatted Text
-
Вставляет {{htmlelement("pre")}} блок, или превращает в него текущий. Все примеры кода должны быть оформлены в такой блок.
-
Headings
-
Кнопки заголовков позволяют вам вставить нужный заголовок. Нажмите на одну из этих кнопок для создания нового заголовка соответственной глубины. По умолчанию заголовки с H2 по H4 включаются в оглавление, но вы можете изменить это, как описано в разделе Информация о странице.
-
Syntax highlighter
-
Подсветка синтаксиса позволяет вам выбрать язык, синтаксис которого будет подсвечиваться в {{htmlelement("pre")}} блоке. Если такой блок не был выбран изначально, он будет создан. Выберите язык используемый в блоке, и блок будет подсвечен соответствующим образом.
-
Insert Code Sample Template
-
Эта кнопка используется системой живых примеров (the live sample system), чтобы помочь вам быстро вставить новый живой пример (live sample). Смотрите Пользование системой живых примеров чтобы узнать подробнее.
-
Insert Code Sample iFrame
-
Вставляет в документ подходящий макрос для отображения нужного живого примера. Смотрите Пользование системой живых примеров для деталей использования и информации о других функциях живых примеров.
-
- -

Списки и поток текста

- -

Эта группа предоставляет инструменты для создания списков и изменения поведения текста в блоках.

- -
-
Insert/remove numbered list
-
Создает или удаляет нумерованный список. Когда вы работаете над списком, при каждом нажатии Enter будет создаваться новый элемент списка. Клавиша Tab может быть использована для увеличения вложенности, а Shift + Tab, соответсвенно, для уменьшения. При нажатии на Enter в пустом элементе список будет закончен. Нажатие ПКМ на списке открывает контекстное меню с опцией Numbered list properties, в которой можно выбрать стиль маркера.
-
Insert/remove bulleted list
-
Создает или удаляет маркированный список. Когда вы работаете над списком, при каждом нажатии Enter будет создаваться новый элемент списка. Клавиша Tab используется для увеличения вложенности, а Shift + Tab для уменьшения. При нажатии на Enter в пустом элементе список будет закончен. Нажатие ПКМ на списке открывает контекстное меню с опцией Bulleted list properties, в которой можно выбрать стиль нумерации (числа, буквы, римские цифры и пр., а также с какой цифры начинать).
-
Definition List
-
Создает новый список с определениями (definition list). Этот список состоит из серии терминов и определений (именно такой список вы сейчас читаете).
-
Definition Term
-
Создает новый блок с термином в списке. Если в данный момент вы не редактируете список, он будет создан. Нажатие на Enter автоматически переключается на редактирование нового определения.
-
Definition Value
-
Создает новый блок с определением в списке. Нажатие на Enter создает новый термин. Нажав дважды, вы покинете список.
-
Decrease indent
-
Уменьшает вложенность. Того же эффекта можно добиться нажав Shift + Tab в списке.
-
Increase indent
-
Увеличивает вложенность. То же самое, что и нажатие Tab в списке.
-
Text direction left-to-right
-
Переключает текущее направление текста на слева направо. Используется при работе с другими языками. Например, при работе с английским текстом в арабском.
-
Text direction right-to-left
-
Переключает текущее направление текста на справа налево. Используется при работе с другими языками. Например, при работе с арабским текстом в английском.
-
- -

Медиа

- -

Данная группа предоставляет инструменты для работы с медиафайлами.

- -
-
Image
-
Вставляет новое изображение в статью. Смотрите Изображения для подробностей.
-
Table
-
Вставляет таблицу в статью. Смотрите Таблицы для подробной информации о таблицах в статьях.
-
Embed YouTube Video
-
Открывает диалоговое окно, в котором вы можете ввести URL для видео YouTube. С этой информацией создается вызов макроса EmbedYouTube. Это безопасный способ встроить видеоконтент.
-
Insert MathML based on (La)TeX
-
Открывает диалоговое окно, в которое вы можете вставить свой код TeX или LaTeX. Этот код будет конвертирован в MathML вставлен в документ в {{htmlelement("math")}} блоке.
-
- -

 

diff --git a/files/ru/mdn/editor/index.html b/files/ru/mdn/editor/index.html deleted file mode 100644 index df98522e38..0000000000 --- a/files/ru/mdn/editor/index.html +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: Руководство по MDN редактору -slug: MDN/Editor -tags: - - Landing - - MDN - - Редактор MDN -translation_of: MDN/Editor ---- -
{{MDNSidebar}}
- -
{{IncludeSubnav("/ru/docs/MDN")}}
- -

WYSIWYG ("what-you-see-is-what-you-get" в переводе "что видишь, то и получишь") — редактор для веб-документов MDN, который позволяет легко делать вклад в новый контент. Это руководство показывает, как использовать редактор и улучшить вашу продуктивность. Пожалуйста, убедитесь в том, что прочитали Условия использования Mozilla и согласны с ними перед тем, как начать редактировать или создавать новые страницы.

- -

Руководство по оформлению MDN предлагает информацию о том, как оформлять и стилизовать контент, включая предпочтительные грамматические и орфографические правила.

- -
-
-
-
Редактор UI элементов
-
Встроенный WYSIWYG редактор на MDN разработан так, чтобы максимально упростить создание, редактирование и улучшение статей и других страниц практически на всем сайте. Окно редактора, как показано ниже, состоит из восьми блоков.
- Это руководство предоставляет информацию о каждом разделе, чтобы вы знали, как использовать все возможности нашего редактора.
-
Изображения
-
Изображения очень часто используются при оформлении статей. Они могут быть снимками экрана, примерами того, как должен выглядеть результат, SVG-диаграммами. Данная статья описывает способы работы с изображениями в контенте сайта MDN.
-
Горячие клавиши в редакторе MDN
-
Существует ряд удобных горячих клавиш, позволяющих вам не отрывать руки от клавиатуры во время работы в UI редактора MDN. Они перечислены в этой статье.
-
Ссылки
-
Ссылки — это ключевой компонент любой вики не только среди множества документов, но и в пределах одного. К счастью, ссылки очень легко создавать, даже несмотря на то, что есть очень много способов сделать их! В статье рассказывается всё о ссылках в редакторе MDN.
-
-
- -
-
-
Перенаправление
-
Иногда вам понадобится создать страницу, которая просто перенаправляет на другую страницу. В этой статье рассказывается, как сделать переадресацию.
-
Режим источника
-
В редакторе MDN есть особая кнопка, позволяющая вам включать режим источника. В этом режиме вы можете видеть HTML-код тела статьи, которую вы пишете. Это руководство поможет вам понять, что вы можете делать в режиме источника, что вам следует с ним делать и, самое важное, чего вам делать не следует.
-
Синтаксические выделения
-
Синтаксическое выделение кода крайне полезно в статьях. Режим синтаксического выделения также используется в нашей системе шаблонов, чтобы определять, как использовать каждый отрывок кода при сборке в готовый экземпляр.
-
Таблицы
-
Таблицы полезны для представления информации. В этой статье описано, как создавать и обслуживать таблицы на MDN и когда стоит и не стоит использовать их.
-
-
-
- -

{{EditorGuideQuicklinks}}

diff --git a/files/ru/mdn/editor/source_mode/index.html b/files/ru/mdn/editor/source_mode/index.html deleted file mode 100644 index af5d7b5535..0000000000 --- a/files/ru/mdn/editor/source_mode/index.html +++ /dev/null @@ -1,128 +0,0 @@ ---- -title: Режим источника -slug: MDN/Editor/Source_mode -tags: - - Guide - - MDN Meta - - NeedsContent - - editor - - Редактор MDN - - Руководство -translation_of: MDN/Editor/Source_mode ---- -
{{MDNSidebar}}
- -

 В редакторе MDN есть особая кнопка, позволяющая вам включать режим источника. В этом режиме вы можете видеть HTML-код тела статьи, которую вы пишите. Это руководство поможет вам понять, что вы можете делать в режиме источника, что вам следует с ним делать и, самое важное, чего вам делать не следует.

- -
-

Перед тем как использовать режим источника, примите во внимание, что мы крайне не рекомендуем использовать режим источника. За исключением случаев, когда то, что вы делаете в режиме источника, соответствует нашему руководству по оформлению кода (мы нуждаемся в опциях, которые, к сожалению, пока что не могут быть созданы без режима источника), вам нет необходимости в использовании этого режима. Смотрите {{anch("Предостережения")}} ниже.

-
- -

Включение режима источника

- -

Включить режим источника очень легко. В левом верхнем углу нажмите кнопку Источник.

- -

Partial screenshot of the editor toolbar, with the Source mode button highlighted

- -

Предостережения

- -

Как упомянуто ранее, вам редко понадобится режим источника. Немного вы сможете сделать в этом режиме. Со временем мы обновим интерфейс редактора, чтобы настроить это немного для вас.

- -

Всего того, что неявно описано где-то в руководстве по сотрудничеству с MDN, не должно быть в источнике. Это значит, что:

- - - -

Работа в режиме источника

- -

В режиме источника вы работаете с HTML-кодом, который составляет контент страницы вики. Если вы не ограничиваетесь обычным редактором, вы должны убедиться в том, что ваша работа соответствует оформлению и что она работает надёжно и безопасно.

- -

К сожалению, клавиша Tab пока что не работает в режиме источника. Используйте два пробела там, где обычно используете Tab.

- -

Элементы и атрибуты, которые MDN не поддерживает, будут удалены после сохранения документа. Вдобавок HTML документа преобразован, чтобы он был более читаемым и совместимым.

- -

Использование режима источника

- -

Здесь описано несколько случаев, когда единственный способ соответствовать оформлению статей MDN — использовать режим источника. Этот раздел описывает эти ситуации и как правильно выполнять данные функции, чтобы не испортить остальное.

- -

Выделение строк в примерах кода

- -

Блоки примеров кода устанавливаются кнопками PRE или Syntax Highlighter в блоках панели инструментов, но вы, возможно, захотите обратить внимание читателей на определённые строки кода. Единственный способ сделать это — открыть режим источника, найти там блок <pre>, содержащий код, и добавить в атрибут class тега <pre>  компонент highlight, отформатированный следующим образом:

- - - -
"hightlight[" <список-номеров-строк> "]"
-
-Где:
-<список-номеров-строк> = [ <номер-строки> | <диапазон-строк> ]#
-<диапазон-строк> = <номер-строки> - <номер-строки>
-<номер-строки> = <число-токен>
- -
-

Выделенные строки не отображаются в редакторе MDN.

-
- -

К примеру, если есть тег <pre class="brush: js;">, и вы хотите выделить строки 4 и 7, то вы меняете тег: <pre class="brush: js; highlight[4, 7]">.

- -

Давайте взглянем на более полный пример:

- -
- - - - - - - - - - - - - -
До выделенияС выделением
-
-var canvas = document.getElementById("canvas");
-var ctx = canvas.getContext("2d");
-
-var path1 = new Path2D();
-path1.rect(10, 10, 100, 100);
-
-var path2 = new Path2D(path1);
-path2.moveTo(220, 60);
-path2.arc(170, 60, 50, 0, 2 * Math.PI);
-
-ctx.stroke(path2);
-
- -

Здесь тег {{HTMLElement("pre")}} равен: <pre class="brush: js;">

-
-
-var canvas = document.getElementById("canvas");
-var ctx = canvas.getContext("2d");
-
-var path1 = new Path2D();
-path1.rect(10, 10, 100, 100);
-
-var path2 = new Path2D(path1);
-path2.moveTo(220, 60);
-path2.arc(170, 60, 50, 0, 2 * Math.PI);
-
-ctx.stroke(path2);
- -

А здесь тег <pre> изменён на: <pre class="brush: js; highlight[4, 7]">

-
-
- -

Стили, которых нет в панели инструментов

- -

У нас есть несколько стилей, которые нельзя применить, не используя режим источника. К счастью, их редко когда используют. Например:

- - diff --git a/files/ru/mdn/editor/tables/index.html b/files/ru/mdn/editor/tables/index.html deleted file mode 100644 index 1f6f988d6a..0000000000 --- a/files/ru/mdn/editor/tables/index.html +++ /dev/null @@ -1,162 +0,0 @@ ---- -title: Таблицы -slug: MDN/Editor/Tables -tags: - - Guide - - MDN - - MDN Meta - - Редактор - - Руководство -translation_of: MDN/Editor/Tables ---- -
{{MDNSidebar}}
- -

Таблицы полезны для представления информации; в этой статье описано, как создавать и обслуживать таблицы на MDN и когда стоит и не стоит использовать их.

- -

В MDN, в основном, мы используем таблицы для представления перечня информации из более чем двух участков информации, приходящихся на один пункт. Если вы создаёте лист из названия элементов и их значений, то лучше создать список описаний вместо таблицы; это потому что мы стараемся по возможности реже использовать таблицы из двух колонок, так как возникают трудности их отображения при чтении на мобильных устройствах.

- -

Пожалуйста, прочтите Руководство по оформлению материалов MDN, чтобы лучше узнать об использовании таблиц и их правильном оформлении; всё же давайте посмотрим, как вставлять и редактировать таблицы.

- -

Создание таблицы

- -

Чтобы вставить таблицу, нажмите кнопку Таблица на панели инструментов, которая выглядит так: as of Aug-2017

- -

Откроется окно Свойства таблицы:

- -

Скриншот окна "Свойства таблицы"

- -

В окне две вкладки: Свойства таблицы и Дополнительно.

- -

Вкладка Свойства таблицы

- -

В этой вкладке вы будете выполнять бо́льшую часть настроек, потому что во вкладке Дополнительно гораздо меньше настроек, которые мы рекомендуем использовать. Опции:

- -
-
Строки
-
Число строк в вашей таблице. Вы также можете добавить строки непосредственно в редакторе, но так будет быстрее.
-
Колонки
-
Число колонок в таблице.
-
Заголовки
-
Позволяет вам обозначить заголовки, если это необходимо. По умолчанию в таблице нет заголовков; однако мы предпочитаем использовать заголовки, поэтому советуем вам использовать их в большинстве случаев. Возможные значения: Без заголовков, Первая строка, Левая колонка и Сверху и слева.
-
Выравнивание
-
Позволяет выравнивать таблицу в левой, правой или центральной части страницы. Пожалуйста, не используйте эту опцию. В нашем руководстве по оформлению указано, что таблицы всегда должны нахадиться слева. (Из этого правила есть исключения.)
-
Заголовок
-
Вы можете выбрать заголовок к таблице; однако мы редко делаем это в MDN, поэтому лучше не использовать эту опцию.
-
Итоги
-
Просто пропустите этот пункт, потому что рядом с таблицей вам придётся писать объяснение.
-
- -

Вкладка Дополнительно

- -

Вкладка Дополнительно предоставляет несколько возможностей, большую часть которых мы не используем на MDN и в будущем уберём.

- -

Скриншот вкладки "Дополнительно"

- -

Как видите, тут немного опций:

- -
-
Идентификатор
-
Идентификатор (id) элемента {{HTMLElement("table")}}. Мы в принципе не используем идентификаторы в таблицах на MDN.
-
Направление текста
-
Позволяет настроить направление текста в таблице. Используется только при локализации контента.
-
Стиль
-
В этом поле вы можете применить собственный стиль CSS к таблице. Вообще не используйте это поле! В таком случае мы просто удалим вашу таблицу. Мы стараемся избавляться от пользовательских стилей там, где применяются наши.
-
CSS классы
-
Добавляет класс к стилю таблицы. Значение всегда должно быть standard-table, явдяющееся нашим стандартным классом для таблиц.
-
- -

Как только вы завершите настройку, нажмите кнопку OK для создания таблицы.

- -

Обслуживание таблиц

- -

Работа с таблицей очень похожа на работу в любом редакторе таблиц — надо просто заполнить ячейки. Клавиша Tab переместит вас на следующую ячейку таблицы или создаст новую строку, если следующей клетки нет.

- -

Кликните правой кнопкой мыши по таблице, чтобы появился ряд опций для регулировки самих ячеек, строчек и колонок таблицы, а ткаже самой таблицы:

- -

Скриншот контекстного меню

- -
-
Вставить
-
В браузерах поддерживается вставка через скрипт (в некоторых браузерах, в том числе в Firefox, это не поддерживается из соображений безопасности). Эта опция вставляет содержимое буфера обмена в текущую ячейку таблицы.
-
Ячейка
-
Открывает подменю для работы с ячейками.
-
Строка
-
Открывает подменю для работы со строками.
-
Колонка
-
Открывает подменю для работы с колонками.
-
Удалить таблицу
-
Удаляет текущую таблицу.
-
Сортировка (Sort Table)
-
Открывает диалоговое окно для сортировки данных в таблице.
-
Свойства таблицы
-
Открывает то же окно для создания таблицы.
-
- -

Подменю Ячейка

- -

Подменю предоставляет опции для манипуляций с ячейками вашей таблицы, и оно выглядит так:

- -

Скриншот подменю "Ячейка" в контекстном меню

- -

Названия опций говорят сами за себя, но стоит оговориться, что Объединить ячейки доступно, только если вы выбрали несколько ячеек. Опции Объединить с правой и Объединить с нижней объединяют текущую ячейку с той, что находится справа или снизу соответственно.

- -

Окно Свойства ячейки

- -

Опция Свойства ячейки открывает диалоговое окно для детальной настройки ячейки. Окно выглядит вот так:

- -

Скриншот окна "Свойства ячейки"

- -

Опции:

- -
-
Ширина
-
Изменяет ширину клетки; вы можете выбрать единицу изменения в выпадающем меню рядом. Пожалуйста, не используете эту опцию. Вам не понадобится изменять ширину клетки, за исключением случаев, когда надо вставить изображение или пример кода в таблицу.
-
Высота
-
Устанавливает высоту клетки (всегда в пикселах). Пожалуйста, не используете эту опцию. Высота клетки определяется автоматически.
-
Перенос по словам
-
Определяет, будет переноситься содержимое ячейки или нет. Всегда должно быть установлено значение по умолчанию, Да.
-
Горизонтальное выравнивание
-
Позволяет устанавливать выравнивание текста по горизонтали. Следует всегда оставлять значение по умолчанию, По левому краю.
-
Вертикальное выравнивание
-
Позволяет устанавливать выравнивание текста по вертикали.
-
Тип ячейки
-
Позволяет вам определить, какой тип у ячейки — Заголовок или Данные. Если установлено значение Заголовок, то будет применена соответствующая стилизация.
-
Объединяет строк
-
Позволяет определить, сколько строк необходимо объединить. Используется редко, но в некоторых таблицах очень полезно.
-
Объединяет колонок
-
Определяет, сколько колонок необходимо объединить.
-
Цвет фона
-
Определяет цвет фона ячейки. Старайтесь не использовать эту фунцию; редкие случаи, когда смена цвета ячейки приемлема, прописаны в классах CSS.
-
Цвет границ
-
Определяет цвет границы ячейки. Старайтесь не использовать эту фунцию; редкие случаи, когда смена цвета границы ячейки приемлема, прописаны в классах CSS.
-
- -

Подменю Строка

- -

Подменю Строка предоставляет опции, используя которые вы можете корректировать строки:

- -

Скриншот подменю "Строка" в контекстном меню

- -

Опции подменю по порядку:

- - - -

Подменю Колонка

- -

Подменю позволяет вам изменять колонки в вашей таблице:

- -

Скриншот подменю "Колонка" в контекстном меню

- -

Опции похожи на опции подменю Строка:

- - - -

{{EditorGuideQuicklinks}}

diff --git "a/files/ru/mdn/editor/\320\263\320\276\321\200\321\217\321\207\320\270\320\265_\320\272\320\273\320\260\320\262\320\270\321\210\320\270/index.html" "b/files/ru/mdn/editor/\320\263\320\276\321\200\321\217\321\207\320\270\320\265_\320\272\320\273\320\260\320\262\320\270\321\210\320\270/index.html" deleted file mode 100644 index 7a697614df..0000000000 --- "a/files/ru/mdn/editor/\320\263\320\276\321\200\321\217\321\207\320\270\320\265_\320\272\320\273\320\260\320\262\320\270\321\210\320\270/index.html" +++ /dev/null @@ -1,146 +0,0 @@ ---- -title: Горячие клавиши в редакторе MDN -slug: MDN/Editor/Горячие_клавиши -tags: - - MDN - - MDN Meta - - Reference - - Горячие клавиши - - Клавиши - - Редактор -translation_of: MDN/Editor/Keyboard_shortcuts ---- -

Существует ряд удобных горячих клавиш, позволяющих вам не отрывать руки от клавиатуры во время работы в UI редактора MDN.

- -

Горячие клавиши перечислены для Windows и Linux; для Mac вместо ключа Control используйте Command.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Сочетание клавишОписание
Ctrl + AВыделить всё
Ctrl + CКопировать
Ctrl + VВставить
Ctrl + Shift + VВставить без форматирования
Ctrl + XВырезать
Ctrl + ZОтменить
Ctrl + YПовторить
Ctrl + KОткрыть редактор ссылок/добавить новую ссылку
Ctrl + Shift + KУдалить ссылку в текущем положении курсора
Ctrl + BПолужирный текст
Ctrl + IКурсив
Ctrl + OВключить стилизацию <code>
Ctrl + Shift + O -

Включить режим просмотра источника

- -
Будьте внимательны при работе в режиме источника: вы должны придерживаться наших стандартов заполнения содержимого. Ознакомьтесь с нашим гайдом по режиму источника, чтобы узнать, как использовать режим источника и что вам следует и не следует делать в нём.
-
Ctrl + P -
-Включить или отключить стилизацию <pre> в текущем блоке.
-
Ctrl + UПодчёркивание
Ctrl + SОпубликовать изменения, не закрывая редактор
Ctrl + Shift + SОпубликовать изменения и закрыть редактор
Ctrl + 0Удалить форматирование в выделенной области (Это ноль, а не буква "О")
От Ctrl + 2 до Ctrl + 5Выбор уровней заголовков от 2 до 5. Уровень 1 предназначен для заголовка страницы, расположенного в верху статьи
Ctrl + Shift + LПреобразование выделенного текста (по порядку): в нумерованный список — в маркированный список — удалить список
TabУвеличивает отступ или же вставляет два пробела. В таблицах перемещает курсор в следующую ячейку или вставляет новый ряд, если следующей клетки нет. Курсор перемещается на следующий абзац, если находится на заголовке страницы
Shift + TabУменьшает отступ. В таблицах перемещает курсор в предыдущую ячейку или вставляет новый ряд, если предыдущей клетки нет. Курсор перемещается на следующий абзац, если находится на заголовке страницы
Shift + SpaceВставляет неразрывный пробел(&nbsp;)
Shift + Enter -

Выводит из блока. К примеру, если вы редактируете блок <pre>Shift + Enter выводит курсор из блока, помещая его обратно в тело статьи

- -
-

На данный момент не поддерживается: {{bug('780055')}}.

-
-
- -

Смотрите также

- - - -
{{MDNSidebar}}
diff --git "a/files/ru/mdn/editor/\320\272\320\260\321\200\321\202\320\270\320\275\320\272\320\270/index.html" "b/files/ru/mdn/editor/\320\272\320\260\321\200\321\202\320\270\320\275\320\272\320\270/index.html" deleted file mode 100644 index f095489297..0000000000 --- "a/files/ru/mdn/editor/\320\272\320\260\321\200\321\202\320\270\320\275\320\272\320\270/index.html" +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: Изображения -slug: MDN/Editor/Картинки -tags: - - Изображение - - Работа с изображениями - - Рисунок - - Руководство -translation_of: MDN/Editor/Images ---- -
{{MDNSidebar}}
- -

Изображения очень часто используются при оформлении статей. Они могут быть снимками экрана (screenshot), примерами того, как должно выглядеть произведение искусства, SVG-диаграммами. Данная статья описывает способы работы с изображениями в контенте сайта MDN.

- -
Замечание: При загрузке изображения, пожалуйста, убедитесь, что используете инструменты оптимизации, чтобы сделать файл маленьким, а загрузку возможной. Это сокращает время загрузки страницы и помогает производительности MDN в целом. Вы можете использовать свой любимый инструмент, если он у вас есть. Иначе, мы предлагаем TinyPNG - удобный Веб инструмент.
- -

После добавления изображения на страницу (смотрите {{SectionOnPage("/en-US/docs/MDN/Contribute/Editor/Basics", "The attachments box")}}), его можно использовать в оформлении статьи. Также можно использовать любые уже загруженные изображения, размещенные на сайте MDN. Для добавления нажмите на кнопку "Изображение" на панели инструментов: Toolbar icon for inserting image

- -

Окно Свойства изображения:

- -

- -

Здесь присутствуют три вкладки: "Данные об изображении" (Image Info), "Ссылка" (Link), "Дополнительно" (Advanced).

- -

Вкладка "Данные об изображении"

- -
-
Прикреплённые файлы (Attachments)
-
Этот выпадающий список содержит прикреплённые к странице элементы. Здесь перечислены только объекты, загруженные в текущем сеансе редактирования или те, которые уже используются на странице.
-
Ссылка (URL)
-
Если есть необходимость использовать рисунок, которого нет в аттачментах, например, файл загружен в прошлом сеансе редактирования или используется где-то на MDN, то можно указать URL рисунка.
-
Альтернативный текст (Alternative text)
-
Текст, который будет показываться вместо изображения, если оно не отображается (например, если пользователь выключил отображение картинок в браузере). Этот текст также используется программами чтения с экрана, поэтому, пожалуйста, поместите соответствующую заметку здесь для удобства доступа.
-
Ширина / Высота (Width / Height)
-
Вы можете настраивать ширину и высоту изображения, как указано в этой статье. По умолчанию эти поля заблокированы для сохранения пропорций изображения, но блокировку можно отключить нажатием на значёк .
-
Граница (Border)
-
Дополнительно можно установить толщину границы вокруг изображения. Рекоммендуется указывать 0 (ноль или оставить пустым) или 1. Используйте эту опцию только в том случае, если фон изображения светлый и его нужно дополнительно выделить на фоне веб-страницы.
-
Горизонтальный отступ / Вертикальгый отступ (HSpace / VSpace)
-
Указывается число пикселей, которое нужно отступить от изображения по горизонтали или вертикали, например, чтобы отодвинуть текст. Обычно эта настройка используется вместе с выравниванием, описанным ниже.
-
Выравнивание (Alignment)
-
По умолчанию изображения отображаются по отдельности от текста или других изображений (текст и новые изображения обычно переносятся на новую строку). Но этой опцией можно указать, какой стороны листа (левой или правой) должно придерживаться изображение и с какой стороны (правой или левой соответстсвенно) текст будет его обтекать. Так приходится оформлять статьи, если изображение маленькое (или, например, узкое и длинное), и тем самым можно сэкономить свободное пространство и повысить удобство чтения. Если используется эта опция, то, вероятно, нужно будет использовать опции горизонтального и вертикального отступа, чтобы немного отодвинуть текст от изображения. Например, для отступа может использоваться значение 6 или 8.
-
- -

Область "Предпросмотр" показывает пример изображения, которое изменится, исходя из введённых параметров.

- -

Вкладка "Ссылка"

- -

Здесь настраивается ссылка, по которой произойдёт переход при клике на изображение. Часто используется ссылка на увеличенное изображение (можно использовать ту же ссылку, что и на вкладке "Данные об изображении"). Пример:

- -

- -
-
Ссылка (URL)
-
Ссылка для перехода при клике на изображение.
-
Цель (Target)
-
Вариант открытия страницы перехода. Значения аналогичные атрибуту {{htmlattrxref("target", "a")}} HTML-тега {{HTMLElement("a")}}. Не рекоммендуется использовать это поле на MDN. На MDN отдаётся предпочтение открытию ссылок на текущей вкладке браузера.
-
- -

Поддерживаемые типы изображений

- -

Вы можете загружать изображения следующих типов: GIF, JPEG, PNG , а также SVG-диаграммы. Предпочитаемые типы на MDN:

- - - -

Можно загружать файлы из Photoshop. Но их нельзя будет использовать для оформления статей, а только выкладывать для загрузки пользователями.

- -

Удаление и изменение

- -

Для удаление изображения из статьи кликните в изображение мышкой (или установите курсор непосредственно до изображения) и нажмите на клавиатуре клавишу "delete".

- -

Можно изменить свойства изображения, кликнув на него дважды или кликнув правой кнопкой мыши и выбрав из выпадающего контекстного меню пункт "Свойства изображения". В обоих случаях откроется один и тот же диалог.

- -

Удалять вложения могут только администраторы MDN. Обычно мы оставляем старые версии изображений, потому что на них могут оставаться ссылки из старых версий документов. В случае обнаружения недопустимых, неуместных или проприетарных изображений, пожалуйста, обратитесь к администратору MDN для удаления такого вложения или заведите инцидент для удаления.

- -

{{EditorGuideQuicklinks}}

diff --git "a/files/ru/mdn/editor/\320\277\320\265\321\200\320\265\320\275\320\260\320\277\321\200\320\260\320\262\320\273\320\265\320\275\320\270\320\265/index.html" "b/files/ru/mdn/editor/\320\277\320\265\321\200\320\265\320\275\320\260\320\277\321\200\320\260\320\262\320\273\320\265\320\275\320\270\320\265/index.html" deleted file mode 100644 index dade13fb99..0000000000 --- "a/files/ru/mdn/editor/\320\277\320\265\321\200\320\265\320\275\320\260\320\277\321\200\320\260\320\262\320\273\320\265\320\275\320\270\320\265/index.html" +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: Перенаправление -slug: MDN/Editor/Перенаправление -tags: - - Гайд - - Переадресация - - Перенаправление - - Удаление -translation_of: MDN/Editor/Redirects ---- -
{{MDNSidebar}}
- -

Иногда вам понадобится создать страницу, которая просто перенаправляет на другую страницу. В этой статье рассказывается, как сделать переадресацию.

- -

Создание перенаправления

- -

Перенаправление необходимо, к примеру, когда страница слилась с другой. Чтобы создать перенаправление, просто нажмите эту кнопку в панели инструментов: .

- -

Она откроет диалоговое окно, в котором запрашивается имя документа и его URL-адрес. Вообще, имя не так важно; оно больше нужно, если вы сами ищете страницу, и вам нужно знать, куда вы перенаправляете. В поле URL должен быть указан абсолютный (полный) путь, например, "/en-US/docs/foo". Относительные ссылки не сработают. Вы можете перенаправить на раздел страницы, используя хэштэг ("#"), например: "/destination/url/here#название_раздела". Таким образом вы перенапривите пользователя прямиком в раздел страницы.

- -

На странице должно быть только перенаправление; перед его созданием переместите всё содержимое в его новый "дом". Удалите также ревизионные флаги с  этой страницы.

- -
-

Замечание: Обязательно удалите все теги со страницы: если вы это не сделаете, страница с перенаправлением будет рядом со страницей, на которую перенаправили (теги-то одинаковые), смущая людей и занимая свободное место на странице результатоыв поиска. Ещё это плохо скажется на поисковой оптимизации.

-
- -

При удалении страницы

- -

Перед удалением страницы подумайте: а не будет ли лучше перенаправить посетителя на другую страницу MDN? Ведь, если он попадёт на страницу по старой ссылке, лучше отправить его на правильную страницу, чем если бы ему выдали ошибку 404 ("страница не найдена"). Удалять страницу стоит только в крйнем случае: если она забита спамом и прочим неуместным контентом.

- -

{{EditorGuideQuicklinks}}

diff --git "a/files/ru/mdn/editor/\321\201\320\270\320\275\321\202\320\260\320\272\321\201\320\270\321\207\320\265\321\201\320\272\320\270\320\265_\320\262\321\213\320\264\320\265\320\273\320\265\320\275\320\270\321\217/index.html" "b/files/ru/mdn/editor/\321\201\320\270\320\275\321\202\320\260\320\272\321\201\320\270\321\207\320\265\321\201\320\272\320\270\320\265_\320\262\321\213\320\264\320\265\320\273\320\265\320\275\320\270\321\217/index.html" deleted file mode 100644 index f959ae7809..0000000000 --- "a/files/ru/mdn/editor/\321\201\320\270\320\275\321\202\320\260\320\272\321\201\320\270\321\207\320\265\321\201\320\272\320\270\320\265_\320\262\321\213\320\264\320\265\320\273\320\265\320\275\320\270\321\217/index.html" +++ /dev/null @@ -1,181 +0,0 @@ ---- -title: Синтаксические выделения -slug: MDN/Editor/Синтаксические_выделения -tags: - - Guide - - Howto - - MDN - - MDN Meta - - Редактор - - Руководство - - выделение -translation_of: MDN/Editor/Syntax_highlighting ---- -
{{MDNSidebar}}
- -

Синтаксическое выделение кода крайне полезно в статьях. Режим синтаксичесого выделения также используется в нашей системе шаблонов, чтобы определять, как использовать каждый отрывок кода при сборке в готовый экземпляр.

- -

Поддержка синтаксических выделений

- -

MDN поддерживает все переодически используемые нами на MDN языки (так же, как и те, что используются лишь иногда):

- -
-
    -
  • Bash shell
  • -
  • -

    C/C++

    -
  • -
  • -

    CSS

    -
  • -
  • HTML
  • -
  • XML
  • -
  • -

    Java

    -
  • -
  • -

    JavaScript

    -
  • -
  • -

    JSON

    -
  • -
  • -

    PHP

    -
  • -
  • -

    Python

    -
  • -
  • -

    SQL 

    -
  • -
-
- -

Синтаксические выделения делают код удобнее в прочтении, особенно когда статья переполнена другими видами текста. Выделения также помогают выделить ошибки в примерах и отрывках кода.

- -

Добавление выделения

- -

Как правило, следует выделять любой блок {{HTMLElement("pre")}}, который представляет код, состоящий из более чем одной строчки; выделение однострочного кода будет зависеть от контекста.

- -

Синтаксические выделения в примерах кода:

- -
    -
  1. -

    Наберите или вставьте код в статью. Например:

    - -

    void main(int argc, char **argv) {

    - -

    printf("Привет, мир!\n");

    - -

    }

    -
  2. -
  3. -

    Выделите текст и нажмите кнопку PRE в панели инструментов. Результат:

    - -
    void main(int argc, char **argv) {
    -
    -printf("Hello world\n");
    -
    -}
    -
    -
  4. -
  5. -

    Нажмите кнопку Syntax Highlighter и выберите название соответстующего коду языка программирования. В нашем примере это C/C++:

    - -
    void main(int argc, char **argv) {
    -
    -printf("Hello world\n");
    -
    -}
    -
  6. -
- -

Вы можете немного упростить процесс, не нажимая кнопку PRE и сразу выбрав нужный вам язык. Добавление выделения автоматически вставит необходимый блок {{HTMLElement("pre")}}, если он ещё не на месте.

- -

Далее представлен перевод раздела {{SectionOnPage("/en-US/docs/MDN/Contribute/Editor/Source_mode", "Выделение строк в режиме источника")}}:

- -

Выделение линий в примере

- -

Блоки примеров кода устанавливаются кнопками PRE или Syntax Highlighter в блоках панели инструментов, но вы, возможно, захотите обратить внимание читателей на определённые строки кода. Единственный способ сделать это — открыть режим источника, найти там блок <pre>, содержащий код, и добавить в атрибут class тега <pre>  компонент highlight, отформатированный следующим образом:

- - - -
"hightlight[" <список-номеров-строк> "]"
-
-Где:
-<список-номеров-строк> = [ <номер-строки> | <диапазон-строк> ]#
-<диапазон-строк> = <номер-строки> - <line-number>
-<номер-строки> = <токен>
- -

К примеру, если есть тег <pre class="brush: js;">, и вы хотите выделить строки 4 и 7, то вы меняете тег: <pre class="brush: js; highlight[4, 7]">.

- -

Давайте взглянем на более полный пример:

- -
- - - - - - - - - - - - - -
До выделенияС выделением
-
-var canvas = document.getElementById("canvas");
-var ctx = canvas.getContext("2d");
-
-var path1 = new Path2D();
-path1.rect(10, 10, 100, 100);
-
-var path2 = new Path2D(path1);
-path2.moveTo(220, 60);
-path2.arc(170, 60, 50, 0, 2 * Math.PI);
-
-ctx.stroke(path2);
-
- -

Здесь тег {{HTMLElement("pre")}} равен: <pre class="brush: js;">

-
-
-var canvas = document.getElementById("canvas");
-var ctx = canvas.getContext("2d");
-
-var path1 = new Path2D();
-path1.rect(10, 10, 100, 100);
-
-var path2 = new Path2D(path1);
-path2.moveTo(220, 60);
-path2.arc(170, 60, 50, 0, 2 * Math.PI);
-
-ctx.stroke(path2);
- -

А здесь тег <pre> был изменён на: <pre class="brush: js; highlight[4, 7]">

-
-
- -
-

Выделенные строки не отображаются в редакторе MDN.

-
- -

Смотрите также

- - - -
{{EditorGuideQuicklinks}}
diff --git "a/files/ru/mdn/editor/\321\201\321\201\321\213\320\273\320\272\320\270/index.html" "b/files/ru/mdn/editor/\321\201\321\201\321\213\320\273\320\272\320\270/index.html" deleted file mode 100644 index 459a965172..0000000000 --- "a/files/ru/mdn/editor/\321\201\321\201\321\213\320\273\320\272\320\270/index.html" +++ /dev/null @@ -1,187 +0,0 @@ ---- -title: Создание ссылок в статьях MDN -slug: MDN/Editor/Ссылки -tags: - - Guide - - MDN - - MDN Meta - - Документация - - Редактор - - Руководство -translation_of: MDN/Editor/Links ---- -
{{MDNSidebar}}
- - - -
-

Обратите внимание, что у нас есть особые правила применения ссылок: они описаны в руководстве по оформлению материалов MDN.

-
- -

Использование панели инструментов

- -

Самый очевидный способ создать ссылку — нажать на кнопку Вставить/Редактировать ссылку на панели инструментов или нажать сочетание Ctl+K (Command-K для Mac). Кнопка ссылки вглядит так: The link button (as of 2015-12-04). Вы можете добавлять текст к выделенному тексту.

- -

Создание ссылки

- -

После нажатия на кнопку ссылки появится диалоговое окно для работы с ссылками:

- -

Окно для работы с ссылками

- -

Здесь вы можете создать новую ссылку. Параметры окна:

- -
-
Ссылка (Link Type)
-
Это тип создаваемой вами ссылки. Тип по умолчанию, URL, используется в сети — или в MDN, или вне его. Вы также можете выбрать "Link to anchor in the text" или "Email". Ссылка-якорь позволяет вам привязать её к якорю, созданному вами ранее с помощью кнопки Вставить / редактировать якорь  на панели инструментов. Опция email позволяет вам настрить: URL-адрес получателя, получателя и сообщение. Чаще всего вы будете использовать тип URL.
-
Поиск ссылки по заголовку / Текст ссылки (Article Title Lookup / Link Text)
-
У этого поля есть две цели: во-первых, вы обозначаете текст, который будет использован как указатель ссылки (или, если вы выделили текст до открытия окна, он будет отображён как указатель ссылки), во-вторых, текст, введённый в это поле, используется для поиска  статей на MDN, чтобы найти возможное направление ссылки. К примеру, если вы введёте "Array" в поле, вы увидите что-то наподобие этого:
- Screenshot of the Link dialog box, showing a lookup menu for the text "Array"
-
- -
-
На картинке вы можете видеть все страницы MDN, чьи заголовки содержат текст, напечатанный вами. Вы можете прокрутить список и выбрать одну из страниц или продолжить набирать текст, сужая список. Заметьте, у названий страниц отображается их язык (в нашем примере это "[en-US]"). Это не отображается в указателе ссылки; так сделано для того, чтобы вы убедились, что вы ссылаетесь на статью того же языка, на котором пишете вы.
-
Прикрепление ссылки (Attachments)
-
В качестве альтернативы вы можете сделать так, чтобы ссылка была привязана к одному из файлов, прикрпеплённому к этой странице. Это отличный способ предоставить ссылку для скачивания примера кода и тому подобное.
-
URL
-
Наконец, поле для URL-адреса позволяет вам ввести URL; в поле также выводятся URL выбранных вами элементов из меню Article Title Lookup или Attachments, если вы их использовали. Нередко используют URL-адреса страниц MDN, поэтому, если вы ссылаетесь на другую страницу MDN, удалите доменное имя ("https://developer.mozilla.org") из начала URL.
-
- -

Как только завершите настройку ссылки, нажмите OK.

- -
-

В верху окна также есть вкладка Advanced. Нет опций, которые мы советуем вам использовать регулярно, по крайней мере, сейчас. Можете быть, в будущем появятся новые стили для ссылок, но мы, вероятно, добавим новую панель инструментов для этих опций.

-
- -

Ссылки

- -

Если у вас есть текст, который вы хотели бы превратить в ссылку, вы можете слегка упростить процесс. Выделите нужный вам текст, затем откройте окно для работы с сылками; поле Article Title / Lookup Text будет заполнено выделенным текстом. К примеру, есть у нас, скажем, следующий текст:

- -
-

You may find it useful to use JavaScript arrays when working on this project.

-
- -

Нам хотелось бы преобразовать arrays в ссылку на файл с соответствующим содержанием. Просто выделите слово и включите окно для работы с ссылками; у вас появится заполненное окно, похожее на изображение выше. Наводя мышь на поле-подсказку, вы можете видеть её относительный путь (его URL относится к developer.mozilla.org), благодаря чему вы можете лучше узнать, где  находится статья и о чём она.

- -

Screenshot of the Link dialog box, showing a lookup menu and a URL tooltip

- -

На примере: подсказки — это возможные совпадения. Кажется, arrays было выбрано удачно; выберем этот вариант. Поле сразу заполняется URL-адресом, поэтому мы просто жмём OK, и цитата будет выглядеть так:

- -
-

You may find it useful to use JavaScript arrays when working on this project.

-
- -

Использование макросов

- -

MDN часто использует макросы, чтобы автоматически создавать термины-ссылки с соответствующим содержанием, стилизуя их как ссылки в сответствии с нашими правилами оформления элементов. Учтите: наше руководство отмечает, что API-термины, элементы и атрибуты HTML, свойства, имена функций CSS и тому подобное,— должны быть стилизованы с помощью элемента {{HTMLElement("code")}}. Также должны быть ссылки на другие страницы MDN.

- -

К использованию макросов для создания ссылок легко привыкнуть, и это предоставляет множество плюсов:

- - - -

Есть очень много таких макросов, и мы не будем останавливаться на них подробно здесь. Вместо этого мы разберём несколько самых часто употребляемых. Если интересно, ознакомьтесь с разделом "Создание гиперссылок" в нашей статье Пользовательский макрос для MDN.

- -
-

Ещё проще посетить KumaScript, где есть любой из этих макросов; ко многим макросам есть комментарии вверху, объясняющие, как макрос работает и какие у него переменные.

-
- -

Ссылка на документацию для API

- -

У нас есть есколько невероятно полезных макросов для создания стилизованных ссылок для API. В этом подразделе перечислены самые удобные; в каждый блок могут быть добавлены доступные параметры, чтобы предоставить больший контроль над выводом. На название каждого макроса можно кликнуть, чтобы увидеть сам код макроса; у каждого макроса есть комментарии вверху, объясняющие, как макрос работает и какие у него переменные.

- -
-
{{TemplateLink("HTMLElement")}}
-
Вставляет в HTML-код название элемента с необходимыми стилизацией и ссылками. К примеру: \{{HTMLElement("table")}} даёт {{HTMLElement("table")}}.
-
{{TemplateLink("cssxref")}}
-
Вставляет в CSS-код документацию свойства, правила или селектора. Например: \{{cssxref("background-color")}} в результате выводит {{cssxref("background-color")}}.
-
{{TemplateLink("domxref")}}
-
Вставляет данный термин API. Пример: \{{domxref("window")}} даёт в результате {{domxref("window")}}, и \{{domxref("window.scrollBy()")}} вставляет {{domxref("window.scrollBy()")}}. Вы также можете вставить дополнительный параметр, чтобы заменить текст: \{{domxref("window.scrollBy", "scrollBy()")}} заменяет {{domxref("window.scrollBy")}} на {{domxref("window.scrollBy", "scrollBy()")}}.
-
{{TemplateLink("SVGElement")}}
-
Вставляет название SVG-элемента с необходимыми стилизацией и ссылками. К примеру: \{{SVGElement("circle")}} даёт {{SVGElement("circle")}}.
-
- -

Добавление якорей

- -

Чтобы применить ссылку к области с таким же названием, следует использовать макрос {{TemplateLink("anch")}}. Синтаксис — проще некуда: \{{anch("Name of destination section")}}. По умолчанию текст ссылки — это название области, но вы можете добавить второй, необязательный, параметр, обозначающий альтернативный текст. Несколько примеров:

- - - -

Ссылки к багам

- -

Вы можете создать ссылку на базу данных Mozilla's Bugzilla с макросом {{TemplateLink("bug")}}. У этого макроса всего один параметр: номер бага, на который ссылаются. К примеру, \{{bug(765642)}} покажет: {{bug(765642)}}.

- -

Таким же образом вы можете создавать ссылки к багам на других брузерах и брузерных движках:

- -
-
WebKit (Safari и т.д.)
-
{{TemplateLink("WebkitBug")}}: \{{webkitbug(31277)}} даёт {{webkitbug(31277)}}.
-
- -

Ссылки к RFC

- -

Суть работы Интернета изложена в RFC. Вы можете с лёгкостью обратиться к RFCs с помощью {{TemplateLink("RFC")}}. Для примера, \{{RFC(2616)}} станет {{RFC(2616)}}. Вы можете при желании снабдить макрос альтернативной ссылкой, чтобы использовать вместо выделенного участка текста или нескольких участков, с описанием, к какой ссылке привязать их.

- -

Ссылки к информации о XPCOM-интерфейсах

- -
-

MDN больше не поддерживает XPCOM-документацию, но внесение вклада приветствуется!

-
- -

Если вы документируете свойства Mozilla, способность быстро создать ссылку к документации XPCOM очень полезна. Здесь несколько макросов для этого.

- -

Синтаксис: \{{interface("interfacename")}}. К примеру, вы написали:

- -
-

When you need to parse or create URIs, the \{{interface("nsIIOService")}} interface can help.

-
- -

В результате получится

- -
-

When you need to parse or create URIs, the {{interface("nsIIOService")}} interface can help.

-
- -

Если вам нужна ссылка к информации о методе или атрибуте XPCOM-интерфейса, макросы {{TemplateLink("ifmethod")}} и {{TemplateLink("ifattribute")}} точно для вас. Названия интерфейса и метода или атрибута, к которым вы ссылаетесь, принимаются за параметры. Макрос {{TemplateLink("ifmethod")}} особенно интересен, т.к. он по-особому форматирует элемент при добавлении стиля родителя после названия метода. Например, \{{ifmethod("nsIIOService", "newURI")}} выводит {{ifmethod("nsIIOService", "newURI")}}. Это контейнер, в котором вы защищены от стилевых изменений MDN в будущем!

- -

Ссылка к привилегированной документации Mozilla

- -

Для вставки Mozilla preference и для того, чтобы привязать её к соответствующей странице в Preference reference, используйте макрос {{TemplateLink("pref")}} . У него всего один параметр: полное название привилегерованного элемента. Например, \{{pref("javascript.options.showInConsole")}} преобразуется в: {{pref("javascript.options.showInConsole")}}.

- -

Ссылка к ресурсам Mozilla

- -

Вы можете ссылаться на дерево ресурсов Mozilla's (хотя не стоит делать это часто), используя макрос {{TemplateLink("source")}}. Вместо указания абсолютного пути вам достаточно указать путь относительно директории /source/. Для примера: \{{source("browser/Makefile.in")}} создаёт эту ссылку: {{source("browser/Makefile.in")}}.

- -

Вы можете при желании снабдить ссылку альтернативным тектсом. Например, как видите, \{{source("browser/Makefile.in", "the browser's makefile")}} преобразуется в: {{source("browser/Makefile.in", "the browser's makefile")}}.

- -
-

Обратите внимание на документацию {{anch("Использование макросов")}}, если вы заинтересованы в более подробном изучении макросов и посетите KumaScript, чтобы больше узнать о системе макросов.

-
- -

Ссылки на рекомендованные статьи

- -

Если вы хотите создать список связанных страниц или другого рекомендованного материала к прочтению, вам следует делать это с помощью создания контейнера быстрых ссылок в боковой панели. Такой подход заменяет наши старые Смотрите также в конце статей. О том, как создавать контейнер с быстрыми ссылками, читайте в статье Быстрые ссылки.

- -

Схемы URL-адресов

- -

В целях безопасности создавайте ссылки, имеющие следующие схемы:

- - - -

Дргуие схемы просто-напросто будут удалены.

- -
-

Особые URL-схемы, такие как about: и chrome: используются Firefox, Google Chrome и некоторыми другими браузерами, чтобы предоставить доступ к особым опциям, таким как привилегерованные элементы, отладочная информация и так далее. Эти ссылки не работают в содержимом статьи, поэтому не создавайте ссылки, используя эти схемы в MDN. То же относится и к схемам javascript: и jar:, которые блокируются большинством браузеров в целях безопасности.

-
- -

{{EditorGuideQuicklinks}}

diff --git a/files/ru/mdn/kuma/index.html b/files/ru/mdn/kuma/index.html deleted file mode 100644 index ee8105bf08..0000000000 --- a/files/ru/mdn/kuma/index.html +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: 'Kuma: вики-платформа MDN' -slug: MDN/Kuma -tags: - - Kuma - - Главная -translation_of: MDN/Kuma ---- -
{{MDNSidebar}}
- -
{{IncludeSubnav("/ru/docs/MDN")}}
- -

Kuma - код на Django, который обслуживает Mozilla Developer Network.

- -

{{SubpagesWithSummaries}}

- -

Начинаем работу с Kuma

- -

Чтобы поучаствовать в Kuma:

- - diff --git a/files/ru/mdn/kuma/troubleshooting_kumascript_errors/index.html b/files/ru/mdn/kuma/troubleshooting_kumascript_errors/index.html deleted file mode 100644 index dfbe9868eb..0000000000 --- a/files/ru/mdn/kuma/troubleshooting_kumascript_errors/index.html +++ /dev/null @@ -1,62 +0,0 @@ ---- -title: Решение проблем с ошибками в KumaScript -slug: MDN/Kuma/Troubleshooting_KumaScript_errors -tags: - - Errors - - KumaScript - - MDN Meta - - Tools - - Ошибки - - Руководство - - инструменты -translation_of: MDN/Tools/KumaScript/Troubleshooting ---- -
{{MDNSidebar}}
- -

Oшибки KumaScript, появляющиеся на странице, могут быть очень неудобными для читателей, из-за больших страшных красных ящиков, но, к счастью, любой человек с учетной записью MDN может отредактировать документ, чтобы исправить эту ошибку. При возникновении ошибки страница добавляется в список документов с ошибками. Редакторы сайта регулярно просматривают этот список, чтобы находить и исправлять ошибки. В этой статье подробно описываются четыре типа ошибок KumaScript и некоторые шаги, которые можно предпринять для их исправления.

- -

DocumentParsingError

- -

DocumentParsingError ошибки появляются, когда у KumaScript есть проблемы с пониманием чего-либо в самом документе. Наиболее распространенной причиной является синтаксическая ошибка в макросе.

- -

Необходимо проверить:

- -
-
Использование фигурных скобок без намерения вызвать макрос.
-
Если вам нужно написать \{ в документе, не вызывая макрос, вы можете экранировать его используя \ таким образом \\{
-
Использование специального символа в параметрах макроса.
-
Если вам нужно использовать " или \ внутри параметра макроса, они могут быть экранированы с помощью \\ или \"
-
Отсутствие запятых между параметрами макроса.
-
Параметры макроса должны быть разделены запятой (,) но не в конце списка параметров, например: \{\{anch("top", "Back to top")}}.
-
HTML тег появляется внутри вызова макроса.
-
Если вы применяете стили к макросу, это будет часто приводить к ошибками, например, тег </code> мог появится внутри кода макроса в исходном коде. Для проверки нажмите просмотр исходника (Source), чтобы увидеть где, и удалить ненужные стили.
-
- -

TemplateLoadingError

- -

TemplateLoadingError ошибка появляется когда KumaScript не может найти макрос для добавления на страницу.

- -

Необходимо проверить:

- -
-
Опечатка в имени макроса или он был переименован.
-
Вы можете взглянуть на список известных макросов в GitHub репозитории.
-
- -
-

Совет: Вы можете легко и быстро перейти к определённому макросу, используя поиск по ключевым словам в Firefox. Смотрите {{SectionOnPage("/ru/docs/MDN/Contribute/Tools/KumaScript", "Использование поиска по ключевым словам для открытия шаблона страницы")}} для пошагового справочника по созданию поиска по ключевым словам.

-
- -

TemplateExecutionError

- -

TemplateExecutionError ошибки появляются, когда KumaScript встречается с ошибкой в макросе. Эти ошибки могут быть исправлены только администраторами и вам нужно сообщить об этом с помощью багрепорта.

- -

Перед отчётом об ошибке, проверьте что она уже не была исправлена. Мы можете заставить KumaScript дать вам свежую версию страницы удерживая нажатой Shift пока вы обновляете (F5) страницу (Shift + Ctrl + R on Windows/Linux, Shift + Cmd + R on Mac).

- -

Если ошибка сохраняется, заведите багрепорт. Включите URL страницы и текст ошибки в сообщение.

- -

Error & Unknown

- -

В этой категории оказываются ошибки, если они не являются никакими другими типами ошибок.

- -

Проверьте исправлено ли, и если ошибка сохраняется заведите багрепорт как описано в TemplateExecutionError.

diff --git a/files/ru/mdn/structures/live_samples/simple_live_sample_demo/index.html b/files/ru/mdn/structures/live_samples/simple_live_sample_demo/index.html deleted file mode 100644 index 393a20bc94..0000000000 --- a/files/ru/mdn/structures/live_samples/simple_live_sample_demo/index.html +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: A simple demo of a live code sample -slug: MDN/Structures/Live_samples/Simple_live_sample_demo -tags: - - MDN Meta - - Конструкции - - Пример -translation_of: MDN/Structures/Live_samples/Simple_live_sample_demo ---- -
{{MDNSidebar}}
- -

Пример

- -

Это очень простой пример показывающий вам, как сделать живой образец на MDN. Для большей информации смотрите Live samples.

- -
<form>
-  <label>Try me<input type="text" name="name"></label>
-  <input type="submit" value="go">
-</form>
- -
form {
-  border-radius: 10px;
-  background: powderblue;
-}
- -
var f = document.querySelector('form');
-
-f.addEventListener('submit', function(ev) {
-  ev.preventDefault();
-  document.querySelectorAll('input')[1].value = 'sending';
-}, false);
- -

{{ EmbedLiveSample('Пример', '', '', '') }}

- -
-

Примечание: На локализованных страницах значение первого параметра должно совпадать с ID заголовка в котором находится пример.

-
diff --git a/files/ru/mdn/tools/kumascript/troubleshooting/index.html b/files/ru/mdn/tools/kumascript/troubleshooting/index.html new file mode 100644 index 0000000000..dfbe9868eb --- /dev/null +++ b/files/ru/mdn/tools/kumascript/troubleshooting/index.html @@ -0,0 +1,62 @@ +--- +title: Решение проблем с ошибками в KumaScript +slug: MDN/Kuma/Troubleshooting_KumaScript_errors +tags: + - Errors + - KumaScript + - MDN Meta + - Tools + - Ошибки + - Руководство + - инструменты +translation_of: MDN/Tools/KumaScript/Troubleshooting +--- +
{{MDNSidebar}}
+ +

Oшибки KumaScript, появляющиеся на странице, могут быть очень неудобными для читателей, из-за больших страшных красных ящиков, но, к счастью, любой человек с учетной записью MDN может отредактировать документ, чтобы исправить эту ошибку. При возникновении ошибки страница добавляется в список документов с ошибками. Редакторы сайта регулярно просматривают этот список, чтобы находить и исправлять ошибки. В этой статье подробно описываются четыре типа ошибок KumaScript и некоторые шаги, которые можно предпринять для их исправления.

+ +

DocumentParsingError

+ +

DocumentParsingError ошибки появляются, когда у KumaScript есть проблемы с пониманием чего-либо в самом документе. Наиболее распространенной причиной является синтаксическая ошибка в макросе.

+ +

Необходимо проверить:

+ +
+
Использование фигурных скобок без намерения вызвать макрос.
+
Если вам нужно написать \{ в документе, не вызывая макрос, вы можете экранировать его используя \ таким образом \\{
+
Использование специального символа в параметрах макроса.
+
Если вам нужно использовать " или \ внутри параметра макроса, они могут быть экранированы с помощью \\ или \"
+
Отсутствие запятых между параметрами макроса.
+
Параметры макроса должны быть разделены запятой (,) но не в конце списка параметров, например: \{\{anch("top", "Back to top")}}.
+
HTML тег появляется внутри вызова макроса.
+
Если вы применяете стили к макросу, это будет часто приводить к ошибками, например, тег </code> мог появится внутри кода макроса в исходном коде. Для проверки нажмите просмотр исходника (Source), чтобы увидеть где, и удалить ненужные стили.
+
+ +

TemplateLoadingError

+ +

TemplateLoadingError ошибка появляется когда KumaScript не может найти макрос для добавления на страницу.

+ +

Необходимо проверить:

+ +
+
Опечатка в имени макроса или он был переименован.
+
Вы можете взглянуть на список известных макросов в GitHub репозитории.
+
+ +
+

Совет: Вы можете легко и быстро перейти к определённому макросу, используя поиск по ключевым словам в Firefox. Смотрите {{SectionOnPage("/ru/docs/MDN/Contribute/Tools/KumaScript", "Использование поиска по ключевым словам для открытия шаблона страницы")}} для пошагового справочника по созданию поиска по ключевым словам.

+
+ +

TemplateExecutionError

+ +

TemplateExecutionError ошибки появляются, когда KumaScript встречается с ошибкой в макросе. Эти ошибки могут быть исправлены только администраторами и вам нужно сообщить об этом с помощью багрепорта.

+ +

Перед отчётом об ошибке, проверьте что она уже не была исправлена. Мы можете заставить KumaScript дать вам свежую версию страницы удерживая нажатой Shift пока вы обновляете (F5) страницу (Shift + Ctrl + R on Windows/Linux, Shift + Cmd + R on Mac).

+ +

Если ошибка сохраняется, заведите багрепорт. Включите URL страницы и текст ошибки в сообщение.

+ +

Error & Unknown

+ +

В этой категории оказываются ошибки, если они не являются никакими другими типами ошибок.

+ +

Проверьте исправлено ли, и если ошибка сохраняется заведите багрепорт как описано в TemplateExecutionError.

diff --git a/files/ru/mdn/tools/page_watching/index.html b/files/ru/mdn/tools/page_watching/index.html deleted file mode 100644 index 04b9dc05ad..0000000000 --- a/files/ru/mdn/tools/page_watching/index.html +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: Подписка на страницы -slug: MDN/Tools/Page_watching -tags: - - MDN Meta - - Подписка - - Руководство - - Страница уровня - - инструменты -translation_of: MDN/Tools/Page_watching ---- -
{{MDNSidebar}}

Ok

- -

Подписка на страницу в MDN позволяет вам получать уведомление по электронной почте всякий раз, когда она обновляется или изменяется. Кнопка «Смотреть» {{FontAwesomeIcon("icon-eye")}} расположена в верхнем правом углу каждой страницы MDN. Чтобы получить доступ к параметрам подписки, наведите курсор на кнопку «Смотреть», чтобы открыть меню «Смотреть»: 

- -

Screenshot of MDN Watch menu

- -

Выберите вариант просмотра только одной страницы или этой страницы и ее подстраниц.

- -

Подписаться на страницу

- -

Нажмите первый вариант «Подписаться на название страницы», чтобы получать уведомление по электронной почте каждый раз, когда пользователь редактирует только одну страницу.

- -

Подпишитесь на страницу и все ее подзаголовки

- -

Нажмите второй вариант «Подписаться на название страницы и все её под-статьи», чтобы получать уведомление по электронной почте каждый раз, когда пользователь редактирует эту страницу, а также любую её подстраницу. Это включает в себя дополнительные страницы, добавленные после того, как вы запросили подписку, поэтому, если в будущем будет создано больше подстраниц, вы также получите уведомления для них.

- -

Отменить подписку на страницу

- -

Чтобы отказаться от подписки и прекратить просмотр страницы, откройте меню «Смотреть» еще раз и нажмите «Отменить подписку на название страницы». Если вы подписаны на страницу, вы увидите только «Отказаться от названия страницы». Вы больше не будете получать электронное письмо при каждом изменении страницы.

- -

Электронные письма с изменением страницы

- -

Если вы подписаны на страницу, каждый раз при сохранении изменений вы получите электронное письмо. Эти письма поступают с notifications@developer.mozilla.org и отправляются на адрес электронной почты, зарегистрированный на вашей учетной записи MDN. Каждое сообщение имеет заголовок формы:

- -
[MDN] Page "Page title" changed by username
- -

Сообщение начинается с повторения информации в заголовке, а затем представляет стандартный разброс содержимого, показывающий точно, что изменилось. Изменения отображаются как исходный HTML-код, который может быть немного странным для чтения, если вы не используете его в контексте MDN.

- -

Ниже diff есть список полезных ссылок, которые вы можете использовать для изменения, включая:

- - - -

В нижней части письма есть уведомление о том, какая подписка сгенерировала электронное письмо, например «Вы подписаны на изменения: ссылка на элемент HTML и все его подтемы», а также ссылку на отмену подписки. Если вы нажмете ссылку, чтобы отказаться от подписки, вы больше не будете получать сообщения для этого запроса на просмотр.

diff --git a/files/ru/mdn/tools/search/index.html b/files/ru/mdn/tools/search/index.html new file mode 100644 index 0000000000..08ba78607f --- /dev/null +++ b/files/ru/mdn/tools/search/index.html @@ -0,0 +1,104 @@ +--- +title: Использование продвинутого поиска +slug: MDN/User_guide/Advanced_search +tags: + - Guide + - MDN +translation_of: MDN/Tools/Search +--- +
{{MDNSidebar}}

В качестве дополнительной возможности внесения для вкладчиков в MDN у нас есть продвинутый механизм поиска, который позволяется вам искать по исходному коду страницы — то есть, по сырому HTML сайта, с макросами вместо их вывода — что позволяет искать использования определённых макросов, атрибутов HTML и тому подобное.

+

На текущий момент для использования продвинутого механизма поиска нет пользовательского интерфейса, но вы можете получить к нему доступ посредством специально сформированных URL. Вы можете получить вывод либо на стандартную страницу с результатами поиска по MDN, либо в формате JSON (последнее означает, что вы можете использовать этот механизм, например, из кода на KumaScript). Эта статья описывает, как всем этим пользоваться.

+
+

Примечание: эти поисковые запросы не предназначены для конструирования распространяемых URL; а предназначены для использования во вспомогательных инструментах и утилитах. В будущем они могут измениться, также не обязательно, что эти запросы самые эффективные.

+
+ +

Формат поискового запроса

+

Продвинутые поисковые запросы позволяются конструировать URL с соответствующими параметрами. Базовый URL может быть одним из следующих:

+
+
https://developer.mozilla.org/en-US/search
+
Используйте этот базовый URL для получения стандартной страницы с результатами поиска по MDN.
+
https://developer.mozilla.org/en-US/search.json
+
Используйте этот базовый URL для получения результатов в формате JSON. О формате результата смотрите раздел {{anch("JSON_result_format", "формат JSON для результата")}}.
+
+

Кроме того, вам нужно добавить соответствующие параметры для получения желаемого результата. Вы можете использовать любую комбинацию следующих параметров:

+
+
locale=
+
Рассматриваемая локаль. По умолчанию рассматриваются все локали. Также вы можете явно указать «все локали» при помощи шаблона "*". Например, вы можете определить locale=en-US для ограничения поиска только по англоязычным страницам.
+
css_classnames=
+
Классы CSS для сопоставления. Этот параметр ограничивает результат поиска страницами, чей HTML-код включает в сеся как минимум одно использование указанных классов.
+
html_attributes=
+
Текст атрибутов HTML для сопоставления. Поиск ведётся по началу текста; то есть, если указаный текст появляется в начале строки атрибута HTML, он будет считаться совпавшим. Подробности смотрите ниже.
+
kumascript_macros=
+
Список искомых макросов KumaScript. Этот параметр позволяет вам находить статьи, использующие определённый макрос; это может быть полезно в тех случаях, если, к примеру, макрос устарел или его параметры поменялись и вам нужно обновить существующие варианты его использования.
+
+ +

Примеры

+

Здесь приведено несколько примеров поисковых запросов.

+ +

Поиск по локали

+
https://developer.mozilla.org/en-US/search?locale=en-US
+

В этом примере возвращается список всех англоязычных статей без каких-либо иных ограничений. На момент написания этой статьи их было 12865 (к тому времени, как вы прочитаете эту статью, их, конечно же, станет больше, поскольку мы постоянно растём)!

+ +

Поиск по имени CSS-класса

+
https://developer.mozilla.org/en-US/search?locale=en-US&css_classnames=smaller
+

В этом примере мы добавили к поисковому условию использование CSS-класса "smaller"; на момент написания этой статьи количество результатов снизилось всего до 6 страниц.

+ +

Поиск по строке атрибута HTML

+
https://developer.mozilla.org/en-US/search?locale=en-US&html_attributes=style
+

Здесь мы ищем использования атрибута "style" на элементах HTML. На момент написания этой статьи мы нашли 4935 таких страниц. Это плохо и это нужно искоренять; мы собираемся заменить все такие вхождения на наши стандартные классы.

+

Также вы можете включать в поисковый запрос значение атрибута, но помните, что если вы захотите включить символы вроде "=" или "/" в ваш поисковый запрос, вы должны их закодировать для использования в URL. Например, чтобы найти страницы, ссылающиеся на www.mozilla.org, вы можете сделать так:

+
https://developer.mozilla.org/en-US/search?locale=en-US&html_attributes=href%3D%22https%3A%2F%2Fwww.mozilla.org
+

Этот поиск вернул 29 результатов. Это удивительно малое количество ссылок на сайт www.mozilla.org!

+ +

Поиск по используемому макросу KumaScript

+
https://developer.mozilla.org/en-US/search?locale=en-US&kumascript_macros=unimplemented_header
+

Этот поисковый запрос ищет использования макроса {{TemplateLink("unimplemented_header")}}. На момент написания этой статьи было найдено шесть страниц. Он позволяет нам искать макросы, чьи параметры были изменены, либо те, которые мы хотим прекратить использовать (последний случай как раз относится к рассматриваемому макросу).

+ +

Формат JSON для результата

+

Когда вы запрашиваете результат в формате JSON, вы по прежнему получаете результаты по одной странице за раз. Каждая страница является объектом KumaScript, который состоит из нескольких частей с метаданными о результатах, плюс массив стандартных объектов страницы с одним дополнительным полем: URL-адресом для начала редактирования страницы.

+

В результирующем объекте содержатся следующие данные:

+
+
count
+
Общее количество найденных результатов.
+
next
+
URL, по которому можно перейти на следующую страницу с результатами (либо {{jsxref("Global_Objects/null", "null")}} для последней страницы).
+
previous
+
URL, по которому можно перейти на предыдущую страницу с результатами (либо {{jsxref("Global_Objects/null", "null")}} для первой страницы).
+
query
+
???
+
page
+
Номер страницы с результатами, описываемой этим объектом.
+
pages
+
Общее количество страниц с результатами.
+
start
+
Номер первого элемента на этой странице с результатами.
+
end
+
Номер последнего элемента на этой странице с результатами.
+
filters
+
Массив конфигураций расличных поисковых фильтров. Эти фильтры доступны в стандартном поиске.
+
documents
+
Массив {{anch("Page_objects", "объектов страницы")}}, описывающих каждую совпавшую страницу.
+
+ +

Объекты страницы

+

Каждый объект страницы содержит следующие поля:

+
+
title
+
Заголовок статьи.
+
slug
+
Идентификатор статьи. Это вся часть URL страницы, следующая за локалью и последующим символом слеша.
+
locale
+
Локаль страницы.
+
excerpt
+
Фрагмент содержания страницы; это либо первый блок обычного текста статьи, либо содержимое, отмеченное классом "SEO Summary".
+
url
+
Полный URL страницы.
+
edit_url
+
Полный URL страницы в режиме редактирования.
+
tags
+
Массив меток страницы.
+
score
+
Значение очков, присвоенное странице поисковым движком.
+
explanation
+
Различная информация от поискового движка о том, почему страница соответствует вашему запросу. Описание этого содержимого выходит за рамки данного документа.
+
diff --git a/files/ru/mdn/tools/unsupported_get_api/index.html b/files/ru/mdn/tools/unsupported_get_api/index.html new file mode 100644 index 0000000000..d42d9c436e --- /dev/null +++ b/files/ru/mdn/tools/unsupported_get_api/index.html @@ -0,0 +1,100 @@ +--- +title: URL-суффиксы +slug: MDN/Tools/URL-suffix +tags: + - HTTP + - Kuma + - MDN Мета + - URL + - Параметры URL + - инструменты +translation_of: MDN/Tools/Document_parameters +--- +
{{MDNSidebar}}
+ +
+

Вики-платформа MDN Kuma не имеет центрального API. Вместо этого наш общий подход заключается в том, чтобы предложить способы превращения доступных для человека ресурсов в удобные для машин данные.

+
+ +
+

Параметры URL GET

+ +

Мы поддерживаем несколько полезных параметров запроса для каждого URL-адреса вики-документа Kuma при получении через HTTP GET или просмотре в браузере.

+ +

Несколько параметров запроса разделяются знаком & вместо начального ?. (См. Примеры макроса.)

+ +
+
summary
+
+

Указывает Куме возвращать только сводку страницы. Если на странице есть контент, помеченный классом «Сводка SEO», этот контент возвращается. Если такого содержания нет, возвращается содержание раздела «Сводка». В противном случае возвращается содержимое первого блока.

+ +
Уведомление об ошибке: В настоящее время существует ошибка, из-за которой сводный параметр возвращает весь документ, если вы также не укажете необработанный параметр. Обратите внимание, что вы также можете получить сводку из возвращенного JSON, используя альтернативное представление $ json.
+
+
raw
+
Указывает Kuma вернуть необработанное содержимое страницы без какого-либо материала обложки, такого как верхние, нижние колонтитулы и т. д. При этом не выполняются шаблоны или сценарии, что удобно для редакторов сборки.
+
Пример: https://wiki.developer.mozilla.org/ru/docs/HTML/HTML5?raw
+
macros
+
Поручает Kuma выполнить все шаблоны на странице. В сочетании с ?raw это предлагает полностью визуализированный контент MDN без оболочки сайт . Поручает Kuma выполнить все шаблоны на странице. В сочетании с ?raw это предлагает полностью визуализированный контент MDN без оболочки сайта. По умолчанию включено без  ?raw (то есть при обычном просмотре сайта), по умолчанию выключено, когда присутствует ?raw.
+
Пример: https://wiki.developer.mozilla.org/ru/docs/HTML/HTML5?raw&macros
+
nomacros
+
+
Указывает Kuma не выполнять шаблоны KumaScript на странице. Поскольку при обычном просмотре сайта для ?macros по умолчанию установлено значение «включено», этот параметр отключает его.
+
+
Пример: https://wiki.developer.mozilla.org/ru/docs/HTML/HTML5?nomacros
+
include
+
Говорит Kuma удалить все блоки, на которых есть класс noinclude. Это полезно для получения вывода таким, каким он был бы при включении на другую страницу, а не на отдельной странице. Часто это удаляет образец кода и тому подобное (хотя не всегда).
+
Пример: https://wiki.developer.mozilla.org/ru/docs/Archive/Mozilla/XUL/Attribute/align?raw&macros&include
+
section=id
+
Указывает Kuma вернуть содержимое только из раздела с указанным якорем/именем привязки.
+
Пример: + + +
Уведомление об ошибке: В настоящее время существует ошибка, из-за которой параметр section  возвращает весь документ, если вы также не укажете параметр raw.
+
+
expand
+
+

В сочетании с представлением $children расширяет ответ JSON с подробной информацией для каждой подстраницы. Он работает как комбинация $children и $json на каждой подстранице. Таким образом, можно узнать о тегах для подстраницы.

+ +

Пример: https://wiki.developer.mozilla.org/ru/docs/MDN/About$children?expand

+
+
+
+ +
+

Ресурсы метаданных документа

+ +

Наряду с параметрами для настройки ответа URL-адреса документа существуют также некоторые альтернативные представления документов, заданные суффиксом URL-адреса:

+ +
+
$toc
+
Указывает Kuma вернуть только оглавление страницы в HTML. Он возвращается как упорядоченный список (то есть , {{HTMLElement("ol")}}).
+
Пример: https://wiki.developer.mozilla.org/ru/docs/MDN/Tools/URL-suffix$toc
+
$json
+
Сообщает Kuma описать страницу в объекте JSON. Этот объект по сути тот же, что и при использовании подпрограммы KumaScript wiki.getPage().
+
Пример: https://wiki.developer.mozilla.org/ru/docs/MDN/About$json
+
$children
+
Говорит Kuma перечислить дочерние темы страницы в JSON. Этот объект по сути тот же, что и при использовании подпрограммы KumaScript pages.subpages().
+
Пример: https://wiki.developer.mozilla.org/ru/docs/MDN/Contribute$children
+
+
(Можно использовать с параметром ?expand для получения более подробного ответа.)
+
+
$compare
+
+

Представляет различия строк исходного текста между ревизиями, указанными в требуемых параметрах запроса ?from и ?to.

+
+
Пример: https://wiki.developer.mozilla.org/ru/docs/Web/API/KeyboardEvent/key/Key_Values$compare?locale=ru&to=1651013&from=1650680
+
$edit
+
Редактирует текущую ревизию данного документа вместо его отображения.
+
Пример: https://wiki.developer.mozilla.org/ru/docs/MDN/Tools/URL-suffix$edit
+
$history
+
Показывает историю последних десяти ревизий данного документа вместо его содержимого. Полную историю можно запросить с помощью значения параметра запроса ?limit=all.
+
Пример: https://wiki.developer.mozilla.org/ru/docs/MDN/Tools/URL-suffix$history?limit=all
+
$revision
+
Отображает номер ревизии документа, который необходимо указать после разделителя «/».
+
Пример: https://wiki.developer.mozilla.org/ru/docs/MDN/Tools/URL-suffix$revision/1652169
+
+
diff --git a/files/ru/mdn/tools/url-suffix/index.html b/files/ru/mdn/tools/url-suffix/index.html deleted file mode 100644 index d42d9c436e..0000000000 --- a/files/ru/mdn/tools/url-suffix/index.html +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: URL-суффиксы -slug: MDN/Tools/URL-suffix -tags: - - HTTP - - Kuma - - MDN Мета - - URL - - Параметры URL - - инструменты -translation_of: MDN/Tools/Document_parameters ---- -
{{MDNSidebar}}
- -
-

Вики-платформа MDN Kuma не имеет центрального API. Вместо этого наш общий подход заключается в том, чтобы предложить способы превращения доступных для человека ресурсов в удобные для машин данные.

-
- -
-

Параметры URL GET

- -

Мы поддерживаем несколько полезных параметров запроса для каждого URL-адреса вики-документа Kuma при получении через HTTP GET или просмотре в браузере.

- -

Несколько параметров запроса разделяются знаком & вместо начального ?. (См. Примеры макроса.)

- -
-
summary
-
-

Указывает Куме возвращать только сводку страницы. Если на странице есть контент, помеченный классом «Сводка SEO», этот контент возвращается. Если такого содержания нет, возвращается содержание раздела «Сводка». В противном случае возвращается содержимое первого блока.

- -
Уведомление об ошибке: В настоящее время существует ошибка, из-за которой сводный параметр возвращает весь документ, если вы также не укажете необработанный параметр. Обратите внимание, что вы также можете получить сводку из возвращенного JSON, используя альтернативное представление $ json.
-
-
raw
-
Указывает Kuma вернуть необработанное содержимое страницы без какого-либо материала обложки, такого как верхние, нижние колонтитулы и т. д. При этом не выполняются шаблоны или сценарии, что удобно для редакторов сборки.
-
Пример: https://wiki.developer.mozilla.org/ru/docs/HTML/HTML5?raw
-
macros
-
Поручает Kuma выполнить все шаблоны на странице. В сочетании с ?raw это предлагает полностью визуализированный контент MDN без оболочки сайт . Поручает Kuma выполнить все шаблоны на странице. В сочетании с ?raw это предлагает полностью визуализированный контент MDN без оболочки сайта. По умолчанию включено без  ?raw (то есть при обычном просмотре сайта), по умолчанию выключено, когда присутствует ?raw.
-
Пример: https://wiki.developer.mozilla.org/ru/docs/HTML/HTML5?raw&macros
-
nomacros
-
-
Указывает Kuma не выполнять шаблоны KumaScript на странице. Поскольку при обычном просмотре сайта для ?macros по умолчанию установлено значение «включено», этот параметр отключает его.
-
-
Пример: https://wiki.developer.mozilla.org/ru/docs/HTML/HTML5?nomacros
-
include
-
Говорит Kuma удалить все блоки, на которых есть класс noinclude. Это полезно для получения вывода таким, каким он был бы при включении на другую страницу, а не на отдельной странице. Часто это удаляет образец кода и тому подобное (хотя не всегда).
-
Пример: https://wiki.developer.mozilla.org/ru/docs/Archive/Mozilla/XUL/Attribute/align?raw&macros&include
-
section=id
-
Указывает Kuma вернуть содержимое только из раздела с указанным якорем/именем привязки.
-
Пример: - - -
Уведомление об ошибке: В настоящее время существует ошибка, из-за которой параметр section  возвращает весь документ, если вы также не укажете параметр raw.
-
-
expand
-
-

В сочетании с представлением $children расширяет ответ JSON с подробной информацией для каждой подстраницы. Он работает как комбинация $children и $json на каждой подстранице. Таким образом, можно узнать о тегах для подстраницы.

- -

Пример: https://wiki.developer.mozilla.org/ru/docs/MDN/About$children?expand

-
-
-
- -
-

Ресурсы метаданных документа

- -

Наряду с параметрами для настройки ответа URL-адреса документа существуют также некоторые альтернативные представления документов, заданные суффиксом URL-адреса:

- -
-
$toc
-
Указывает Kuma вернуть только оглавление страницы в HTML. Он возвращается как упорядоченный список (то есть , {{HTMLElement("ol")}}).
-
Пример: https://wiki.developer.mozilla.org/ru/docs/MDN/Tools/URL-suffix$toc
-
$json
-
Сообщает Kuma описать страницу в объекте JSON. Этот объект по сути тот же, что и при использовании подпрограммы KumaScript wiki.getPage().
-
Пример: https://wiki.developer.mozilla.org/ru/docs/MDN/About$json
-
$children
-
Говорит Kuma перечислить дочерние темы страницы в JSON. Этот объект по сути тот же, что и при использовании подпрограммы KumaScript pages.subpages().
-
Пример: https://wiki.developer.mozilla.org/ru/docs/MDN/Contribute$children
-
-
(Можно использовать с параметром ?expand для получения более подробного ответа.)
-
-
$compare
-
-

Представляет различия строк исходного текста между ревизиями, указанными в требуемых параметрах запроса ?from и ?to.

-
-
Пример: https://wiki.developer.mozilla.org/ru/docs/Web/API/KeyboardEvent/key/Key_Values$compare?locale=ru&to=1651013&from=1650680
-
$edit
-
Редактирует текущую ревизию данного документа вместо его отображения.
-
Пример: https://wiki.developer.mozilla.org/ru/docs/MDN/Tools/URL-suffix$edit
-
$history
-
Показывает историю последних десяти ревизий данного документа вместо его содержимого. Полную историю можно запросить с помощью значения параметра запроса ?limit=all.
-
Пример: https://wiki.developer.mozilla.org/ru/docs/MDN/Tools/URL-suffix$history?limit=all
-
$revision
-
Отображает номер ревизии документа, который необходимо указать после разделителя «/».
-
Пример: https://wiki.developer.mozilla.org/ru/docs/MDN/Tools/URL-suffix$revision/1652169
-
-
diff --git a/files/ru/mdn/user_guide/advanced_search/index.html b/files/ru/mdn/user_guide/advanced_search/index.html deleted file mode 100644 index 08ba78607f..0000000000 --- a/files/ru/mdn/user_guide/advanced_search/index.html +++ /dev/null @@ -1,104 +0,0 @@ ---- -title: Использование продвинутого поиска -slug: MDN/User_guide/Advanced_search -tags: - - Guide - - MDN -translation_of: MDN/Tools/Search ---- -
{{MDNSidebar}}

В качестве дополнительной возможности внесения для вкладчиков в MDN у нас есть продвинутый механизм поиска, который позволяется вам искать по исходному коду страницы — то есть, по сырому HTML сайта, с макросами вместо их вывода — что позволяет искать использования определённых макросов, атрибутов HTML и тому подобное.

-

На текущий момент для использования продвинутого механизма поиска нет пользовательского интерфейса, но вы можете получить к нему доступ посредством специально сформированных URL. Вы можете получить вывод либо на стандартную страницу с результатами поиска по MDN, либо в формате JSON (последнее означает, что вы можете использовать этот механизм, например, из кода на KumaScript). Эта статья описывает, как всем этим пользоваться.

-
-

Примечание: эти поисковые запросы не предназначены для конструирования распространяемых URL; а предназначены для использования во вспомогательных инструментах и утилитах. В будущем они могут измениться, также не обязательно, что эти запросы самые эффективные.

-
- -

Формат поискового запроса

-

Продвинутые поисковые запросы позволяются конструировать URL с соответствующими параметрами. Базовый URL может быть одним из следующих:

-
-
https://developer.mozilla.org/en-US/search
-
Используйте этот базовый URL для получения стандартной страницы с результатами поиска по MDN.
-
https://developer.mozilla.org/en-US/search.json
-
Используйте этот базовый URL для получения результатов в формате JSON. О формате результата смотрите раздел {{anch("JSON_result_format", "формат JSON для результата")}}.
-
-

Кроме того, вам нужно добавить соответствующие параметры для получения желаемого результата. Вы можете использовать любую комбинацию следующих параметров:

-
-
locale=
-
Рассматриваемая локаль. По умолчанию рассматриваются все локали. Также вы можете явно указать «все локали» при помощи шаблона "*". Например, вы можете определить locale=en-US для ограничения поиска только по англоязычным страницам.
-
css_classnames=
-
Классы CSS для сопоставления. Этот параметр ограничивает результат поиска страницами, чей HTML-код включает в сеся как минимум одно использование указанных классов.
-
html_attributes=
-
Текст атрибутов HTML для сопоставления. Поиск ведётся по началу текста; то есть, если указаный текст появляется в начале строки атрибута HTML, он будет считаться совпавшим. Подробности смотрите ниже.
-
kumascript_macros=
-
Список искомых макросов KumaScript. Этот параметр позволяет вам находить статьи, использующие определённый макрос; это может быть полезно в тех случаях, если, к примеру, макрос устарел или его параметры поменялись и вам нужно обновить существующие варианты его использования.
-
- -

Примеры

-

Здесь приведено несколько примеров поисковых запросов.

- -

Поиск по локали

-
https://developer.mozilla.org/en-US/search?locale=en-US
-

В этом примере возвращается список всех англоязычных статей без каких-либо иных ограничений. На момент написания этой статьи их было 12865 (к тому времени, как вы прочитаете эту статью, их, конечно же, станет больше, поскольку мы постоянно растём)!

- -

Поиск по имени CSS-класса

-
https://developer.mozilla.org/en-US/search?locale=en-US&css_classnames=smaller
-

В этом примере мы добавили к поисковому условию использование CSS-класса "smaller"; на момент написания этой статьи количество результатов снизилось всего до 6 страниц.

- -

Поиск по строке атрибута HTML

-
https://developer.mozilla.org/en-US/search?locale=en-US&html_attributes=style
-

Здесь мы ищем использования атрибута "style" на элементах HTML. На момент написания этой статьи мы нашли 4935 таких страниц. Это плохо и это нужно искоренять; мы собираемся заменить все такие вхождения на наши стандартные классы.

-

Также вы можете включать в поисковый запрос значение атрибута, но помните, что если вы захотите включить символы вроде "=" или "/" в ваш поисковый запрос, вы должны их закодировать для использования в URL. Например, чтобы найти страницы, ссылающиеся на www.mozilla.org, вы можете сделать так:

-
https://developer.mozilla.org/en-US/search?locale=en-US&html_attributes=href%3D%22https%3A%2F%2Fwww.mozilla.org
-

Этот поиск вернул 29 результатов. Это удивительно малое количество ссылок на сайт www.mozilla.org!

- -

Поиск по используемому макросу KumaScript

-
https://developer.mozilla.org/en-US/search?locale=en-US&kumascript_macros=unimplemented_header
-

Этот поисковый запрос ищет использования макроса {{TemplateLink("unimplemented_header")}}. На момент написания этой статьи было найдено шесть страниц. Он позволяет нам искать макросы, чьи параметры были изменены, либо те, которые мы хотим прекратить использовать (последний случай как раз относится к рассматриваемому макросу).

- -

Формат JSON для результата

-

Когда вы запрашиваете результат в формате JSON, вы по прежнему получаете результаты по одной странице за раз. Каждая страница является объектом KumaScript, который состоит из нескольких частей с метаданными о результатах, плюс массив стандартных объектов страницы с одним дополнительным полем: URL-адресом для начала редактирования страницы.

-

В результирующем объекте содержатся следующие данные:

-
-
count
-
Общее количество найденных результатов.
-
next
-
URL, по которому можно перейти на следующую страницу с результатами (либо {{jsxref("Global_Objects/null", "null")}} для последней страницы).
-
previous
-
URL, по которому можно перейти на предыдущую страницу с результатами (либо {{jsxref("Global_Objects/null", "null")}} для первой страницы).
-
query
-
???
-
page
-
Номер страницы с результатами, описываемой этим объектом.
-
pages
-
Общее количество страниц с результатами.
-
start
-
Номер первого элемента на этой странице с результатами.
-
end
-
Номер последнего элемента на этой странице с результатами.
-
filters
-
Массив конфигураций расличных поисковых фильтров. Эти фильтры доступны в стандартном поиске.
-
documents
-
Массив {{anch("Page_objects", "объектов страницы")}}, описывающих каждую совпавшую страницу.
-
- -

Объекты страницы

-

Каждый объект страницы содержит следующие поля:

-
-
title
-
Заголовок статьи.
-
slug
-
Идентификатор статьи. Это вся часть URL страницы, следующая за локалью и последующим символом слеша.
-
locale
-
Локаль страницы.
-
excerpt
-
Фрагмент содержания страницы; это либо первый блок обычного текста статьи, либо содержимое, отмеченное классом "SEO Summary".
-
url
-
Полный URL страницы.
-
edit_url
-
Полный URL страницы в режиме редактирования.
-
tags
-
Массив меток страницы.
-
score
-
Значение очков, присвоенное странице поисковым движком.
-
explanation
-
Различная информация от поискового движка о том, почему страница соответствует вашему запросу. Описание этого содержимого выходит за рамки данного документа.
-
diff --git a/files/ru/mdn/user_guide/deleting_pages/index.html b/files/ru/mdn/user_guide/deleting_pages/index.html deleted file mode 100644 index ffd7d04664..0000000000 --- a/files/ru/mdn/user_guide/deleting_pages/index.html +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: Удаление страниц -slug: MDN/User_guide/Deleting_pages -tags: - - Guide - - MDN -translation_of: MDN/Tools/Page_deletion ---- -
{{MDNSidebar}}

Только администраторы MDN имеют право и могут удалять страницы. Эта статья описывает, как отправить запрос на удаление страницы с MDN.

-

Чтобы организовать удаление страницы, вы должны сделать следующее:

-
    -
  1. Не очищайте и не изменяйте содержимое страницы. Мы хотим видеть эту страницу во время удаления.
  2. -
  3. Добавьте метку «junk» к странице. Не удаляйте другие метки.
  4. -
  5. Если страница особенно срочно нуждается в удалении (например, её содержимое неуместно, оскорбительно или технически опасно), уведомите администратора MDN.
  6. -
-

Администратор удалит страницу, когда это будет возможно, после того как убедится, что это удаление целесообразно.

diff --git a/files/ru/mdn/user_guide/feeds/index.html b/files/ru/mdn/user_guide/feeds/index.html deleted file mode 100644 index ba43bf1809..0000000000 --- a/files/ru/mdn/user_guide/feeds/index.html +++ /dev/null @@ -1,73 +0,0 @@ ---- -title: Ленты новостей MDN -slug: MDN/User_guide/Feeds -tags: - - Kuma -translation_of: MDN/Tools/Feeds ---- -
{{MDNSidebar}}

Вики MDN предлагает ряд лент новостей, которые вы можете использовать для слежения за сайтом. В будущем их, вероятно, будет больше, а некоторые из них до сих пор ещё в разработке, но эта информация всё равно может быть для вас полезна.

- -

Получение доступа к лентам новостей

-

Все ленты новостей начинаются со следующего базового URL:

-
https://developer.mozilla.org/<локаль>/docs/feeds/<формат>/
-

Заполнители в базовом URL могут быть заменены следующими значениями:

- -

Если вы используете формат json, вы также можете определить дополнительный параметр запроса ?callback=<имя функции обратного вызова>, который следует соглашению JSONP для загрузки данных как JavaScript.

- -

Доступные ленты

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ЛентаОписание
all -

Все недавно изменённые статьи, упорядоченные по дате изменения. Также она включает в себя новые статьи. Все изменения объединяются в одну запись в ленте новостей для каждой статьи. Например:

-

https://developer.mozilla.org/ru/docs/feeds/rss/all

-
revisions -

Все ревизии статей, упорядоченные по дате изменения, включая новые статьи. Каждая ревизия занимает отдельную запись в ленте. Например:

-

https://developer.mozilla.org/ru/docs/feeds/atom/revisions

-
tag/<имя-метки> -

Недавно изменённые статьи, упорядоченные по дате изменения. В ленту включаются только статьи с определённой меткой. Например:

-

https://developer.mozilla.org/ru/docs/feeds/json/tag/CSS?callback=loadFeed

-
files -

Недавно изменённые или загруженные файлы. Например:

-

https://developer.mozilla.org/ru/docs/feeds/atom/files

-
l10n-updates -

Переводные статьи, чей оригинал был изменён с последнего редактирования этой статьи. Например:

-

https://developer.mozilla.org/ru/docs/feeds/atom/l10n-updates

-
needs-review[/<тип-проверки>] -

Список статей, требующих определённой проверки, либо статьи, требующие любой проверки, если тип проверки не указан. Тип проверки может быть одним из technical, editorial или kumascript.

-

https://developer.mozilla.org/ru/docs/feeds/json/needs-review

-

https://developer.mozilla.org/ru/docs/feeds/rss/needs-review/technical

-

https://developer.mozilla.org/ru/docs/feeds/atom/needs-review/editorial

-

https://developer.mozilla.org/ru/docs/feeds/atom/needs-review/kumascript

-
diff --git a/files/ru/mdn/user_guide/index.html b/files/ru/mdn/user_guide/index.html deleted file mode 100644 index 88a0659232..0000000000 --- a/files/ru/mdn/user_guide/index.html +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: Руководство пользователя MDN -slug: MDN/User_guide -tags: - - Documentation - - Landing - - MDN -translation_of: MDN/Tools -translation_of_original: MDN/User_guide ---- -
{{MDNSidebar}}

Сайт сети разработчиков Mozilla является продвинутой системой для поиска, чтения и внесения документации и примеров исходного кода для веб-разработчиков (а также для разработчиков под браузер Firefox и ОС Firefox). Руководство пользователя MDN предоставляет статьи, в подробностях описывающие, как использовать MDN для поиска нужной вам документации и, если вы желаете, как помочь сделать материалы лучше: более полными и обширными.

-
- {{LandingPageListSubpages}}
diff --git a/files/ru/mdn/user_guide/linking_to_mdn/index.html b/files/ru/mdn/user_guide/linking_to_mdn/index.html deleted file mode 100644 index 093ce13265..0000000000 --- a/files/ru/mdn/user_guide/linking_to_mdn/index.html +++ /dev/null @@ -1,63 +0,0 @@ ---- -title: Проставление ссылок на MDN -slug: MDN/User_guide/Linking_to_MDN -tags: - - Documentation - - Guide - - MDN -translation_of: MDN/About/Linking_to_MDN ---- -
{{MDNSidebar}}

Мы регулярно получаем от пользователей вопросы о том, как сослаться на MDN, или даже разрешено ли это делать. Краткий ответ таков: да, вы можете ссылаться на MDN! Читайте дальше, чтобы узнать о руководящих принципах и лучших практиках!

- - -

Да! Разумеется! Дело не только в том, что гипертекст — это сущность веба, это так же способ указать вашим пользователям на ценные ресурсы и показать своё доверие к работе нашего сообщества.

-

Так что, да, мы определённо рекомендуем вам ссылаться на содержимое MDN. Не стесняетесь: ссылайтесь на главную страницу MDN, или, ещё лучше, сразу на конкретную страницу MDN, в случае необходимости. Смотрите ниже лучшие практики определения того, на какую страницу ссылаться.

- - -

Не существует специальной страницы, на которую вы должны ссылаться. Важно то, насколько релевантна страница для ваших читателей.

- -

Но на самом деле, вы должны ссылаться на наиболее подходящую к вашему содержимому и для ваших пользователей страницу. Не забывайте, что важны ваши читатели, а не ссылки на нас.

- -

Как создать хорошую ссылку?

-

Создание ссылок — дело тривиальное, но создание хороших ссылок — это нечто более сложное. Существует несколько способов создать ссылки:

- -

Ссылки в тексте

-

Это самый полезный вид ссылок: они нацелены на предоставление пользователям дополнительной информации по данной концепции. В основном такие ссылки ведут на страницы, содержащие связанную информацию, а не на домашнюю страницу веб-сайта (хотя, конечно, есть и исключения).

-
-

… с помощью API IndexedDB данные можно хранить в локальной базе данных…

-
-

Такие ссылки очень ценны как для пользователя, который получает информацию, доступную в один щелчок мыши, так и для MDN, так как пользователям, пришедших к нам по точному контексту, скорее всего понравится наше содержимое. Поскольку наша миссия состоит в том, чтобы читатели нашли то, что им нужно, как можно быстрее, это определённо очень хорошая вещь.

- -

Что не надо делать при проставлении ссылок в тексте

-

Проставление ссылок в тексте действительно очень клёво и полезно, но есть несколько вещей, которых нужно избегать:

- - -

Добавление баннера или изображения на ваш сайт

-

Другим способом сослаться на MDN является добавление изображения со ссылкой вне основного текста страницы, например, в боковую панель. Он имеет другое значение: тогда как проставление ссылок в тексте является способом предоставления дополнительной информации вашим пользователям, добавление изображения со ссылкой в боковую панель — это способ показать вашу поддержку проекту MDN или способ продвинуть MDN. Также это способ предложения MDN в качестве единого ресурса со всей информацией.

-

Не стесняйтесь показывать нам вашу поддержку: посетите страницу продвижения MDN и создайте кнопку специально для вашего сайта. Конечно, вы вольны разместить ссылку на другую страницу, например, на одну из целевых страниц.

- -

Автоматическое проставление ссылок на MDN из WordPress

-

Мы создали плагин WordPress, который автоматически проставляет ссылки на выбранные термины в записях вашего блога на соответствующие страницы MDN. Делает он это разумно, в соответствии с рекомендациями, изложенными выше и может быть большим подспорьем для блоггеров, пишущих о концепциях веба. Взгляните на него, и попробуйте установить, если вы думаете, что он может быть полезен.

-

Большое спасибо вам за вашу поддержку!

diff --git a/files/ru/mdn/yari/index.html b/files/ru/mdn/yari/index.html new file mode 100644 index 0000000000..ee8105bf08 --- /dev/null +++ b/files/ru/mdn/yari/index.html @@ -0,0 +1,25 @@ +--- +title: 'Kuma: вики-платформа MDN' +slug: MDN/Kuma +tags: + - Kuma + - Главная +translation_of: MDN/Kuma +--- +
{{MDNSidebar}}
+ +
{{IncludeSubnav("/ru/docs/MDN")}}
+ +

Kuma - код на Django, который обслуживает Mozilla Developer Network.

+ +

{{SubpagesWithSummaries}}

+ +

Начинаем работу с Kuma

+ +

Чтобы поучаствовать в Kuma:

+ + diff --git "a/files/ru/mdn/\321\201\320\276\320\276\320\261\321\211\320\265\321\201\321\202\320\262\320\276/conversations/index.html" "b/files/ru/mdn/\321\201\320\276\320\276\320\261\321\211\320\265\321\201\321\202\320\262\320\276/conversations/index.html" deleted file mode 100644 index 1440b5cdcd..0000000000 --- "a/files/ru/mdn/\321\201\320\276\320\276\320\261\321\211\320\265\321\201\321\202\320\262\320\276/conversations/index.html" +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: MDN community conversations -slug: MDN/Сообщество/Conversations -tags: - - MDN Meta - - Руководство - - Сообщество -translation_of: MDN/Community/Conversations ---- -
{{MDNSidebar}}
- -

"Работа" MDN происходит на её сайте, но "сообщество" также общается через (асинхронные) дискуссии и (синхронные) чаты и встречи.

- -

Дискуссии и обмен информацией.

- -

Для того, чтобы делиться информацией и вести дискусиию, MDN имеет раздел ("MDN") на форуме Mozilla. Используйте данный раздел для всех тем, связанных с MDN, включая создание, перевод и обслуживание документации; Разработка платформы MDN; и планирование, постановка целей и отслеживание прогресса.

- - - -

Архив записей

- -

До июня 2017 года обсуждения, связанные с MDN, проходили в списках рассылки, которые были переданы и заархивированы группами Google. Если вы хотите найти эти прошлые обсуждения, вы можете посмотреть группы Google, соответствующие старым спискам рассылки. (Да, мы знаем, что эти имена совпадают и сбивают с толку. Исторический случай. Приносим извинения.)

- -
-
mozilla.dev.mdc a.k.a. dev-mdc
-
Данный список предназначался для обсуждения документации.
-
mozilla.dev.mdn a.k.a. dev-mdn
-
Этот список посвещался базовой разработке платформы MDN Kuma.
-
mozilla.mdn a.k.a. mdn@
-
Этот форум был предназначен для обсуждения на высоком уровне планирования и определения приоритетов, для веб-сайта MDN и других связанных инициатив.
-
- -

Синхронный чат

- -

Matrix - платформа для общения в реальном времени от Mozilla, протокол чата для которого у Mozilla есть собственный сервер

- -

Чат с веб-документацией MDN является основным каналом для обсуждения содержания MDN. Мы говорим о написании, организации контента и так далее. У нас также есть здесь разговоры о «кулерах» - это способ нашего сообщества поддерживать связь и просто тусоваться. Эта комната, скорее всего, будет активна в будние дни в Северной Америке и Европе.

- -

Возможно, вы захотите узнать больше об использовании Matrix с Mozilla и, если вам это действительно нравится, установите автономное Matrix приложение, Riot.im.

- -

What about IRC?

- -

В течение многих лет Mozilla использовала Internet Relay Chat (IRC) для обсуждения в реальном времени. С начала 2020 года IRC устарел и заменен Matrix. Вы можете встретить ссылки на IRC-каналы во многих местах, в том числе на MDN. Вы можете помочь, обновив ссылки на IRC-каналы, которые вы найдете на MDN, чтобы они указывали на соответствующие комнаты Matrix. Если вы не уверены, что представляет собой комната Matrix по теме, спросите в общей комнате. У проектов или тем, которые больше не активны, может не быть комнаты Matrix; в таких случаях просто удалите ссылку.

- -

Присоеденяйся к нашим встречам (и другим событиям)

- -

The MDN team holds a number of regular meetings that are open to the MDN community. See the MDN Meetings page on the Mozilla wiki for details on the schedule, agendas and notes, and info on how to join.

- -

See the MDN Events calendar for these and other meetings, local meetups, and other events. The recurring meetings are summarized on the MDN Meetings wiki page

diff --git "a/files/ru/mdn/\321\201\320\276\320\276\320\261\321\211\320\265\321\201\321\202\320\262\320\276/index.html" "b/files/ru/mdn/\321\201\320\276\320\276\320\261\321\211\320\265\321\201\321\202\320\262\320\276/index.html" deleted file mode 100644 index 5824e576e4..0000000000 --- "a/files/ru/mdn/\321\201\320\276\320\276\320\261\321\211\320\265\321\201\321\202\320\262\320\276/index.html" +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: Присоединяйся к сообществу MDN -slug: MDN/Сообщество -tags: - - МДН - - Руководство - - Сообщество -translation_of: MDN/Community ---- -
{{MDNSidebar}}
- -
{{IncludeSubnav("/ru/docs/MDN")}}
- -
-

MDN (аббревиатура Mozilla Developer Network) - это больше чем wiki: это сообщество разработчиков работающих вместе, чтобы сделать MDN лучшим ресурсом для разработчиков, которые используют открытые Веб-технологии.

-
- -

Мы хотели бы, чтобы вы внесли свой вклад в MDN, но еще больше мы бы хотели, чтобы вы участвовали в сообществе MDN. Вот как присоединиться, за три простых шага:

- -
    -
  1. Создайте MDN аккаунт.
  2. -
  3. Присоединитесь к обсуждению.
  4. -
  5. Смотрите, что происходит.
  6. -
- -

Как работает сообщество

- -

Следующие статьи наиболее подробно описывают сообщество MDN.

- -
-
-
-
Роли сообщества
-
Есть определённое количество ролей в MDN сообществе с разной степенью ответственности.
-
Док-спринты
-
Это руководство по организации спринтов документации. Оно содержит советы и подсказки от людей, которые уже проводили док-спринты, чтобы помочь вам организовать свой.
-
Смотрите, что происходит
-
MDN создана сообществом Mozilla Developer Network. Вот несколько способов, которыми мы можем поделиться с вами информацией о том, что мы делаем.
-
- -
-
-
- -
-
-
Обсуждения сообщества MDN
-
"Работа" MDN происходит на её сайте, но "сообщество" также общается через (асинхронные) дискуссии и (синхронные) чаты и встречи.
-
Работа в сообществе
-
Большая часть вклада в документацию на MDN какого-либо значительного размера требует знаний, как работать, как часть MDN сообщества. Эта статья содержит советы, которые помогут вам сделать большую часть ваших взаимодействий с другими редакторами и разработчиками.
-
-
-
diff --git "a/files/ru/mdn/\321\201\320\276\320\276\320\261\321\211\320\265\321\201\321\202\320\262\320\276/whats_happening/index.html" "b/files/ru/mdn/\321\201\320\276\320\276\320\261\321\211\320\265\321\201\321\202\320\262\320\276/whats_happening/index.html" deleted file mode 100644 index fb74f6342c..0000000000 --- "a/files/ru/mdn/\321\201\320\276\320\276\320\261\321\211\320\265\321\201\321\202\320\262\320\276/whats_happening/index.html" +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Следите за событиями -slug: MDN/Сообщество/Whats_happening -translation_of: MDN/Community/Whats_happening ---- -
{{MDNSidebar}}
- -

MDN представлено вам через Mozilla Developer Network community. Вот несколько способов, с помощью которых мы делимся информацией о том, что делаем.

- -

Блоги

- -
-
Mozilla Hacks
-
Новости и углубленное освещение Веб-технологий и особенностей Mozilla.
-
Engaging Developers
-
Повышение активности и обсуждения среди сообщества, участвующих в MDN в Mozilla.
-
- -

Короткие советы

- - - -

Панель состояния

- -

Взгляните на страницу Статус документации, чтобы увидеть, что происходит со всем содержимым MDN. Вы можете увидеть какие статьи нуждаются в написании или обновлении, каким темам требуется наибольшая помощь и многое-многое другое.

- -

MDN встречи

- -

Есть целый ряд регулярных встреч для отслеживания и совместного прогресса на различных MDN проектах и процессах. Они описаны на вики странице MDN встреч.

- -

Для того, чтобы получить общее представление о том, что происходит, лучшим способом для участия является встреча MDN-сообщества, которое проходит каждые две недели по средам, с 10:00 по тихоокеанскому времени США (UTC-0800 с октября по март, UTC-0700 в марте-октябре), на канале #mdn IRC. Посмотрите вики страницу встреч сообщества MDN для повесток дня и заметки из прошлых встреч.

- -

Публичный календарь событий MDN содержит встречи MDN сообщества, doc спринты, и другие события связанные с MDN. Если вы видите встречу, которое происходит в канале "mdn" в системе видеоконференции Vidyo, вы можете присоединиться к разговору.

diff --git "a/files/ru/mdn/\321\201\320\276\320\276\320\261\321\211\320\265\321\201\321\202\320\262\320\276/working_in_community/index.html" "b/files/ru/mdn/\321\201\320\276\320\276\320\261\321\211\320\265\321\201\321\202\320\262\320\276/working_in_community/index.html" deleted file mode 100644 index 9f5faaf33d..0000000000 --- "a/files/ru/mdn/\321\201\320\276\320\276\320\261\321\211\320\265\321\201\321\202\320\262\320\276/working_in_community/index.html" +++ /dev/null @@ -1,108 +0,0 @@ ---- -title: Работа в сообществе -slug: MDN/Сообщество/Working_in_community -tags: - - Community - - Guide - - MDN Meta - - Руководство - - Сообщество -translation_of: MDN/Community/Working_in_community ---- -
{{MDNSidebar}}
- -

Большая часть вклада в документацию MDN в каких-либо значительных масштабах умение работать в рамках MDN-сообщества. Эта статья подскажет, как внести максимальный вклад в работу с другими редакторами и командами разработчиков.

- -

Общее руководство по этикету

- -

Вот некоторые общие указания при работе в сообществе Mozilla.

- - - -

Будьте тактичны

- -

Всегда будьте тактичны и уважительны, когда общаетесь с другими.

- -

Вежливо указывайте на ошибки

- -

Если ваша цель в контакте с кем-то - попросить их сделать что-то по-другому или указать на ошибку, которую они совершили (особенно если они повторяют это постоянно), начните свое сообщение с положительного комментария. Это смягчает удар, так сказать, демонстрирует, что вы пытаетесь быть полезным и не позиционирует вас как невоспитанного человека.

- -

Например, если новый участник создает много страниц без тегов и вы хотели бы указать на эту проблему, тогда ваше сообщение для него могло бы выглядеть так (то, что вам нужно изменить для конкретного случая, подчеркивается):

- -
-

Привет, MrBigglesworth, я заметил Ваш вклад в документацию API Wormhole, Ваша помощь неоценима! Мне особенно нравится, как Вы сбалансировали свой уровень детализации с удобочитаемостью. Тем не менее, Вы могли бы сделать эти статьи еще лучше и полезнее, если бы в дальнейшем добавили правильные теги к страницам.

- -

Подробные сведения смотри в руководстве по тегам MDN (https://developer.mozilla.org/en-US/docs/MDN/Contribute/Howto/Tag).

- -

Еще раз спасибо, я надеюсь на Ваше сотрудничество в будущем!

-
- -

Обмен знаниями

- -

Когда вы участвуете в MDN проекте, вы можете общаться с другими членами сообщества и быть в курсе происходящего. Вы можете обмениваться идеями, изменениями статуса и тому подобным с другими. Для этого есть соответствующие инструменты и информационные ресурсы.

- -

Способы коммуникации

- -

Существует несколько способов взаимодействия с другими участниками (разработчиками и писателями), каждый из которых имеет свой набор правил этикета.

- -

Bugzilla

- -

При написании документации, связанной с исправлением ошибок в рамках системы Bugzilla, вы часто будете общаться с людьми, имеющим отношение к соответствующим ошибкам. Никогда не забывайте о руководстве по этикету Bugzilla Etiquette!

- -

Email

- -

Вы можете также связаться с кем-то через электронную почту, если у вас есть необходимые адреса email.

- -
-

Примечание: Как правило, если кто-то разместил свой адрес электронной почты в документах о технологии, которую вы документируете, дал вам свой адрес электронной почты лично или имеет общеизвестный электронный адрес, то электронная почта является приемлемым способом "первого контакта". Если вы достали email адрес другим методом, то вы, вероятно, должны сначала попытаться получить разрешение в IRC или списке рассылки до тех пор, пока ваши попытки не будут исчерпаны.

-
- -

Инструменты статуса контента

- -

Есть несколько полезных инструментов, которые предоставляют информацию о состоянии документов.

- -
-
Панель управления ревизиями
-
Панель управления ревизиями документов предоставляет очень удобный инструмент для обзора изменений, внесенных в контент MDN. Вы можете видеть историю последних изменений, выбрать временной диапазон для просмотра. Вы можете использовать фильтр по языку, имени разработчика, теме и другим атрибутам. Просматривая список ревизий документов, вы можете просмотреть изменения, внесенные в каждую ревизию, быстро открыть страницу, просмотреть полную историю или даже отменить изменения (если у вас есть необходимые привилегии).
-
Обзор статуса документации
-
Страница обзора статуса документации содержит список всех областей MDN, которые были сконфигурированы для отслеживания статуса. Она содержит информацию о том, сколько страниц нуждаются в различных доработках. Выбрав конкретную тему, вы можете просмотреть подробные списки документов, которые необходимо доработать. Это могут быть страницы, которые не имеют тегов, или помечены индикаторами "необходимо выполнить определенные виды работ". Вы можете даже просмотреть списки страниц, которые не обновлялись в течение длительного времени и могут быть устаревшими, а также список ошибок, которые были отмечены как влияющие на документацию в этой области.
-
Планы проектов документации
-
Для некоторых проектов созданы планы документации, которые помогают отслеживать то, что еще необходимо сделать. К таким проектам относятся проекты на стадии планирования или большие, постоянные проекты.
-
MDN Taiga
-
Штатные сотрудники MDN используют инструмент под названием Taiga для управления текущими и будущими проектами документации. Вы также можете посмотреть чем мы занимаемся и какие проекты планируются в ближайшем будущем. Некоторые из них будут взяты на себя штатными сотрудниками, но вы также можете взяться за них, если захотите! Для получения дополнительной информации о живых технологических процессах, сопровождаемых командой MDN, смотрите нашу Страницу технологических процессов на Mozilla wiki.
-
- -

Сообщество разработчиков

- -

Членам писательского сообщества MDN важно поддерживать нормальные отношения с разработчиками. Разработчики создают программное обеспечение, которым мы пользуемся. Они владеют полезной для нас информацией. Критически важным является поддерживать с ними хорошие отношения. Чем более адекватны вы будете в общении с разработчиками, тем у вас больше шансов на то, что они ответят на ваши вопросы быстро, аккуратно и тщательно!

- -

Не забывайте, что вы являетесь представителем писательского сообщество MDN. Пожалуйста, помогите нам сохранить наши отличные рабочие отношения с командой разработчиков, сделав каждое их взаимодействие с нашей командой писателей примером хорошей работы.

- -

Для того, чтобы найти подходящего человека для обсуждения ваших вопросов (не забывая о сделанных выше замечаниях) можете обратиться к ресурсу module owners lists.

- -

Сообщество писателей

- -

Писательское сообщество является достаточно большим. Хотя число постоянных участников невелико, но есть несколько сотен людей, которые вносят свой вклад время от времени. В основном эти люди искренне любят Web, Mozilla и/или документацию, поэтому взаимодействовать с ними почти всегда очень легко.

- -

Для получения более подробной информации, смотрите статью Join the community.

- -

Наиболее вероятным местом, где вы могли бы напрямую пересечься с другими писателями является IRC канал {{IRCLink("mdn")}}. Этот канал зарезервирован специально для дискуссий о документации. По поводу особенностей IRC этикета смотрите статью из Mozilla Support "Getting Started with IRC". Вы можете дискутировать с нами также на Дискуссионном форуме MDN. Уместно заметить, что IRC, как правило, используют для быстрых, более личных бесед, а дискуссионный форум обычно используют для продолжительных бесед.

- -

Имея ввиду {{anch("Общее руководство по этикету")}}, вы увидите, что все идет обычно очень гладко.

- -

Смотри также

- - diff --git a/files/ru/mdn_at_ten/contributing_to_mdn/index.html b/files/ru/mdn_at_ten/contributing_to_mdn/index.html deleted file mode 100644 index a8227dafed..0000000000 --- a/files/ru/mdn_at_ten/contributing_to_mdn/index.html +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: Участие в MDN -slug: MDN_at_ten/Contributing_to_MDN -tags: - - MDN Мета - - Mozilla - - Участие -translation_of: MDN_at_ten/Contributing_to_MDN ---- -
-
-

Как принять участие

- -

Внести свой вклад в MDN очень просто, и есть два способа начать работу. Вы видите страницу, которую можно улучшить (исправив опечатку, добавив новую информацию или исправив технические ошибки)? Просто нажмите большую синюю кнопку "Редактировать" в верхней части страницы. Вы знаете что-то, чего мы еще не освещаем? Просто создайте новую страницу; наше сообщество замечательных обозревателей и редакторов позаботится о том, чтобы ваша страница соответствовала нашему руководству по оформлению и находилась в нужном месте на сайте. Не переживайте из-за того, чтобы получилось «полностью правильно». Каждый может помочь сделать Интернет лучше.

-
- -
-
-
-

Присоединяйтесь!

- -

Присоединяйтесь к нам в обучении мира разработке открытой сети!

- -

Быстый старт

-
-
-
-
- -
-
-

Выборка профилей участников

- -

MDN состоит из огромного сообщества участников. Хотя мы не можем предложить профили всех из них (это было бы очень долго!), Мы можем рассказать кое-что о некоторых из тех, кто внес существенный или важный вклад, а также о тех, кто скорее всего, будет доступен в чате MDN Web Docs, чтобы помочь вам, если вам понадобится помощь в вашем участии.

- -
-
-

Chris Blizzard
- Former Director of Evangelism, Mozilla

- -

Blizzard oversaw and drove Mozilla Developer Center's transition from focusing on Mozilla-specific material to a community-maintained resource useful to a variety of Web developers.

- -

Николай Пономарёв
- Доброволец

- -

Nickolay был одним из самых ранних участников, помогая с первоначальными усилиями по очистке DevEdge. С тех пор он продолжает вносить свой вклад во многих областях, как для веб-стандартов, так и для продуктов Mozilla.

- -

Andrew Overholt
- Engineering Manager

- -

Andrew возглавляет команду разработчиков веб-API. В рамках своей работы он побуждает всех разработчиков DOM и API помочь убедиться, что документация отличная, предоставляет информацию, которая нужна команде разработчиков, просматривает документацию и помогает с примерами кода. Этот пример очень и очень радует команду MDN.

- -

Jérémie Patonnier
- Project Manager

- -

Jérémie начал вносить свой вклад в MDN в 2011 году, документируя свойства SVG, поскольку эта информация была ему нужна для его собственной работы. Jérémie стал лидером французского сообщества MDN, проводя регулярные сессии "Mercredi Docs" (документ среды) в офисе Mozilla Париж. В настоящее время он возглавляет усилия по созданию области обучения, а также по улучшению и упорядочиванию данных о совместимости браузеров в MDN.

- -

Julien (Sphinx)
- Доброволец

- -

Julien внес «львиную долю» усилий на перевод всего раздела JavaScript в MDN на французский язык. Многие другие участники также помогли в этой работе, но Julien провел много ночей и выходных в течение нескольких месяцев, переводя статьи на JavaScript.

- -

Jeff Walden
- Software Engineer, JavaScript Engine

- -

Jeff Walden сейчас входит в команду SpiderMonkey, которая внесла свой вклад в MDN с самого его начала и во многих областях, включая XPCOM, сборку и тестирование Mozilla, JavaScript, CSS и многое другое.

-
- -
-

Priyanka Nag
- Доброволец

- -

Priyanka Nag присоединилась к MDN в 2012 году, но стала активно работать с сообществом MDN только после саммита Mozilla в 2013 году, где она встретилась и работала с Luke Crouch и David Walsh из команды разработчиков MDN; это послужило ее главным вдохновением, чтобы начать вносить свой вклад в MDN. Priyanka в основном любит проповедовать MDN, проводить мероприятия MDN и знакомить с MDN больше людей, а также время от времени вносить некоторые правки в вики. В настоящее время она работает техническим писателем в Red Hat и с гордостью утверждает, что ее интерес к техническому писательству начался с ее вклада в MDN, который в конечном итоге оказал большое влияние на ее решение о карьере.

- -

Saurabh Nair
- Доброволец

- -

Saurabh он вносит свой вклад в MDN с 2011 года и стал более активным в прошлом году. Он входит в команду “spam watch”, которая следит за спам-страницами, удаляя их и запрещая спамеров, как только они появляются. Поскольку он живет в Индии, он может делать это, пока сотрудники MDN в Европе и Северной Америке спят.

- -

Eric Shepherd (Sheppy)
- Senior Technical Writer

- -

{{UserLink("Sheppy")}} был первым штатным писателем, нанятым Mozilla для работы исключительно над документацией для разработчиков, начиная с 3 апреля 2006 года. Он пишет обо всем, что требует освещения, в том числе о вещах, с которыми никто другой не хочет иметь ничего общего. На протяжении многих лет он много писал обо всем, от дополнений до XUL.

- -

Sebastian Zartner
- Доброволец

- -

Sebastian внёс первый вклад в MDNв 2007 году, когда он работал над немецкими переводами, но вскоре он начал работать над английскими. Он внёс большой вклад как в содержание, так и в структуру справочника CSS, включая создание JSON API для страниц CSS и макросов, использующих это API.

-
-
-
- -
{{TenthCampaignQuote(7)}} {{TenthCampaignQuote(5)}}
-
diff --git a/files/ru/mdn_at_ten/index.html b/files/ru/mdn_at_ten/index.html deleted file mode 100644 index bbbdcccd01..0000000000 --- a/files/ru/mdn_at_ten/index.html +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: 10-летие MDN -slug: MDN_at_ten -tags: - - MDN -translation_of: MDN_at_ten ---- -
Празднуем 10-летие документирования Web.
- -
-
-

История MDN

- -

В начале 2005 года небольшая группа идеалистов поставила цель создать новый, свободный и поддерживаемый сообществом интернет-ресурс для всех web-разработчиков. Их прекрасная и смелая идея переросла в Mozilla Developer Network — главный ресурс для всех открытых web-технологий. Десять лет спустя наше мировое сообщество стало больше чем когда-либо, и вместе мы продолжаем создавать документацию, примеры кода и обучающие ресурсы для всех открытых веб-технологий, включая CSS, HTML и JavaScript и всего остального, что делает открытый Web ещё лучше.

- -

Узнать большеabout the history

- - -

Участвие в MDN

- -

В течение десяти лет сообщество MDN создавала документацию для открытого Web'а. От исправления простых опечаток до написания целых сайтов и совершенно новых API. Каждому есть что предложить, и этот вклад не является слишком большим или слишком маленьким. У нас есть более 90 000 страниц контента, которые были написаны или переведены членами нашего выдающегося сообщества Mozillians. Вы можете стать одним из них.

- -

Узнать большеabout contributing

- -

 

- -

 

-
- -
{{TenthCampaignQuote}}
- -

Содержание

- -
    -
  1. 10-летие MDN
  2. -
  3. История MDN
  4. -
  5. Участие в MDN
  6. -
-
diff --git a/files/ru/mozilla/add-ons/webextensions/internationalization/index.html b/files/ru/mozilla/add-ons/webextensions/internationalization/index.html new file mode 100644 index 0000000000..36a37820d9 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/internationalization/index.html @@ -0,0 +1,405 @@ +--- +title: Интернационализация +slug: Mozilla/Add-ons/WebExtensions/Интернационализация +translation_of: Mozilla/Add-ons/WebExtensions/Internationalization +--- +
{{AddonSidebar}}
+ +

API WebExtensions предоставляет полезный модуль для интернационализации расширений — i18n. В этой статье мы рассмотрим его особенности и пример его работы. Система для расширений, построенных с помощью API WebExtension, i18n похожа на библиотеки JavaScript для i18n, такие как i18n.js.

+ +
+

Расширение, используемое в этой статье в качестве примера, — notify-link-clicks-i18n — доступно на GitHub. Читая последующие секции этой статьи, Вы можете исследовать его исходный код.

+
+ +

Структура интернализированного расширения

+ +

Интернационализированное расширение может содержать такие же элементы, как и любое другое расширение — фоновые скрипты, встраиваемые скрипты, и т. д. — а также дополнительные инструмены, позволяющие переключаться между разными локализациями. Их можно представить следующим деревом директорий:

+ + + +

Давайте отдельно рассмотрим каждый элемент — последующие секции представляют собой шаги, которым стоит следовать во время интернационализации вашего расширения.

+ +

Добавление локализованных строк в _locales

+ +
+
Вы можете определить тэг языка при помощи инструмента Find  на странице определения языковых тегов. Обратите внимание на то, что при поиске еужно использовать английское название языка
+
+ +

Каждая система i18n требует предоставить строки во всех локализациях, которые Вы хотите поддерживать. В расширениях они хранятся в директории  _locales, размещенной внутри корневой директории. Строки каждой локализации (также называемые сообщениями) хранятся в файле messages.json, находящемся в поддиректории _locales, название которой - тег языка локализации.

+ +

Стоит заметить, что если тег включает в себя и базовый язык, и его региональный вариант, то по конвенции эти язык и вариант разделяются дефисом: например, "en-US". Однако в поддиректориях _locales, вместо дефиса используется нижнее подчеркивание: "en_US".

+ +

Таким образом, в нашем примере существую директории "en" (английский), "de" (немецкий), "nl" (голландский), and "ja" (японский). Внутри каждой из них находится файл messages.json .

+ +

Давайте рассмотрим структуру одного из этих файлов (_locales/en/messages.json):

+ +
{
+  "extensionName": {
+    "message": "Notify link clicks i18n",
+    "description": "Name of the extension."
+  },
+
+  "extensionDescription": {
+    "message": "Shows a notification when the user clicks on links.",
+    "description": "Description of the extension."
+  },
+
+  "notificationTitle": {
+    "message": "Click notification",
+    "description": "Title of the click notification."
+  },
+
+  "notificationContent": {
+    "message": "You clicked $URL$.",
+    "description": "Tells the user which link they clicked.",
+    "placeholders": {
+      "url" : {
+        "content" : "$1",
+        "example" : "https://developer.mozilla.org"
+      }
+    }
+  }
+}
+ +

Это стандартный файл JSON — каждый из его элементов является объектом с именем, содержащим сообщение (message) и описание (description). Оба предмета - строки; $URL$ — это заполнитель, который заменяется подстрокой, когда элемент notificationContent вызывается расширением. Вы научитесь это делать в секции {{anch("Получение сообщений из JavaScript")}}.

+ +
+

Примечание: Вы можете найти больше информации о структуре messages.json здесь.

+
+ +

Интернационализация manifest.json

+ +

Для интернационализации файла manifest.json нужно предпринять несколько шагов.

+ +

Получение локализованных строк в манифестах

+ +

Ваш файл manifest.json содержит строки, отображаемые пользователю, такие как имя и описание расширения. Если Вы интернационализируете эти строки и поместите их переводы в messages.json, то эти переводы будут отображаться пользователю в зависимости от локализации его браузера.

+ +

Чтобы интернационализировать строки, их нужно указывать следующим образом:

+ +
"name": "__MSG_extensionName__",
+"description": "__MSG_extensionDescription__",
+ +

Здесь мы получаем сообщения, зависящие от локализации браузера, а не просто статические строки.

+ +

Чтобы получить строку сообщения, ее нужно указать следующим образом:

+ +
    +
  1. Два подчеркивания
  2. +
  3. Строка "MSG"
  4. +
  5. Одно подчеркивание
  6. +
  7. Имя сообщения так как оно указано в messages.json
  8. +
  9. Два подчеркивания
  10. +
+ +
__MSG_ + messageName + __
+ +

Локализация по умолчанию

+ +

Еше одно поле. которое нужно указать в manifest.json — это default_locale:

+ +
"default_locale": "en"
+ +

Этот параметр устанавливает локализацию по умолчанию, используемую, если расширение не поддерживает локализацию браузера пользователя. Любые сообщения, недоступные в текущей локализации, будут браться из той локализации, которая установлена по умолчанию. There are some more details to be aware of in terms of how the browser selects strings — see {{anch("Выбор локализованной строки")}}.

+ +

CSS, зависящий от локализации

+ +

Локализованные строки также можно получить из CSS-файлов расширения. Например, Вы можете создать поля CSS, зависящие от локализации, так:

+ +
header {
+  background-image: url(../images/__MSG_extensionName__/header.png);
+}
+ +

Этот функционал может быть полезен, однако, возможно, для этих целей стоит использовать {{anch("Заранее определенные сообщения")}}.

+ +

Получение сообщений из JavaScript

+ +

Допустим, Вы добавили сообщения в Ваш manifest.json. Чтобы Ваше расширение начало использовать правильные языки, соответствующие сообщения следует вызывать при помощи JavaScript. API i18n достаточно прост и содержит всего 4 основных метода:

+ + + +

В нашем примере notify-link-clicks-i18n , фоновый скрипт содержит следующие строки:

+ +
var title = browser.i18n.getMessage("notificationTitle");
+var content = browser.i18n.getMessage("notificationContent", message.url);
+ +

Первая из них получает поле notificationTitle message из доступного файла messages.json, соответствующее наиболее подходящей локализации . Вторая строка похожа на первую, но в ней метод принимает URL в качестве второго параметра. Зачем? С помощью этого параметра мы указываем, на что нужно заменить заполнитель $URL$ в поле notificationContent message:

+ +
"notificationContent": {
+  "message": "You clicked $URL$.",
+  "description": "Tells the user which link they clicked.",
+  "placeholders": {
+    "url" : {
+      "content" : "$1",
+      "example" : "https://developer.mozilla.org"
+    }
+  }
+}
+
+ +

Объект "placeholders"  определяет все заполнители и то, откуда их нужно получать. Заполнитель "url" указывает, что информация о нем должна содержаться в $1 — первое значение, заданное внутри второго параметра getMessage(). Поскольку заролнитель называется "url",  $URL$ используется для его вызова внутри сообщения (то есть для заполнителя "name" нужно использовать $NAME$, и т. д.). Если Вы хотите задать значения нескольких заполнителей, их можно передавать во второй аргумент {{WebExtAPIRef("i18n.getMessage()")}} в виде массива — массив [a, b, c] передает значения $1, $2 и $3, и т. д. внутрь messages.json.

+ +

Давайте посмотрим на пример: изначально сообщение notificationContent в файле en/messages.json такое:

+ +
You clicked $URL$.
+ +

Пусть эта ссылка указывает на https://developer.mozilla.org. После вызова {{WebExtAPIRef("i18n.getMessage()")}}, содержание второго параметра становится доступно в messages.json в качестве значения $1, замещающего $URL$, так как это указано в заполнителе  "url". Таким образом, итоговое значение строки:

+ +
You clicked https://developer.mozilla.org.
+ +

Прямое использование заполнителей

+ +

Переменные ($1, $2, $3, и т. д.) можно вставлять напрямую в сообщения. Например, можно переписать объект "notificationContent" следующим образом:

+ +
"notificationContent": {
+  "message": "You clicked $1.",
+  "description": "Tells the user which link they clicked."
+}
+ +

Этот метод может показаться более быстрым и простым, но другой способ (использование "placeholders") считается лучшей практикой. Это вызвано тем, что имена заполнителей (например "url") и примеры помогают понять, что означают заполнители — через неделю после написания кода Вы, наверное, забудете, что обозначают заполнители $1$8, что менее вероятно, если заполнители именованы.

+ +

Заданные замены

+ +

Значения заполнителей можно задавать вручную, если Вы хотите, чтобы каждый раз это значение было одним и тем же, а не определялось переменной в коде. Например:

+ +
"mdn_banner": {
+  "message": "For more information on web technologies, go to $MDN$.",
+  "description": "Tell the user about MDN",
+  "placeholders": {
+    "mdn": {
+      "content": "https://developer.mozilla.org/"
+    }
+  }
+}
+ +

В этом примере мы сами задаем значение заполнителя, а не получаем его из переменной, такой как $1. Это может быть полезно, если сообщение очень сложное, и Вы хотите разделить значения, чтобы сделать строки более читаемыми. К тому же, доступ к этим значениям можно получить внутри программы.

+ +

Вы также можете использовать такие замены для указания частей строки, не нуждающихся в переводе, таких как имена или названия.

+ +

Выбор локализованной строки

+ +

Локализации могут быть указаны с помощью кода языка, например fr или en. Они также могут содержать региональный код, например en_US или en_GB, описывающий региональный вариант языка. Когда вы запрашиваете строку у системы i18n, системы возвращает ее используя следующий алгоритм:

+ +
    +
  1. Если для текущей локализации существует файл messages.json, содержащий требуемую строку, возвращается она.
  2. +
  3. Иначе,если текущая локализация — региональный вариант (например en_US) и существует файл messages.json для этого языка, но без указания региона  (например en), содержащий строку, возвращается она.
  4. +
  5. Иначе, если существует файл messages.json для default_locale, указанной в manifest.json, и этот файл содержит нужную строку, возвращается она.
  6. +
  7. В противном случае возвращается пустая строка.
  8. +
+ +

Рассмотрим следующий пример:

+ + + +

Пусть default_locale установлен как fr, а текущая локализация браузера — en_GB:

+ + + +

Заранее определенные сообщения

+ +

Модуль i18n module предоставляет заранее определенные сообщения, которые можно вызвать таким же образом, как мы это делали в разделе {{anch("Интернационализация manifest.json")}}. Например:

+ +
__MSG_extensionName__
+ +

Заранее определенные сообщения используют такой же синтаксис, за исключением @@ перед именем сообщения, например:

+ +
__MSG_@@ui_locale__
+ +

Следующая таблица содержит различные заранее определенные сообщения:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Message nameDescription
@@extension_id +

Внутренний UUID расширения. Эту строку можно использовать для создания URL ресурсов внутри расширения.Даже нелокализованные расширения могут использовать это сообщения.

+ +

Это сообщения нельзя использовать в manifest.json.

+ +

Также стоит заметить, что этот ID — не ID аддона, которое возвращает {{WebExtAPIRef("runtime.id")}}, и которое может быть установлено с помощью ключа applications в manifest.json. Это сгенерированный UUID, содержащийся в URL аддона. Это означает, что данную величину нельзя использовать в качестве параметра extensionId  метода {{WebExtAPIRef("runtime.sendMessage()")}}, или для проверки поля id объекта {{WebExtAPIRef("runtime.MessageSender")}}.

+
@@ui_localeТекущая локализация; эту строку можно использовать для создания URL, зависящих от локализации.
@@bidi_dirНаправления чтения, либо "ltr" для языков, таких как английский, где текст читается слева направо, либо "rtl" для языков, считающихся справа налево, таких как арабский.
@@bidi_reversed_dirЕсли @@bidi_dir имеет значение "ltr", то возвращает "rtl"; иначе "ltr".
@@bidi_start_edgeЕсли @@bidi_dir имеет значение "ltr", то возвращает "left"; иначе "right".
@@bidi_end_edgeЕсли @@bidi_dir имеет значение "ltr", то возвращает "right"; иначе "left".
+ +

Возвращаясь к нашему примеру, лучше было бы написать:

+ +
header {
+  background-image: url(../images/__MSG_@@ui_locale__/header.png);
+}
+ +

Теперь мы можем хранить изображения в директориях поддерживаемых локализаций — en, de, и т. д. — что выглядит логичней.

+ +

Давайте рассмотрим пример использования сообщений @@bidi_* в файле CSS:

+ +
body {
+  direction: __MSG_@@bidi_dir__;
+}
+
+div#header {
+  margin-bottom: 1.05em;
+  overflow: hidden;
+  padding-bottom: 1.5em;
+  padding-__MSG_@@bidi_start_edge__: 0;
+  padding-__MSG_@@bidi_end_edge__: 1.5em;
+  position: relative;
+}
+ +

Для языков, в которых текст читается слева направо, таких как английский, правила CSS, использующие заранее определенные сообщения, сверху задают такие значения:

+ +
direction: ltr;
+padding-left: 0;
+padding-right: 1.5em;
+
+ +

Для языков, читающихся справа налево, значения будут следующими:

+ +
direction: rtl;
+padding-right: 0;
+padding-left: 1.5em;
+ +

Тестирование расширения

+ +

Начиная с Firefox 45, расширения могут быть временно установлены с диска — подробнее об этом написано в статье Loading from disk. Сделайте это и попробуйте протестировать наше расширение notify-link-clicks-i18n. Перейдите на одну из Ваших любимых страниц и нажмите на ссылку, чтобы проверить, появляется ли сообщения, содержащее URL нажатой ссылки.

+ +

Затем измените локализацию Firefox на какую-либо поддерживающуюся расширением, которое Вы хотите протестировать.

+ +
    +
  1. Откройте "about:config" в Firefox, и найдите параметр intl.locale.requested (обратите внимание на версию Firefox: в версиях до Firefox 59 этот параметр называется general.useragent.locale).
  2. +
  3. Если параметр существует, нажмите на него дважды (или нажмите Return/Enter), чтобы выбрать его, введите языковой код локализации, которую Вы хотите протестировать и нажмите "OK" (или Return/Enter). Например, в нашем примере расширение поддерживает "en" (английский), "de" (немецкий), "nl" (голландский), and "ja" (японский). Вы также можете указать пустую строку ("") в качестве значения. В этом случае браузер выберет язык Вашей ОС по умолчанию.
  4. +
  5. Если параметр intl.locale.requested не существует, нажмите правой кнопкой мыши на список параметров (или откройте контекстное меню при помощи клавиатуры), и выберите "New", а затем "String". Введите intl.locale.requested как имя настройки и, "de", "nl", и т. д. как значение, как это описано в шаге 2.
  6. +
  7. Найдите intl.locale.matchOS и, если параметр существует и равен true, дважды нажмите на него и установите на false.
  8. +
  9. Перезапустите браузер, чтобы изменения вступили в силу.
  10. +
+ +
+

Примечание: Этот метод работает, даже если у Вас не установлен языковой пакет для выбранного языка. В этом случае UI браузера просто будет использовать Ваш язык по умолчанию.

+
+ +
    +
+ +
+

Примечание: Чтобы изменить результат getUILanguage требуется языковой пакет, поскольку он отражает язык UI браузера, а не язык сообщений расширения.

+
+ +

Еше раз загрузите расширение с диска и протестируйте локализацию:

+ + + +

{{EmbedYouTube("R7--fp5pPGg")}}

diff --git a/files/ru/mozilla/add-ons/webextensions/modify_a_web_page/index.html b/files/ru/mozilla/add-ons/webextensions/modify_a_web_page/index.html new file mode 100644 index 0000000000..0f58364706 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/modify_a_web_page/index.html @@ -0,0 +1,238 @@ +--- +title: Модификация веб страницы +slug: Mozilla/Add-ons/WebExtensions/модификация_веб_страницы +translation_of: Mozilla/Add-ons/WebExtensions/Modify_a_web_page +--- +

 

+ +
{{AddonSidebar}}
+ +

Одним из наиболее распространённых вариантов использования расширений является внесение изменение в веб-страницу. К примеру, расширение может изменить стиль, применённый к странице, скрыть существующие или вставить на страницу дополнительные DOM-узлы.

+ +

Существует два способа сделать это используя WebExtensions API:

+ + + +

В любом случае, эти скрипты называются контентными скриптами, и отличаются от других скриптов, которые составляют расширение:

+ + + +

В этой статье мы рассмотрим оба способа загрузки скрипта.

+ +

Модификация страниц, подпадающих под URL-шаблон

+ +

Прежде всего создадим новую директорию, назовём её "modify-page". В этой директории, создадим файл "manifest.json", со следующим содержимым:

+ +
{
+
+  "manifest_version": 2,
+  "name": "modify-page",
+  "version": "1.0",
+
+  "content_scripts": [
+    {
+      "matches": ["https://developer.mozilla.org/*"],
+      "js": ["page-eater.js"]
+    }
+  ]
+
+}
+ +

Ключ content_scripts - это как мы загружаем скрипты на страницы, соответстующие URL-шаблону. В нашем случае, content_scripts говорит браузеру загрузить скрипт "page-eater.js" на все страницы, начинающиеся с https://developer.mozilla.org/.

+ +
+

Поскольку свойство "js" ключа content_scripts это массив, вы можете использовать его, для внедрения более одного скрипта. Если вы сделаете это, страницы получат набор, как если бы эти скрипты были загружены самой страницей, они будут загружены в той же очерёдности, в которой они расположены в массиве.

+
+ +
+

Ключ content_scripts также имеет свойство  "css", которое вы можете использовать для вставки CSS-таблиц.

+
+ +

Далее, создадим файл "page-eater.js", внутри директории "modify-page":

+ +
document.body.textContent = "";
+
+var header = document.createElement('h1');
+header.textContent = "Эта страница была съедена";
+document.body.appendChild(header);
+ +

Теперь установим расширение, и перейдём на страницу https://developer.mozilla.org/:

+ +

{{EmbedYouTube("lxf2Tkg6U1M")}}

+ +
+

Обратите внимание, несмотря на то, что в указанном видео, на странице addons.mozilla.org всё работает нормально, на текущий момент, для этого сайта, контентные скрипты заблокированы.

+
+ +

Программная модификация страницы

+ +

Что, если вы всё еще хотите "съедать" страницы, но лишь в тех случаях, когда пользователь попросил об этом? Давайте обновим этот пример таким образом, чтобы мы внедряли контентный скрипт, когда пользователь выбирает соответствующий пункт контентного меню.

+ +

Для начала обновим "manifest.json":

+ +
{
+
+  "manifest_version": 2,
+  "name": "modify-page",
+  "version": "1.0",
+
+  "permissions": [
+    "activeTab",
+    "contextMenus"
+  ],
+
+  "background": {
+    "scripts": ["background.js"]
+  }
+
+}
+ +

Мы удалили ключ content_scripts и добавили два новых:

+ + + +

Давайте создадим этот файл. Создадим новый файл "background.js" в директории "modify-page" и поместим в него следующий код:

+ +
browser.contextMenus.create({
+  id: "eat-page",
+  title: "Съесть эту страницу"
+});
+
+browser.contextMenus.onClicked.addListener(function(info, tab) {
+  if (info.menuItemId == "eat-page") {
+    browser.tabs.executeScript({
+      file: "page-eater.js"
+    });
+  }
+});
+
+ +

В этом скрипте мы создаём элемент контекстного меню, передавая ему определённый идентификатор и заголовок (текст будет отображаться в элементе контекстного меню). Затем мы настраиваем обработчик событий таким образом, чтобы когда пользователь выбирает пункт контекстного меню, осуществлялась проверка, наш ли это элемент eat-page. Если это так - внедряем скрипт "page-eater.js" в текущую вкладку, используя tabs.executeScript() API. Это API опционально принимает идентификатор вкладки, в качестве аргумента. Мы опустили его, это означает, что скрипт будет внедряться в текущую активную вкладку.

+ +

На данном этапе расширение должно иметь следующий вид:

+ +
modify-page/
+    background.js
+    manifest.json
+    page-eater.js
+ +

Теперь перезагрузим расширение, откроем страницу (на этот раз любую) активируем контекстное меню и выберем "Съесть эту страницу":

+ +

{{EmbedYouTube("zX4Bcv8VctA")}}

+ +
+

Обратите внимание, несмотря на то, что в указанном видео, на странице addons.mozilla.org всё работает нормально, на текущий момент, для этого сайта, контентные скрипты заблокированы.

+
+ +

Обмен сообщениями

+ +

Контентные и фоновые скрипты не могут на прямую взаимодействовать друг с другом. Не смотря на это они могут взаимодействовать с помощью обмена сообщениями. Для этого один конец создаёт обработчик сообщений, а другой - может посылать сообщения. В следующей таблице представлены API-интерфейсы, задействованные с каждой стороны:

+ + + + + + + + + + + + + + + + + + + +
В контентном скриптеВ фоновом скрипте
Отправка сообщенияbrowser.runtime.sendMessage()browser.tabs.sendMessage()
Получение сообщенияbrowser.runtime.onMessagebrowser.runtime.onMessage
+ +

Давайте обновим наш пример, чтобы посмотреть, как послать сообщение из фонового скрипта.

+ +

Изменим "background.js" :

+ +
browser.contextMenus.create({
+  id: "eat-page",
+  title: "Съесть эту страницу"
+});
+
+function messageTab(tabs) {
+  browser.tabs.sendMessage(tabs[0].id, {
+    replacement: "Message from the extension!"
+  });
+}
+
+browser.contextMenus.onClicked.addListener(function(info, tab) {
+  if (info.menuItemId == "eat-page") {
+    browser.tabs.executeScript({
+      file: "page-eater.js"
+    });
+
+    var querying = browser.tabs.query({
+      active: true,
+      currentWindow: true
+    });
+    querying.then(messageTab);
+  }
+});
+
+ +

Теперь, после внедрения "page-eater.js", мы используем tabs.query(), чтобы получить текущую открытую вкладку и используем tabs.sendMessage(), для отправки сообщения контентному скрипту, загруженному на этой вкладке. Сообщение несёт полезную нагрузку {replacement: "Message from the extension!"}.

+ +

Далее, обновим "page-eater.js":

+ +
function eatPage(request, sender, sendResponse) {
+  document.body.textContent = "";
+
+  var header = document.createElement('h1');
+  header.textContent = request.replacement;
+  document.body.appendChild(header);
+}
+
+browser.runtime.onMessage.addListener(eatPage);
+
+ +

Теперь, вместо простого "поедания страницы", контентный скрипт ждёт сообщение, используя runtime.onMessage. Когда сообщение получено, контентный скрипт выполняет в точности такой же код, как и а примере ранее, за исключением того, что заменяющий текст берётся из request.replacement.

+ +

Если мы хотим отправить сообщение наоборот, из контентного скрипта в фоновый, настройка будет обратной данному примеру, за исключением того, что мы будем использовать runtime.sendMessage() в контентном скрипте.

+ +
+

Все эти примеры внедряют JavaScript; вы можете программно внедрять стилевые таблицы CSS используя функцию tabs.insertCSS().

+
+ +

Узнать больше

+ + diff --git "a/files/ru/mozilla/add-ons/webextensions/\320\270\320\275\321\202\320\265\321\200\320\275\320\260\321\206\320\270\320\276\320\275\320\260\320\273\320\270\320\267\320\260\321\206\320\270\321\217/index.html" "b/files/ru/mozilla/add-ons/webextensions/\320\270\320\275\321\202\320\265\321\200\320\275\320\260\321\206\320\270\320\276\320\275\320\260\320\273\320\270\320\267\320\260\321\206\320\270\321\217/index.html" deleted file mode 100644 index 36a37820d9..0000000000 --- "a/files/ru/mozilla/add-ons/webextensions/\320\270\320\275\321\202\320\265\321\200\320\275\320\260\321\206\320\270\320\276\320\275\320\260\320\273\320\270\320\267\320\260\321\206\320\270\321\217/index.html" +++ /dev/null @@ -1,405 +0,0 @@ ---- -title: Интернационализация -slug: Mozilla/Add-ons/WebExtensions/Интернационализация -translation_of: Mozilla/Add-ons/WebExtensions/Internationalization ---- -
{{AddonSidebar}}
- -

API WebExtensions предоставляет полезный модуль для интернационализации расширений — i18n. В этой статье мы рассмотрим его особенности и пример его работы. Система для расширений, построенных с помощью API WebExtension, i18n похожа на библиотеки JavaScript для i18n, такие как i18n.js.

- -
-

Расширение, используемое в этой статье в качестве примера, — notify-link-clicks-i18n — доступно на GitHub. Читая последующие секции этой статьи, Вы можете исследовать его исходный код.

-
- -

Структура интернализированного расширения

- -

Интернационализированное расширение может содержать такие же элементы, как и любое другое расширение — фоновые скрипты, встраиваемые скрипты, и т. д. — а также дополнительные инструмены, позволяющие переключаться между разными локализациями. Их можно представить следующим деревом директорий:

- - - -

Давайте отдельно рассмотрим каждый элемент — последующие секции представляют собой шаги, которым стоит следовать во время интернационализации вашего расширения.

- -

Добавление локализованных строк в _locales

- -
-
Вы можете определить тэг языка при помощи инструмента Find  на странице определения языковых тегов. Обратите внимание на то, что при поиске еужно использовать английское название языка
-
- -

Каждая система i18n требует предоставить строки во всех локализациях, которые Вы хотите поддерживать. В расширениях они хранятся в директории  _locales, размещенной внутри корневой директории. Строки каждой локализации (также называемые сообщениями) хранятся в файле messages.json, находящемся в поддиректории _locales, название которой - тег языка локализации.

- -

Стоит заметить, что если тег включает в себя и базовый язык, и его региональный вариант, то по конвенции эти язык и вариант разделяются дефисом: например, "en-US". Однако в поддиректориях _locales, вместо дефиса используется нижнее подчеркивание: "en_US".

- -

Таким образом, в нашем примере существую директории "en" (английский), "de" (немецкий), "nl" (голландский), and "ja" (японский). Внутри каждой из них находится файл messages.json .

- -

Давайте рассмотрим структуру одного из этих файлов (_locales/en/messages.json):

- -
{
-  "extensionName": {
-    "message": "Notify link clicks i18n",
-    "description": "Name of the extension."
-  },
-
-  "extensionDescription": {
-    "message": "Shows a notification when the user clicks on links.",
-    "description": "Description of the extension."
-  },
-
-  "notificationTitle": {
-    "message": "Click notification",
-    "description": "Title of the click notification."
-  },
-
-  "notificationContent": {
-    "message": "You clicked $URL$.",
-    "description": "Tells the user which link they clicked.",
-    "placeholders": {
-      "url" : {
-        "content" : "$1",
-        "example" : "https://developer.mozilla.org"
-      }
-    }
-  }
-}
- -

Это стандартный файл JSON — каждый из его элементов является объектом с именем, содержащим сообщение (message) и описание (description). Оба предмета - строки; $URL$ — это заполнитель, который заменяется подстрокой, когда элемент notificationContent вызывается расширением. Вы научитесь это делать в секции {{anch("Получение сообщений из JavaScript")}}.

- -
-

Примечание: Вы можете найти больше информации о структуре messages.json здесь.

-
- -

Интернационализация manifest.json

- -

Для интернационализации файла manifest.json нужно предпринять несколько шагов.

- -

Получение локализованных строк в манифестах

- -

Ваш файл manifest.json содержит строки, отображаемые пользователю, такие как имя и описание расширения. Если Вы интернационализируете эти строки и поместите их переводы в messages.json, то эти переводы будут отображаться пользователю в зависимости от локализации его браузера.

- -

Чтобы интернационализировать строки, их нужно указывать следующим образом:

- -
"name": "__MSG_extensionName__",
-"description": "__MSG_extensionDescription__",
- -

Здесь мы получаем сообщения, зависящие от локализации браузера, а не просто статические строки.

- -

Чтобы получить строку сообщения, ее нужно указать следующим образом:

- -
    -
  1. Два подчеркивания
  2. -
  3. Строка "MSG"
  4. -
  5. Одно подчеркивание
  6. -
  7. Имя сообщения так как оно указано в messages.json
  8. -
  9. Два подчеркивания
  10. -
- -
__MSG_ + messageName + __
- -

Локализация по умолчанию

- -

Еше одно поле. которое нужно указать в manifest.json — это default_locale:

- -
"default_locale": "en"
- -

Этот параметр устанавливает локализацию по умолчанию, используемую, если расширение не поддерживает локализацию браузера пользователя. Любые сообщения, недоступные в текущей локализации, будут браться из той локализации, которая установлена по умолчанию. There are some more details to be aware of in terms of how the browser selects strings — see {{anch("Выбор локализованной строки")}}.

- -

CSS, зависящий от локализации

- -

Локализованные строки также можно получить из CSS-файлов расширения. Например, Вы можете создать поля CSS, зависящие от локализации, так:

- -
header {
-  background-image: url(../images/__MSG_extensionName__/header.png);
-}
- -

Этот функционал может быть полезен, однако, возможно, для этих целей стоит использовать {{anch("Заранее определенные сообщения")}}.

- -

Получение сообщений из JavaScript

- -

Допустим, Вы добавили сообщения в Ваш manifest.json. Чтобы Ваше расширение начало использовать правильные языки, соответствующие сообщения следует вызывать при помощи JavaScript. API i18n достаточно прост и содержит всего 4 основных метода:

- - - -

В нашем примере notify-link-clicks-i18n , фоновый скрипт содержит следующие строки:

- -
var title = browser.i18n.getMessage("notificationTitle");
-var content = browser.i18n.getMessage("notificationContent", message.url);
- -

Первая из них получает поле notificationTitle message из доступного файла messages.json, соответствующее наиболее подходящей локализации . Вторая строка похожа на первую, но в ней метод принимает URL в качестве второго параметра. Зачем? С помощью этого параметра мы указываем, на что нужно заменить заполнитель $URL$ в поле notificationContent message:

- -
"notificationContent": {
-  "message": "You clicked $URL$.",
-  "description": "Tells the user which link they clicked.",
-  "placeholders": {
-    "url" : {
-      "content" : "$1",
-      "example" : "https://developer.mozilla.org"
-    }
-  }
-}
-
- -

Объект "placeholders"  определяет все заполнители и то, откуда их нужно получать. Заполнитель "url" указывает, что информация о нем должна содержаться в $1 — первое значение, заданное внутри второго параметра getMessage(). Поскольку заролнитель называется "url",  $URL$ используется для его вызова внутри сообщения (то есть для заполнителя "name" нужно использовать $NAME$, и т. д.). Если Вы хотите задать значения нескольких заполнителей, их можно передавать во второй аргумент {{WebExtAPIRef("i18n.getMessage()")}} в виде массива — массив [a, b, c] передает значения $1, $2 и $3, и т. д. внутрь messages.json.

- -

Давайте посмотрим на пример: изначально сообщение notificationContent в файле en/messages.json такое:

- -
You clicked $URL$.
- -

Пусть эта ссылка указывает на https://developer.mozilla.org. После вызова {{WebExtAPIRef("i18n.getMessage()")}}, содержание второго параметра становится доступно в messages.json в качестве значения $1, замещающего $URL$, так как это указано в заполнителе  "url". Таким образом, итоговое значение строки:

- -
You clicked https://developer.mozilla.org.
- -

Прямое использование заполнителей

- -

Переменные ($1, $2, $3, и т. д.) можно вставлять напрямую в сообщения. Например, можно переписать объект "notificationContent" следующим образом:

- -
"notificationContent": {
-  "message": "You clicked $1.",
-  "description": "Tells the user which link they clicked."
-}
- -

Этот метод может показаться более быстрым и простым, но другой способ (использование "placeholders") считается лучшей практикой. Это вызвано тем, что имена заполнителей (например "url") и примеры помогают понять, что означают заполнители — через неделю после написания кода Вы, наверное, забудете, что обозначают заполнители $1$8, что менее вероятно, если заполнители именованы.

- -

Заданные замены

- -

Значения заполнителей можно задавать вручную, если Вы хотите, чтобы каждый раз это значение было одним и тем же, а не определялось переменной в коде. Например:

- -
"mdn_banner": {
-  "message": "For more information on web technologies, go to $MDN$.",
-  "description": "Tell the user about MDN",
-  "placeholders": {
-    "mdn": {
-      "content": "https://developer.mozilla.org/"
-    }
-  }
-}
- -

В этом примере мы сами задаем значение заполнителя, а не получаем его из переменной, такой как $1. Это может быть полезно, если сообщение очень сложное, и Вы хотите разделить значения, чтобы сделать строки более читаемыми. К тому же, доступ к этим значениям можно получить внутри программы.

- -

Вы также можете использовать такие замены для указания частей строки, не нуждающихся в переводе, таких как имена или названия.

- -

Выбор локализованной строки

- -

Локализации могут быть указаны с помощью кода языка, например fr или en. Они также могут содержать региональный код, например en_US или en_GB, описывающий региональный вариант языка. Когда вы запрашиваете строку у системы i18n, системы возвращает ее используя следующий алгоритм:

- -
    -
  1. Если для текущей локализации существует файл messages.json, содержащий требуемую строку, возвращается она.
  2. -
  3. Иначе,если текущая локализация — региональный вариант (например en_US) и существует файл messages.json для этого языка, но без указания региона  (например en), содержащий строку, возвращается она.
  4. -
  5. Иначе, если существует файл messages.json для default_locale, указанной в manifest.json, и этот файл содержит нужную строку, возвращается она.
  6. -
  7. В противном случае возвращается пустая строка.
  8. -
- -

Рассмотрим следующий пример:

- - - -

Пусть default_locale установлен как fr, а текущая локализация браузера — en_GB:

- - - -

Заранее определенные сообщения

- -

Модуль i18n module предоставляет заранее определенные сообщения, которые можно вызвать таким же образом, как мы это делали в разделе {{anch("Интернационализация manifest.json")}}. Например:

- -
__MSG_extensionName__
- -

Заранее определенные сообщения используют такой же синтаксис, за исключением @@ перед именем сообщения, например:

- -
__MSG_@@ui_locale__
- -

Следующая таблица содержит различные заранее определенные сообщения:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Message nameDescription
@@extension_id -

Внутренний UUID расширения. Эту строку можно использовать для создания URL ресурсов внутри расширения.Даже нелокализованные расширения могут использовать это сообщения.

- -

Это сообщения нельзя использовать в manifest.json.

- -

Также стоит заметить, что этот ID — не ID аддона, которое возвращает {{WebExtAPIRef("runtime.id")}}, и которое может быть установлено с помощью ключа applications в manifest.json. Это сгенерированный UUID, содержащийся в URL аддона. Это означает, что данную величину нельзя использовать в качестве параметра extensionId  метода {{WebExtAPIRef("runtime.sendMessage()")}}, или для проверки поля id объекта {{WebExtAPIRef("runtime.MessageSender")}}.

-
@@ui_localeТекущая локализация; эту строку можно использовать для создания URL, зависящих от локализации.
@@bidi_dirНаправления чтения, либо "ltr" для языков, таких как английский, где текст читается слева направо, либо "rtl" для языков, считающихся справа налево, таких как арабский.
@@bidi_reversed_dirЕсли @@bidi_dir имеет значение "ltr", то возвращает "rtl"; иначе "ltr".
@@bidi_start_edgeЕсли @@bidi_dir имеет значение "ltr", то возвращает "left"; иначе "right".
@@bidi_end_edgeЕсли @@bidi_dir имеет значение "ltr", то возвращает "right"; иначе "left".
- -

Возвращаясь к нашему примеру, лучше было бы написать:

- -
header {
-  background-image: url(../images/__MSG_@@ui_locale__/header.png);
-}
- -

Теперь мы можем хранить изображения в директориях поддерживаемых локализаций — en, de, и т. д. — что выглядит логичней.

- -

Давайте рассмотрим пример использования сообщений @@bidi_* в файле CSS:

- -
body {
-  direction: __MSG_@@bidi_dir__;
-}
-
-div#header {
-  margin-bottom: 1.05em;
-  overflow: hidden;
-  padding-bottom: 1.5em;
-  padding-__MSG_@@bidi_start_edge__: 0;
-  padding-__MSG_@@bidi_end_edge__: 1.5em;
-  position: relative;
-}
- -

Для языков, в которых текст читается слева направо, таких как английский, правила CSS, использующие заранее определенные сообщения, сверху задают такие значения:

- -
direction: ltr;
-padding-left: 0;
-padding-right: 1.5em;
-
- -

Для языков, читающихся справа налево, значения будут следующими:

- -
direction: rtl;
-padding-right: 0;
-padding-left: 1.5em;
- -

Тестирование расширения

- -

Начиная с Firefox 45, расширения могут быть временно установлены с диска — подробнее об этом написано в статье Loading from disk. Сделайте это и попробуйте протестировать наше расширение notify-link-clicks-i18n. Перейдите на одну из Ваших любимых страниц и нажмите на ссылку, чтобы проверить, появляется ли сообщения, содержащее URL нажатой ссылки.

- -

Затем измените локализацию Firefox на какую-либо поддерживающуюся расширением, которое Вы хотите протестировать.

- -
    -
  1. Откройте "about:config" в Firefox, и найдите параметр intl.locale.requested (обратите внимание на версию Firefox: в версиях до Firefox 59 этот параметр называется general.useragent.locale).
  2. -
  3. Если параметр существует, нажмите на него дважды (или нажмите Return/Enter), чтобы выбрать его, введите языковой код локализации, которую Вы хотите протестировать и нажмите "OK" (или Return/Enter). Например, в нашем примере расширение поддерживает "en" (английский), "de" (немецкий), "nl" (голландский), and "ja" (японский). Вы также можете указать пустую строку ("") в качестве значения. В этом случае браузер выберет язык Вашей ОС по умолчанию.
  4. -
  5. Если параметр intl.locale.requested не существует, нажмите правой кнопкой мыши на список параметров (или откройте контекстное меню при помощи клавиатуры), и выберите "New", а затем "String". Введите intl.locale.requested как имя настройки и, "de", "nl", и т. д. как значение, как это описано в шаге 2.
  6. -
  7. Найдите intl.locale.matchOS и, если параметр существует и равен true, дважды нажмите на него и установите на false.
  8. -
  9. Перезапустите браузер, чтобы изменения вступили в силу.
  10. -
- -
-

Примечание: Этот метод работает, даже если у Вас не установлен языковой пакет для выбранного языка. В этом случае UI браузера просто будет использовать Ваш язык по умолчанию.

-
- -
    -
- -
-

Примечание: Чтобы изменить результат getUILanguage требуется языковой пакет, поскольку он отражает язык UI браузера, а не язык сообщений расширения.

-
- -

Еше раз загрузите расширение с диска и протестируйте локализацию:

- - - -

{{EmbedYouTube("R7--fp5pPGg")}}

diff --git "a/files/ru/mozilla/add-ons/webextensions/\320\274\320\276\320\264\320\270\321\204\320\270\320\272\320\260\321\206\320\270\321\217_\320\262\320\265\320\261_\321\201\321\202\321\200\320\260\320\275\320\270\321\206\321\213/index.html" "b/files/ru/mozilla/add-ons/webextensions/\320\274\320\276\320\264\320\270\321\204\320\270\320\272\320\260\321\206\320\270\321\217_\320\262\320\265\320\261_\321\201\321\202\321\200\320\260\320\275\320\270\321\206\321\213/index.html" deleted file mode 100644 index 0f58364706..0000000000 --- "a/files/ru/mozilla/add-ons/webextensions/\320\274\320\276\320\264\320\270\321\204\320\270\320\272\320\260\321\206\320\270\321\217_\320\262\320\265\320\261_\321\201\321\202\321\200\320\260\320\275\320\270\321\206\321\213/index.html" +++ /dev/null @@ -1,238 +0,0 @@ ---- -title: Модификация веб страницы -slug: Mozilla/Add-ons/WebExtensions/модификация_веб_страницы -translation_of: Mozilla/Add-ons/WebExtensions/Modify_a_web_page ---- -

 

- -
{{AddonSidebar}}
- -

Одним из наиболее распространённых вариантов использования расширений является внесение изменение в веб-страницу. К примеру, расширение может изменить стиль, применённый к странице, скрыть существующие или вставить на страницу дополнительные DOM-узлы.

- -

Существует два способа сделать это используя WebExtensions API:

- - - -

В любом случае, эти скрипты называются контентными скриптами, и отличаются от других скриптов, которые составляют расширение:

- - - -

В этой статье мы рассмотрим оба способа загрузки скрипта.

- -

Модификация страниц, подпадающих под URL-шаблон

- -

Прежде всего создадим новую директорию, назовём её "modify-page". В этой директории, создадим файл "manifest.json", со следующим содержимым:

- -
{
-
-  "manifest_version": 2,
-  "name": "modify-page",
-  "version": "1.0",
-
-  "content_scripts": [
-    {
-      "matches": ["https://developer.mozilla.org/*"],
-      "js": ["page-eater.js"]
-    }
-  ]
-
-}
- -

Ключ content_scripts - это как мы загружаем скрипты на страницы, соответстующие URL-шаблону. В нашем случае, content_scripts говорит браузеру загрузить скрипт "page-eater.js" на все страницы, начинающиеся с https://developer.mozilla.org/.

- -
-

Поскольку свойство "js" ключа content_scripts это массив, вы можете использовать его, для внедрения более одного скрипта. Если вы сделаете это, страницы получат набор, как если бы эти скрипты были загружены самой страницей, они будут загружены в той же очерёдности, в которой они расположены в массиве.

-
- -
-

Ключ content_scripts также имеет свойство  "css", которое вы можете использовать для вставки CSS-таблиц.

-
- -

Далее, создадим файл "page-eater.js", внутри директории "modify-page":

- -
document.body.textContent = "";
-
-var header = document.createElement('h1');
-header.textContent = "Эта страница была съедена";
-document.body.appendChild(header);
- -

Теперь установим расширение, и перейдём на страницу https://developer.mozilla.org/:

- -

{{EmbedYouTube("lxf2Tkg6U1M")}}

- -
-

Обратите внимание, несмотря на то, что в указанном видео, на странице addons.mozilla.org всё работает нормально, на текущий момент, для этого сайта, контентные скрипты заблокированы.

-
- -

Программная модификация страницы

- -

Что, если вы всё еще хотите "съедать" страницы, но лишь в тех случаях, когда пользователь попросил об этом? Давайте обновим этот пример таким образом, чтобы мы внедряли контентный скрипт, когда пользователь выбирает соответствующий пункт контентного меню.

- -

Для начала обновим "manifest.json":

- -
{
-
-  "manifest_version": 2,
-  "name": "modify-page",
-  "version": "1.0",
-
-  "permissions": [
-    "activeTab",
-    "contextMenus"
-  ],
-
-  "background": {
-    "scripts": ["background.js"]
-  }
-
-}
- -

Мы удалили ключ content_scripts и добавили два новых:

- - - -

Давайте создадим этот файл. Создадим новый файл "background.js" в директории "modify-page" и поместим в него следующий код:

- -
browser.contextMenus.create({
-  id: "eat-page",
-  title: "Съесть эту страницу"
-});
-
-browser.contextMenus.onClicked.addListener(function(info, tab) {
-  if (info.menuItemId == "eat-page") {
-    browser.tabs.executeScript({
-      file: "page-eater.js"
-    });
-  }
-});
-
- -

В этом скрипте мы создаём элемент контекстного меню, передавая ему определённый идентификатор и заголовок (текст будет отображаться в элементе контекстного меню). Затем мы настраиваем обработчик событий таким образом, чтобы когда пользователь выбирает пункт контекстного меню, осуществлялась проверка, наш ли это элемент eat-page. Если это так - внедряем скрипт "page-eater.js" в текущую вкладку, используя tabs.executeScript() API. Это API опционально принимает идентификатор вкладки, в качестве аргумента. Мы опустили его, это означает, что скрипт будет внедряться в текущую активную вкладку.

- -

На данном этапе расширение должно иметь следующий вид:

- -
modify-page/
-    background.js
-    manifest.json
-    page-eater.js
- -

Теперь перезагрузим расширение, откроем страницу (на этот раз любую) активируем контекстное меню и выберем "Съесть эту страницу":

- -

{{EmbedYouTube("zX4Bcv8VctA")}}

- -
-

Обратите внимание, несмотря на то, что в указанном видео, на странице addons.mozilla.org всё работает нормально, на текущий момент, для этого сайта, контентные скрипты заблокированы.

-
- -

Обмен сообщениями

- -

Контентные и фоновые скрипты не могут на прямую взаимодействовать друг с другом. Не смотря на это они могут взаимодействовать с помощью обмена сообщениями. Для этого один конец создаёт обработчик сообщений, а другой - может посылать сообщения. В следующей таблице представлены API-интерфейсы, задействованные с каждой стороны:

- - - - - - - - - - - - - - - - - - - -
В контентном скриптеВ фоновом скрипте
Отправка сообщенияbrowser.runtime.sendMessage()browser.tabs.sendMessage()
Получение сообщенияbrowser.runtime.onMessagebrowser.runtime.onMessage
- -

Давайте обновим наш пример, чтобы посмотреть, как послать сообщение из фонового скрипта.

- -

Изменим "background.js" :

- -
browser.contextMenus.create({
-  id: "eat-page",
-  title: "Съесть эту страницу"
-});
-
-function messageTab(tabs) {
-  browser.tabs.sendMessage(tabs[0].id, {
-    replacement: "Message from the extension!"
-  });
-}
-
-browser.contextMenus.onClicked.addListener(function(info, tab) {
-  if (info.menuItemId == "eat-page") {
-    browser.tabs.executeScript({
-      file: "page-eater.js"
-    });
-
-    var querying = browser.tabs.query({
-      active: true,
-      currentWindow: true
-    });
-    querying.then(messageTab);
-  }
-});
-
- -

Теперь, после внедрения "page-eater.js", мы используем tabs.query(), чтобы получить текущую открытую вкладку и используем tabs.sendMessage(), для отправки сообщения контентному скрипту, загруженному на этой вкладке. Сообщение несёт полезную нагрузку {replacement: "Message from the extension!"}.

- -

Далее, обновим "page-eater.js":

- -
function eatPage(request, sender, sendResponse) {
-  document.body.textContent = "";
-
-  var header = document.createElement('h1');
-  header.textContent = request.replacement;
-  document.body.appendChild(header);
-}
-
-browser.runtime.onMessage.addListener(eatPage);
-
- -

Теперь, вместо простого "поедания страницы", контентный скрипт ждёт сообщение, используя runtime.onMessage. Когда сообщение получено, контентный скрипт выполняет в точности такой же код, как и а примере ранее, за исключением того, что заменяющий текст берётся из request.replacement.

- -

Если мы хотим отправить сообщение наоборот, из контентного скрипта в фоновый, настройка будет обратной данному примеру, за исключением того, что мы будем использовать runtime.sendMessage() в контентном скрипте.

- -
-

Все эти примеры внедряют JavaScript; вы можете программно внедрять стилевые таблицы CSS используя функцию tabs.insertCSS().

-
- -

Узнать больше

- - diff --git "a/files/ru/mozilla/add-ons/webextensions/\320\277\320\265\321\200\320\265\320\262\320\276\320\264/index.html" "b/files/ru/mozilla/add-ons/webextensions/\320\277\320\265\321\200\320\265\320\262\320\276\320\264/index.html" deleted file mode 100644 index 4ceb3eab28..0000000000 --- "a/files/ru/mozilla/add-ons/webextensions/\320\277\320\265\321\200\320\265\320\262\320\276\320\264/index.html" +++ /dev/null @@ -1,218 +0,0 @@ ---- -title: Отладка -slug: Mozilla/Add-ons/WebExtensions/Перевод -tags: - - Firefox - - Mozilla - - Отладка - - Пособие - - Предоставление Веб-страниц -translation_of: Mozilla/Add-ons/WebExtensions/Debugging ---- -
{{AddonSidebar}}
- -
This article explains how you can use the Firefox developer tools to debug extensions built with WebExtension APIs.
- -

An extension can consist of various different pieces — background scripts, popups, options pages, content scripts, sidebars — and you'll need to use a slightly different workflow to debug each piece. So each piece gets a top-level section in this article, and the intention is that these sections can be read in isolation. We'll begin by introducing the Add-on Debugger, which you'll use to debug most of the pieces of your extension.

- - - -

The Add-on Debugger

- -

For most of this article we'll use the Add-on Debugger. To open the Add-on Debugger:

- - - -

You'll then see a new window open. The main Firefox window will be switched into the foreground, so you'll have to click on the new window to bring it in front.

- -

{{EmbedYouTube("G2a65ewjfj0")}}

- -

This new window is sometimes called a "toolbox" and contains the debugging tools we'll use. It has a tabbed interface: the row of tabs along the top lets you switch between the different tools:

- -

- -

In this article we'll use three debugging tools:

- - - -

Debugging background scripts

- -
-

The examples in this section use the "notify-link-clicks-l10n" example extension. If you'd like to play along, you can find this example in the webextensions-examples repository.

-
- -

Background scripts stay loaded for the lifetime of the extension. They're loaded inside an invisible "background page": by default this is an empty HTML document, but you can specify your own HTML content using the "background" key in "manifest.json".

- -

You can debug background scripts using the Add-on Debugger.

- -

In the Add-on Debugger's Console you'll see logged output, including calls to console.log() from your own background scripts and any errors the browser raises as it executes them. Note that at the moment, the console shows all errors raised by the browser, not just errors related to your extensions code.

- -

For example, the notify-link-clicks-i18n example extension logs a message from its background script when it receives a message from one of its content scripts:

- -

{{EmbedYouTube("WDQsBU-rpN0")}}

- -

Using the Console's command line, you can access and modify the objects created by your background scripts.

- -

For example, here we call the notify() function defined in the extension's background script:

- -

{{EmbedYouTube("g-Qgf8Mc2wg")}}

- -

If you switch to the Debugger, you'll see all your extension's background scripts. You can set breakpoints, step through code, and do everything else you'd expect to be able to do in a debugger.

- -

{{EmbedYouTube("MNeaz2jdmzY")}}

- -

If you press the Escape key while you're in the Debugger, the toolbox will be split, with the bottom half now occupied by the Console. While you're at a breakpoint, you can now modify the program's state using the console. See Split console for more on this.

- -

Debugging options pages

- -

Options pages are HTML pages that the extension developer can supply, that contain options for the extension. They are typically displayed in an iframe in the Add-ons Manager (to see the Add-ons Manager, visit the "about:addons" page).

- -

To debug options pages:

- - - -

Any JavaScript sources it includes are then listed in the Debugger:

- -

{{EmbedYouTube("BUMG-M8tFF4")}}

- -
-

This video uses the favourite-colour example extension.

-
- -

You'll also see any messages logged by your code in the Add-on Debugger's Console.

- -

You can also use the Add-on Debugger to debug the page's HTML and CSS. First, though, you need to point the tools at the iframe that hosts the options page. To do this: open the options page, click the icon highlighted in the screenshot below, and select the options page from the drop-down list:

- -

- -

Now switch to the Inspector tab, and you'll be able to examine and edit HTML and CSS for the page:

- -

{{EmbedYouTube("-2m3ubFAU94")}}

- -

Debugging popups

- -

Popups are dialogs that are attached to browser actions or page actions. They are specified using an HTML document that can include CSS and JavaScript sources for styling and behavior. Whenever the popup is visible, you can use the Add-on Debugger to debug its code.

- -

One problem with popups is that if a popup is open and you click outside the popup, the popup is closed and its code is unloaded. This obviously makes them impossible to debug. To suppress this behavior, select Disable Popup Auto-Hide from the Elipsis menu as shown below:

- -

- -

Now, when you open a popup it will stay open until you press Escape.

- -
-

Note: This change applies to built-in browser popups, like the Elipsis menu (...), as well as extension popups.

- -

The setting does not persist across sessions. When you close the window, the setting reverts to auto-hide popups.

-Internally, this button just toggles the ui.popup.disable_autohide preference, which you can toggle manually using about:config.
- -

When the popup is open, its JavaScript sources will be listed in the Debugger. You can set breakpoints and modify the program's internal state:

- -

{{EmbedYouTube("hzwnR8qoz2I")}}

- -
-

This video uses the beastify example extension.

-
- -

You can also use the Add-on Debugger to debug the popup's HTML and CSS. First, though, you need to point the tools at the popup's document. To do this: open the popup, then click the icon highlighted in the screenshot below and select the popup's page from the drop-down list:

- -

Now switch to the Inspector, and you'll be able to examine and edit the popup's HTML and CSS:

- -

{{EmbedYouTube("6lvdm7jaq7Y")}}

- -

Debugging content scripts

- -

You can use the Add-on Debugger to debug background pages, options pages, and popups. However, you can't use it to debug content scripts. This is because, in multiprocess Firefox, content scripts run in a different process from the other parts of your extension. The browser console has similar limitations.

- -

To debug content scripts attached to a web page, use the normal web developer tools for that page:

- - - -

{{EmbedYouTube("f46hMLELyaI")}}

- -

By default, the tools are shown attached to the bottom of browser tab, to reflect the fact that they are attached to this tab. You'll see any output from console.log() statements in your content scripts. You will also see your content scripts listed in the Debugger, where you'll be able to set breakpoints, step through the code, and so on.

- -

{{EmbedYouTube("Hx3GU_fEPeo")}}

- -
-

This video uses the notify-link-clicks-i18n example extension.

-
- -
-

If the developer tools tab was not already open when the content script was injected, sometimes the content script is not listed in the debugger panel. If you experience this, reloading the page with the developer tools tab open should fix the problem.

-
- -

Debugging sidebars

- -

Sidebars are HTML pages opened as a sidebar in the browser UI that the extension developer can supply.

- -

To debug sidebars:

- - - -

Any JavaScript sources it includes are then listed in the Debugger.

- -

You'll also see any messages logged by your code in the Add-on Debugger's Console.

- -

You can also use the Add-on Debugger to debug the page's HTML and CSS. First, though, you need to point the tools at the iframe that hosts the options page. To do this: open the sidebar, click the icon highlighted in the screenshot below, and select the sidebar from the drop-down list:

- -

- -

Debug runtime permission requests

- -

 

- -

Runtime permissions granted in your extension are persistent. Therefore, if you want to test cases where the permission has not been granted you will need to add a feature to programmatically remove the permission, use the Extensions Permission Manager, or give your extension a new ID. For more information, see Retest runtime permission grants in Test permission requests.

- -

 

- -

Debugging developer tools pages & panels

- -

Developer tools are extended by loading a hidden HTML page when devtools are opened and developer tools panels are HTML pages displayed as a developer tool in the browser UI that the extension developer can supply.

- -

To debug the developer tools page:

- - - -

To debug developer tools panels:

- - - -

Any JavaScript sources it includes are then listed in the Debugger.

- -

You'll also see any messages logged by your code in the Add-on Debugger's Console.

- -

You can also use the Add-on Debugger to debug the page's HTML and CSS. First, though, you need to point the tools at the iframe that hosts the options page. To do this: open the sidebar, click the icon highlighted in the screenshot below, and select the sidebar from the drop-down list:

- -

- -

Debugging Browser Restarts

- -

If your extension is active in ways that might be affected by the browser restarting, such as a session being restored, then you may want to do extra testing to ensure your code works as expected in those conditions.

- -

See Testing persistent and restart features for more details.

diff --git a/files/ru/mozilla/developer_guide/introduction/index.html b/files/ru/mozilla/developer_guide/introduction/index.html new file mode 100644 index 0000000000..206d60c40d --- /dev/null +++ b/files/ru/mozilla/developer_guide/introduction/index.html @@ -0,0 +1,24 @@ +--- +title: Введение (альтернативные проекты) +slug: Introduction_(alternate) +translation_of: Mozilla/Developer_guide/Introduction +translation_of_original: Introduction_(alternate) +--- +

Хотя Firefox в значительной степени написан на C++, есть много способов помочь сообществу, не зная C++.

+

Firefox/Thunderbird/ и др.

+

Хотя Firefox и другие продукты Mozilla, построенные на базе кода Mozilla, написаны на C++, у них есть много компонентов, написанных на других языках:

+ +

Для начала ознакомьтесь с основным руководством - почти всё написанное в нём можно применить и к вышеупомянутым проблемам, в том числе поиск багов, с фикса которых можно начать, а также описание системы наставников.

+

Веб сайты

+

Mozilla имеет более 100 различных веб-проектов и инструментов, почти все из которых - проекты с открытым кодом. Есть ресурсы getting started with Mozilla's main web sites, а также mostly-up-to-date list of web development projects с участием Mozilla, и мы постоянно стремимся расширять этот список. В этих списках Вы найдете много интересных проектов и узнаете, как помочь их развитию.

+

Проекты на гитхабе

+

Mozilla github страница содержит более 100 проектов, в которых Вы можете принять участие. Эти проекты разрабатываются с использованием обычной GitHub практики, так что для начала работы над каким-либо проектом Вам нужно лишь форкнуть его. Мы с нетерпением ждем Ваших запросов на мёрдж! Среди этих проектов есть и такие высоко-профильные, как Jetpack и многие другие.

+

Mozilla Mercurial репозитории

+

Многие Mozilla-проекты лежат в своих собственных репозиториях на hg.mozilla.org. Там можно увидеть иерархию директорий проектов, а также какие из них в настоящее время поддерживается (подсказка - не все из них!). В числе таких проектов - многие основные сферы деятельности Mozilla, такие как QA, RelEng, localization, webtools, core developers' user repos и другие.

+

Другие способы принять участие

+

Есть много способов внести свой вклад в сообщество Mozilla, помимо программирования. Если вы хотите принять участие в дизайне, поддержке, переводе, тестировании или в других видах вспомогательной деятельности, см. страницу волонтеров.

diff --git a/files/ru/mozilla/developer_guide/source_code/index.html b/files/ru/mozilla/developer_guide/source_code/index.html new file mode 100644 index 0000000000..f8ea35c33a --- /dev/null +++ b/files/ru/mozilla/developer_guide/source_code/index.html @@ -0,0 +1,9 @@ +--- +title: Работа с исходным кодом Mozilla +slug: Mozilla/Developer_guide/Исходный_код +tags: + - Разработка в Mozilla + - Средний уровень +translation_of: Mozilla/Developer_guide/Source_Code +--- +textex diff --git "a/files/ru/mozilla/developer_guide/\320\270\321\201\321\205\320\276\320\264\320\275\321\213\320\271_\320\272\320\276\320\264/index.html" "b/files/ru/mozilla/developer_guide/\320\270\321\201\321\205\320\276\320\264\320\275\321\213\320\271_\320\272\320\276\320\264/index.html" deleted file mode 100644 index f8ea35c33a..0000000000 --- "a/files/ru/mozilla/developer_guide/\320\270\321\201\321\205\320\276\320\264\320\275\321\213\320\271_\320\272\320\276\320\264/index.html" +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: Работа с исходным кодом Mozilla -slug: Mozilla/Developer_guide/Исходный_код -tags: - - Разработка в Mozilla - - Средний уровень -translation_of: Mozilla/Developer_guide/Source_Code ---- -textex diff --git a/files/ru/mozilla/firefox/releases/1.5/using_firefox_1.5_caching/index.html b/files/ru/mozilla/firefox/releases/1.5/using_firefox_1.5_caching/index.html new file mode 100644 index 0000000000..2db6fe3556 --- /dev/null +++ b/files/ru/mozilla/firefox/releases/1.5/using_firefox_1.5_caching/index.html @@ -0,0 +1,210 @@ +--- +title: Использование кэширования в Firefox 1.5 +slug: Using_Firefox_1.5_caching +translation_of: Mozilla/Firefox/Releases/1.5/Using_Firefox_1.5_caching +--- +
{{FirefoxSidebar}}

 

+ +

Введение

+ +

Firefox 1.5 использует кэширование целых Web-страниц, включая их JavaScript-состояния, в рамках сессии браузера. Переходы по посещённым страницам вперёд-назад не требуют загрузки страниц, а JavaScript-состояния сохраняются. Эта функция, обозначаемая иногда как bfcache (Back-Forward Cache), делает навигацию по страницам очень быстрой. Такое кэшированное состояние сохраняется, пока пользователь не закроет браузер.

+ +

Есть случаи, в которых Firefox не кэширует страницы. Вот некоторые обычные программные причины того, что страница не кэширована:

+ + + +

Эта новая функция кэширования меняет поведение загрузки страницы, так что Web-авторы могут захотеть:

+ + + +

Это позволяют сделать два новых события браузера.

+ +

Новые события браузера

+ +

Если вы используете эти новые события, ваши страницы продолжат правильно отображаться в других браузерах (мы протестировали старые версии Firefox, Internet Explorer, Opera и Safari), а при загрузке в Firefox 1.5 добавится новая функциональность кэширования.

+ +

Примечание: по состоянию на октябрь 2009 года разработческие версии Safari добавили поддержку этих новых событий (см. webkit-баг).

+ +

Стандартное поведение для Web-страниц следующее:

+ +
    +
  1. Пользователь переходит на страницу.
  2. +
  3. По мере загрузки страницы выполняются инлайновые скрипты.
  4. +
  5. Как только страница загрузилась, срабатывает обработчик onload.
  6. +
+ +

Некоторые страницы включают четвёртый шаг. Если страница использует обработчик unload или beforeunload handler, он срабатывает прежде чем пользователь уходит со страницы. Если присутствует обработчик unload, эта страница не будет кэширована.

+ +

Когда пользователь переходит на кэшированную страницу, инлайновые скрипты и обработчик onload не запускаются (шаги 2 и 3), так как в большинстве случаев эффекты этих скриптов были сохранены.

+ +

Если страница содержит скрипты или иное поведение, запускаемое в течение загрузки, которое вы хотите продолжить выполнять каждый раз, когда пользователь заходит на страницу, или если вы хотите знать, когда пользователь заходит на кэшированную страницу, используйте новое событие pageshow.

+ +

Если у вас есть поведение, запускаемое, когда пользователь уходит со страницы, но вы хотите воспользоваться новой функциональностью кэширования, и поэтому не хотите использовать обработчик unload, используйте новое событие pagehide.

+ +

Событие pageshow

+ +

Это событие работает так же, как событие load, но срабатывает каждый раз при загрузке страницы (в то время как событие load в Firefox 1.5 не срабатывает, когда страница загружается из кэша). При первой загрузке страницы событие pageshow срабатывает сразу после события load. Событие pageshow использует булевское свойство persisted, которое выставляется в false при начальной загрузке. Оно выставляется в true, если это не начальная загрузка (то есть когда страница уже кэширована).

+ +

Выполняйте любой JavaScript-код, который должен отработать при каждой загрузке страницы, при срабатывании событий pageshow.

+ +

Вызывая JavaScript-функции в обработчике события pageshow, вы можете обеспечить их вызов при загрузке страницы в браузерах, отличных от Firefox 1.5, вызывая этот обработчик в обработчике события load, как показано в примере ниже.

+ +

Событие pagehide

+ +

Если вы хотите определить поведение, которое происходит, когда пользователь уходит со страницы, но не хотите использовать событие unload (что воспрепятствовало бы кэшированию страницы), вы можете использовать новое событие pagehide. Как и pageshow, событие pagehide использует булевское свойство persisted. Оно выставляется в false, если страница не кэширована в браузере, а в true,— если кэширована. Когда это свойство выставлено в false, обработчик unload, если он есть, вызывается сразу после события pagehide.

+ +

Firefox 1.5 пытается имитировать события загрузки в том же порядке, в каком они срабатывают при начальной загрузке страницы. Фреймы обрабатываются таким же образом, что и документ верхнего уровня. Если страница содержит фреймы, то при загрузке кэшированной страницы:

+ + + +

Кэширование страницы несмотря на обработчики unload и beforeunload

+ +

Если вы хотите использовать события unload или beforeunload, сохранив кэширование страницы, вы можете просто удалить эти события в обработчике события и восстановить их в обработчике pageshow, если возвращаетесь на эту страницу:

+ +
window.addEventListener('pageshow', PageShowHandler, false);
+window.addEventListener('unload', UnloadHandler, false);
+
+function PageShowHandler() {
+	window.addEventListener('unload', UnloadHandler, false);
+}
+
+function UnloadHandler() {
+	window.removeEventListener('unload', UnloadHandler, false);
+}
+
+ +

Пример кода

+ +

Приведённый ниже пример реализует страницу, которая использует обработчики load и pageshow. Поведение этой страницы следующее:

+ + + + + + + +

В этом примере:

+ + + +
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+   "http://www.w3.org/TR/html4/loose.dtd">
+<HTML>
+<head>
+<title>Order query : Firefox 1.5 Example</title>
+<style type="text/css">
+body, p {
+	font-family: Verdana, sans-serif;
+	font-size: 12px;
+   	}
+</style>
+<script type="text/javascript">
+function onLoad() {
+	loadOnlyFirst();
+	onPageShow();
+}
+
+function onPageShow() {
+//вычисление текущего времени
+	var currentTime= new Date();
+	var year=currentTime.getFullYear();
+	var month=currentTime.getMonth()+1;
+	var day=currentTime.getDate();
+	var hour=currentTime.getHours();
+	var min=currentTime.getMinutes();
+	var sec=currentTime.getSeconds();
+	var mil=currentTime.getMilliseconds();
+	var displayTime = (month + "/" + day + "/" + year + " " +
+		hour + ":" + min + ":" + sec + ":" + mil);
+	document.getElementById("timefield").value=displayTime;
+}
+
+function loadOnlyFirst() {
+	document.zipForm.name.focus();
+}
+</script>
+</head>
+<body onload="onLoad();" onpageshow="if (event.persisted) onPageShow();">
+<h2>Order query</h2>
+
+<form name="zipForm" action="http://www.example.com/formresult.html" method="get">
+<label for="timefield">Date and time:</label>
+<input type="text" id="timefield"><br>
+<label for="name">Name:</label>
+<input type="text" id="name"><br>
+<label for="address">Email address:</label>
+<input type="text" id="address"><br>
+<label for="order">Order number:</label>
+<input type="text" id="order"><br>
+<input type="submit" name="submit" value="Submit Query">
+</form>
+</body>
+</html>
+
+ +

Напротив, если приведённая выше страница не слушает событие pageshow и выполняет все вычисления в обработчике события load (если код написан так, как показано в примере ниже), как положение курсора, так и дата/время в Firefox 1.5 будут кэшированы, когда пользователь when the user navigated away from the page. When the user returned to the page, the cached date/time would display.

+ +
<script>
+function onLoad() {
+	loadOnlyFirst();
+
+//calculate current time
+	var currentTime= new Date();
+	var year = currentTime.getFullYear();
+	var month = currentTime.getMonth()+1;
+	var day = currentTime.getDate();
+	var hour=currentTime.getHours();
+	var min=currentTime.getMinutes();
+	var sec=currentTime.getSeconds();
+	var mil=currentTime.getMilliseconds();
+	var displayTime = (month + "/" + day + "/" + year + " " +
+		hour + ":" + min + ":" + sec + ":" + mil);
+	document.getElementById("timefield").value=displayTime;
+}
+
+function loadOnlyFirst() {
+	document.zipForm.name.focus();
+}
+</script>
+</head>
+
+<body onload="onLoad();">
+
+ +

Developing Firefox extensions

+ +

Firefox 1.5 extensions need to allow for this caching functionality. If you are developing a Firefox extension that you want to be compatible with both 1.5 and earlier versions, make sure that it listens for the load event for triggers that can be cached and listens for the pageshow event for triggers that shouldn’t be cached.

+ +

For instance, the Google Toolbar for Firefox should listen for the load event for the autolink function and to the pageshow event for the PageRank function in order to be compatible with both 1.5 and earlier versions.

+ +

{{ languages( { "it": "it/Usare_il_caching_di_Firefox_1.5", "de": "de/Benutzen_des_Zwischenspeichers_in_Firefox_1.5_(caching)", "fr": "fr/Utilisation_du_cache_de_Firefox_1.5", "ja": "ja/Using_Firefox_1.5_caching" } ) }}

diff --git a/files/ru/mozilla/firefox/releases/3.5/index.html b/files/ru/mozilla/firefox/releases/3.5/index.html new file mode 100644 index 0000000000..a3e9f4c276 --- /dev/null +++ b/files/ru/mozilla/firefox/releases/3.5/index.html @@ -0,0 +1,312 @@ +--- +title: Firefox 3.5 для разработчика +slug: Firefox_3.5_для_разработчика +translation_of: Mozilla/Firefox/Releases/3.5 +--- +
{{FirefoxSidebar}}

Firefox 3.5 вводит ряд новых возможностей, а также дополнительную и улучшенную поддержку для самых различных веб-стандартов. Данная статья представляет собой исчерпывающий перечень нововведений со ссылками на статьи, освещающие основные усовершенствования.

+

Новые возможности для разработчиков

+

Для разработчиков веб-сайтов и веб-приложений

+

Поддержка HTML 5

+
+
+ Использование аудио и видео
+
+ В Firefox 3.5 добавлена поддержка элементов HTML 5 audio и video.
+
+ Offline resources in Firefox
+
+ Firefox 3.5 now fully supports the HTML 5 offline resource specification.
+
+ Drag and drop
+
+ The HTML 5 drag and drop API allows support for dragging and dropping items within and between web sites.  This also provides a simpler API for use by extensions and Mozilla-based applications.
+
+

Newly-supported CSS features

+
+
+ Downloadable fonts support
+
+ The new {{ cssxref("@font-face") }} @rule lets web pages provide downloadable fonts, so that sites can be rendered exactly as the page author expects.
+
+ CSS media queries
+
+ Firefox 3.5 now supports CSS media queries, which enhance support for media-dependent style sheets.
+
+ {{ cssxref(":before") }} and {{ cssxref(":after") }} updated to CSS 2.1
+
+ The :before and :after pseudo-elements have been updated to full CSS 2.1 support, adding support for the position, float, list-style-*, and some display properties.
+
+ ch units for length
+
+ The ch unit can now be used anywhere that accepts a unit of length. 1ch is the width of the "0" (zero) character.
+
+ {{ cssxref("opacity") }}
+
+ The -moz-opacity Mozilla extension to CSS has been removed in favor of the standard opacity property.
+
+ {{ cssxref("text-shadow") }}
+
+ The text-shadow property, which allows web content to specify shadow effects to apply to text and text decorations, is now supported.
+
+ {{ cssxref("word-wrap") }}
+
+ This newly-supported property lets content specify whether or not lines may be broken within words in order to prevent overflow when an otherwise unbreakable string is too long to fit on one line.
+
+ white-space property supports the pre-line value
+
+ The {{ cssxref("white-space") }} property now accepts the pre-line value.
+
+ {{ cssxref("-moz-box-shadow") }}
+
+ {{ cssxref("-moz-border-image") }}
+
+ {{ cssxref("-moz-column-rule") }}
+
+ {{ cssxref("-moz-column-rule-width") }}
+
+ {{ cssxref("-moz-column-rule-style") }}
+
+ {{ cssxref("-moz-column-rule-color") }}
+
+ Firefox 3.5 adds support for these Mozilla extensions to CSS.
+
+ The {{ cssxref("color_value#Mozilla_Extensions","-moz-nativehyperlinktext") }} color value
+
+ This new color value represents the user's system's default hyperlink color.
+
+ The {{ cssxref("-moz-window-shadow") }} property and the {{ cssxref(":-moz-system-metric(mac-graphite-theme)") }} pseudo-class
+
+ These new CSS features were added to facilitate theming.
+
+ New values for {{ cssxref("-moz-appearance") }}
+
+ The -moz-win-glass and -moz-mac-unified-toolbar values have been added to -moz-appearance.
+
+ Using CSS transforms
+
+ Firefox 3.5 supports CSS transforms.  See {{ cssxref("-moz-transform") }} and {{ cssxref("-moz-transform-origin") }} for details.
+
+ {{ cssxref(":nth-child") }}
+
+ {{ cssxref(":nth-last-child") }}
+
+ {{ cssxref(":nth-of-type") }}
+
+ {{ cssxref(":nth-last-of-type") }}
+
+ {{ cssxref(":first-of-type") }}
+
+ {{ cssxref(":last-of-type") }}
+
+ {{ cssxref(":only-of-type") }}
+
+ These selectors are all newly-supported in Firefox 3.5.
+
+

Новые возможности DOM

+
+
+ localStorage
+
+ Firefox 3.5 adds support for the Web Storage localStorage property, which provides a way for web applications to store data locally on the client's computer.
+
+ Using web workers
+
+ Firefox 3.5 supports web workers to allow easy multi-threading support in web applications.
+
+ Using geolocation
+
+ Firefox 3.5 supports the Geolocation API, which allows web applications to obtain information about the user's current location if a provider for that information is installed and enabled.
+
+ Locating DOM elements using selectors
+
+ The selectors API allows querying a document to locate the elements that match a given selection rule.
+
+ Mouse gesture events
+
+ Firefox 3.5 supports mouse gesture events such as trackpad swipes.
+
+ The NodeIterator object
+
+ The NodeIterator object provides support for iterating over the list of the nodes in a DOM subtree.
+
+ The MozAfterPaint event
+
+ This new DOM event is sent after painting updates in windows.
+
+ The MozMousePixelScroll event
+
+ This new DOM event allows detection of pixel-based mouse scroll wheel events instead of line-based scroll events.
+
+

Новые возможности JavaScript

+
+
+ Новое в JavaScript 1.8.1
+
+ Обзор всех изменений в JavaScript 1.8.1.
+
+ Object.getPrototypeOf()
+
+ Новый метод, возвращающий прототип указанного объекта.
+
+ Использование встроенного JSON
+
+ Firefox 3.5 имеет встроенную поддержку JSON.
+
+ Новые методы обрезки строк в объекте String
+
+ Объект String теперь имеет методы trim(), trimLeft() и trimRight().
+
+

Networking

+
+
+ Cross-site access controls for HTTP
+
+ In Firefox 3.5, it's now possible for HTTP requests, including those made by XMLHttpRequest, to work across domains if the server supports it.
+
+ Progress events for XMLHttpRequest
+
+ Progress events are now offered to enable extensions to monitor the progress of requests.
+
+ Improved Synchronous XMLHttpRequest support
+
+ DOM Timeout and Input Events are now suppressed during a synchronous XMLHttpRequest.
+
+ Controlling DNS prefetching
+
+ Firefox 3.5 provides DNS prefetching, whereby it performs domain name resolution ahead of time for links included in the current page, in order to save time when links are actually clicked.  This article describes how you can tune your web site to disable prefetching, or to adjust how prefetching operates.
+
+

New Canvas features

+
+
+ HTML 5 text API for canvas elements
+
+ Canvas elements now support the HTML 5 text API.
+
+ Shadow effects in a canvas
+
+ Canvas shadow effects are now supported.
+
+ createImageData()
+
+ The canvas method createImageData() is now supported, allowing code to specifically create an ImageData object instead of requiring it to be done automatically. This can improve performance of other ImageData methods by preventing them from having to create the object.
+
+ moz-opaque attribute
+
+ Added the moz-opaque DOM attribute, which lets the canvas know whether or not translucency will be a factor.  If the canvas knows there's no translucency, painting performance can be optimized.
+
+

New SVG features

+
+
+ Applying SVG effects to HTML content
+
+ You can now apply SVG effects to HTML and XHTML content; this article describes how.
+
+

Miscellaneous new features

+
+
+ ICC color correction in Firefox
+
+ Firefox 3.5 now supports ICC color correction for tagged images.
+
+ The defer attribute is now supported on script elements
+
+ This attribute indicates to the browser that it may choose to continue to parse and render the page without waiting for the script to finish executing.
+
+

Другие улучшения

+ +

Для разработчиков дополнений

+

If you're an extension developer, you should start by reading Updating extensions for Firefox 3.5, which offers a helpful overview of what changes may affect your extension.

+

New components and functionality

+
+
+ Supporting private browsing mode
+
+ Firefox 3.5 offers Private Browsing mode, which doesn't record the user's activities.  Extensions may support private browsing following the guidelines offered by this article.
+
+ Security changes in Firefox 3.5
+
+ This article covers security-related changes in Firefox 3.5.
+
+ Theme changes in Firefox 3.5
+
+ This article covers theme-related changes in Firefox 3.5.
+
+ Monitoring WiFi access points
+
+ Code with UniversalXPConnect privileges can now monitor the list of available access points, getting information on their SSIDs, MAC addresses, and signal strength.  This can be used in tandem with Geolocation to offer WiFi-based location service.
+
+

Notable changes and improvements

+ +

Новые возможности для конечного пользователя

+

User experience

+
+
+ Location aware browsing
+
+ If you choose, you may allow Firefox 3.5 to share information about your current location with web sites.  Firefox 3.5 can use information about the network you're connected to to share your location. Of course, it asks for your permission before doing so, to ensure your privacy.
+
+ Open audio and video support
+
+ Firefox 3.5 supports embedded video and audio using the open Ogg format, as well as WAV for audio. No plugins, no confusing error messages about needing to install something or other that turns out not to be available on your platform anyway.
+
+ Local data storage
+
+ Web applications can now use Web Storage's local storage capabilities to store data on your computer.  This is great for anything from site preferences to more complex data.
+
+

Безопасность и приватность

+
+
+ Private Browsing
+
+ Need to use someone else's computer? Switch on Private Browsing mode and nothing will be recorded about your session, including cookies, history, and any other potentially private information.
+
+ Better privacy controls
+
+ The Privacy preference pane has been completely redesigned to offer users more control over their private information. Users can choose to retain or discard anything including history information, cookies, downloads, and form field information.  In addition, users can specify whether or not to include history and/or bookmarks in the location bar's automated suggestions, so you can keep private web addresses from popping up unexpectedly while typing in the location bar.
+
+

Производительность

+
+
+ Faster JavaScript performance
+
+ JavaScript, the "J" in "AJAX," is sped up dramatically in Firefox 3.5 with the new TraceMonkey JavaScript engine.  Web applications are much faster than in Firefox 3.
+
+ Faster page rendering
+
+ Web content draws faster in Firefox 3.5, thanks to technologies such as "speculative parsing." Your users don't need to know what it means, other than "it makes things draw faster."
+
+

Смотрите также

+ diff --git a/files/ru/mozilla/firefox/releases/3/index.html b/files/ru/mozilla/firefox/releases/3/index.html new file mode 100644 index 0000000000..98537faee9 --- /dev/null +++ b/files/ru/mozilla/firefox/releases/3/index.html @@ -0,0 +1,299 @@ +--- +title: Firefox 3 для разработчиков +slug: Firefox_3_for_developers +translation_of: Mozilla/Firefox/Releases/3 +--- +
{{FirefoxSidebar}}

Если вы разработчик и хотите познакомится со всеми возможностями Firefox 3 вы пришли по адресу. В этой статье представлен список новых статей, в которых рассказывается о новых возможностях Firefox 3. В статьях не будут представлены сведения о незначительных изменениях, однако они помогут вам познакомится с существенными обновлениями.

+

Новые возможности для разработчиков в Firefox 3

+

Для веб-мастеров и разработчиков приложений

+
+
+ Обновление веб-приложений для Firefox 3
+
+ Предоставляет информацию об изменениях которые вам возможно нужно внести, чтобы получить выгоду от новых возможностей Firefox 3.
+
+
+
+ Online и offline события
+
+ Firefox 3 поддерживает WHATWG online и offline события, которые позволяют приложениям и расширениям определять есть ли активное Интернет соединение, и так же позволяет определять когда появляется и пропадает соединение.
+
+
+
+ Веб-ориентированные обработчики протоколов
+
+ Теперь вы можете регистрировать веб-приложения как обработчик протокола используя метод navigator.registerProtocolHandler().
+
+
+
+ Рисование текста с использованием canvas
+
+ Теперь вы можете рисовать текст с ипользованием нестандартизированного API canvas поддерживаемого Firefox 3.
+
+
+
+ Поддержка преобразований для canvas
+
+ Firefox now supports the transform() and setTransform() methods on canvases.
+
+
+
+ Using microformats
+
+ Firefox now has APIs for working with microformats.
+
+
+
+ Drag and drop events
+
+ Firefox 3 supports new events that are sent to the source node for a drag operation when the drag begins and ends.
+
+
+
+ Focus management in HTML
+
+ The new HTML 5 activeElement and hasFocus attributes are supported.
+
+
+
+ Offline resources in Firefox
+
+ Firefox now lets web applications request that resources be cached to allow the application to be used while offline.
+
+
+
+ CSS improvements in Firefox 3
+
+ Firefox 3 features a number of improvements in its CSS support.
+
+
+
+ DOM improvements in Firefox 3
+
+ Firefox 3 offers a number of new features in Firefox 3's DOM implementation, including support for several Internet Explorer extensions to the DOM.
+
+
+
+ JavaScript 1.8 support
+
+ Firefox 3 offers JavaScript 1.8.
+
+
+
+ EXSLT support
+
+ Firefox 3 provides support for a substantial subset of the EXSLT extensions to XSLT.
+
+
+
+ SVG improvements in Firefox 3
+
+ SVG support in Firefox 3 has been upgraded significantly, with support for over two dozen new filters, several new elements and attributes, and other improvements.
+
+
+
+ Animated PNG graphics
+
+ Firefox 3 supports the animated PNG (APNG) image format.
+
+

For XUL and extension developers

+
Notable changes and improvements
+
+
+ Updating extensions for Firefox 3
+
+ Provides a guide to the things you'll need to do to update your extension to work with Firefox 3.
+
+
+
+ XUL improvements in Firefox 3
+
+ Firefox 3 offers a number of new XUL elements, including new sliding scales, the date and time pickers, and spin buttons.
+
+
+
+ Templates in Firefox 3
+
+ Templates have been significantly improved in Firefox 3. The key improvement allows the use of custom query processors to allow data sources other than RDF to be used.
+
+
+
+ Securing updates
+
+ In order to provide a more secure add-on upgrade path for users, add-ons are now required to provide a secure method for obtaining updates before they can be installed. Add-ons hosted at AMO automatically provide this. Any add-ons installed that do not provide a secure update method when the user upgrades to Firefox 3 will be automatically disabled. Firefox will however continue to check for updates to the extension over the insecure path and attempt to install any update offered (installation will fail if the update also fails to provide a secure update method).
+
+
+
+ Places migration guide
+
+ An article about how to update an existing extension to use the Places API.
+
+
+
+ Download Manager improvements in Firefox 3
+
+ The Firefox 3 Download Manager features new and improved APIs, including support for multiple progress listeners.
+
+
+
+ Using nsILoginManager
+
+ The Password Manager has been replaced by the new Login Manager.
+
+
+
+ Embedding XBL bindings
+
+ You can now use the data: URL scheme from chrome code to embed XBL bindings directly instead of having them in separate XML files.
+
+
+
+ Localizing extension descriptions
+
+ Firefox 3 offers a new method for localizing add-on metadata. This lets the localized details be available as soon as the add-on has been downloaded, as well as when the add-on is disabled.
+
+
+
+ Localization and Plurals
+
+ Firefox 3 adds the new PluralForm module, which provides tools to aid in correctly pluralizing words in multiple localizations.
+
+
+
+ Theme changes in Firefox 3
+
+ Notes and information of use to people who want to create themes for Firefox 3.
+
+
New components and functionality
+
+
+ FUEL Library
+
+ FUEL is about making it easier for extension developers to be productive, by minimizing some of the XPCOM formality and adding some "modern" JavaScript ideas.
+
+
+
+ Places
+
+ The history and bookmarks APIs have been completely replaced by the new Places API.
+
+
+
+ Idle service
+
+ Firefox 3 offers the new {{ Interface("nsIIdleService") }} interface, which lets extensions determine how long it's been since the user last pressed a key or moved their mouse.
+
+
+
+ ZIP writer
+
+ The new {{ Interface("nsIZipWriter") }} interface lets extensions create ZIP archives.
+
+
+
+ Full page zoom
+
+ Firefox 3 improves the user experience by offering full page zoom in addition to text-only zoom.
+
+
+
+ Interfacing with the XPCOM cycle collector
+
+ XPCOM code can now take advantage of the cycle collector, which helps ensure that unused memory gets released instead of leaking.
+
+
+
+ The Thread Manager
+
+ Firefox 3 provides the new {{ Interface("nsIThreadManager") }} interface, along with new interfaces for threads and thread events, which provides a convenient way to create and manage threads in your code.
+
+
+
+ JavaScript modules
+
+ Firefox 3 now offers a new shared code module mechanism that lets you easily create modules in JavaScript that can be loaded by extensions and applications for use, much like shared libraries.
+
+
+
+ The nsIJSON interface
+
+ Firefox 3 offers the new {{ Interface("nsIJSON") }} interface, which offers high-performance encoding and decoding of JSON strings.
+
+
+
+ The nsIParentalControlsService interface
+
+ Firefox 3 now supports the Microsoft Windows Vista parental controls feature, and allows code to interact with it.
+
+
+
+ Using content preferences
+
+ Firefox 3 includes a new service for getting and setting arbitrary site-specific preferences that extensions as well as core code can use to keep track of their users' preferences for individual sites.
+
+
+
+ Plug-in Monitoring
+
+ A new component of the plugin system is now available to measure how long it takes plugins (e.g., Macromedia Flash) to execute their calls.
+
+
Fixed bugs
+
+
+ Notable bugs fixed in Firefox 3
+
+ This article provides information about bugs that have been fixed in Firefox 3.
+
+

New features for end users

+

User experience

+ +

Security and privacy

+ +

Performance

+ +

See also

+ +

{{ languages( { "es": "es/Firefox_3_para_desarrolladores", "fr": "fr/Firefox_3_pour_les_d\u00e9veloppeurs", "ja": "ja/Firefox_3_for_developers", "zh-tw": "zh_tw/Firefox_3_for_developers", "ko": "ko/Firefox_3_for_developers", "pl": "pl/Firefox_3_dla_programist\u00f3w", "pt": "pt/Firefox_3_para_desenvolvedores" } ) }}

diff --git a/files/ru/orphaned/glossary/polifill/index.html b/files/ru/orphaned/glossary/polifill/index.html new file mode 100644 index 0000000000..caffde4878 --- /dev/null +++ b/files/ru/orphaned/glossary/polifill/index.html @@ -0,0 +1,13 @@ +--- +title: Полифил +slug: Glossary/Polifill +tags: + - Glossary + - Глоссарий + - Словарь +--- +

Полифил (англ. "polyfill") — это фрагмент кода, предоставляющий функционал необходимой технологии, которая будет нативным образом представлена браузером. Другими словами, код будет работать в точности так, как технология, которую он, собственно, и предназначен представлять. Подделка архитектуры API интерфейса, если вам угодно.

+ +

Ссылки

+ +

Что такое полифил? http://webknowledge.ru/chto-takoe-polyfill/

diff --git a/files/ru/orphaned/learn/how_to_contribute/index.html b/files/ru/orphaned/learn/how_to_contribute/index.html new file mode 100644 index 0000000000..caed3b7970 --- /dev/null +++ b/files/ru/orphaned/learn/how_to_contribute/index.html @@ -0,0 +1,85 @@ +--- +title: Как сделать вклад в Обучающую Зону MDN +slug: Learn/Как_сделать_вклад +tags: + - Вклад + - Документация + - Новичку + - Новичок + - Обучение + - Правила + - Руководство +translation_of: Learn/How_to_contribute +--- +
{{LearnSidebar}}
+ +

Оказались ли вы здесь впервые или в результате глубокого поиска, вас, вероятно, привело сюда желание помочь Обучающей Зоне MDN. И это отличная новость!

+ +

На этой странице вы найдёте всё необходимое для того, чтобы помочь улучшить обучающий контент MDN. Здесь есть много вещей, которые вы можете сделать, в зависимости от того, сколько времени у вас есть и кем вы являетесь новичком, веб-разработчиком или учителем.

+ +
+

Руководство по написанию новой статьи в обучающем пространстве можно посмотреть на странице How to write an article to help people learn about the Web.

+
+ +

Найдите конкретные задачи

+ +

Для организации своих задач участники сообщества используют Trello board. Там вы можете найти конкретные задачи проекта, ожидающие выполнения. Если вы хотите использовать её, просто создайте Trello аккаунт и напишите Chris Mills, чтобы он дал доступ к записи на доску.

+ +

Принятие участия - это также отличный способ повеселиться, одновременно изучая новое. Если вы запутались или у вас есть вопросы, не стесняйтесь написать нам в наш список рассылки или IRC канал (подробности указаны внизу этой страницы). Chris Mills заведует Обучающей Зоной — вы также можете попробовать написать ему напрямую.

+ +

В следующих разделах описаны некоторые идеи касательно задач, которыми вы могли бы заняться.

+ +

Я новичок

+ +

Это круто! Новички очень важны для создания и предоставления отзывов об материалах для обучения. Ваш уникальный взгляд представителя целевой аудитории данных статей может сделать вас бесценным участником нашей команды. В самом деле, если вы "застряли" в процессе изучения какой-либо темы по одной из наших статей, или находите эту статью в некотором роде запутанной, вы можете либо исправить её сами, либо сообщить об этой проблеме нам, чтобы мы позаботились о её исправлении.

+ +

Вот как, например, вы можете помочь:

+ +
+
Добавьте теги к нашим статьям (5 мин)
+
Добавление тегов к контенту MDN - один из самых легких способов внести свой вклад. Помощь в этом направлении очень ценна, поскольку теги широко применяются в MDN, чтобы вписать информацию в контекст. Начать можно с просмотра списков словарных и обучающих статей.
+
Прочитайте и проверьте статью в словаре (5 мин)
+
Нам очень важен ваш взгляд, как начинающего, на наш контент. Если вы считаете, что статья в словаре слишком сложна, значит, её необходимо улучшить. Не стесняйтесь вносить любые необходимые, на ваш взгляд, изменения. Если вам кажется, что у вас недостаточно навыков, чтобы самостоятельно отредактировать статью, можете сообщить нам о ней в нашем списке рассылки.
+
Напишите новую статью для словаря (20 минут)
+
Это самый эффективный способ узнать что-то новое. Выберите понятие, которое вам хотелось бы изучить, и в процессе изучения пишите о нем статью для словаря. Объяснить какую-либо вещь другим - отличный способ закрепить знание в голове, и разобраться самому, при этом помогая другим. Everybody wins!
+
Прочитайте и проверьте обучающую статью (2 часа)
+
Эта задача очень похожа на проверку статей в словаре (см. выше), она лишь занимает больше времени, поскольку обычно такие статьи значительно длиннее.
+
+ +

Я веб-разработчик

+ +

Фантастика! Ваши технические навыки - именно то, что помогает нам убедиться в технической точности контента для новичков. Поскольку данная конкретная часть MDN посвящена обучению Вебу, постарайтесь делать ваши объяснения максимально простыми, но не чересчур простыми, они не должны стать бесполезны. Понятность важнее, чем чрезмерная точность.

+ +
+
Прочитайте и проверьте статью в словаре (5 мин)
+
Нам важно, чтобы вы, как веб-разработчик, убедились в том, что наш контент технически точен, но при этом не слишком сложен. Не стесняйтесь делать любые изменения, которые вам покажутся нужными. Если вы хотите обсудить контент до того, как приступать к редактированию, напишите нам в список рассылки или IRC канал.
+
Напишите новую статью для словаря (20 минут)
+
Разъяснение технического жаргона - хороший способ научиться быть одновременно технически точным и простым. Новички будут вам за это благодарны. У нас есть много терминов без определений, которые нуждаются в вашем внимании. Выберите один и приступайте!
+
Прочитайте и проверьте обучающую статью (2 часа)
+
Это тоже самое, что и проверка статьи в словаре (см.выше), но занимает больше времени, поскольку обычно такие статьи значительно длиннее.
+
Напишите новую обучающую статью (4 часа или больше)
+
MDN не хватает ясных и доходчивых статей об использовании веб-технологий (HTML, CSS, JavaScript, и т.д). Кроме того, у нас есть старый контент, который нуждается в редактуре и изменениях. Доведите ваши умения до предела, чтобы сделать веб-технологии пригодными для использования даже начинающими.
+
Создайте упражнения, примеры кода или интерактивные обучающие инструменты (? часов)
+
Все наши обучающие статьи требуют материалов, как мы это называем, "активного обучения", так как эффективнее всего люди учатся, выполняя что-либо самостоятельно. Под такого рода материалами подразумеваются упражнения или интерактивный контент, которые помогают пользователю применять и оперировать понятиями, описанными в статье. Существует множество способов создания контента активного обучения, от написания образцов кода с помощью JSFiddle или подобных инструментов, до построения fully hackable интерактивного контента в Thimble. Раскройте ваш творческий потенциал!
+
+ +

Я учитель

+ +

У MDN долгая история совершенствования в техническом плане, но нам не хватает глубины понимания того, как лучше обучать новичков. Именно на этом этапе мы нуждаемся в вас, как в преподавателях и педагогах. Вы можете помочь нам гарантировать, что наши материалы обеспечивают хороший, практикоориентированный образовательный путь для наших читателей.

+ +
+
Прочитайте и проверьте статью в словаре (15 мин)
+
Просмотрите словарную статью и не стесняйтесь вносить любые необходимые, на ваш взгляд, изменения. Если вы хотели бы обсудить контент перед тем, как редактировать, напишите нам в наш список рассылки или IRC канал.
+
Напишите новую статью для словаря (1 час)
+
Новички очень нуждаются в ясных, простых определениях терминов и базовом обзоре понятий в словаре. Ваш педагогический опыт может помочь нам создать превосходные словарные статьи; у нас есть множество терминов без определений, которые нуждаются в вашем внимании. Выбирайте один из них и приступайте.
+
Добавьте илллюстрации и/или схемы в статью (1 час)
+
Как вам, наверное, известно, иллюстрации - бесценная часть любого обучающего материала. Зачастую именно их нам не хватает на MDN, и ваши навыки могут улучшить ситуацию в данной области. Посмотрите список статей, у которых отсутствует иллюстративный материал, и выберите одну, к которой вам бы хотелось создать графику.
+
Прочитайте и проверьте обучающую статью (2 часа)
+
Это тоже самое, что и проверка статьи в словаре (см.выше), но занимает больше времени, поскольку обычно такие статьи значительно длиннее.
+
Напишите новую обучающую статью (4 часа)
+
Нам нужны простые, доходчивые статьи о Web экосистеме и прочих практических темах в связанных областях. Поскольку данные обучающие статьи должны быть скорее образовательными, чем охватывать целиком всю имеющуюся информацию, ваш опыт касательно того, что именно нужно осветить и как, будет очень ценен.
+
Создайте упражнения, викторины или интерактивные обучающие инструменты (? часа)
+
Все наши обучающие статьи требуют материалов "активного обучения", то есть упражнений или интерактивного контента, которые помогают пользователю углубиться и научиться использовать концепции, описанные в статье. В этой области вы можете сделать многое, от создания викторин до построения fully hackable интерактивного контента с Thimble. Раскройте вашу творческую сторону!
+
Создайте пути обучения (? часа)
+
Чтобы предоставить прогрессивные и доступные для понимания руководства, нам необходимо объединять контент в пути. Это способ собрать существующий контент и выяснить, чего в нем недостает для написания обучающей статьи.
+
diff --git a/files/ru/orphaned/learn/html/forms/html5_updates/index.html b/files/ru/orphaned/learn/html/forms/html5_updates/index.html new file mode 100644 index 0000000000..ad5a8bc7e6 --- /dev/null +++ b/files/ru/orphaned/learn/html/forms/html5_updates/index.html @@ -0,0 +1,149 @@ +--- +title: Формы в HTML +slug: Web/Guide/HTML/Формы_в_HTML +tags: + - HTML + - HTML5 + - Введение + - Интернет + - Любитель + - Новичок + - Обзор + - Руководство + - Формы +translation_of: Learn/HTML/Forms/HTML5_updates +--- +

Элементы и атрибуты форм в HTML5 предоставляют большие возможности семантической верстки, чем HTML4, а также позволяет отказаться от использования JavaScript и CSS, которое было ранее необходимо для HTML4. Большие возможности в формах HTML5 делают удобным для пользователей отправление информации с различных веб-сайтов. Они также предоставляют эти возможности для тех пользователей, у которых отключена поддержка JavaScript.

+ +

Эта статья описывает изменения в HTML-формах, представленных в HTML5. Для более подробного руководства по использованию формами, просмотрите наше обширное руководство по HTML-формам.

+ +

Элемент <input>

+ +

В элементе {{HTMLElement("input")}} появились новые значения для атрибута {{htmlattrxref("type", "input")}}. (Просмотрите справочник {{HTMLElement("input")}} для получения полного списка атрибутов, значений и их использования для этого элемента.)

+ + + +

Также, элемент {{HTMLElement("input")}} получил новые атрибуты:

+ + + +

Текстовое поле

+ +

<input> с атрибутом type="text" определяет однострочное поле для ввода.

+ +
<form>
+  Введите свое имя: <input type="text" name="name">
+</form>
+ +

Флажок

+ +

<input> с атрибутом type="checkbox" определяет флажок.

+ +
<input type="checkbox" name="chk" value="" checked> Подписаться на рассылку
+ +

Переключатель

+ +

<input> с атрибутом type="radio" определяет радио кнопку.

+ +
<form>
+  <input type="radio" name="animal" value="monkey">Обезьяна<br>
+  <input type="radio" name="animal" value="cat">Кот<br>
+  <input type="radio" name="animal" value="other">Другое
+</form>
+ +

Элемент <form>

+ +

Элемент {{HTMLElement("form")}} получил новый атрибут:

+ + + +

Элемент <datalist>

+ +

Элемент {{HTMLElement("datalist")}} представляет собой список элементов {{HTMLElement("option")}}, который необходимо предложить при вводе поля {{HTMLElement("input")}}.

+ +

Вы можете использовать атрибут {{htmlattrxref("list", "input")}} в элементе {{HTMLElement("input")}}, чтобы связать текстовое поле с элементом {{HTMLElement("datalist")}}.

+ +

Элемент <output>

+ +

Элемент {{HTMLElement("output")}} представляет собой результат каких-либо вычислений.

+ +

Вы можете использовать атрибут {{htmlattrxref("for", "output")}} для указания связи между элементом {{HTMLElement("output")}} и другими элементами в документе, которые повлияли на расчет (к примеру, поля для ввода параметров). Значением атрибута {{htmlattrxref("for", "output")}} является список ID других элементов, разделенный пробелами.

+ +

{{non-standard_inline}} Gecko 2.0 (but not necessarily other browser engines) supports defining custom validity constraints and error messages for {{HTMLElement("output")}} elements, and therefore applies the {{Cssxref(":invalid")}}, {{Cssxref(":valid")}}, {{Cssxref(":-moz-ui-invalid")}}, and {{Cssxref(":-moz-ui-valid")}} CSS pseudo-classes to them. This can be helpful in situations where the calculated result violates a business rule, but no specific input value does (for example, "The total of percentages must not exceed 100").

+ +

Атрибут placeholder

+ +

Атрибут {{htmlattrxref("placeholder", "input")}} в элементах {{HTMLElement("input")}} и {{HTMLElement("textarea")}} отображает подсказки для пользователей, которые показывают, что можно ввести в эти поля. Текст в placeholder не должен содержать символов перевода строки или возврата каретки.

+ +

Атрибут autofocus

+ +

Атрибут {{htmlattrxref("autofocus", "input")}} позволяет указать для элемента формы автоматическое получение фокуса после полной загрузки страницы, если пользователь сам не переместит фокус на другой элемент, например, этот атрибут можно указать для различных полей ввода. Только один элемент в документе должен иметь этот атрибут, который содержит Boolean значение. Этот атрибут может быть установлен в {{HTMLElement("input")}}, {{HTMLElement("button")}}, {{HTMLElement("select")}} и {{HTMLElement("textarea")}} элементах.  {{htmlattrxref("autofocus", "input")}} нельзя установить в элементах input c атрибутом type установленным в значение hidden (это означает, что ты не можешь автоматически устанавливать фокус в скрытых полях).

+ +

DOM свойство label.control

+ +

DOM интерфейс HTMLLabelElement , помимо свойств, относящихся к HTML элементу {{HTMLElement("label")}} , предоставляет дополнительное свойство  control, возвращающее поле ввода, для которого предназначен {{HTMLElement("label")}}. Оно либо указывается в атрибуте {{htmlattrxref("for", "label")}} , либо является первым вложенным полем ввода.

+ +

Constraint Validation

+ +

HTML5 provides syntax and API items to support client-side validation of forms. While this functionality does not replace server-side validation, which is still necessary for security and data integrity, client-side validation can support a better user experience by giving the user immediate feedback about the input data.

+ +

If the title attribute is set on the {{HTMLElement("input")}} element, its value is used as tooltip. However, if the validation fails, this tooltip text will be replaced with the associated error message. It is possible to customize this error message using the non-standard {{htmlattrxref("x-moz-errormessage")}} attribute or when calling the setCustomValidity() method.

+ +
<input type="email" title="Please, provide an e-mail" x-moz-errormessage="This is not a valid e-mail">
+ +
Note: Constraint validation is not supported on {{HTMLElement("button")}} elements in a form; to style a button based on the validity of the associated form, use the {{cssxref(":-moz-submit-invalid")}} pseudo-class.
+ +

HTML Syntax for Constraint Validation

+ +

The following items in HTML5 syntax can be used to specify constraints on form data.

+ + + +

In addition, you can prevent constraint validation by specifying the {{htmlattrxref("novalidate", "form")}} attribute on the {{HTMLElement("form")}}, or the {{htmlattrxref("formnovalidate", "button")}} attribute on the {{HTMLElement("button")}} element and on the {{HTMLElement("input")}} element (when {{htmlattrxref("type", "input")}} is submit or image). These attributes indicate that the form is not to be validated when it is submitted.

+ +

Constraint Validation API

+ +

The following DOM properties and methods related to constraint validation are available to client-side scripts:

+ + + +

See also

+ + diff --git a/files/ru/orphaned/mdn/about/linking_to_mdn/index.html b/files/ru/orphaned/mdn/about/linking_to_mdn/index.html new file mode 100644 index 0000000000..093ce13265 --- /dev/null +++ b/files/ru/orphaned/mdn/about/linking_to_mdn/index.html @@ -0,0 +1,63 @@ +--- +title: Проставление ссылок на MDN +slug: MDN/User_guide/Linking_to_MDN +tags: + - Documentation + - Guide + - MDN +translation_of: MDN/About/Linking_to_MDN +--- +
{{MDNSidebar}}

Мы регулярно получаем от пользователей вопросы о том, как сослаться на MDN, или даже разрешено ли это делать. Краткий ответ таков: да, вы можете ссылаться на MDN! Читайте дальше, чтобы узнать о руководящих принципах и лучших практиках!

+ + +

Да! Разумеется! Дело не только в том, что гипертекст — это сущность веба, это так же способ указать вашим пользователям на ценные ресурсы и показать своё доверие к работе нашего сообщества.

+

Так что, да, мы определённо рекомендуем вам ссылаться на содержимое MDN. Не стесняетесь: ссылайтесь на главную страницу MDN, или, ещё лучше, сразу на конкретную страницу MDN, в случае необходимости. Смотрите ниже лучшие практики определения того, на какую страницу ссылаться.

+ + +

Не существует специальной страницы, на которую вы должны ссылаться. Важно то, насколько релевантна страница для ваших читателей.

+ +

Но на самом деле, вы должны ссылаться на наиболее подходящую к вашему содержимому и для ваших пользователей страницу. Не забывайте, что важны ваши читатели, а не ссылки на нас.

+ +

Как создать хорошую ссылку?

+

Создание ссылок — дело тривиальное, но создание хороших ссылок — это нечто более сложное. Существует несколько способов создать ссылки:

+ +

Ссылки в тексте

+

Это самый полезный вид ссылок: они нацелены на предоставление пользователям дополнительной информации по данной концепции. В основном такие ссылки ведут на страницы, содержащие связанную информацию, а не на домашнюю страницу веб-сайта (хотя, конечно, есть и исключения).

+
+

… с помощью API IndexedDB данные можно хранить в локальной базе данных…

+
+

Такие ссылки очень ценны как для пользователя, который получает информацию, доступную в один щелчок мыши, так и для MDN, так как пользователям, пришедших к нам по точному контексту, скорее всего понравится наше содержимое. Поскольку наша миссия состоит в том, чтобы читатели нашли то, что им нужно, как можно быстрее, это определённо очень хорошая вещь.

+ +

Что не надо делать при проставлении ссылок в тексте

+

Проставление ссылок в тексте действительно очень клёво и полезно, но есть несколько вещей, которых нужно избегать:

+ + +

Добавление баннера или изображения на ваш сайт

+

Другим способом сослаться на MDN является добавление изображения со ссылкой вне основного текста страницы, например, в боковую панель. Он имеет другое значение: тогда как проставление ссылок в тексте является способом предоставления дополнительной информации вашим пользователям, добавление изображения со ссылкой в боковую панель — это способ показать вашу поддержку проекту MDN или способ продвинуть MDN. Также это способ предложения MDN в качестве единого ресурса со всей информацией.

+

Не стесняйтесь показывать нам вашу поддержку: посетите страницу продвижения MDN и создайте кнопку специально для вашего сайта. Конечно, вы вольны разместить ссылку на другую страницу, например, на одну из целевых страниц.

+ +

Автоматическое проставление ссылок на MDN из WordPress

+

Мы создали плагин WordPress, который автоматически проставляет ссылки на выбранные термины в записях вашего блога на соответствующие страницы MDN. Делает он это разумно, в соответствии с рекомендациями, изложенными выше и может быть большим подспорьем для блоггеров, пишущих о концепциях веба. Взгляните на него, и попробуйте установить, если вы думаете, что он может быть полезен.

+

Большое спасибо вам за вашу поддержку!

diff --git a/files/ru/orphaned/mdn/community/conversations/index.html b/files/ru/orphaned/mdn/community/conversations/index.html new file mode 100644 index 0000000000..1440b5cdcd --- /dev/null +++ b/files/ru/orphaned/mdn/community/conversations/index.html @@ -0,0 +1,53 @@ +--- +title: MDN community conversations +slug: MDN/Сообщество/Conversations +tags: + - MDN Meta + - Руководство + - Сообщество +translation_of: MDN/Community/Conversations +--- +
{{MDNSidebar}}
+ +

"Работа" MDN происходит на её сайте, но "сообщество" также общается через (асинхронные) дискуссии и (синхронные) чаты и встречи.

+ +

Дискуссии и обмен информацией.

+ +

Для того, чтобы делиться информацией и вести дискусиию, MDN имеет раздел ("MDN") на форуме Mozilla. Используйте данный раздел для всех тем, связанных с MDN, включая создание, перевод и обслуживание документации; Разработка платформы MDN; и планирование, постановка целей и отслеживание прогресса.

+ + + +

Архив записей

+ +

До июня 2017 года обсуждения, связанные с MDN, проходили в списках рассылки, которые были переданы и заархивированы группами Google. Если вы хотите найти эти прошлые обсуждения, вы можете посмотреть группы Google, соответствующие старым спискам рассылки. (Да, мы знаем, что эти имена совпадают и сбивают с толку. Исторический случай. Приносим извинения.)

+ +
+
mozilla.dev.mdc a.k.a. dev-mdc
+
Данный список предназначался для обсуждения документации.
+
mozilla.dev.mdn a.k.a. dev-mdn
+
Этот список посвещался базовой разработке платформы MDN Kuma.
+
mozilla.mdn a.k.a. mdn@
+
Этот форум был предназначен для обсуждения на высоком уровне планирования и определения приоритетов, для веб-сайта MDN и других связанных инициатив.
+
+ +

Синхронный чат

+ +

Matrix - платформа для общения в реальном времени от Mozilla, протокол чата для которого у Mozilla есть собственный сервер

+ +

Чат с веб-документацией MDN является основным каналом для обсуждения содержания MDN. Мы говорим о написании, организации контента и так далее. У нас также есть здесь разговоры о «кулерах» - это способ нашего сообщества поддерживать связь и просто тусоваться. Эта комната, скорее всего, будет активна в будние дни в Северной Америке и Европе.

+ +

Возможно, вы захотите узнать больше об использовании Matrix с Mozilla и, если вам это действительно нравится, установите автономное Matrix приложение, Riot.im.

+ +

What about IRC?

+ +

В течение многих лет Mozilla использовала Internet Relay Chat (IRC) для обсуждения в реальном времени. С начала 2020 года IRC устарел и заменен Matrix. Вы можете встретить ссылки на IRC-каналы во многих местах, в том числе на MDN. Вы можете помочь, обновив ссылки на IRC-каналы, которые вы найдете на MDN, чтобы они указывали на соответствующие комнаты Matrix. Если вы не уверены, что представляет собой комната Matrix по теме, спросите в общей комнате. У проектов или тем, которые больше не активны, может не быть комнаты Matrix; в таких случаях просто удалите ссылку.

+ +

Присоеденяйся к нашим встречам (и другим событиям)

+ +

The MDN team holds a number of regular meetings that are open to the MDN community. See the MDN Meetings page on the Mozilla wiki for details on the schedule, agendas and notes, and info on how to join.

+ +

See the MDN Events calendar for these and other meetings, local meetups, and other events. The recurring meetings are summarized on the MDN Meetings wiki page

diff --git a/files/ru/orphaned/mdn/community/index.html b/files/ru/orphaned/mdn/community/index.html new file mode 100644 index 0000000000..5824e576e4 --- /dev/null +++ b/files/ru/orphaned/mdn/community/index.html @@ -0,0 +1,53 @@ +--- +title: Присоединяйся к сообществу MDN +slug: MDN/Сообщество +tags: + - МДН + - Руководство + - Сообщество +translation_of: MDN/Community +--- +
{{MDNSidebar}}
+ +
{{IncludeSubnav("/ru/docs/MDN")}}
+ +
+

MDN (аббревиатура Mozilla Developer Network) - это больше чем wiki: это сообщество разработчиков работающих вместе, чтобы сделать MDN лучшим ресурсом для разработчиков, которые используют открытые Веб-технологии.

+
+ +

Мы хотели бы, чтобы вы внесли свой вклад в MDN, но еще больше мы бы хотели, чтобы вы участвовали в сообществе MDN. Вот как присоединиться, за три простых шага:

+ +
    +
  1. Создайте MDN аккаунт.
  2. +
  3. Присоединитесь к обсуждению.
  4. +
  5. Смотрите, что происходит.
  6. +
+ +

Как работает сообщество

+ +

Следующие статьи наиболее подробно описывают сообщество MDN.

+ +
+
+
+
Роли сообщества
+
Есть определённое количество ролей в MDN сообществе с разной степенью ответственности.
+
Док-спринты
+
Это руководство по организации спринтов документации. Оно содержит советы и подсказки от людей, которые уже проводили док-спринты, чтобы помочь вам организовать свой.
+
Смотрите, что происходит
+
MDN создана сообществом Mozilla Developer Network. Вот несколько способов, которыми мы можем поделиться с вами информацией о том, что мы делаем.
+
+ +
+
+
+ +
+
+
Обсуждения сообщества MDN
+
"Работа" MDN происходит на её сайте, но "сообщество" также общается через (асинхронные) дискуссии и (синхронные) чаты и встречи.
+
Работа в сообществе
+
Большая часть вклада в документацию на MDN какого-либо значительного размера требует знаний, как работать, как часть MDN сообщества. Эта статья содержит советы, которые помогут вам сделать большую часть ваших взаимодействий с другими редакторами и разработчиками.
+
+
+
diff --git a/files/ru/orphaned/mdn/community/whats_happening/index.html b/files/ru/orphaned/mdn/community/whats_happening/index.html new file mode 100644 index 0000000000..fb74f6342c --- /dev/null +++ b/files/ru/orphaned/mdn/community/whats_happening/index.html @@ -0,0 +1,37 @@ +--- +title: Следите за событиями +slug: MDN/Сообщество/Whats_happening +translation_of: MDN/Community/Whats_happening +--- +
{{MDNSidebar}}
+ +

MDN представлено вам через Mozilla Developer Network community. Вот несколько способов, с помощью которых мы делимся информацией о том, что делаем.

+ +

Блоги

+ +
+
Mozilla Hacks
+
Новости и углубленное освещение Веб-технологий и особенностей Mozilla.
+
Engaging Developers
+
Повышение активности и обсуждения среди сообщества, участвующих в MDN в Mozilla.
+
+ +

Короткие советы

+ + + +

Панель состояния

+ +

Взгляните на страницу Статус документации, чтобы увидеть, что происходит со всем содержимым MDN. Вы можете увидеть какие статьи нуждаются в написании или обновлении, каким темам требуется наибольшая помощь и многое-многое другое.

+ +

MDN встречи

+ +

Есть целый ряд регулярных встреч для отслеживания и совместного прогресса на различных MDN проектах и процессах. Они описаны на вики странице MDN встреч.

+ +

Для того, чтобы получить общее представление о том, что происходит, лучшим способом для участия является встреча MDN-сообщества, которое проходит каждые две недели по средам, с 10:00 по тихоокеанскому времени США (UTC-0800 с октября по март, UTC-0700 в марте-октябре), на канале #mdn IRC. Посмотрите вики страницу встреч сообщества MDN для повесток дня и заметки из прошлых встреч.

+ +

Публичный календарь событий MDN содержит встречи MDN сообщества, doc спринты, и другие события связанные с MDN. Если вы видите встречу, которое происходит в канале "mdn" в системе видеоконференции Vidyo, вы можете присоединиться к разговору.

diff --git a/files/ru/orphaned/mdn/community/working_in_community/index.html b/files/ru/orphaned/mdn/community/working_in_community/index.html new file mode 100644 index 0000000000..9f5faaf33d --- /dev/null +++ b/files/ru/orphaned/mdn/community/working_in_community/index.html @@ -0,0 +1,108 @@ +--- +title: Работа в сообществе +slug: MDN/Сообщество/Working_in_community +tags: + - Community + - Guide + - MDN Meta + - Руководство + - Сообщество +translation_of: MDN/Community/Working_in_community +--- +
{{MDNSidebar}}
+ +

Большая часть вклада в документацию MDN в каких-либо значительных масштабах умение работать в рамках MDN-сообщества. Эта статья подскажет, как внести максимальный вклад в работу с другими редакторами и командами разработчиков.

+ +

Общее руководство по этикету

+ +

Вот некоторые общие указания при работе в сообществе Mozilla.

+ + + +

Будьте тактичны

+ +

Всегда будьте тактичны и уважительны, когда общаетесь с другими.

+ +

Вежливо указывайте на ошибки

+ +

Если ваша цель в контакте с кем-то - попросить их сделать что-то по-другому или указать на ошибку, которую они совершили (особенно если они повторяют это постоянно), начните свое сообщение с положительного комментария. Это смягчает удар, так сказать, демонстрирует, что вы пытаетесь быть полезным и не позиционирует вас как невоспитанного человека.

+ +

Например, если новый участник создает много страниц без тегов и вы хотели бы указать на эту проблему, тогда ваше сообщение для него могло бы выглядеть так (то, что вам нужно изменить для конкретного случая, подчеркивается):

+ +
+

Привет, MrBigglesworth, я заметил Ваш вклад в документацию API Wormhole, Ваша помощь неоценима! Мне особенно нравится, как Вы сбалансировали свой уровень детализации с удобочитаемостью. Тем не менее, Вы могли бы сделать эти статьи еще лучше и полезнее, если бы в дальнейшем добавили правильные теги к страницам.

+ +

Подробные сведения смотри в руководстве по тегам MDN (https://developer.mozilla.org/en-US/docs/MDN/Contribute/Howto/Tag).

+ +

Еще раз спасибо, я надеюсь на Ваше сотрудничество в будущем!

+
+ +

Обмен знаниями

+ +

Когда вы участвуете в MDN проекте, вы можете общаться с другими членами сообщества и быть в курсе происходящего. Вы можете обмениваться идеями, изменениями статуса и тому подобным с другими. Для этого есть соответствующие инструменты и информационные ресурсы.

+ +

Способы коммуникации

+ +

Существует несколько способов взаимодействия с другими участниками (разработчиками и писателями), каждый из которых имеет свой набор правил этикета.

+ +

Bugzilla

+ +

При написании документации, связанной с исправлением ошибок в рамках системы Bugzilla, вы часто будете общаться с людьми, имеющим отношение к соответствующим ошибкам. Никогда не забывайте о руководстве по этикету Bugzilla Etiquette!

+ +

Email

+ +

Вы можете также связаться с кем-то через электронную почту, если у вас есть необходимые адреса email.

+ +
+

Примечание: Как правило, если кто-то разместил свой адрес электронной почты в документах о технологии, которую вы документируете, дал вам свой адрес электронной почты лично или имеет общеизвестный электронный адрес, то электронная почта является приемлемым способом "первого контакта". Если вы достали email адрес другим методом, то вы, вероятно, должны сначала попытаться получить разрешение в IRC или списке рассылки до тех пор, пока ваши попытки не будут исчерпаны.

+
+ +

Инструменты статуса контента

+ +

Есть несколько полезных инструментов, которые предоставляют информацию о состоянии документов.

+ +
+
Панель управления ревизиями
+
Панель управления ревизиями документов предоставляет очень удобный инструмент для обзора изменений, внесенных в контент MDN. Вы можете видеть историю последних изменений, выбрать временной диапазон для просмотра. Вы можете использовать фильтр по языку, имени разработчика, теме и другим атрибутам. Просматривая список ревизий документов, вы можете просмотреть изменения, внесенные в каждую ревизию, быстро открыть страницу, просмотреть полную историю или даже отменить изменения (если у вас есть необходимые привилегии).
+
Обзор статуса документации
+
Страница обзора статуса документации содержит список всех областей MDN, которые были сконфигурированы для отслеживания статуса. Она содержит информацию о том, сколько страниц нуждаются в различных доработках. Выбрав конкретную тему, вы можете просмотреть подробные списки документов, которые необходимо доработать. Это могут быть страницы, которые не имеют тегов, или помечены индикаторами "необходимо выполнить определенные виды работ". Вы можете даже просмотреть списки страниц, которые не обновлялись в течение длительного времени и могут быть устаревшими, а также список ошибок, которые были отмечены как влияющие на документацию в этой области.
+
Планы проектов документации
+
Для некоторых проектов созданы планы документации, которые помогают отслеживать то, что еще необходимо сделать. К таким проектам относятся проекты на стадии планирования или большие, постоянные проекты.
+
MDN Taiga
+
Штатные сотрудники MDN используют инструмент под названием Taiga для управления текущими и будущими проектами документации. Вы также можете посмотреть чем мы занимаемся и какие проекты планируются в ближайшем будущем. Некоторые из них будут взяты на себя штатными сотрудниками, но вы также можете взяться за них, если захотите! Для получения дополнительной информации о живых технологических процессах, сопровождаемых командой MDN, смотрите нашу Страницу технологических процессов на Mozilla wiki.
+
+ +

Сообщество разработчиков

+ +

Членам писательского сообщества MDN важно поддерживать нормальные отношения с разработчиками. Разработчики создают программное обеспечение, которым мы пользуемся. Они владеют полезной для нас информацией. Критически важным является поддерживать с ними хорошие отношения. Чем более адекватны вы будете в общении с разработчиками, тем у вас больше шансов на то, что они ответят на ваши вопросы быстро, аккуратно и тщательно!

+ +

Не забывайте, что вы являетесь представителем писательского сообщество MDN. Пожалуйста, помогите нам сохранить наши отличные рабочие отношения с командой разработчиков, сделав каждое их взаимодействие с нашей командой писателей примером хорошей работы.

+ +

Для того, чтобы найти подходящего человека для обсуждения ваших вопросов (не забывая о сделанных выше замечаниях) можете обратиться к ресурсу module owners lists.

+ +

Сообщество писателей

+ +

Писательское сообщество является достаточно большим. Хотя число постоянных участников невелико, но есть несколько сотен людей, которые вносят свой вклад время от времени. В основном эти люди искренне любят Web, Mozilla и/или документацию, поэтому взаимодействовать с ними почти всегда очень легко.

+ +

Для получения более подробной информации, смотрите статью Join the community.

+ +

Наиболее вероятным местом, где вы могли бы напрямую пересечься с другими писателями является IRC канал {{IRCLink("mdn")}}. Этот канал зарезервирован специально для дискуссий о документации. По поводу особенностей IRC этикета смотрите статью из Mozilla Support "Getting Started with IRC". Вы можете дискутировать с нами также на Дискуссионном форуме MDN. Уместно заметить, что IRC, как правило, используют для быстрых, более личных бесед, а дискуссионный форум обычно используют для продолжительных бесед.

+ +

Имея ввиду {{anch("Общее руководство по этикету")}}, вы увидите, что все идет обычно очень гладко.

+ +

Смотри также

+ + diff --git a/files/ru/orphaned/mdn/contribute/howto/create_an_mdn_account/index.html b/files/ru/orphaned/mdn/contribute/howto/create_an_mdn_account/index.html new file mode 100644 index 0000000000..99857a600a --- /dev/null +++ b/files/ru/orphaned/mdn/contribute/howto/create_an_mdn_account/index.html @@ -0,0 +1,42 @@ +--- +title: Как создать MDN аккаунт +slug: MDN/Contribute/Howto/Create_an_MDN_account +tags: + - Документация + - Начинающий + - Руководство +translation_of: MDN/Contribute/Howto/Create_an_MDN_account +--- +
{{MDNSidebar}}
+ +

Чтобы вносить любые изменения в контент на MDN, вам будет нужен MDN профиль (для чтения и поиска сайту он не нужен). Данное руководство поможет вам создать ваш MDN профиль.

+ +
+
Дл чего MDN нужен адрес моей электронной почты?
+
+Адрес вашей электронной почты используется для восстановления аккаунта. Иногда адрес может понадобиться администраторам MDN, чтобы написать вам по вопросам, связанным с вашим аккаунтом либо с вашей активностью на данном сайте.
+
+Кроме того, вы можете дополнительно подписаться на уведомления (например, when specific pages are changed) и сообщения (например, если вы решите присоединиться к нашей команде бета-тестирования, то сможете получать по электронной почте сведения о новых возможностях сайта, которые нужно протестировать).
+
+Адрес вашей электронной почты никогда не будет показан на MDN и будет использоваться только согласно нашей политике конфиденциальности.
+ +
Если вы вошли в MDN через аккаунт GitHub, и вы используете режим "noreply" в настройках почтового адреса на GitHub, вы не получите сообщений (включая оповещения от страниц, на которые вы подписаны) от MDN.
+
+
+ +
    +
  1. В верхней части каждой страницы MDN есть кнопка с надписью Войти. Наведите курсор мыши на неё (или нажмите на неё, если вы на мобильном устройстве), чтобы отобразить список сервисов, которые мы поддерживаем для регистрации в MDN.
  2. +
  3. Выберите аккаунт для того, чтобы Войти в систему. Сейчас доступны GitHub и Google. Обратите внимание, что если вы выберете GitHub, то ссылка на ваш GitHub-профиль будет отображаться на публичной странице вашего профиля MDN.
  4. +
  5. Следуйте инструкциям, чтобы подключить выбранную учетную запись к MDN (например, форма для входа через GitHub будет выглядеть как на картинке ниже).
  6. +
  7. После того, как служба аутентификации вернет вас на сайт MDN, вам будет предложено ввести имя пользователя MDN и адрес электронной почты. Ваше имя пользователя будет отображаться публично, чтобы при вкладе в развитие сообщества было видно ваше авторство. Не используйте свой адрес электронной почты в качестве имени пользователя.
  8. +
  9. Нажмите Создать мой профиль MDN.
  10. +
  11. Если адрес электронной почты, указанный в шаге 4, не то же самый, который вы используете на выбранном для аутентификации сервисе, то проверьте свою электронную почту и нажмите на ссылку в письме с подтверждением, которое мы выслали вам.
  12. +
+ +

Это всё! Теперь у вас есть аккаунт MDN, и вы можете сразу начать  редактировать контент сообщества!

+ +

Нажмите на своё имя в верхней части любой страницы MDN, чтобы увидеть свой профиль. В профиле нажмите Редактировать, если хотите внести изменения или дополнения.

+ +
+

Новые имена пользователей не могут содержать пробелы или символ"@". Выбирая имя, помните, что оно будет отображаться публично, чтобы было видно, что именно вы проделали ту или иную работу.

+
diff --git a/files/ru/orphaned/mdn/contribute/howto/do_a_technical_review/index.html b/files/ru/orphaned/mdn/contribute/howto/do_a_technical_review/index.html new file mode 100644 index 0000000000..ba395e2669 --- /dev/null +++ b/files/ru/orphaned/mdn/contribute/howto/do_a_technical_review/index.html @@ -0,0 +1,57 @@ +--- +title: Как сделать технический обзор +slug: MDN/Contribute/Howto/Do_a_technical_review +tags: + - Guide + - Howto + - MDN Meta + - Как сделать + - Руководство +translation_of: MDN/Contribute/Howto/Do_a_technical_review +--- +
{{MDNSidebar}}
+ +

Технический обзор заключается в рассмотрении технической точности и полноты статьи и её корректировки, если это необходимо. Если автор статьи хочет, чтобы кто-нибудь ещё проверил техническое содержание статьи, то он ставит пометку "Технический обзор" при редактировании. Часто автор связывается с определённым инженером для выполнения технического обзора, но кто-либо с техническими знаниями и опытом в теме также может сделать это.

+ +

Эта статья описывает, как выполнить технический обзор, тем самым гарантируя точность содержания MDN.

+ +
+
В чём задача?
+
Обзор и исправление статей на техническую точность и полноту.
+
Где это необходимо сделать?
+
В конкретных статьях, которые отмечены как требующие технического обзора.
+
Что Вы должны знать, чтобы выполнить задачу?
+
+
    +
  • Экспертные знания в теме, которую Вы обозреваете.
  • +
  • Возможность редактирования статьи на MDN.
  • +
+
+
Какие действия нужно выполнить, чтобы сделать это?
+
+
    +
  1. Выберите статью для обзора: +
      +
    1. Перейдите к списку страниц, которые нуждаются в техническом обзоре. В этом списке перечислены все страницы, для которых был запрошен технический обзор.
    2. +
    3. Выберите страницу, с темой которой Вы очень хорошо знакомы.
    4. +
    5. Нажмите на ссылку статьи, чтобы загрузить страницу.
    6. +
    +
  2. +
  3. Прочитайте статью, обращая пристально внимание на технические детали: Верна ли статья? Чего-то не хватает? Не стесняйтесь переключаться на другую статью, если выбранная не устраивает Вас.
  4. +
  5. Если ошибок нет, то Вам не нужно редактировать статью, чтобы отметить её как просмотренную. Посмотрите на окно "быстрого обзора" в левой боковой панели страницы:
    +
    + Выберите флажок Технический и нажмите Обзор завершен.
  6. +
  7. Если Вы нашли ошибки, которые нужно исправить: +
      +
    1. Нажмите кнопку Редактировать в верхней части страницы; она переместит Вас в редактор MDN.
    2. +
    3. Исправьте неверную техническую информацию и добавьте важную информацию, которая отсутствует.
    4. +
    5. Введите Комментарий к ревизии в нижней части статьи, который описывает, что Вы сделали, например, "Технический обзор закончен". Если Вы исправляли информацию, добавьте это в Ваш комментарий, например, "Технический обзор: исправлено описание параметров".
    6. +
    7. Отмените флажок Технический под Требуется проверка?.
    8. +
    9. Нажмите кнопку Сохранить изменения.
    10. +
    +
  8. +
+
+
+ +

Поздравляем! Вы только что завершили свой первый технический обзор! Спасибо вам за вашу помощь! 

diff --git a/files/ru/orphaned/mdn/contribute/howto/do_an_editorial_review/index.html b/files/ru/orphaned/mdn/contribute/howto/do_an_editorial_review/index.html new file mode 100644 index 0000000000..eab3b47fde --- /dev/null +++ b/files/ru/orphaned/mdn/contribute/howto/do_an_editorial_review/index.html @@ -0,0 +1,52 @@ +--- +title: Как сделать редакционный обзор +slug: MDN/Contribute/Howto/Do_an_editorial_review +tags: + - Guide + - Howto + - MDN Meta + - Как сделать + - Руководство +translation_of: MDN/Contribute/Howto/Do_an_editorial_review +--- +
{{MDNSidebar}}

Редакционный обзор заключается в исправлении опечаток и орфографических, грамматических, оборотных или текстовых ошибок в статье. Не все участники обладают лингвистическими навыками, но, благодаря их знаниям, появляются чрезвычайно полезные статьи, которые нуждаются в техническом редактировании и исправлении; это делается в редакционном обзоре.

+ +

Эта статья описывает выполнение редакционного обзора для поддержания точности содержания MDN.

+ +
+
В чём задача?
+
Техническое редактирование и исправление статей, которые отмечены как требующие редакционного обзора.
+
Где это необходимо сделать?
+
В конкретных статьях, которые отмечены как требующие редакционного обзора.
+
Что Вы должны знать, чтобы выполнить задачу?
+
Вы должны иметь хорошие грамматические и орфографические навыки в русском языке.
+
Какие действия нужно выполнить, чтобы сделать это?
+
+
    +
  1. Выберите статью для обзора: +
      +
    1. Перейдите к списку страниц, которые нуждаются в редакционном обзоре.  В этом списке перечислены все страницы, для которых был запрошен редакционный обзор.
    2. +
    3. Выберите страницу.
    4. +
    5. Нажмите на ссылку статьи, чтобы загрузить страницу.
    6. +
    +
  2. +
  3. Прочитайте статью, обращая пристальное внимание на опечатки и орфографические, грамматические или оборотные ошибки. Не стесняйтесь переключаться на другую статью, если выбранная не устраивает Вас.
  4. +
  5. Если ошибок нет, то Вам не нужно редактировать статью, чтобы отметить её как прошедшую корректуру. Посмотрите на окно "быстрого обзора" в левой боковой панели страницы:
    +
    + Выберите флажок Редакционный и нажмите Обзор завершен.
  6. +
  7. Если Вы нашли ошибки, которые нужно исправить: +
      +
    1. Нажмите кнопку Редактировать в верхней части страницы; она переместит Вас в редактор MDN.
    2. +
    3. Исправьте все опечатки и орфографические, грамматические или оборотные ошибки, которые Вы видите.
    4. +
    5. Введите Комментарий ревизии в нижней части статьи; что-то вроде 'Редакционный обзор: исправлены опечатки, грамматика и орфография'.
    6. +
    7. Снимите флажок Редакционный под Требуется проверка?.
    8. +
    9. Нажмите кнопку Сохранить изменения.
    10. +
    +
  8. +
+ +
+

Из-за соображений производительности Ваши правки могут не сразу появиться на странице.

+
+
+
diff --git a/files/ru/orphaned/mdn/contribute/howto/set_the_summary_for_a_page/index.html b/files/ru/orphaned/mdn/contribute/howto/set_the_summary_for_a_page/index.html new file mode 100644 index 0000000000..26d5101d9d --- /dev/null +++ b/files/ru/orphaned/mdn/contribute/howto/set_the_summary_for_a_page/index.html @@ -0,0 +1,41 @@ +--- +title: Как оптимизировать страницы +slug: MDN/Contribute/Howto/Как_оптимизировать_страницы +translation_of: MDN/Contribute/Howto/Set_the_summary_for_a_page +--- +
{{MDNSidebar}}

Вы можете заняться оптимизацией любой страницы на MDN, для поисковой оптимизации страницы, вы можете выбрать любую страницу: пусть то будет Лендинговая страница или подсказки. Это должен быть текст, который связан по смыслу с контентом страницы. Все слова должны быть уникальными и не должны встречаться в тексте.

+ +

 

+ +
+
Что необходимо сделать?
+
Выделить ключевые слова и написать оптимизированную (SEO) статью .
+
Где это нужно сделать?
+
На любых страницах, которые еще не оптимизированы, либо на страницах, которые не достаточно хорошо оптимизированы.
+
Необходимые знания и навыки для выполнения этого задания?
+
Навыки использования MDN редактора; владение Английским языком на уровне - native; умение писать SEO-статьи.
+
Что необходимо для этого сделать?
+
+
    +
  1. Выбрать страницу, на которой необходимо провести оптимизацию: +
      +
    1. На этой странице MDN выберите раздел, в котором вы сильны (например, HTML):
      +
    2. +
    3. На этой странице, нажмите СТРАНИЦЫ (Pages) в разделе Резюме (Summary). В этом разделе вы увидите индекс всех страниц. Так же вы увидите ссылки на страницы (слева), а тэги и SEO - статьи справа:
      +
    4. +
    5. Выберите страницу, которую необходимо оптимизировать:
      +
    6. +
    7. Кликните на ссылку, чтобы перейти на эту страницу.
    8. +
    +
  2. +
  3. Нажмите кнопку Правка (Edit), чтобы открыть MDN редактор.
  4. +
  5. Составьте одно - два предложения в качестве SEO-статьи. При необходимости отредактируйте уже существующую статью.
  6. +
  7. Выберите текст, который будет использован в качестве SEO.
  8. +
  9. На панели инструментов выберите виджет Styles. Выберите SEO Summary. (В исходном коде страницы будет создано {{HTMLElement("span")}} элемент с class="seoSummary" вокруг выделенного текста.)
    +
  10. +
  11. Сохраните свои изменения, желательно с комментариями. Для облегчения понимания ваших трудов другим участникам.
  12. +
+
+
+ +

 

diff --git a/files/ru/orphaned/mdn/contribute/howto/tag_javascript_pages/index.html b/files/ru/orphaned/mdn/contribute/howto/tag_javascript_pages/index.html new file mode 100644 index 0000000000..0c0ed4eca9 --- /dev/null +++ b/files/ru/orphaned/mdn/contribute/howto/tag_javascript_pages/index.html @@ -0,0 +1,74 @@ +--- +title: Как пометить страницы JavaScript +slug: MDN/Contribute/Howto/Метки_JavaScript_страниц +tags: + - Guide + - Howto + - JavaScript + - MDN Meta +translation_of: MDN/Contribute/Howto/Tag_JavaScript_pages +--- +
{{MDNSidebar}}

Маркировка состоит из добавления метаданных на страницы, чтобы связанный контент можно было сгруппировать, например, в инструменте поиска.

+ +
+
Где это нужно сделать?
+
Внутри определенных JavaScript-страниц без тегов
+
Что вам нужно знать, чтобы выполнить эту задачу?
+
Базовые знания JavaScript, например, знание метода или свойства.
+
Каковы шаги для этого?
+
+
    +
  1. Выберите одну из страниц в списке, указанном выше.
  2. +
  3. Нажмите ссылку на статью, чтобы загрузить страницу.
  4. +
  5. После загрузки страницы, нажмите кнопку EDIT рядом с нее названием; это перенесет вас в редактор MDN.
  6. +
  7. Как минимум тег JavaScript нужно добавить. Так же здесь список возможных тегов для добавления: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ТегКакие страницы использовать
    Methodметоды
    Propertyсвойства
    prototypeпрототипы
    Object type nameметоды объекта; например String.fromCharCode должен иметь тег String
    ECMAScript6 и Experimentalвозможности (фичи) которые были добавлены в новой версии ECMAScript
    Deprecatedустаревшие функции (использование которых не рекомендуется, но поддерживается)
    Obsoleteустаревшие функции (которые больше не поддерживаются в современных браузерах)
    othersСм. Стандарты тегов MDN для других возможных меток
    +
  8. +
  9. Сохранить с комментарием.
  10. +
  11. Готово!
  12. +
+
+
+ +

 

diff --git a/files/ru/orphaned/mdn/editor/basics/index.html b/files/ru/orphaned/mdn/editor/basics/index.html new file mode 100644 index 0000000000..10b5d91eb9 --- /dev/null +++ b/files/ru/orphaned/mdn/editor/basics/index.html @@ -0,0 +1,62 @@ +--- +title: Редактор UI элементов +slug: MDN/Editor/Basics +translation_of: MDN/Editor/Basics +--- +
{{MDNSidebar}}
+ +

Встроенный WYSIWYG редактор на MDN разработан так, чтобы максимально упростить создание, редактирование и улучшение статей и других страниц практически на всем сайте. Окно редактора, как показано ниже, состоит из восьми блоков.
+ Это руководство предоставляет информацию о каждом разделе, чтобы вы знали, как использовать все возможности нашего редактора.

+ +
+

Note: Мы постоянно работаем над улучшением MDN, так что может наступить такой момент, когда эта документация и скриншоты к ней окажутся немного устаревшими. Чтобы идти в ногу со временем - мы будем периодически обновлять документацию.

+
+ +

Edit page with en/ru labels

+ +

Интерфейс редактора содержит следующие разделы, как показано выше. Нажмите на ссылку ниже чтобы прочесть о конкретном разделе.

+ + + +

Поле редактирования

+ +

Поле редактирования - это, конечно же. место где вы вводите текст.

+ +

Нажатие правой кнопки мыши (ПКМ) в поле редактирования показывает дополнительные опции, в зависимости от контекста. Нажатие ПКМ на таблице, например, предлагает опции для работы с таблицами, а на списке, соответственно, опции для работы со списками. По умолчанию редактор использует свое собственное контекстное меню в поле редактирования. Чтобы открыть стандартное браузерное контекстное меню, при нажатии ПКМ зажмите Shift или Control (Command на Mac OS X).

+ +

Во время работы в окне редактирования вы можете использовать специальные сочетания клавиш.

+ +

Примечание

+ +

После того как вы закончили свою работу, настоятельно рекомендуется добавлять к своим изменениям примечание. Оно будет показано в истории изменений к этой странице, а также в обзорной панели изменений (Revision Dashboard). Это поможет объяснить и донести смысл ваших изменений до тех, кто может просматривать их позже. Чтобы добавить свое примечание, просто заполните это поле перед нажатием на кнопку Сохранить/Опубликовать.

+ +

Вот несколько причин почему это полезно:

+ + + +

Запрос проверки

+ +

MDN сообщество использует проверки (reviews) для того чтобы следить за качеством контента и улучшать его. Это работает с помощью переключения флажка у нужного пункта. Вы можете узнать больше о технической проверке (technical review) и редакционной проверке (editorial review) в руководствах "Как сделать".

+ +

Для запроса проверки статьи, над которой вы работали, переключите флажок возле нужного пункта. Техническую проверку следует запрашивать каждый раз, когда вы вносите изменения в технические детали работы чего-либо. Редакционная же проверка хороший выбор когда вы хотите посторонней оценки стиля или качества вашего текста.

+ +

Несмотря на то что эти опции добавляют вашу работу в соответсвующие списки (needing technical review или needing editorial review), это не означает что она будет проверена немедленно. Для технической проверки хорошей идеей будет прямо обратиться к специалистам в этой области (см. subject-matter expert). Для редакционной проверки вы можете написать на форуме MDN (см. MDN discussion forum) с просьбой проверить вашу работу.

+ +

Будьте внимательны, убедитесь что установили нужные флажки перед нажатием кнопки Сохранить/Опубликовать.

+ +

 

+ +

{{EditorGuideQuicklinks}}

diff --git a/files/ru/orphaned/mdn/editor/basics/page_controls/index.html b/files/ru/orphaned/mdn/editor/basics/page_controls/index.html new file mode 100644 index 0000000000..3f49c886b4 --- /dev/null +++ b/files/ru/orphaned/mdn/editor/basics/page_controls/index.html @@ -0,0 +1,37 @@ +--- +title: Элементы управления страницей в редакторе MDN +slug: MDN/Editor/Basics/Page_controls +tags: + - Beginner + - Guide + - editor +translation_of: MDN/Editor/Basics/Page_controls +--- +
{{MDNSidebar}}
+ +

Элементы управления состоят из кнопок, затрагивающих страницу в целом. Они расположены наверху и внизу страницы, для удобства прокрутки страницы. Здесь расположены четыре кнопки:

+ +
+

Если вы пытаетесь сохранить вашу работу и ваши изменения отклоняются как некорректные, но вы уверены, что ваш контент подходит для MDN,  вам следует связаться с командой редакторов для разрешения проблемы.

+
+ +
+
Сохранить и продолжить редактирование
+
Эта кнопка сохраняет и публикует страницу, не закрывая редактор. Это позволяет периодически сохранять вашу работу, оставляя запись в истории. Благодаря этому вы сможете при необходимости откатить изменения, или приостановить работу и продолжить в удобное время. Эта функция недоступна при создании новых страниц. Смотрите также раздел о примечании, чтобы узнать как оставить комментарий к вашим изменениям и зачем это делать. 
+
Опубликовать
+
Эта кнопка сохраняет и публикует изменения, а также закрывает редактор и возвращает вас на страницу в обычном режиме.
+
Предварительный просмотр
+
Эта кнопка открывает новую вкладку или окно, в котором показано как будут выглядить ваши изменения после публикации. Это подразумевает, что все ваши макросы и шаблоны будут показаны как уже обработанные. Обратите внимание, что ваша работа не будет сохранена при использовании этой опции. Эта возомжность позволяет вам проверить, до того как вы сделали свои изменения публичными, не допустили ли вы ошибок в своих шаблонах, макросах, или при оформлении текста. Если вы столкнулись с ошибками выполнения скриптов, смотрите Troubleshooting scripting error while previewing a page.
+
+
+

Внимание: В настоящее время некоторые шамблоны и макросы не выполняются корректно при предварительном просмотре, оставляя страницу без части контента (таких как боковые меню), и, следовательно, частично искажая страницу. Кроме того, если SCAYT включен (и если страница содержит определенные рабочие макросы или шаблоны), режим предварительного просмотра может выдавать ошибку выполнения скриптов.

+
+
+
Отменить
+
Эта кнопка отменяет все ваши несохраненные изменения. Вы будете возвращены на страницу в обычном режиме чтения.
+
+
+

Warning: Occasionally Discard can malfunction and start acting more like a partial "discard," undoing many of your changes without exiting the editor. If this happens to you, you should save, exit, and re-enter the editor.

+
+
+
diff --git a/files/ru/orphaned/mdn/editor/basics/toolbar/index.html b/files/ru/orphaned/mdn/editor/basics/toolbar/index.html new file mode 100644 index 0000000000..8a01621158 --- /dev/null +++ b/files/ru/orphaned/mdn/editor/basics/toolbar/index.html @@ -0,0 +1,256 @@ +--- +title: Панель инструментов редактора MDN +slug: MDN/Editor/Basics/Toolbar +tags: + - Beginner + - editor +translation_of: MDN/Editor/Basics/Toolbar +--- +
{{MDNSidebar}}
+ +

Панель инструментов редактора предоставляет вам возможность менять внешний вид и структуру документов во время работы. Эта статья описывает назначение кнопок в панели инструментов.  

+ +

На панели расположено три ряда. На первых двух - кнопки, а на третьем HTML контекст, который показывает вам какой элемент вы редактируете в данный момент. На скриншоте ниже, например, редактирование происходит в {{htmlelement("p")}} элементе. 

+ +

Screenshot of the toolbar, with labels for the button groupsКнопки на панели инструментов разделены на девять групп. Давайте взглянем на все. Мы будем изучать кнопки в каждой группе по порядку, слева направо.

+ + + +

Документ

+ +

Кнопки из этой группы используются для управления на уровне всего документа.

+ +
+
Source
+
Кнопка Source позволяет переключаться между редактированием в режиме WYSIWYG и редактированием разметки HTML. Мы просим вас избегать редактирования разметки, т.к. в таком случае очень легко неправильно оформить статью или вовсе столкнуться с ошибками. Правда в настоящее время у редактора могут встречаться некоторые причуды в работе, из-за которых сделать некоторые вещи не удастся, не отредактировав разметку напрямую. Смотрите Режим разметки в редакторе MDN чтобы более подробно изучить этот режим и понять что в разметке писать можно, а чего писать не следует.
+
Publish
+
То же что и кнопка Опубликовать.
+
+ +
+

Примечание: Если вы пытаетесь сохранить вашу работу и ваши изменения отклоняются как некорректные, но вы уверены, что ваш контент подходит для MDN, вам следует связаться с командой редакторов для разрешения проблемы.

+
+ +
+
Preview
+
Аналог кнопки Предварительный просмотр.
+
+ +

Правка

+ +

Функции этих кнопок очень схожи с соответствующими из меню Правка в любом другом редакторе.

+ +
+
Paste / Вставить
+
Вставить контент из буфера обмена в поле редактора.
+
Paste as plain text / Вставить как обычный текст
+
Открывает диалоговое окно в которое вы можете вставить текст. Этот текст будет отделен от всего лишнего, так что вы не вставите случайно текст с лишними стилями или ссылками. После вставки текста, вы можете его отредактировать, если нужно, а затем, кликнув на кнопку OK, вставить на страницу.
+
+
+

Примечание: Обратите внимание, что во время вставки контента в редактор, если вы копировали стилизованный контент (например, скопированный с другого сайта  код  с подсветкой синтаксиса),  вы можете случайно вставить вместе с ним стили или посторонние классы. Пожалуйста, будьте внимательны и не допускайте этого. Проверяйте свои изменения в режиме разметки, если требуется, чтобы удалить лишние стили и классы (или позаботьтесь об этом заранее, воспользовавшись кнопкой "Paste as plain text").

+
+
+
Undo
+
Отменить последнее изменение.
+
Redo
+
Применить последнее отмененное изменение.
+
+ +

Работа с текстом

+ +
+
Find / Найти
+
Открывает диалоговое окно Find and Replace в режиме "Find", который позволяет найти в вашем документе определенную строку.
+
Replace / Заменить
+
Открывает диалоговое окно Find and Replace в режиме "Replace", с помощью которого можно найти нужную строку и заменить на новую.
+
+ +

Кнопки Find и Replace открывают одно и то же диалоговое окно, которое имеет несколько опций для поиска и, опционально, замены текста.

+ +
+
Spell Checker / Проверка правописания
+
Эта кнопка открывает меню с несколькими пунктами: +
+
Enable SCAYT/Disable SCAYT
+
Включает или отключает Spell Check As You Type (SCAYT)
+
Options
+
Если SCAYT включен, этот пункт открывает диалоговое окно SCAYT во вкладке с опциями для настройки SCAYT.
+
Languages
+
Если SCAYT включен, этот пункт открывает диалоговое окно SCAYT во вкладке "Languages", где вы можете выбрать язык для проверки правописания.
+
Dictionaries
+
Если SCAYT включен, этот пункт открывает диалоговое окно SCAYT во вкладке "Dictionaries", где вы можете сами выбрать словарь, который SCAYT будет использовать.
+
About SCAYT
+
Если SCAYT включен, этот пункт открывает диалоговое окно SCAYT во вкладке "About", в которой написано о SCAYT.
+
Check Spelling
+
Этот пункт открывает диалоговое окно Spell Checker, в котором вы можете проверить правописание в пакетном режиме (batch mode) для всего документа. Вы можете воспользоваться вкладкой Grammar для проверки грамматических ошибок, или воспользоваться вкладкой Thesaurus для поиска синонимов для слов в документе.
+
+
+
+ +

Вид

+ +

Эта группа позволяет настроить вид отображения интерфейса редактора. 

+ +
+
Maximize
+
Эта кнопка разворачивает интерфейс редактора (то есть панель инструментов и поле редактирования) во всё окно браузера, предоставляя вам как можно больше места для работы.
+
Show blocks
+
Эта кнопка отображает контуры вокруг блочных элементов в вашем документе. Это может быть удобным для проверки структуры документа без необходимости заглядывать в разметку.
+
+ +

Строковые стили

+ +

Строковые стили содержат распространенные стили, которые могут вам пригодиться при оформлении текста.

+ +
+
Bold
+
Переключает жирный стиль текста, создавая при этом в разметке элемент {{htmlelement("strong")}}.
+
Italic
+
Переключает курсив. Создает {{htmlelement("em")}} элемент.
+
Underline
+
Переключает нижнее подчеркивание. Создает {{htmlelement("u")}} элемент.
+
Strike through
+
Переключает перечеркивание. Создает {{htmlelement("s")}} элемент.
+
Subscript
+
Переключает нижний индекс. Создает {{htmlelement("sub")}} элемент.
+
Superscript
+
Переключает верхний индекс. Создает {{htmlelement("sup")}} элемент. Заметьте, что такой строковый стиль не используется на MDN, так что вам вряд ли когда-нибудь пригодится эта кнопка.
+
Remove format
+
Удаляет текущий строковый стиль в выделенном тексте.
+
Code
+
Переключает стиль для кода. Создает {{htmlelement("code")}} элемент. Это используется для представления в тексте имен переменных, функций, объектов, файлов и т.п.
+
+ +

Работа со ссылками

+ +

Данная группа предоставляет инструменты для работы со ссылками.

+ +
+
Link
+
Создает новую ссылку. При нажатии вызывается окно создания ссылки, работа с которым подробна описана в Ссылки с помощью панели инструментов.
+
Unlink
+
Удаляет ссылку в месте, где расположен курсор.
+
Anchor
+
Создает якорь в месте, где расположен курсор. Заметьте, что вам не нужно создавать якорь для заголовков, редактор автоматически создает {{htmlattrxref("id")}} для каждого заголовка, заменяя пробелы в названии на нижние подчеркивания. Например, заголовок этой секции имеет id, значение которого Работа_со_ссылками.
+
Create a redirect
+
Встраивает переадресацию на другую страницу. Смотрите Создание переадресаций для подробной информации.
+
+ +

Специальные стили

+ +

Кнопка Styles - это выпадающее меню, предлагающее на выбор специальные стили форматирования текста.

+ +

Блочные стили

+ +
+
None
+
Удаляет стиль с выбранного блока.
+
Note box
+
Создает блок с примечание, как показано ниже. Вы должны всегда начинать примечание со слова "Примечание:" жирными буквами.
+
+ +
+

Примечание: Это поле с примечанием.

+
+ +
+
Warning box
+
Создает блок с предупреждением, как показано ниже. Блок должен всегда начинаться со слова "Внимание:" жирными буквами.
+
+ +
+

Внимание: Это поле с предупреждением.

+
+ +
+
Two columns
+
Делает выделенный текст или блок двухколоночным на браузерах, которые это поддерживают.
+
Three columns
+
Делает выделенный текст или блок трехколоночным на браузерах, которые это поддерживают.
+
Syntax box
+
Создает поле для синтаксиса, как показано ниже. Это создает {{htmlelement("pre")}}. Вы можете также использовать кнопку "PRE".
+
+
Это поле для синтаксиса
+
+
Hidden when reading
+
Создает блок, который видно только в режиме редактирования. Это не то же, что и HTML-комментарий, который виден только в режиме разметки.
+
+ +

Строковые стили

+ +
+
SEO summary
+
Этот специальный стиль используется чтобы выделить предложение или два, которые будут использованы как краткое описание для поисковой оптимизации. Он также используется макросами для автоматического создания посадочных страниц. Если вы не воспользуетесь этим стилем, MDN автоматически использует первый абзац вашей статьи. Но иногда это не самый лучший вариант и лучше воспользоваться предложенным стилем.
+
+ +

Блоки

+ +

Эта группа включает опции для прочих стилей блоков. Некоторые из них относятся к стандартному HTML, а другие - уникальны, т.к. относятся к Kuma.

+ +
+
Blockquote
+
Вставляет блок для цитаты. Пожалуйста, не используйте это. Блоки с цитатами не являются частью нашего стайлгайда, и эта кнопка будет удалена в ближайшем будущем.
+
Preformatted Text
+
Вставляет {{htmlelement("pre")}} блок, или превращает в него текущий. Все примеры кода должны быть оформлены в такой блок.
+
Headings
+
Кнопки заголовков позволяют вам вставить нужный заголовок. Нажмите на одну из этих кнопок для создания нового заголовка соответственной глубины. По умолчанию заголовки с H2 по H4 включаются в оглавление, но вы можете изменить это, как описано в разделе Информация о странице.
+
Syntax highlighter
+
Подсветка синтаксиса позволяет вам выбрать язык, синтаксис которого будет подсвечиваться в {{htmlelement("pre")}} блоке. Если такой блок не был выбран изначально, он будет создан. Выберите язык используемый в блоке, и блок будет подсвечен соответствующим образом.
+
Insert Code Sample Template
+
Эта кнопка используется системой живых примеров (the live sample system), чтобы помочь вам быстро вставить новый живой пример (live sample). Смотрите Пользование системой живых примеров чтобы узнать подробнее.
+
Insert Code Sample iFrame
+
Вставляет в документ подходящий макрос для отображения нужного живого примера. Смотрите Пользование системой живых примеров для деталей использования и информации о других функциях живых примеров.
+
+ +

Списки и поток текста

+ +

Эта группа предоставляет инструменты для создания списков и изменения поведения текста в блоках.

+ +
+
Insert/remove numbered list
+
Создает или удаляет нумерованный список. Когда вы работаете над списком, при каждом нажатии Enter будет создаваться новый элемент списка. Клавиша Tab может быть использована для увеличения вложенности, а Shift + Tab, соответсвенно, для уменьшения. При нажатии на Enter в пустом элементе список будет закончен. Нажатие ПКМ на списке открывает контекстное меню с опцией Numbered list properties, в которой можно выбрать стиль маркера.
+
Insert/remove bulleted list
+
Создает или удаляет маркированный список. Когда вы работаете над списком, при каждом нажатии Enter будет создаваться новый элемент списка. Клавиша Tab используется для увеличения вложенности, а Shift + Tab для уменьшения. При нажатии на Enter в пустом элементе список будет закончен. Нажатие ПКМ на списке открывает контекстное меню с опцией Bulleted list properties, в которой можно выбрать стиль нумерации (числа, буквы, римские цифры и пр., а также с какой цифры начинать).
+
Definition List
+
Создает новый список с определениями (definition list). Этот список состоит из серии терминов и определений (именно такой список вы сейчас читаете).
+
Definition Term
+
Создает новый блок с термином в списке. Если в данный момент вы не редактируете список, он будет создан. Нажатие на Enter автоматически переключается на редактирование нового определения.
+
Definition Value
+
Создает новый блок с определением в списке. Нажатие на Enter создает новый термин. Нажав дважды, вы покинете список.
+
Decrease indent
+
Уменьшает вложенность. Того же эффекта можно добиться нажав Shift + Tab в списке.
+
Increase indent
+
Увеличивает вложенность. То же самое, что и нажатие Tab в списке.
+
Text direction left-to-right
+
Переключает текущее направление текста на слева направо. Используется при работе с другими языками. Например, при работе с английским текстом в арабском.
+
Text direction right-to-left
+
Переключает текущее направление текста на справа налево. Используется при работе с другими языками. Например, при работе с арабским текстом в английском.
+
+ +

Медиа

+ +

Данная группа предоставляет инструменты для работы с медиафайлами.

+ +
+
Image
+
Вставляет новое изображение в статью. Смотрите Изображения для подробностей.
+
Table
+
Вставляет таблицу в статью. Смотрите Таблицы для подробной информации о таблицах в статьях.
+
Embed YouTube Video
+
Открывает диалоговое окно, в котором вы можете ввести URL для видео YouTube. С этой информацией создается вызов макроса EmbedYouTube. Это безопасный способ встроить видеоконтент.
+
Insert MathML based on (La)TeX
+
Открывает диалоговое окно, в которое вы можете вставить свой код TeX или LaTeX. Этот код будет конвертирован в MathML вставлен в документ в {{htmlelement("math")}} блоке.
+
+ +

 

diff --git a/files/ru/orphaned/mdn/editor/images/index.html b/files/ru/orphaned/mdn/editor/images/index.html new file mode 100644 index 0000000000..f095489297 --- /dev/null +++ b/files/ru/orphaned/mdn/editor/images/index.html @@ -0,0 +1,78 @@ +--- +title: Изображения +slug: MDN/Editor/Картинки +tags: + - Изображение + - Работа с изображениями + - Рисунок + - Руководство +translation_of: MDN/Editor/Images +--- +
{{MDNSidebar}}
+ +

Изображения очень часто используются при оформлении статей. Они могут быть снимками экрана (screenshot), примерами того, как должно выглядеть произведение искусства, SVG-диаграммами. Данная статья описывает способы работы с изображениями в контенте сайта MDN.

+ +
Замечание: При загрузке изображения, пожалуйста, убедитесь, что используете инструменты оптимизации, чтобы сделать файл маленьким, а загрузку возможной. Это сокращает время загрузки страницы и помогает производительности MDN в целом. Вы можете использовать свой любимый инструмент, если он у вас есть. Иначе, мы предлагаем TinyPNG - удобный Веб инструмент.
+ +

После добавления изображения на страницу (смотрите {{SectionOnPage("/en-US/docs/MDN/Contribute/Editor/Basics", "The attachments box")}}), его можно использовать в оформлении статьи. Также можно использовать любые уже загруженные изображения, размещенные на сайте MDN. Для добавления нажмите на кнопку "Изображение" на панели инструментов: Toolbar icon for inserting image

+ +

Окно Свойства изображения:

+ +

+ +

Здесь присутствуют три вкладки: "Данные об изображении" (Image Info), "Ссылка" (Link), "Дополнительно" (Advanced).

+ +

Вкладка "Данные об изображении"

+ +
+
Прикреплённые файлы (Attachments)
+
Этот выпадающий список содержит прикреплённые к странице элементы. Здесь перечислены только объекты, загруженные в текущем сеансе редактирования или те, которые уже используются на странице.
+
Ссылка (URL)
+
Если есть необходимость использовать рисунок, которого нет в аттачментах, например, файл загружен в прошлом сеансе редактирования или используется где-то на MDN, то можно указать URL рисунка.
+
Альтернативный текст (Alternative text)
+
Текст, который будет показываться вместо изображения, если оно не отображается (например, если пользователь выключил отображение картинок в браузере). Этот текст также используется программами чтения с экрана, поэтому, пожалуйста, поместите соответствующую заметку здесь для удобства доступа.
+
Ширина / Высота (Width / Height)
+
Вы можете настраивать ширину и высоту изображения, как указано в этой статье. По умолчанию эти поля заблокированы для сохранения пропорций изображения, но блокировку можно отключить нажатием на значёк .
+
Граница (Border)
+
Дополнительно можно установить толщину границы вокруг изображения. Рекоммендуется указывать 0 (ноль или оставить пустым) или 1. Используйте эту опцию только в том случае, если фон изображения светлый и его нужно дополнительно выделить на фоне веб-страницы.
+
Горизонтальный отступ / Вертикальгый отступ (HSpace / VSpace)
+
Указывается число пикселей, которое нужно отступить от изображения по горизонтали или вертикали, например, чтобы отодвинуть текст. Обычно эта настройка используется вместе с выравниванием, описанным ниже.
+
Выравнивание (Alignment)
+
По умолчанию изображения отображаются по отдельности от текста или других изображений (текст и новые изображения обычно переносятся на новую строку). Но этой опцией можно указать, какой стороны листа (левой или правой) должно придерживаться изображение и с какой стороны (правой или левой соответстсвенно) текст будет его обтекать. Так приходится оформлять статьи, если изображение маленькое (или, например, узкое и длинное), и тем самым можно сэкономить свободное пространство и повысить удобство чтения. Если используется эта опция, то, вероятно, нужно будет использовать опции горизонтального и вертикального отступа, чтобы немного отодвинуть текст от изображения. Например, для отступа может использоваться значение 6 или 8.
+
+ +

Область "Предпросмотр" показывает пример изображения, которое изменится, исходя из введённых параметров.

+ +

Вкладка "Ссылка"

+ +

Здесь настраивается ссылка, по которой произойдёт переход при клике на изображение. Часто используется ссылка на увеличенное изображение (можно использовать ту же ссылку, что и на вкладке "Данные об изображении"). Пример:

+ +

+ +
+
Ссылка (URL)
+
Ссылка для перехода при клике на изображение.
+
Цель (Target)
+
Вариант открытия страницы перехода. Значения аналогичные атрибуту {{htmlattrxref("target", "a")}} HTML-тега {{HTMLElement("a")}}. Не рекоммендуется использовать это поле на MDN. На MDN отдаётся предпочтение открытию ссылок на текущей вкладке браузера.
+
+ +

Поддерживаемые типы изображений

+ +

Вы можете загружать изображения следующих типов: GIF, JPEG, PNG , а также SVG-диаграммы. Предпочитаемые типы на MDN:

+ + + +

Можно загружать файлы из Photoshop. Но их нельзя будет использовать для оформления статей, а только выкладывать для загрузки пользователями.

+ +

Удаление и изменение

+ +

Для удаление изображения из статьи кликните в изображение мышкой (или установите курсор непосредственно до изображения) и нажмите на клавиатуре клавишу "delete".

+ +

Можно изменить свойства изображения, кликнув на него дважды или кликнув правой кнопкой мыши и выбрав из выпадающего контекстного меню пункт "Свойства изображения". В обоих случаях откроется один и тот же диалог.

+ +

Удалять вложения могут только администраторы MDN. Обычно мы оставляем старые версии изображений, потому что на них могут оставаться ссылки из старых версий документов. В случае обнаружения недопустимых, неуместных или проприетарных изображений, пожалуйста, обратитесь к администратору MDN для удаления такого вложения или заведите инцидент для удаления.

+ +

{{EditorGuideQuicklinks}}

diff --git a/files/ru/orphaned/mdn/editor/index.html b/files/ru/orphaned/mdn/editor/index.html new file mode 100644 index 0000000000..df98522e38 --- /dev/null +++ b/files/ru/orphaned/mdn/editor/index.html @@ -0,0 +1,47 @@ +--- +title: Руководство по MDN редактору +slug: MDN/Editor +tags: + - Landing + - MDN + - Редактор MDN +translation_of: MDN/Editor +--- +
{{MDNSidebar}}
+ +
{{IncludeSubnav("/ru/docs/MDN")}}
+ +

WYSIWYG ("what-you-see-is-what-you-get" в переводе "что видишь, то и получишь") — редактор для веб-документов MDN, который позволяет легко делать вклад в новый контент. Это руководство показывает, как использовать редактор и улучшить вашу продуктивность. Пожалуйста, убедитесь в том, что прочитали Условия использования Mozilla и согласны с ними перед тем, как начать редактировать или создавать новые страницы.

+ +

Руководство по оформлению MDN предлагает информацию о том, как оформлять и стилизовать контент, включая предпочтительные грамматические и орфографические правила.

+ +
+
+
+
Редактор UI элементов
+
Встроенный WYSIWYG редактор на MDN разработан так, чтобы максимально упростить создание, редактирование и улучшение статей и других страниц практически на всем сайте. Окно редактора, как показано ниже, состоит из восьми блоков.
+ Это руководство предоставляет информацию о каждом разделе, чтобы вы знали, как использовать все возможности нашего редактора.
+
Изображения
+
Изображения очень часто используются при оформлении статей. Они могут быть снимками экрана, примерами того, как должен выглядеть результат, SVG-диаграммами. Данная статья описывает способы работы с изображениями в контенте сайта MDN.
+
Горячие клавиши в редакторе MDN
+
Существует ряд удобных горячих клавиш, позволяющих вам не отрывать руки от клавиатуры во время работы в UI редактора MDN. Они перечислены в этой статье.
+
Ссылки
+
Ссылки — это ключевой компонент любой вики не только среди множества документов, но и в пределах одного. К счастью, ссылки очень легко создавать, даже несмотря на то, что есть очень много способов сделать их! В статье рассказывается всё о ссылках в редакторе MDN.
+
+
+ +
+
+
Перенаправление
+
Иногда вам понадобится создать страницу, которая просто перенаправляет на другую страницу. В этой статье рассказывается, как сделать переадресацию.
+
Режим источника
+
В редакторе MDN есть особая кнопка, позволяющая вам включать режим источника. В этом режиме вы можете видеть HTML-код тела статьи, которую вы пишете. Это руководство поможет вам понять, что вы можете делать в режиме источника, что вам следует с ним делать и, самое важное, чего вам делать не следует.
+
Синтаксические выделения
+
Синтаксическое выделение кода крайне полезно в статьях. Режим синтаксического выделения также используется в нашей системе шаблонов, чтобы определять, как использовать каждый отрывок кода при сборке в готовый экземпляр.
+
Таблицы
+
Таблицы полезны для представления информации. В этой статье описано, как создавать и обслуживать таблицы на MDN и когда стоит и не стоит использовать их.
+
+
+
+ +

{{EditorGuideQuicklinks}}

diff --git a/files/ru/orphaned/mdn/editor/keyboard_shortcuts/index.html b/files/ru/orphaned/mdn/editor/keyboard_shortcuts/index.html new file mode 100644 index 0000000000..7a697614df --- /dev/null +++ b/files/ru/orphaned/mdn/editor/keyboard_shortcuts/index.html @@ -0,0 +1,146 @@ +--- +title: Горячие клавиши в редакторе MDN +slug: MDN/Editor/Горячие_клавиши +tags: + - MDN + - MDN Meta + - Reference + - Горячие клавиши + - Клавиши + - Редактор +translation_of: MDN/Editor/Keyboard_shortcuts +--- +

Существует ряд удобных горячих клавиш, позволяющих вам не отрывать руки от клавиатуры во время работы в UI редактора MDN.

+ +

Горячие клавиши перечислены для Windows и Linux; для Mac вместо ключа Control используйте Command.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Сочетание клавишОписание
Ctrl + AВыделить всё
Ctrl + CКопировать
Ctrl + VВставить
Ctrl + Shift + VВставить без форматирования
Ctrl + XВырезать
Ctrl + ZОтменить
Ctrl + YПовторить
Ctrl + KОткрыть редактор ссылок/добавить новую ссылку
Ctrl + Shift + KУдалить ссылку в текущем положении курсора
Ctrl + BПолужирный текст
Ctrl + IКурсив
Ctrl + OВключить стилизацию <code>
Ctrl + Shift + O +

Включить режим просмотра источника

+ +
Будьте внимательны при работе в режиме источника: вы должны придерживаться наших стандартов заполнения содержимого. Ознакомьтесь с нашим гайдом по режиму источника, чтобы узнать, как использовать режим источника и что вам следует и не следует делать в нём.
+
Ctrl + P +
+Включить или отключить стилизацию <pre> в текущем блоке.
+
Ctrl + UПодчёркивание
Ctrl + SОпубликовать изменения, не закрывая редактор
Ctrl + Shift + SОпубликовать изменения и закрыть редактор
Ctrl + 0Удалить форматирование в выделенной области (Это ноль, а не буква "О")
От Ctrl + 2 до Ctrl + 5Выбор уровней заголовков от 2 до 5. Уровень 1 предназначен для заголовка страницы, расположенного в верху статьи
Ctrl + Shift + LПреобразование выделенного текста (по порядку): в нумерованный список — в маркированный список — удалить список
TabУвеличивает отступ или же вставляет два пробела. В таблицах перемещает курсор в следующую ячейку или вставляет новый ряд, если следующей клетки нет. Курсор перемещается на следующий абзац, если находится на заголовке страницы
Shift + TabУменьшает отступ. В таблицах перемещает курсор в предыдущую ячейку или вставляет новый ряд, если предыдущей клетки нет. Курсор перемещается на следующий абзац, если находится на заголовке страницы
Shift + SpaceВставляет неразрывный пробел(&nbsp;)
Shift + Enter +

Выводит из блока. К примеру, если вы редактируете блок <pre>Shift + Enter выводит курсор из блока, помещая его обратно в тело статьи

+ +
+

На данный момент не поддерживается: {{bug('780055')}}.

+
+
+ +

Смотрите также

+ + + +
{{MDNSidebar}}
diff --git a/files/ru/orphaned/mdn/editor/links/index.html b/files/ru/orphaned/mdn/editor/links/index.html new file mode 100644 index 0000000000..459a965172 --- /dev/null +++ b/files/ru/orphaned/mdn/editor/links/index.html @@ -0,0 +1,187 @@ +--- +title: Создание ссылок в статьях MDN +slug: MDN/Editor/Ссылки +tags: + - Guide + - MDN + - MDN Meta + - Документация + - Редактор + - Руководство +translation_of: MDN/Editor/Links +--- +
{{MDNSidebar}}
+ + + +
+

Обратите внимание, что у нас есть особые правила применения ссылок: они описаны в руководстве по оформлению материалов MDN.

+
+ +

Использование панели инструментов

+ +

Самый очевидный способ создать ссылку — нажать на кнопку Вставить/Редактировать ссылку на панели инструментов или нажать сочетание Ctl+K (Command-K для Mac). Кнопка ссылки вглядит так: The link button (as of 2015-12-04). Вы можете добавлять текст к выделенному тексту.

+ +

Создание ссылки

+ +

После нажатия на кнопку ссылки появится диалоговое окно для работы с ссылками:

+ +

Окно для работы с ссылками

+ +

Здесь вы можете создать новую ссылку. Параметры окна:

+ +
+
Ссылка (Link Type)
+
Это тип создаваемой вами ссылки. Тип по умолчанию, URL, используется в сети — или в MDN, или вне его. Вы также можете выбрать "Link to anchor in the text" или "Email". Ссылка-якорь позволяет вам привязать её к якорю, созданному вами ранее с помощью кнопки Вставить / редактировать якорь  на панели инструментов. Опция email позволяет вам настрить: URL-адрес получателя, получателя и сообщение. Чаще всего вы будете использовать тип URL.
+
Поиск ссылки по заголовку / Текст ссылки (Article Title Lookup / Link Text)
+
У этого поля есть две цели: во-первых, вы обозначаете текст, который будет использован как указатель ссылки (или, если вы выделили текст до открытия окна, он будет отображён как указатель ссылки), во-вторых, текст, введённый в это поле, используется для поиска  статей на MDN, чтобы найти возможное направление ссылки. К примеру, если вы введёте "Array" в поле, вы увидите что-то наподобие этого:
+ Screenshot of the Link dialog box, showing a lookup menu for the text "Array"
+
+ +
+
На картинке вы можете видеть все страницы MDN, чьи заголовки содержат текст, напечатанный вами. Вы можете прокрутить список и выбрать одну из страниц или продолжить набирать текст, сужая список. Заметьте, у названий страниц отображается их язык (в нашем примере это "[en-US]"). Это не отображается в указателе ссылки; так сделано для того, чтобы вы убедились, что вы ссылаетесь на статью того же языка, на котором пишете вы.
+
Прикрепление ссылки (Attachments)
+
В качестве альтернативы вы можете сделать так, чтобы ссылка была привязана к одному из файлов, прикрпеплённому к этой странице. Это отличный способ предоставить ссылку для скачивания примера кода и тому подобное.
+
URL
+
Наконец, поле для URL-адреса позволяет вам ввести URL; в поле также выводятся URL выбранных вами элементов из меню Article Title Lookup или Attachments, если вы их использовали. Нередко используют URL-адреса страниц MDN, поэтому, если вы ссылаетесь на другую страницу MDN, удалите доменное имя ("https://developer.mozilla.org") из начала URL.
+
+ +

Как только завершите настройку ссылки, нажмите OK.

+ +
+

В верху окна также есть вкладка Advanced. Нет опций, которые мы советуем вам использовать регулярно, по крайней мере, сейчас. Можете быть, в будущем появятся новые стили для ссылок, но мы, вероятно, добавим новую панель инструментов для этих опций.

+
+ +

Ссылки

+ +

Если у вас есть текст, который вы хотели бы превратить в ссылку, вы можете слегка упростить процесс. Выделите нужный вам текст, затем откройте окно для работы с сылками; поле Article Title / Lookup Text будет заполнено выделенным текстом. К примеру, есть у нас, скажем, следующий текст:

+ +
+

You may find it useful to use JavaScript arrays when working on this project.

+
+ +

Нам хотелось бы преобразовать arrays в ссылку на файл с соответствующим содержанием. Просто выделите слово и включите окно для работы с ссылками; у вас появится заполненное окно, похожее на изображение выше. Наводя мышь на поле-подсказку, вы можете видеть её относительный путь (его URL относится к developer.mozilla.org), благодаря чему вы можете лучше узнать, где  находится статья и о чём она.

+ +

Screenshot of the Link dialog box, showing a lookup menu and a URL tooltip

+ +

На примере: подсказки — это возможные совпадения. Кажется, arrays было выбрано удачно; выберем этот вариант. Поле сразу заполняется URL-адресом, поэтому мы просто жмём OK, и цитата будет выглядеть так:

+ +
+

You may find it useful to use JavaScript arrays when working on this project.

+
+ +

Использование макросов

+ +

MDN часто использует макросы, чтобы автоматически создавать термины-ссылки с соответствующим содержанием, стилизуя их как ссылки в сответствии с нашими правилами оформления элементов. Учтите: наше руководство отмечает, что API-термины, элементы и атрибуты HTML, свойства, имена функций CSS и тому подобное,— должны быть стилизованы с помощью элемента {{HTMLElement("code")}}. Также должны быть ссылки на другие страницы MDN.

+ +

К использованию макросов для создания ссылок легко привыкнуть, и это предоставляет множество плюсов:

+ + + +

Есть очень много таких макросов, и мы не будем останавливаться на них подробно здесь. Вместо этого мы разберём несколько самых часто употребляемых. Если интересно, ознакомьтесь с разделом "Создание гиперссылок" в нашей статье Пользовательский макрос для MDN.

+ +
+

Ещё проще посетить KumaScript, где есть любой из этих макросов; ко многим макросам есть комментарии вверху, объясняющие, как макрос работает и какие у него переменные.

+
+ +

Ссылка на документацию для API

+ +

У нас есть есколько невероятно полезных макросов для создания стилизованных ссылок для API. В этом подразделе перечислены самые удобные; в каждый блок могут быть добавлены доступные параметры, чтобы предоставить больший контроль над выводом. На название каждого макроса можно кликнуть, чтобы увидеть сам код макроса; у каждого макроса есть комментарии вверху, объясняющие, как макрос работает и какие у него переменные.

+ +
+
{{TemplateLink("HTMLElement")}}
+
Вставляет в HTML-код название элемента с необходимыми стилизацией и ссылками. К примеру: \{{HTMLElement("table")}} даёт {{HTMLElement("table")}}.
+
{{TemplateLink("cssxref")}}
+
Вставляет в CSS-код документацию свойства, правила или селектора. Например: \{{cssxref("background-color")}} в результате выводит {{cssxref("background-color")}}.
+
{{TemplateLink("domxref")}}
+
Вставляет данный термин API. Пример: \{{domxref("window")}} даёт в результате {{domxref("window")}}, и \{{domxref("window.scrollBy()")}} вставляет {{domxref("window.scrollBy()")}}. Вы также можете вставить дополнительный параметр, чтобы заменить текст: \{{domxref("window.scrollBy", "scrollBy()")}} заменяет {{domxref("window.scrollBy")}} на {{domxref("window.scrollBy", "scrollBy()")}}.
+
{{TemplateLink("SVGElement")}}
+
Вставляет название SVG-элемента с необходимыми стилизацией и ссылками. К примеру: \{{SVGElement("circle")}} даёт {{SVGElement("circle")}}.
+
+ +

Добавление якорей

+ +

Чтобы применить ссылку к области с таким же названием, следует использовать макрос {{TemplateLink("anch")}}. Синтаксис — проще некуда: \{{anch("Name of destination section")}}. По умолчанию текст ссылки — это название области, но вы можете добавить второй, необязательный, параметр, обозначающий альтернативный текст. Несколько примеров:

+ + + +

Ссылки к багам

+ +

Вы можете создать ссылку на базу данных Mozilla's Bugzilla с макросом {{TemplateLink("bug")}}. У этого макроса всего один параметр: номер бага, на который ссылаются. К примеру, \{{bug(765642)}} покажет: {{bug(765642)}}.

+ +

Таким же образом вы можете создавать ссылки к багам на других брузерах и брузерных движках:

+ +
+
WebKit (Safari и т.д.)
+
{{TemplateLink("WebkitBug")}}: \{{webkitbug(31277)}} даёт {{webkitbug(31277)}}.
+
+ +

Ссылки к RFC

+ +

Суть работы Интернета изложена в RFC. Вы можете с лёгкостью обратиться к RFCs с помощью {{TemplateLink("RFC")}}. Для примера, \{{RFC(2616)}} станет {{RFC(2616)}}. Вы можете при желании снабдить макрос альтернативной ссылкой, чтобы использовать вместо выделенного участка текста или нескольких участков, с описанием, к какой ссылке привязать их.

+ +

Ссылки к информации о XPCOM-интерфейсах

+ +
+

MDN больше не поддерживает XPCOM-документацию, но внесение вклада приветствуется!

+
+ +

Если вы документируете свойства Mozilla, способность быстро создать ссылку к документации XPCOM очень полезна. Здесь несколько макросов для этого.

+ +

Синтаксис: \{{interface("interfacename")}}. К примеру, вы написали:

+ +
+

When you need to parse or create URIs, the \{{interface("nsIIOService")}} interface can help.

+
+ +

В результате получится

+ +
+

When you need to parse or create URIs, the {{interface("nsIIOService")}} interface can help.

+
+ +

Если вам нужна ссылка к информации о методе или атрибуте XPCOM-интерфейса, макросы {{TemplateLink("ifmethod")}} и {{TemplateLink("ifattribute")}} точно для вас. Названия интерфейса и метода или атрибута, к которым вы ссылаетесь, принимаются за параметры. Макрос {{TemplateLink("ifmethod")}} особенно интересен, т.к. он по-особому форматирует элемент при добавлении стиля родителя после названия метода. Например, \{{ifmethod("nsIIOService", "newURI")}} выводит {{ifmethod("nsIIOService", "newURI")}}. Это контейнер, в котором вы защищены от стилевых изменений MDN в будущем!

+ +

Ссылка к привилегированной документации Mozilla

+ +

Для вставки Mozilla preference и для того, чтобы привязать её к соответствующей странице в Preference reference, используйте макрос {{TemplateLink("pref")}} . У него всего один параметр: полное название привилегерованного элемента. Например, \{{pref("javascript.options.showInConsole")}} преобразуется в: {{pref("javascript.options.showInConsole")}}.

+ +

Ссылка к ресурсам Mozilla

+ +

Вы можете ссылаться на дерево ресурсов Mozilla's (хотя не стоит делать это часто), используя макрос {{TemplateLink("source")}}. Вместо указания абсолютного пути вам достаточно указать путь относительно директории /source/. Для примера: \{{source("browser/Makefile.in")}} создаёт эту ссылку: {{source("browser/Makefile.in")}}.

+ +

Вы можете при желании снабдить ссылку альтернативным тектсом. Например, как видите, \{{source("browser/Makefile.in", "the browser's makefile")}} преобразуется в: {{source("browser/Makefile.in", "the browser's makefile")}}.

+ +
+

Обратите внимание на документацию {{anch("Использование макросов")}}, если вы заинтересованы в более подробном изучении макросов и посетите KumaScript, чтобы больше узнать о системе макросов.

+
+ +

Ссылки на рекомендованные статьи

+ +

Если вы хотите создать список связанных страниц или другого рекомендованного материала к прочтению, вам следует делать это с помощью создания контейнера быстрых ссылок в боковой панели. Такой подход заменяет наши старые Смотрите также в конце статей. О том, как создавать контейнер с быстрыми ссылками, читайте в статье Быстрые ссылки.

+ +

Схемы URL-адресов

+ +

В целях безопасности создавайте ссылки, имеющие следующие схемы:

+ + + +

Дргуие схемы просто-напросто будут удалены.

+ +
+

Особые URL-схемы, такие как about: и chrome: используются Firefox, Google Chrome и некоторыми другими браузерами, чтобы предоставить доступ к особым опциям, таким как привилегерованные элементы, отладочная информация и так далее. Эти ссылки не работают в содержимом статьи, поэтому не создавайте ссылки, используя эти схемы в MDN. То же относится и к схемам javascript: и jar:, которые блокируются большинством браузеров в целях безопасности.

+
+ +

{{EditorGuideQuicklinks}}

diff --git a/files/ru/orphaned/mdn/editor/redirects/index.html b/files/ru/orphaned/mdn/editor/redirects/index.html new file mode 100644 index 0000000000..dade13fb99 --- /dev/null +++ b/files/ru/orphaned/mdn/editor/redirects/index.html @@ -0,0 +1,31 @@ +--- +title: Перенаправление +slug: MDN/Editor/Перенаправление +tags: + - Гайд + - Переадресация + - Перенаправление + - Удаление +translation_of: MDN/Editor/Redirects +--- +
{{MDNSidebar}}
+ +

Иногда вам понадобится создать страницу, которая просто перенаправляет на другую страницу. В этой статье рассказывается, как сделать переадресацию.

+ +

Создание перенаправления

+ +

Перенаправление необходимо, к примеру, когда страница слилась с другой. Чтобы создать перенаправление, просто нажмите эту кнопку в панели инструментов: .

+ +

Она откроет диалоговое окно, в котором запрашивается имя документа и его URL-адрес. Вообще, имя не так важно; оно больше нужно, если вы сами ищете страницу, и вам нужно знать, куда вы перенаправляете. В поле URL должен быть указан абсолютный (полный) путь, например, "/en-US/docs/foo". Относительные ссылки не сработают. Вы можете перенаправить на раздел страницы, используя хэштэг ("#"), например: "/destination/url/here#название_раздела". Таким образом вы перенапривите пользователя прямиком в раздел страницы.

+ +

На странице должно быть только перенаправление; перед его созданием переместите всё содержимое в его новый "дом". Удалите также ревизионные флаги с  этой страницы.

+ +
+

Замечание: Обязательно удалите все теги со страницы: если вы это не сделаете, страница с перенаправлением будет рядом со страницей, на которую перенаправили (теги-то одинаковые), смущая людей и занимая свободное место на странице результатоыв поиска. Ещё это плохо скажется на поисковой оптимизации.

+
+ +

При удалении страницы

+ +

Перед удалением страницы подумайте: а не будет ли лучше перенаправить посетителя на другую страницу MDN? Ведь, если он попадёт на страницу по старой ссылке, лучше отправить его на правильную страницу, чем если бы ему выдали ошибку 404 ("страница не найдена"). Удалять страницу стоит только в крйнем случае: если она забита спамом и прочим неуместным контентом.

+ +

{{EditorGuideQuicklinks}}

diff --git a/files/ru/orphaned/mdn/editor/source_mode/index.html b/files/ru/orphaned/mdn/editor/source_mode/index.html new file mode 100644 index 0000000000..af5d7b5535 --- /dev/null +++ b/files/ru/orphaned/mdn/editor/source_mode/index.html @@ -0,0 +1,128 @@ +--- +title: Режим источника +slug: MDN/Editor/Source_mode +tags: + - Guide + - MDN Meta + - NeedsContent + - editor + - Редактор MDN + - Руководство +translation_of: MDN/Editor/Source_mode +--- +
{{MDNSidebar}}
+ +

 В редакторе MDN есть особая кнопка, позволяющая вам включать режим источника. В этом режиме вы можете видеть HTML-код тела статьи, которую вы пишите. Это руководство поможет вам понять, что вы можете делать в режиме источника, что вам следует с ним делать и, самое важное, чего вам делать не следует.

+ +
+

Перед тем как использовать режим источника, примите во внимание, что мы крайне не рекомендуем использовать режим источника. За исключением случаев, когда то, что вы делаете в режиме источника, соответствует нашему руководству по оформлению кода (мы нуждаемся в опциях, которые, к сожалению, пока что не могут быть созданы без режима источника), вам нет необходимости в использовании этого режима. Смотрите {{anch("Предостережения")}} ниже.

+
+ +

Включение режима источника

+ +

Включить режим источника очень легко. В левом верхнем углу нажмите кнопку Источник.

+ +

Partial screenshot of the editor toolbar, with the Source mode button highlighted

+ +

Предостережения

+ +

Как упомянуто ранее, вам редко понадобится режим источника. Немного вы сможете сделать в этом режиме. Со временем мы обновим интерфейс редактора, чтобы настроить это немного для вас.

+ +

Всего того, что неявно описано где-то в руководстве по сотрудничеству с MDN, не должно быть в источнике. Это значит, что:

+ + + +

Работа в режиме источника

+ +

В режиме источника вы работаете с HTML-кодом, который составляет контент страницы вики. Если вы не ограничиваетесь обычным редактором, вы должны убедиться в том, что ваша работа соответствует оформлению и что она работает надёжно и безопасно.

+ +

К сожалению, клавиша Tab пока что не работает в режиме источника. Используйте два пробела там, где обычно используете Tab.

+ +

Элементы и атрибуты, которые MDN не поддерживает, будут удалены после сохранения документа. Вдобавок HTML документа преобразован, чтобы он был более читаемым и совместимым.

+ +

Использование режима источника

+ +

Здесь описано несколько случаев, когда единственный способ соответствовать оформлению статей MDN — использовать режим источника. Этот раздел описывает эти ситуации и как правильно выполнять данные функции, чтобы не испортить остальное.

+ +

Выделение строк в примерах кода

+ +

Блоки примеров кода устанавливаются кнопками PRE или Syntax Highlighter в блоках панели инструментов, но вы, возможно, захотите обратить внимание читателей на определённые строки кода. Единственный способ сделать это — открыть режим источника, найти там блок <pre>, содержащий код, и добавить в атрибут class тега <pre>  компонент highlight, отформатированный следующим образом:

+ + + +
"hightlight[" <список-номеров-строк> "]"
+
+Где:
+<список-номеров-строк> = [ <номер-строки> | <диапазон-строк> ]#
+<диапазон-строк> = <номер-строки> - <номер-строки>
+<номер-строки> = <число-токен>
+ +
+

Выделенные строки не отображаются в редакторе MDN.

+
+ +

К примеру, если есть тег <pre class="brush: js;">, и вы хотите выделить строки 4 и 7, то вы меняете тег: <pre class="brush: js; highlight[4, 7]">.

+ +

Давайте взглянем на более полный пример:

+ +
+ + + + + + + + + + + + + +
До выделенияС выделением
+
+var canvas = document.getElementById("canvas");
+var ctx = canvas.getContext("2d");
+
+var path1 = new Path2D();
+path1.rect(10, 10, 100, 100);
+
+var path2 = new Path2D(path1);
+path2.moveTo(220, 60);
+path2.arc(170, 60, 50, 0, 2 * Math.PI);
+
+ctx.stroke(path2);
+
+ +

Здесь тег {{HTMLElement("pre")}} равен: <pre class="brush: js;">

+
+
+var canvas = document.getElementById("canvas");
+var ctx = canvas.getContext("2d");
+
+var path1 = new Path2D();
+path1.rect(10, 10, 100, 100);
+
+var path2 = new Path2D(path1);
+path2.moveTo(220, 60);
+path2.arc(170, 60, 50, 0, 2 * Math.PI);
+
+ctx.stroke(path2);
+ +

А здесь тег <pre> изменён на: <pre class="brush: js; highlight[4, 7]">

+
+
+ +

Стили, которых нет в панели инструментов

+ +

У нас есть несколько стилей, которые нельзя применить, не используя режим источника. К счастью, их редко когда используют. Например:

+ + diff --git a/files/ru/orphaned/mdn/editor/syntax_highlighting/index.html b/files/ru/orphaned/mdn/editor/syntax_highlighting/index.html new file mode 100644 index 0000000000..f959ae7809 --- /dev/null +++ b/files/ru/orphaned/mdn/editor/syntax_highlighting/index.html @@ -0,0 +1,181 @@ +--- +title: Синтаксические выделения +slug: MDN/Editor/Синтаксические_выделения +tags: + - Guide + - Howto + - MDN + - MDN Meta + - Редактор + - Руководство + - выделение +translation_of: MDN/Editor/Syntax_highlighting +--- +
{{MDNSidebar}}
+ +

Синтаксическое выделение кода крайне полезно в статьях. Режим синтаксичесого выделения также используется в нашей системе шаблонов, чтобы определять, как использовать каждый отрывок кода при сборке в готовый экземпляр.

+ +

Поддержка синтаксических выделений

+ +

MDN поддерживает все переодически используемые нами на MDN языки (так же, как и те, что используются лишь иногда):

+ +
+
    +
  • Bash shell
  • +
  • +

    C/C++

    +
  • +
  • +

    CSS

    +
  • +
  • HTML
  • +
  • XML
  • +
  • +

    Java

    +
  • +
  • +

    JavaScript

    +
  • +
  • +

    JSON

    +
  • +
  • +

    PHP

    +
  • +
  • +

    Python

    +
  • +
  • +

    SQL 

    +
  • +
+
+ +

Синтаксические выделения делают код удобнее в прочтении, особенно когда статья переполнена другими видами текста. Выделения также помогают выделить ошибки в примерах и отрывках кода.

+ +

Добавление выделения

+ +

Как правило, следует выделять любой блок {{HTMLElement("pre")}}, который представляет код, состоящий из более чем одной строчки; выделение однострочного кода будет зависеть от контекста.

+ +

Синтаксические выделения в примерах кода:

+ +
    +
  1. +

    Наберите или вставьте код в статью. Например:

    + +

    void main(int argc, char **argv) {

    + +

    printf("Привет, мир!\n");

    + +

    }

    +
  2. +
  3. +

    Выделите текст и нажмите кнопку PRE в панели инструментов. Результат:

    + +
    void main(int argc, char **argv) {
    +
    +printf("Hello world\n");
    +
    +}
    +
    +
  4. +
  5. +

    Нажмите кнопку Syntax Highlighter и выберите название соответстующего коду языка программирования. В нашем примере это C/C++:

    + +
    void main(int argc, char **argv) {
    +
    +printf("Hello world\n");
    +
    +}
    +
  6. +
+ +

Вы можете немного упростить процесс, не нажимая кнопку PRE и сразу выбрав нужный вам язык. Добавление выделения автоматически вставит необходимый блок {{HTMLElement("pre")}}, если он ещё не на месте.

+ +

Далее представлен перевод раздела {{SectionOnPage("/en-US/docs/MDN/Contribute/Editor/Source_mode", "Выделение строк в режиме источника")}}:

+ +

Выделение линий в примере

+ +

Блоки примеров кода устанавливаются кнопками PRE или Syntax Highlighter в блоках панели инструментов, но вы, возможно, захотите обратить внимание читателей на определённые строки кода. Единственный способ сделать это — открыть режим источника, найти там блок <pre>, содержащий код, и добавить в атрибут class тега <pre>  компонент highlight, отформатированный следующим образом:

+ + + +
"hightlight[" <список-номеров-строк> "]"
+
+Где:
+<список-номеров-строк> = [ <номер-строки> | <диапазон-строк> ]#
+<диапазон-строк> = <номер-строки> - <line-number>
+<номер-строки> = <токен>
+ +

К примеру, если есть тег <pre class="brush: js;">, и вы хотите выделить строки 4 и 7, то вы меняете тег: <pre class="brush: js; highlight[4, 7]">.

+ +

Давайте взглянем на более полный пример:

+ +
+ + + + + + + + + + + + + +
До выделенияС выделением
+
+var canvas = document.getElementById("canvas");
+var ctx = canvas.getContext("2d");
+
+var path1 = new Path2D();
+path1.rect(10, 10, 100, 100);
+
+var path2 = new Path2D(path1);
+path2.moveTo(220, 60);
+path2.arc(170, 60, 50, 0, 2 * Math.PI);
+
+ctx.stroke(path2);
+
+ +

Здесь тег {{HTMLElement("pre")}} равен: <pre class="brush: js;">

+
+
+var canvas = document.getElementById("canvas");
+var ctx = canvas.getContext("2d");
+
+var path1 = new Path2D();
+path1.rect(10, 10, 100, 100);
+
+var path2 = new Path2D(path1);
+path2.moveTo(220, 60);
+path2.arc(170, 60, 50, 0, 2 * Math.PI);
+
+ctx.stroke(path2);
+ +

А здесь тег <pre> был изменён на: <pre class="brush: js; highlight[4, 7]">

+
+
+ +
+

Выделенные строки не отображаются в редакторе MDN.

+
+ +

Смотрите также

+ + + +
{{EditorGuideQuicklinks}}
diff --git a/files/ru/orphaned/mdn/editor/tables/index.html b/files/ru/orphaned/mdn/editor/tables/index.html new file mode 100644 index 0000000000..1f6f988d6a --- /dev/null +++ b/files/ru/orphaned/mdn/editor/tables/index.html @@ -0,0 +1,162 @@ +--- +title: Таблицы +slug: MDN/Editor/Tables +tags: + - Guide + - MDN + - MDN Meta + - Редактор + - Руководство +translation_of: MDN/Editor/Tables +--- +
{{MDNSidebar}}
+ +

Таблицы полезны для представления информации; в этой статье описано, как создавать и обслуживать таблицы на MDN и когда стоит и не стоит использовать их.

+ +

В MDN, в основном, мы используем таблицы для представления перечня информации из более чем двух участков информации, приходящихся на один пункт. Если вы создаёте лист из названия элементов и их значений, то лучше создать список описаний вместо таблицы; это потому что мы стараемся по возможности реже использовать таблицы из двух колонок, так как возникают трудности их отображения при чтении на мобильных устройствах.

+ +

Пожалуйста, прочтите Руководство по оформлению материалов MDN, чтобы лучше узнать об использовании таблиц и их правильном оформлении; всё же давайте посмотрим, как вставлять и редактировать таблицы.

+ +

Создание таблицы

+ +

Чтобы вставить таблицу, нажмите кнопку Таблица на панели инструментов, которая выглядит так: as of Aug-2017

+ +

Откроется окно Свойства таблицы:

+ +

Скриншот окна "Свойства таблицы"

+ +

В окне две вкладки: Свойства таблицы и Дополнительно.

+ +

Вкладка Свойства таблицы

+ +

В этой вкладке вы будете выполнять бо́льшую часть настроек, потому что во вкладке Дополнительно гораздо меньше настроек, которые мы рекомендуем использовать. Опции:

+ +
+
Строки
+
Число строк в вашей таблице. Вы также можете добавить строки непосредственно в редакторе, но так будет быстрее.
+
Колонки
+
Число колонок в таблице.
+
Заголовки
+
Позволяет вам обозначить заголовки, если это необходимо. По умолчанию в таблице нет заголовков; однако мы предпочитаем использовать заголовки, поэтому советуем вам использовать их в большинстве случаев. Возможные значения: Без заголовков, Первая строка, Левая колонка и Сверху и слева.
+
Выравнивание
+
Позволяет выравнивать таблицу в левой, правой или центральной части страницы. Пожалуйста, не используйте эту опцию. В нашем руководстве по оформлению указано, что таблицы всегда должны нахадиться слева. (Из этого правила есть исключения.)
+
Заголовок
+
Вы можете выбрать заголовок к таблице; однако мы редко делаем это в MDN, поэтому лучше не использовать эту опцию.
+
Итоги
+
Просто пропустите этот пункт, потому что рядом с таблицей вам придётся писать объяснение.
+
+ +

Вкладка Дополнительно

+ +

Вкладка Дополнительно предоставляет несколько возможностей, большую часть которых мы не используем на MDN и в будущем уберём.

+ +

Скриншот вкладки "Дополнительно"

+ +

Как видите, тут немного опций:

+ +
+
Идентификатор
+
Идентификатор (id) элемента {{HTMLElement("table")}}. Мы в принципе не используем идентификаторы в таблицах на MDN.
+
Направление текста
+
Позволяет настроить направление текста в таблице. Используется только при локализации контента.
+
Стиль
+
В этом поле вы можете применить собственный стиль CSS к таблице. Вообще не используйте это поле! В таком случае мы просто удалим вашу таблицу. Мы стараемся избавляться от пользовательских стилей там, где применяются наши.
+
CSS классы
+
Добавляет класс к стилю таблицы. Значение всегда должно быть standard-table, явдяющееся нашим стандартным классом для таблиц.
+
+ +

Как только вы завершите настройку, нажмите кнопку OK для создания таблицы.

+ +

Обслуживание таблиц

+ +

Работа с таблицей очень похожа на работу в любом редакторе таблиц — надо просто заполнить ячейки. Клавиша Tab переместит вас на следующую ячейку таблицы или создаст новую строку, если следующей клетки нет.

+ +

Кликните правой кнопкой мыши по таблице, чтобы появился ряд опций для регулировки самих ячеек, строчек и колонок таблицы, а ткаже самой таблицы:

+ +

Скриншот контекстного меню

+ +
+
Вставить
+
В браузерах поддерживается вставка через скрипт (в некоторых браузерах, в том числе в Firefox, это не поддерживается из соображений безопасности). Эта опция вставляет содержимое буфера обмена в текущую ячейку таблицы.
+
Ячейка
+
Открывает подменю для работы с ячейками.
+
Строка
+
Открывает подменю для работы со строками.
+
Колонка
+
Открывает подменю для работы с колонками.
+
Удалить таблицу
+
Удаляет текущую таблицу.
+
Сортировка (Sort Table)
+
Открывает диалоговое окно для сортировки данных в таблице.
+
Свойства таблицы
+
Открывает то же окно для создания таблицы.
+
+ +

Подменю Ячейка

+ +

Подменю предоставляет опции для манипуляций с ячейками вашей таблицы, и оно выглядит так:

+ +

Скриншот подменю "Ячейка" в контекстном меню

+ +

Названия опций говорят сами за себя, но стоит оговориться, что Объединить ячейки доступно, только если вы выбрали несколько ячеек. Опции Объединить с правой и Объединить с нижней объединяют текущую ячейку с той, что находится справа или снизу соответственно.

+ +

Окно Свойства ячейки

+ +

Опция Свойства ячейки открывает диалоговое окно для детальной настройки ячейки. Окно выглядит вот так:

+ +

Скриншот окна "Свойства ячейки"

+ +

Опции:

+ +
+
Ширина
+
Изменяет ширину клетки; вы можете выбрать единицу изменения в выпадающем меню рядом. Пожалуйста, не используете эту опцию. Вам не понадобится изменять ширину клетки, за исключением случаев, когда надо вставить изображение или пример кода в таблицу.
+
Высота
+
Устанавливает высоту клетки (всегда в пикселах). Пожалуйста, не используете эту опцию. Высота клетки определяется автоматически.
+
Перенос по словам
+
Определяет, будет переноситься содержимое ячейки или нет. Всегда должно быть установлено значение по умолчанию, Да.
+
Горизонтальное выравнивание
+
Позволяет устанавливать выравнивание текста по горизонтали. Следует всегда оставлять значение по умолчанию, По левому краю.
+
Вертикальное выравнивание
+
Позволяет устанавливать выравнивание текста по вертикали.
+
Тип ячейки
+
Позволяет вам определить, какой тип у ячейки — Заголовок или Данные. Если установлено значение Заголовок, то будет применена соответствующая стилизация.
+
Объединяет строк
+
Позволяет определить, сколько строк необходимо объединить. Используется редко, но в некоторых таблицах очень полезно.
+
Объединяет колонок
+
Определяет, сколько колонок необходимо объединить.
+
Цвет фона
+
Определяет цвет фона ячейки. Старайтесь не использовать эту фунцию; редкие случаи, когда смена цвета ячейки приемлема, прописаны в классах CSS.
+
Цвет границ
+
Определяет цвет границы ячейки. Старайтесь не использовать эту фунцию; редкие случаи, когда смена цвета границы ячейки приемлема, прописаны в классах CSS.
+
+ +

Подменю Строка

+ +

Подменю Строка предоставляет опции, используя которые вы можете корректировать строки:

+ +

Скриншот подменю "Строка" в контекстном меню

+ +

Опции подменю по порядку:

+ + + +

Подменю Колонка

+ +

Подменю позволяет вам изменять колонки в вашей таблице:

+ +

Скриншот подменю "Колонка" в контекстном меню

+ +

Опции похожи на опции подменю Строка:

+ + + +

{{EditorGuideQuicklinks}}

diff --git a/files/ru/orphaned/mdn/structures/live_samples/simple_live_sample_demo/index.html b/files/ru/orphaned/mdn/structures/live_samples/simple_live_sample_demo/index.html new file mode 100644 index 0000000000..393a20bc94 --- /dev/null +++ b/files/ru/orphaned/mdn/structures/live_samples/simple_live_sample_demo/index.html @@ -0,0 +1,37 @@ +--- +title: A simple demo of a live code sample +slug: MDN/Structures/Live_samples/Simple_live_sample_demo +tags: + - MDN Meta + - Конструкции + - Пример +translation_of: MDN/Structures/Live_samples/Simple_live_sample_demo +--- +
{{MDNSidebar}}
+ +

Пример

+ +

Это очень простой пример показывающий вам, как сделать живой образец на MDN. Для большей информации смотрите Live samples.

+ +
<form>
+  <label>Try me<input type="text" name="name"></label>
+  <input type="submit" value="go">
+</form>
+ +
form {
+  border-radius: 10px;
+  background: powderblue;
+}
+ +
var f = document.querySelector('form');
+
+f.addEventListener('submit', function(ev) {
+  ev.preventDefault();
+  document.querySelectorAll('input')[1].value = 'sending';
+}, false);
+ +

{{ EmbedLiveSample('Пример', '', '', '') }}

+ +
+

Примечание: На локализованных страницах значение первого параметра должно совпадать с ID заголовка в котором находится пример.

+
diff --git a/files/ru/orphaned/mdn/tools/feeds/index.html b/files/ru/orphaned/mdn/tools/feeds/index.html new file mode 100644 index 0000000000..ba43bf1809 --- /dev/null +++ b/files/ru/orphaned/mdn/tools/feeds/index.html @@ -0,0 +1,73 @@ +--- +title: Ленты новостей MDN +slug: MDN/User_guide/Feeds +tags: + - Kuma +translation_of: MDN/Tools/Feeds +--- +
{{MDNSidebar}}

Вики MDN предлагает ряд лент новостей, которые вы можете использовать для слежения за сайтом. В будущем их, вероятно, будет больше, а некоторые из них до сих пор ещё в разработке, но эта информация всё равно может быть для вас полезна.

+ +

Получение доступа к лентам новостей

+

Все ленты новостей начинаются со следующего базового URL:

+
https://developer.mozilla.org/<локаль>/docs/feeds/<формат>/
+

Заполнители в базовом URL могут быть заменены следующими значениями:

+ +

Если вы используете формат json, вы также можете определить дополнительный параметр запроса ?callback=<имя функции обратного вызова>, который следует соглашению JSONP для загрузки данных как JavaScript.

+ +

Доступные ленты

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ЛентаОписание
all +

Все недавно изменённые статьи, упорядоченные по дате изменения. Также она включает в себя новые статьи. Все изменения объединяются в одну запись в ленте новостей для каждой статьи. Например:

+

https://developer.mozilla.org/ru/docs/feeds/rss/all

+
revisions +

Все ревизии статей, упорядоченные по дате изменения, включая новые статьи. Каждая ревизия занимает отдельную запись в ленте. Например:

+

https://developer.mozilla.org/ru/docs/feeds/atom/revisions

+
tag/<имя-метки> +

Недавно изменённые статьи, упорядоченные по дате изменения. В ленту включаются только статьи с определённой меткой. Например:

+

https://developer.mozilla.org/ru/docs/feeds/json/tag/CSS?callback=loadFeed

+
files +

Недавно изменённые или загруженные файлы. Например:

+

https://developer.mozilla.org/ru/docs/feeds/atom/files

+
l10n-updates +

Переводные статьи, чей оригинал был изменён с последнего редактирования этой статьи. Например:

+

https://developer.mozilla.org/ru/docs/feeds/atom/l10n-updates

+
needs-review[/<тип-проверки>] +

Список статей, требующих определённой проверки, либо статьи, требующие любой проверки, если тип проверки не указан. Тип проверки может быть одним из technical, editorial или kumascript.

+

https://developer.mozilla.org/ru/docs/feeds/json/needs-review

+

https://developer.mozilla.org/ru/docs/feeds/rss/needs-review/technical

+

https://developer.mozilla.org/ru/docs/feeds/atom/needs-review/editorial

+

https://developer.mozilla.org/ru/docs/feeds/atom/needs-review/kumascript

+
diff --git a/files/ru/orphaned/mdn/tools/page_deletion/index.html b/files/ru/orphaned/mdn/tools/page_deletion/index.html new file mode 100644 index 0000000000..ffd7d04664 --- /dev/null +++ b/files/ru/orphaned/mdn/tools/page_deletion/index.html @@ -0,0 +1,16 @@ +--- +title: Удаление страниц +slug: MDN/User_guide/Deleting_pages +tags: + - Guide + - MDN +translation_of: MDN/Tools/Page_deletion +--- +
{{MDNSidebar}}

Только администраторы MDN имеют право и могут удалять страницы. Эта статья описывает, как отправить запрос на удаление страницы с MDN.

+

Чтобы организовать удаление страницы, вы должны сделать следующее:

+
    +
  1. Не очищайте и не изменяйте содержимое страницы. Мы хотим видеть эту страницу во время удаления.
  2. +
  3. Добавьте метку «junk» к странице. Не удаляйте другие метки.
  4. +
  5. Если страница особенно срочно нуждается в удалении (например, её содержимое неуместно, оскорбительно или технически опасно), уведомите администратора MDN.
  6. +
+

Администратор удалит страницу, когда это будет возможно, после того как убедится, что это удаление целесообразно.

diff --git a/files/ru/orphaned/mdn/tools/page_watching/index.html b/files/ru/orphaned/mdn/tools/page_watching/index.html new file mode 100644 index 0000000000..04b9dc05ad --- /dev/null +++ b/files/ru/orphaned/mdn/tools/page_watching/index.html @@ -0,0 +1,50 @@ +--- +title: Подписка на страницы +slug: MDN/Tools/Page_watching +tags: + - MDN Meta + - Подписка + - Руководство + - Страница уровня + - инструменты +translation_of: MDN/Tools/Page_watching +--- +
{{MDNSidebar}}

Ok

+ +

Подписка на страницу в MDN позволяет вам получать уведомление по электронной почте всякий раз, когда она обновляется или изменяется. Кнопка «Смотреть» {{FontAwesomeIcon("icon-eye")}} расположена в верхнем правом углу каждой страницы MDN. Чтобы получить доступ к параметрам подписки, наведите курсор на кнопку «Смотреть», чтобы открыть меню «Смотреть»: 

+ +

Screenshot of MDN Watch menu

+ +

Выберите вариант просмотра только одной страницы или этой страницы и ее подстраниц.

+ +

Подписаться на страницу

+ +

Нажмите первый вариант «Подписаться на название страницы», чтобы получать уведомление по электронной почте каждый раз, когда пользователь редактирует только одну страницу.

+ +

Подпишитесь на страницу и все ее подзаголовки

+ +

Нажмите второй вариант «Подписаться на название страницы и все её под-статьи», чтобы получать уведомление по электронной почте каждый раз, когда пользователь редактирует эту страницу, а также любую её подстраницу. Это включает в себя дополнительные страницы, добавленные после того, как вы запросили подписку, поэтому, если в будущем будет создано больше подстраниц, вы также получите уведомления для них.

+ +

Отменить подписку на страницу

+ +

Чтобы отказаться от подписки и прекратить просмотр страницы, откройте меню «Смотреть» еще раз и нажмите «Отменить подписку на название страницы». Если вы подписаны на страницу, вы увидите только «Отказаться от названия страницы». Вы больше не будете получать электронное письмо при каждом изменении страницы.

+ +

Электронные письма с изменением страницы

+ +

Если вы подписаны на страницу, каждый раз при сохранении изменений вы получите электронное письмо. Эти письма поступают с notifications@developer.mozilla.org и отправляются на адрес электронной почты, зарегистрированный на вашей учетной записи MDN. Каждое сообщение имеет заголовок формы:

+ +
[MDN] Page "Page title" changed by username
+ +

Сообщение начинается с повторения информации в заголовке, а затем представляет стандартный разброс содержимого, показывающий точно, что изменилось. Изменения отображаются как исходный HTML-код, который может быть немного странным для чтения, если вы не используете его в контексте MDN.

+ +

Ниже diff есть список полезных ссылок, которые вы можете использовать для изменения, включая:

+ + + +

В нижней части письма есть уведомление о том, какая подписка сгенерировала электронное письмо, например «Вы подписаны на изменения: ссылка на элемент HTML и все его подтемы», а также ссылку на отмену подписки. Если вы нажмете ссылку, чтобы отказаться от подписки, вы больше не будете получать сообщения для этого запроса на просмотр.

diff --git a/files/ru/orphaned/mozilla/add-ons/webextensions/debugging/index.html b/files/ru/orphaned/mozilla/add-ons/webextensions/debugging/index.html new file mode 100644 index 0000000000..4ceb3eab28 --- /dev/null +++ b/files/ru/orphaned/mozilla/add-ons/webextensions/debugging/index.html @@ -0,0 +1,218 @@ +--- +title: Отладка +slug: Mozilla/Add-ons/WebExtensions/Перевод +tags: + - Firefox + - Mozilla + - Отладка + - Пособие + - Предоставление Веб-страниц +translation_of: Mozilla/Add-ons/WebExtensions/Debugging +--- +
{{AddonSidebar}}
+ +
This article explains how you can use the Firefox developer tools to debug extensions built with WebExtension APIs.
+ +

An extension can consist of various different pieces — background scripts, popups, options pages, content scripts, sidebars — and you'll need to use a slightly different workflow to debug each piece. So each piece gets a top-level section in this article, and the intention is that these sections can be read in isolation. We'll begin by introducing the Add-on Debugger, which you'll use to debug most of the pieces of your extension.

+ + + +

The Add-on Debugger

+ +

For most of this article we'll use the Add-on Debugger. To open the Add-on Debugger:

+ + + +

You'll then see a new window open. The main Firefox window will be switched into the foreground, so you'll have to click on the new window to bring it in front.

+ +

{{EmbedYouTube("G2a65ewjfj0")}}

+ +

This new window is sometimes called a "toolbox" and contains the debugging tools we'll use. It has a tabbed interface: the row of tabs along the top lets you switch between the different tools:

+ +

+ +

In this article we'll use three debugging tools:

+ + + +

Debugging background scripts

+ +
+

The examples in this section use the "notify-link-clicks-l10n" example extension. If you'd like to play along, you can find this example in the webextensions-examples repository.

+
+ +

Background scripts stay loaded for the lifetime of the extension. They're loaded inside an invisible "background page": by default this is an empty HTML document, but you can specify your own HTML content using the "background" key in "manifest.json".

+ +

You can debug background scripts using the Add-on Debugger.

+ +

In the Add-on Debugger's Console you'll see logged output, including calls to console.log() from your own background scripts and any errors the browser raises as it executes them. Note that at the moment, the console shows all errors raised by the browser, not just errors related to your extensions code.

+ +

For example, the notify-link-clicks-i18n example extension logs a message from its background script when it receives a message from one of its content scripts:

+ +

{{EmbedYouTube("WDQsBU-rpN0")}}

+ +

Using the Console's command line, you can access and modify the objects created by your background scripts.

+ +

For example, here we call the notify() function defined in the extension's background script:

+ +

{{EmbedYouTube("g-Qgf8Mc2wg")}}

+ +

If you switch to the Debugger, you'll see all your extension's background scripts. You can set breakpoints, step through code, and do everything else you'd expect to be able to do in a debugger.

+ +

{{EmbedYouTube("MNeaz2jdmzY")}}

+ +

If you press the Escape key while you're in the Debugger, the toolbox will be split, with the bottom half now occupied by the Console. While you're at a breakpoint, you can now modify the program's state using the console. See Split console for more on this.

+ +

Debugging options pages

+ +

Options pages are HTML pages that the extension developer can supply, that contain options for the extension. They are typically displayed in an iframe in the Add-ons Manager (to see the Add-ons Manager, visit the "about:addons" page).

+ +

To debug options pages:

+ + + +

Any JavaScript sources it includes are then listed in the Debugger:

+ +

{{EmbedYouTube("BUMG-M8tFF4")}}

+ +
+

This video uses the favourite-colour example extension.

+
+ +

You'll also see any messages logged by your code in the Add-on Debugger's Console.

+ +

You can also use the Add-on Debugger to debug the page's HTML and CSS. First, though, you need to point the tools at the iframe that hosts the options page. To do this: open the options page, click the icon highlighted in the screenshot below, and select the options page from the drop-down list:

+ +

+ +

Now switch to the Inspector tab, and you'll be able to examine and edit HTML and CSS for the page:

+ +

{{EmbedYouTube("-2m3ubFAU94")}}

+ +

Debugging popups

+ +

Popups are dialogs that are attached to browser actions or page actions. They are specified using an HTML document that can include CSS and JavaScript sources for styling and behavior. Whenever the popup is visible, you can use the Add-on Debugger to debug its code.

+ +

One problem with popups is that if a popup is open and you click outside the popup, the popup is closed and its code is unloaded. This obviously makes them impossible to debug. To suppress this behavior, select Disable Popup Auto-Hide from the Elipsis menu as shown below:

+ +

+ +

Now, when you open a popup it will stay open until you press Escape.

+ +
+

Note: This change applies to built-in browser popups, like the Elipsis menu (...), as well as extension popups.

+ +

The setting does not persist across sessions. When you close the window, the setting reverts to auto-hide popups.

+Internally, this button just toggles the ui.popup.disable_autohide preference, which you can toggle manually using about:config.
+ +

When the popup is open, its JavaScript sources will be listed in the Debugger. You can set breakpoints and modify the program's internal state:

+ +

{{EmbedYouTube("hzwnR8qoz2I")}}

+ +
+

This video uses the beastify example extension.

+
+ +

You can also use the Add-on Debugger to debug the popup's HTML and CSS. First, though, you need to point the tools at the popup's document. To do this: open the popup, then click the icon highlighted in the screenshot below and select the popup's page from the drop-down list:

+ +

Now switch to the Inspector, and you'll be able to examine and edit the popup's HTML and CSS:

+ +

{{EmbedYouTube("6lvdm7jaq7Y")}}

+ +

Debugging content scripts

+ +

You can use the Add-on Debugger to debug background pages, options pages, and popups. However, you can't use it to debug content scripts. This is because, in multiprocess Firefox, content scripts run in a different process from the other parts of your extension. The browser console has similar limitations.

+ +

To debug content scripts attached to a web page, use the normal web developer tools for that page:

+ + + +

{{EmbedYouTube("f46hMLELyaI")}}

+ +

By default, the tools are shown attached to the bottom of browser tab, to reflect the fact that they are attached to this tab. You'll see any output from console.log() statements in your content scripts. You will also see your content scripts listed in the Debugger, where you'll be able to set breakpoints, step through the code, and so on.

+ +

{{EmbedYouTube("Hx3GU_fEPeo")}}

+ +
+

This video uses the notify-link-clicks-i18n example extension.

+
+ +
+

If the developer tools tab was not already open when the content script was injected, sometimes the content script is not listed in the debugger panel. If you experience this, reloading the page with the developer tools tab open should fix the problem.

+
+ +

Debugging sidebars

+ +

Sidebars are HTML pages opened as a sidebar in the browser UI that the extension developer can supply.

+ +

To debug sidebars:

+ + + +

Any JavaScript sources it includes are then listed in the Debugger.

+ +

You'll also see any messages logged by your code in the Add-on Debugger's Console.

+ +

You can also use the Add-on Debugger to debug the page's HTML and CSS. First, though, you need to point the tools at the iframe that hosts the options page. To do this: open the sidebar, click the icon highlighted in the screenshot below, and select the sidebar from the drop-down list:

+ +

+ +

Debug runtime permission requests

+ +

 

+ +

Runtime permissions granted in your extension are persistent. Therefore, if you want to test cases where the permission has not been granted you will need to add a feature to programmatically remove the permission, use the Extensions Permission Manager, or give your extension a new ID. For more information, see Retest runtime permission grants in Test permission requests.

+ +

 

+ +

Debugging developer tools pages & panels

+ +

Developer tools are extended by loading a hidden HTML page when devtools are opened and developer tools panels are HTML pages displayed as a developer tool in the browser UI that the extension developer can supply.

+ +

To debug the developer tools page:

+ + + +

To debug developer tools panels:

+ + + +

Any JavaScript sources it includes are then listed in the Debugger.

+ +

You'll also see any messages logged by your code in the Add-on Debugger's Console.

+ +

You can also use the Add-on Debugger to debug the page's HTML and CSS. First, though, you need to point the tools at the iframe that hosts the options page. To do this: open the sidebar, click the icon highlighted in the screenshot below, and select the sidebar from the drop-down list:

+ +

+ +

Debugging Browser Restarts

+ +

If your extension is active in ways that might be affected by the browser restarting, such as a session being restored, then you may want to do extra testing to ensure your code works as expected in those conditions.

+ +

See Testing persistent and restart features for more details.

diff --git a/files/ru/orphaned/toolkit_api/index.html b/files/ru/orphaned/toolkit_api/index.html new file mode 100644 index 0000000000..48d33c6e3a --- /dev/null +++ b/files/ru/orphaned/toolkit_api/index.html @@ -0,0 +1,18 @@ +--- +title: Toolkit API (Инструментарий АПИ) +slug: Toolkit_API +tags: + - Toolkit API +--- +

Mozilla Toolkit это набор программных интерфейсов (APIs) собранных на базе Gecko которые обеспечивают продвинутые службы на базе XUL приложенияй. Эти службы включают:

+ +

Официальное руководство

+ +

Дополнительная информация

+

Следующие страницы разработчика содержат примеры и обсуждение конкретных тем

+

XUL; XUL Overlays; Developing Extensions; XULRunner; Developing Themes; DOM; RDF; Storage; Creating Help Documentation

+

Categories

+

Interwiki Language Links

+

{{ languages( { "ca": "ca/API_del_Toolkit", "es": "es/API_del_Toolkit", "fr": "fr/API_du_toolkit", "it": "it/Toolkit_API", "ja": "ja/Toolkit_API", "ko": "ko/Toolkit_API", "pl": "pl/Toolkit_API" } ) }}

diff --git a/files/ru/orphaned/tools/add-ons/dom_inspector/index.html b/files/ru/orphaned/tools/add-ons/dom_inspector/index.html new file mode 100644 index 0000000000..0e2c41dc29 --- /dev/null +++ b/files/ru/orphaned/tools/add-ons/dom_inspector/index.html @@ -0,0 +1,57 @@ +--- +title: DOM Inspector +slug: Tools/Add-ons/DOM_Inspector +translation_of: Tools/Add-ons/DOM_Inspector +--- +
{{ToolsSidebar}}

Инспектор DOM (также известный как DOMi) — инструмент для разработчиков, используемый для проверки, просмотра и редактирования объектной модели документа - обычных веб-страниц или XUL windows. По иерархии DOM можно перемещаться с помощью двух окон, отображающих целый ряд различных представлений документа и всех вложенных в него узлов.

+ +
+

Этот инструмент является дополнением для приложений, основанных на XUL, таких как Firefox и Thunderbird. Если вы ищете инспектор DOM, который встроен в Firefox, обратитесь к разделу документации Инспектор страницы.

+
+ +

Документация

+ +
+
Введение в инспектор DOM
+
Руководствоваться учебник, который поможет вам начать работу с DOM Inspector.
+
+ +
+
FAQ инспектор DOM
+
Ответы на общие вопросы по DOM Inspector.
+
+ +
+
страницы на MozillaZine
+
Более подробную информацию о DOM Inspector.
+
как скомпилировать инспектор DOM
+
Сообщение в блоге на здание инспектор DOM от источника.
+
+ +

Получение инспектор DOM

+ +
+
Firefox и Thunderbird
+
Вы можете скачать и установить Инспектор DOM на веб-сайте AMO. (Thunderbird пользователей, использующих AMO в Firefox следует сохранить ссылку установки, или посетить страницу Инспектор DOM для Thunderbird).
+
+ +
+
Thunderbird 2
+
Инспектор DOM для Thunderbird 2 доступен из Дополнений для Thunderbird. Или настройте Thunderbird сами со следующими параметрами:
+
+ +
ac_add_options --enable-extensions="default inspector"
+ac_add_options --enable-inspector-apis
+ +
+
Mozilla Suite и SeaMonkey
+
Выберите Инструменты > Веб-разработка > Инспектор DOM. Вы также можете установить боковую панель через Правка > Настройки > Дополнительно > Инспектор DOM, затем просто откройте панель инспектора DOM и посетите любой веб-сайт.
+
+ +

Отчет об ошибке в DOM Inspector

+ +

Использовать удобно именованный раздел компонент «Инспектор DOM» в Bugzilla.

+ +

Чтобы узнать о тех, кто знает код DOM Inspector и где он живет, см. листинг модуля DOM Inspector.

+ +

{{ languages( { "es": "es/DOM_Inspector", "it": "it/DOM_Inspector", "fr": "fr/Inspecteur_DOM", "ja": "ja/DOM_Inspector", "ko": "ko/DOM_Inspector", "pl": "pl/Inspektor_DOM" } ) }}

diff --git a/files/ru/orphaned/tools/add-ons/index.html b/files/ru/orphaned/tools/add-ons/index.html new file mode 100644 index 0000000000..ab408aeb18 --- /dev/null +++ b/files/ru/orphaned/tools/add-ons/index.html @@ -0,0 +1,15 @@ +--- +title: Add-ons +slug: Tools/Add-ons +tags: + - NeedsTranslation + - TopicStub +translation_of: Tools/Add-ons +--- +
{{ToolsSidebar}}

Developer tools that are not built into Firefox, but ship as separate add-ons.

+ +
+
WebSocket Monitor
+
Examine the data exchanged in a WebSocket connection.
+
 
+
diff --git a/files/ru/orphaned/web/api/web_crypto_api/checking_authenticity_with_password/index.html b/files/ru/orphaned/web/api/web_crypto_api/checking_authenticity_with_password/index.html new file mode 100644 index 0000000000..ea8ec86586 --- /dev/null +++ b/files/ru/orphaned/web/api/web_crypto_api/checking_authenticity_with_password/index.html @@ -0,0 +1,33 @@ +--- +title: Проверка подлинности данных с паролем +slug: Web/API/Web_Crypto_API/Checking_authenticity_with_password +tags: + - HMAC + - Web Crypto +translation_of: Web/API/Web_Crypto_API/Checking_authenticity_with_password +--- +

{{APIRef("Web Crypto API")}}{{draft}}

+ +

Проверка подлинности данных может быть выполнена с помощью Web Crypto API. В этой статье мы покажем как создавать и управлять подписями, используя хэш-функцию и пароль.

+ +

HMAC алгоритм генерирует хэш на основе передаваемых ключа и данных, которые нужно подписать. Позже, идентичный хэш может быть вычислен заного любым пользователем, у которого имеется ключ. Необходимость ключа позволяет хранить данные и хэш вместе: злоумышленник не сможет создать хэш для измененных данных, не имея ключа.

+ +

Стоит заметить, что алгоритм никак не связан с какой-либо другой информацией о владельце: знание ключа – необходимое и достаточное условие для изменения данных.

+ +

Предположим, данные хранятся на компьютере. Чтобы получить доступ к записи или чтению, мы будем использовать localforage.js – библиотека-обертка над хранилищами браузера. Эта библиотека необязательна и используется в качестве примера для удобства, чтобы сосредоточиться на криптографии.

+ +

Данные, доступ к которым мы хотим получить, имеют следующую форму:

+ +

 

+ +

где data – данные для подписания и signature – подпись, информация для проверки подлинности.

+ +

Криптографические ключи невозможно выучить наизусть, а обычные пароли недостаточно безопасны. Чтобы решить эту проблему, криптографы создали алгоритмы для создания криптографических ключей из паролей. Знание пароля позволяет воссоздать ключ и использовать его.

+ +

Запрашиваем пароль у пользователя для генерации ключа:

+ +
 
+ +

С этим ключом мы можем вычислить хэш данных.

+ +
 
diff --git "a/files/ru/orphaned/web/guide/ajax/\321\201_\321\207\320\265\320\263\320\276_\320\275\320\260\321\207\320\260\321\202\321\214_question_/index.html" "b/files/ru/orphaned/web/guide/ajax/\321\201_\321\207\320\265\320\263\320\276_\320\275\320\260\321\207\320\260\321\202\321\214_question_/index.html" new file mode 100644 index 0000000000..f66d6b1dbf --- /dev/null +++ "b/files/ru/orphaned/web/guide/ajax/\321\201_\321\207\320\265\320\263\320\276_\320\275\320\260\321\207\320\260\321\202\321\214_question_/index.html" @@ -0,0 +1,6 @@ +--- +title: С чего начать? +slug: Web/Guide/AJAX/С_чего_начать? +--- +

IKFIA +

diff --git a/files/ru/orphaned/web/html/element/element/index.html b/files/ru/orphaned/web/html/element/element/index.html new file mode 100644 index 0000000000..183d25eb92 --- /dev/null +++ b/files/ru/orphaned/web/html/element/element/index.html @@ -0,0 +1,112 @@ +--- +title: +slug: Web/HTML/Element/element +translation_of: Web/HTML/Element/element +--- +

{{obsolete_header}}

+ +
+

Заметка: Этот элемент удален из спецификации. Смотри здесь больше дополнительной информации от редактора спецификации.

+
+ +

Краткая информация

+ +

HTML <element> element используется для определения новых пользовательских элементов DOM.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Категория контентаПрозрачный контент.
Разрешенный контент???
Недопустимые теги{{no_tag_omission}}
Разрешенные родительские элементы???
DOM интерфейс{{domxref("HTMLElement")}}
+ +

Атрибуты

+ +

Этот элемент включает глобальные атрибуты.

+ +

Примеры

+ +

Текст здесь.

+ +
Больше текста здесь.
+
+ +

Характеристики

+ +

Элемент <element> ранее был в черновике спецификации Настраеваемых Элементов, но был удален.

+ +

Совместимость с браузером

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Базовая поддержка{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Базовая поддержка{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

Смотрите также

+ +
    +
  • Web-компоненты: {{HTMLElement("content")}}, {{HTMLElement("shadow")}}, {{HTMLElement("template")}}
  • +
+ +
{{HTMLRef}}
diff --git a/files/ru/orphaned/web/html/global_attributes/dropzone/index.html b/files/ru/orphaned/web/html/global_attributes/dropzone/index.html new file mode 100644 index 0000000000..19c7d5d01b --- /dev/null +++ b/files/ru/orphaned/web/html/global_attributes/dropzone/index.html @@ -0,0 +1,43 @@ +--- +title: dropzone +slug: Web/HTML/Global_attributes/dropzone +translation_of: Web/HTML/Global_attributes/dropzone +--- +

{{HTMLSidebar("Global_attributes")}}{{SeeCompatTable}}

+ +

Глобальный атрибут dropzone является перечисляемым атрбутом, указывающем, какие типы содержимого могут быть опущены в элементе, используя {{domxref("HTML_Drag_and_Drop_API","HTML Drag and Drop API")}}. Может иметь следующие значения:

+ +
    +
  • copy, которая указывает что сброс создает копию перетаскиваемого элемента.
  • +
  • move, которое указывает, что перетаскиваемы элемент будет перемещен в новое местоположение.
  • +
  • link, которая создает ссылку на перетаскивамые данные.
  • +
+ +

Спецификации

+ + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('HTML5.1', "editing.html#the-dropzone-attribute", "dropzone")}}{{Spec2('HTML5.1')}}Снимок {{SpecName('HTML WHATWG')}}, начальное определение
+ +

Поддержка браузерами

+ + + +

{{Compat("html.global_attributes.dropzone")}}

+ +

Смотрите также

+ + diff --git "a/files/ru/orphaned/web/javascript/guide/\320\276\320\261_\321\215\321\202\320\276\320\274_\321\200\321\203\320\272\320\276\320\262\320\276\320\264\321\201\321\202\320\262\320\265/index.html" "b/files/ru/orphaned/web/javascript/guide/\320\276\320\261_\321\215\321\202\320\276\320\274_\321\200\321\203\320\272\320\276\320\262\320\276\320\264\321\201\321\202\320\262\320\265/index.html" new file mode 100644 index 0000000000..397327911c --- /dev/null +++ "b/files/ru/orphaned/web/javascript/guide/\320\276\320\261_\321\215\321\202\320\276\320\274_\321\200\321\203\320\272\320\276\320\262\320\276\320\264\321\201\321\202\320\262\320\265/index.html" @@ -0,0 +1,68 @@ +--- +title: Об этом руководстве +slug: Web/JavaScript/Guide/Об_этом_руководстве +--- +

 

+

JavaScript является кросс-платформенным, объектно-ориентированный язык сценариев. Это руководство объясняет все, что нужно знать об использовании JavaScript.

+

Новые возможности в версиях JavaScript

+
/* Note: To add a link to new JavaScript version description
+add version number to versionList variable below. The page linked to
+must reside in /en/JavaScript/New_in_JavaScript/N, where N is version number. */
+
+var versionList = ["1.5", "1.6", "1.7", "1.8", "1.8.1", "1.8.5"];
+var s = "";
+<ul>
+  foreach (var i in versionList){
+    let s = "/en/JavaScript/New_in_JavaScript/" .. i;
+    <li>web.link(s, wiki.getPage(s).title)</li>;
+  }
+</ul>;
+
+

То, что вы должны уже знать

+

This guide assumes you have the following basic background:

+
  • Общее представление о сети Интернет и World Wide Web (WWW).
  • Хорошие знания языка гипертекстовой разметки (HTML).
  • +
+

Некоторый опыт программирования на языках, таких как C или Visual Basic, полезен, но не обязателен.

+

Версии JavaScript

+ +
Таблица №1 версии JavaScript и веб-браузера Navigator
JavaScript version Navigator version
JavaScript 1.0 Navigator 2.0
JavaScript 1.1 Navigator 3.0
JavaScript 1.2 Navigator 4.0-4.05
JavaScript 1.3 Navigator 4.06-4.7x
JavaScript 1.4  
JavaScript 1.5 Navigator 6.0
Mozilla (браузер с открытым исходным кодом)
JavaScript 1.6 Firefox 1.5, other Mozilla 1.8-based products
JavaScript 1.7 Firefox 2, other Mozilla 1.8.1-based products
JavaScript 1.8 Firefox 3, other Gecko 1.9-based products
+

 

+
Каждая версия Netscape Enterprise Server, также поддерживает различные версии JavaScript. Чтобы помочь вам писать сценарии, которые совместимы с несколькими версиями Enterprise Server, это руководство использует аббревиатуру для обозначения версии сервера, в котором каждая функция была реализована.
+
+ +
Таблица №2 Аббревиатуры в версиях Netscape Enterprise Server
Аббревиатура Версия Server Enterprise
NES 2.0 Netscape Enterprise Server 2.0
NES 3.0 Netscape Enterprise Server 3.0
+

Где найти информацию о JavaScript

+

JavaScript документация включает в себя следующие книги:

+
  • JavaScript Guide (это руководство) предоставляет информацию о языке JavaScript и его объектах.
  • JavaScript Reference содержит справочный материал о языке JavaScript.
  • +
+

Если вы новичок в JavaScript, начните с руководства JavaScript. Если у вас есть твердое понимание основы, вы можете использовать Справочник по JavaScript чтобы получить более подробную информацию на отдельных объектах и ​​операторах.

+

Советы для изучения JavaScript

+

Начало работы с JavaScript очень просто: все, что вам нужно, это современный веб-браузер. Это руководство включает в себя некоторые функции JavaScript, которые только в настоящее время доступна в последней версии Firefox (и других браузеров с движком Gecko), поэтому рекомендуется использование самых последних версий Firefox.

+

Интерактивный интерпретатор

+

Диалоговый JavaScript незамедлительно - неоценимая помощь изучению языка, так как это предоставляет вам возможность пробовать вещи в интерактивном режиме без необходимости сохранить файл и обновить страницу. Ошибочная Консоль Firefox, доступная через меню Инструменты, обеспечивает простой путь пробовать диалоговый JavaScript: Только вводят линию кода и щелкают кнопку "Evaluate".

+

Image:ErrorConsole.png

+

Firebug

+

Более передовой диалоговый незамедлительно - доступный использующий Firebug, дополнение к Firefox. Выражения, которые вы печатаете, интерпретируются как объекты и связанные с другими частями Firebug. Например, вы можете добавить 5 плюс 5, изменять регистр строки, get a clickable link to the document, or get a link to an element:

+

+

Использование стрелки на правом нижнем углу дает команду редактор для многострочного сценариев.

+

Firebug also provides an advanced DOM inspector, a JavaScript debugger, a profiling tool and various other utilities. JavaScript code running in a Web page can call, console.log(), a function that prints its arguments to the Firebug console.

+

Many of the examples in this guide use alert() to show messages as they execute. If you have Firebug installed you can use console.log() in place of alert() when running these examples.

+

Document conventions

+

JavaScript applications run on many operating systems; the information in this book applies to all versions. File and directory paths are given in Windows format (with backslashes separating directory names). For Unix versions, the directory paths are the same, except that you use slashes instead of backslashes to separate directories.

+

This guide uses uniform resource locators (URLs) of the following form:

+

http://server.domain/path/file.html

+

In these URLs, server represents the name of the server on which you run your application, such as research1 or www; domain represents your Internet domain name, such as netscape.com or uiuc.edu; path represents the directory structure on the server; and file.html represents an individual file name. In general, items in italics in URLs are placeholders and items in normal monospace font are literals. If your server has Secure Sockets Layer (SSL) enabled, you would use https instead of http in the URL.

+

This guide uses the following font conventions:

+
  • The monospace font is used for sample code and code listings, API and language elements (such as method names and property names), file names, path names, directory names, HTML tags, and any text that must be typed on the screen. (Monospace italic font is used for placeholders embedded in code.)
  • Italic type is used for book titles, emphasis, variables and placeholders, and words used in the literal sense.
  • Boldface type is used for glossary terms.
  • +
+
autoPreviousNext("JSGChapters");
+wiki.languages({
+  "zh-tw": "zh_tw/Core_JavaScript_1.5_教學/關於",
+  "es": "es/Gu\u00eda_JavaScript_1.5/Acerca_de_esta_gu\u00eda",
+  "fr": "fr/Guide_JavaScript_1.5/\u00c0_propos",
+  "ja": "ja/Core_JavaScript_1.5_Guide/About",
+  "ko": "ko/Core_JavaScript_1.5_Guide/About",
+  "pl": "pl/Przewodnik_po_j\u0119zyku_JavaScript_1.5/O_tym_przewodniku",
+  "zh-cn": "cn/Core_JavaScript_1.5_Guide/\u5173\u4e8e"
+})
+
diff --git a/files/ru/orphaned/web/javascript/reference/global_objects/array/prototype/index.html b/files/ru/orphaned/web/javascript/reference/global_objects/array/prototype/index.html new file mode 100644 index 0000000000..4d04fc0736 --- /dev/null +++ b/files/ru/orphaned/web/javascript/reference/global_objects/array/prototype/index.html @@ -0,0 +1,171 @@ +--- +title: Array.prototype +slug: Web/JavaScript/Reference/Global_Objects/Array/prototype +tags: + - Array + - JavaScript + - Property + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Array/prototype +--- +
{{JSRef("Global_Objects", "Array")}}
+ +

Сводка

+ +

Свойство Array.prototype представляет прототип для конструктора {{jsxref("Global_Objects/Array", "Array", "массива")}}.

+ +
{{js_property_attributes(0, 0, 0)}}
+ +

Описание

+ +

Экземпляры Array наследуются от Array.prototype. Как и с остальными конструкторами, вы можете изменять прототип конструктора объекта для применения изменений ко всем экземплярам класса Array.

+ +

Небольшой факт: Array.prototype сам является экземпляром Array:

+ +
Array.isArray(Array.prototype); // true
+ +

Свойства

+ +
+
Array.prototype.constructor
+
Определяет функцию, создающую прототип объекта.
+
{{jsxref("Array.prototype.length")}}
+
Отражает количество элементов в массиве.
+
+ +

Методы

+ +

Методы изменения

+ +

Эти методы изменяют массив:

+ +
+
{{jsxref("Array.prototype.copyWithin()")}} {{experimental_inline}}
+
Копирует последовательность элементов массива внутри массива.
+
{{jsxref("Array.prototype.fill()")}} {{experimental_inline}}
+
Заполняет все элементы массива от начального индекса до конечного индекса указанным значением.
+
{{jsxref("Array.prototype.pop()")}}
+
Удаляет последний элемент из массива и возвращает его.
+
{{jsxref("Array.prototype.push()")}}
+
Добавляет один или более элементов в конец массива и возвращает новую длину массива.
+
{{jsxref("Array.prototype.reverse()")}}
+
Переворачивает порядок элементов в массиве — первый элемент становится последним, а последний — первым.
+
{{jsxref("Array.prototype.shift()")}}
+
Удаляет первый элемент из массива и возвращает его.
+
{{jsxref("Array.prototype.sort()")}}
+
Сортирует элементы массива на месте и возвращает отсортированный массив.
+
{{jsxref("Array.prototype.splice()")}}
+
Добавляет и/или удаляет элементы из массива.
+
{{jsxref("Array.prototype.unshift()")}}
+
Добавляет один или более элементов в начало массива и возвращает новую длину массива.
+
+ +

Методы доступа

+ +

Эти методы не изменяют массив, а просто возвращают его в ином представлении.

+ +
+
{{jsxref("Array.prototype.concat()")}}
+
Возвращает новый массив, состоящий из данного массива, соединённого с другим массивом и/или значением (списком массивов/значений).
+
{{jsxref("Array.prototype.includes()")}} {{experimental_inline}}
+
Определяет, содержится ли в массиве указанный элемент, возвращая, соответственно, true или false.
+
{{jsxref("Array.prototype.join()")}}
+
Объединяет все элементы массива в строку.
+
{{jsxref("Array.prototype.slice()")}}
+
Извлекает диапазон значений и возвращает его в виде нового массива.
+
{{jsxref("Array.prototype.toSource()")}} {{non-standard_inline}}
+
Возвращает литеральное представление указанного массива; вы можете использовать это значение для создания нового массива. Переопределяет метод {{jsxref("Object.prototype.toSource()")}}.
+
{{jsxref("Array.prototype.toString()")}}
+
Возвращает строковое представление массива и его элементов. Переопределяет метод {{jsxref("Object.prototype.toString()")}}.
+
{{jsxref("Array.prototype.toLocaleString()")}}
+
Возвращает локализованное строковое представление массива и его элементов. Переопределяет метод {{jsxref("Object.prototype.toLocaleString()")}}.
+
{{jsxref("Array.prototype.indexOf()")}}
+
Возвращает первый (наименьший) индекс элемента внутри массива, равный указанному значению; или -1, если значение не найдено.
+
{{jsxref("Array.prototype.lastIndexOf()")}}
+
Возвращает последний (наибольший) индекс элемента внутри массива, равный указанному значению; или -1, если значение не найдено.
+
+ +

Методы обхода

+ +

Некоторые методы принимают в качестве аргументов функции, вызываемые при обработке массива. Когда вызываются эти методы, достаётся длина массива, и любой элемент, добавленный свыше этой длины изнутри функции обратного вызова не посещается. Другие изменения в массиве (установка значения или удаление элемента) могут повлиять на результаты операции, если изменённый элемент метод посещает после изменения. Хотя специфическое поведение этих методов в таких случаях хорошо определено, вы не должны на него полагаться, чтобы не запутывать других людей, читающих ваш код. Если вам нужно изменить массив, лучше вместо этого скопируйте его в новый массив.

+ +
+
{{jsxref("Array.prototype.forEach()")}}
+
Вызывает функцию для каждого элемента в массиве.
+
{{jsxref("Array.prototype.entries()")}} {{experimental_inline}}
+
Возвращает новый объект итератора массива Array Iterator, содержащий пары ключ / значение для каждого индекса в массиве.
+
{{jsxref("Array.prototype.every()")}}
+
Возвращает true, если каждый элемент в массиве удовлетворяет условию проверяющей функции.
+
{{jsxref("Array.prototype.some()")}}
+
Возвращает true, если хотя бы один элемент в массиве удовлетворяет условию проверяющей функции.
+
{{jsxref("Array.prototype.filter()")}}
+
Создаёт новый массив со всеми элементами этого массива, для которых функция фильтрации возвращает true.
+
{{jsxref("Array.prototype.find()")}} {{experimental_inline}}
+
Возвращает искомое значение в массиве, если элемент в массиве удовлетворяет условию проверяющей функции или {{jsxref("Global_Objects/undefined", "undefined")}}, если такое значение не найдено.
+
{{jsxref("Array.prototype.findIndex()")}} {{experimental_inline}}
+
Возвращает искомый индекс в массиве, если элемент в массиве удовлетворяет условию проверяющей функции или -1, если такое значение не найдено.
+
{{jsxref("Array.prototype.keys()")}} {{experimental_inline}}
+
Возвращает новый итератор массива, содержащий ключи каждого индекса в массиве.
+
{{jsxref("Array.prototype.map()")}}
+
Создаёт новый массив с результатами вызова указанной функции на каждом элементе данного массива.
+
{{jsxref("Array.prototype.reduce()")}}
+
Применяет функцию к аккумулятору и каждому значению массива (слева-направо), сводя его к одному значению.
+
{{jsxref("Array.prototype.reduceRight()")}}
+
Применяет функцию к аккумулятору и каждому значению массива (справа-налево), сводя его к одному значению.
+
{{jsxref("Array.prototype.values()")}} {{experimental_inline}}
+
Возвращает новый объект итератора массива Array Iterator, содержащий значения для каждого индекса в массиве.
+
{{jsxref("Array.prototype.@@iterator()", "Array.prototype[@@iterator]()")}} {{experimental_inline}}
+
Возвращает новый объект итератора массива Array Iterator, содержащий значения для каждого индекса в массиве.
+
+ +

Общие методы

+ +

Многие методы JavaScript-массива спроектированы таким образом, чтобы иметь возможность применяться ко всем объектам, «выглядящим похоже» на массивы. То есть, они могут использоваться на любом объекте, имеющим свойство length и к элементам которого можно получить доступ через числовые имена свойств (как при индексации: array[5]). TODO: предоставить примеры с Array.prototype.forEach.call и добавлением методов к объекту, как сделано для {{jsxref("Global_Objects/JavaArray", "JavaArray")}} или {{jsxref("Global_Objects/String", "String")}}. Некоторые методы, например {{jsxref("Array.join", "join")}}, только читают свойство length и числовые свойства объекта, на котором они вызываются. Другие, вроде {{jsxref("Array.reverse", "reverse")}} требуют, чтобы числовые свойства и свойство length объекта были изменяемыми; эти методы не могут вызываться на объектах вроде {{jsxref("Global_Objects/String", "String")}}, которые не позволяют установку своего свойства length или синтезирование числовых свойств.

+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
ECMAScript 1-е издание.СтандартИзначальное определение.
{{SpecName('ES5.1', '#sec-15.4.3.1', 'Array.prototype')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-array.prototype', 'Array.prototype')}}{{Spec2('ES6')}} 
+ +

Совместимость с браузерами

+ +

 

+ + + +

{{Compat("javascript.builtins.Array.prototype")}}

+ +

 

+ +
 
+ +

Смотрите также

+ +
    +
  • {{jsxref("Global_Objects/Array", "Array")}}
  • +
  • {{jsxref("Function.prototype")}}
  • +
diff --git a/files/ru/orphaned/web/javascript/reference/global_objects/asyncfunction/prototype/index.html b/files/ru/orphaned/web/javascript/reference/global_objects/asyncfunction/prototype/index.html new file mode 100644 index 0000000000..9d0c21f241 --- /dev/null +++ b/files/ru/orphaned/web/javascript/reference/global_objects/asyncfunction/prototype/index.html @@ -0,0 +1,55 @@ +--- +title: AsyncFunction.prototype +slug: Web/JavaScript/Reference/Global_Objects/AsyncFunction/prototype +translation_of: Web/JavaScript/Reference/Global_Objects/AsyncFunction/prototype +--- +
{{JSRef}}
+ +

Свойство AsyncFunction.prototype представляет прототип объекта  {{jsxref("AsyncFunction")}} .

+ +

Описание

+ +

Объект {{jsxref("AsyncFunction")}} наследуется от AsyncFunction.prototype. AsyncFunction.prototype не может быть модифицирован.

+ +

Свойства

+ +
+
AsyncFunction.constructor
+
Начальное значение {{jsxref("AsyncFunction")}}.
+
AsyncFunction.prototype[@@toStringTag]
+
Возвращает "AsyncFunction".
+
+ +

Specifications

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-async-function-constructor-prototype', 'AsyncFunction.prototype')}}{{Spec2('ESDraft')}}Initial definition in ES2017.
+ +

Browser compatibility

+ +
+ + +

{{Compat("javascript.builtins.AsyncFunction.prototype")}}

+
+ +

See also

+ +
    +
  • {{jsxref("AsyncFunction")}}
  • +
  • {{jsxref("Function")}}
  • +
diff --git "a/files/ru/orphaned/web/javascript/reference/global_objects/math/\320\274\320\265\321\202\320\276\320\264_math.max()_/index.html" "b/files/ru/orphaned/web/javascript/reference/global_objects/math/\320\274\320\265\321\202\320\276\320\264_math.max()_/index.html" new file mode 100644 index 0000000000..ab66d8acb0 --- /dev/null +++ "b/files/ru/orphaned/web/javascript/reference/global_objects/math/\320\274\320\265\321\202\320\276\320\264_math.max()_/index.html" @@ -0,0 +1,136 @@ +--- +title: Метод Math.max() +slug: Web/JavaScript/Reference/Global_Objects/Math/Метод_Math.max()_ +tags: + - JavaScript + - Math + - Method + - Reference +--- +
{{JSRef("Global_Objects", "Math")}}
+ +
 
+ +

Сводка

+ +

Метод Math.max() возвращает наибольшее из нуля или более чисел.

+ +

Синтаксис

+ +
Math.max([value1[, value2[, ...]]])
+ +

Параметры

+ +
+
value1, value2, ...
+
Числа.
+
+ +

Описание

+ +

Поскольку метод max() является статическим методом объекта Math, вы всегда должны использовать его как Math.max(), а не пытаться вызывать метод на созданном экземпляре объекта Math (поскольку объект Math не является конструктором).

+ +

При вызове без аргументов результатом вызова будет значение -{{jsxref("Global_Objects/Infinity", "Infinity")}}.

+ +

Если хотя бы один из аргументов не может быть преобразован в число, результатом будет {{jsxref("Global_Objects/NaN", "NaN")}}.

+ +

Примеры

+ +

Пример: использование метода Math.max()

+ +
Math.max(10, 20);   //  20
+Math.max(-10, -20); // -10
+Math.max(-10, 20);  //  20
+
+ +

Следующая функция использует метод {{jsxref("Function.prototype.apply()")}} для нахождения максимального элемента в числовом массиве. Вызов getMaxOfArray([1, 2, 3]) эквивалентен вызову Math.max(1, 2, 3), однако вы можете использовать функцию getMaxOfArray() вместе с программно сконструированными массивами любого размера.

+ +
function getMaxOfArray(numArray) {
+  return Math.max.apply(null, numArray);
+}
+
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарии
ECMAScript 1-е издание.СтандартИзначальное определение. Реализована в JavaScript 1.0.
{{SpecName('ES5.1', '#sec-15.8.2.11', 'Math.max')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-math.max', 'Math.max')}}{{Spec2('ES6')}} 
+ +

Совместимость с браузерами

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
ВозможностьChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
ВозможностьAndroidChrome для AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

Смотрите также

+ +
    +
  • {{jsxref("Math.min()")}}
  • +
diff --git a/files/ru/orphaned/web/manifest/serviceworker/index.html b/files/ru/orphaned/web/manifest/serviceworker/index.html new file mode 100644 index 0000000000..11681a7060 --- /dev/null +++ b/files/ru/orphaned/web/manifest/serviceworker/index.html @@ -0,0 +1,91 @@ +--- +title: serviceworker +slug: Web/Manifest/serviceworker +tags: + - Manifest + - ServiceWorker + - Web +translation_of: Web/Manifest/serviceworker +--- +
{{QuickLinksWithSubpages("/ru/docs/Web/Manifest")}}
+ +
{{obsolete_header}}
+ + + + + + + + + + + + + + + + +
TypeObject
MandatoryNo
Example +
+"serviceworker": {
+  "src": "./serviceworker.js"
+}
+
+ +

serviceworker описывает {{domxref('Service_Worker_API', 'рабочий сервис')}}, который разработчик намеревается установить для управления PWA.

+ +

Examples

+ +
"serviceworker": {
+  "src": "./serviceworker.js",
+  "scope": "/app",
+  "type": "",
+  "update_via_cache": "none"
+}
+
+ +

Значения

+ +

Сервисный работник может содержать следующие значения (требуется только src):

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
ПараметрОписание
src +

URL-адрес для загрузки сценария рабочего сервиса. Это единственный обязательный параметр для serviceworker.

+
scope +

Строка, представляющая URL, который определяет область регистрации рабочего сервиса; то есть, какой диапазон URL-адресов может контролировать рабочий сервис. Обычно это относительный URL-адрес, относительно базового URL-адреса приложения. По умолчанию в качестве области действия для регистрации рабочего сервиса задан каталог, в котором находится сценарий рабочий сервис.

+
type?
update_via_cache +

Нужно ли обходить кэш пользовательского агента при получении рабочего сервиса.

+
+ +

Browser compatibility

+ + + +

{{Compat("html.manifest.serviceworker")}}

diff --git a/files/ru/orphaned/web/security/information_security_basics/index.html b/files/ru/orphaned/web/security/information_security_basics/index.html new file mode 100644 index 0000000000..0d36d99bad --- /dev/null +++ b/files/ru/orphaned/web/security/information_security_basics/index.html @@ -0,0 +1,30 @@ +--- +title: Основы по информационной безопасности +slug: Web/Security/Information_Security_Basics +translation_of: Web/Security/Information_Security_Basics +--- +

Базовое понимание информационной безопасности, поможет обезопасить ваше программное обеспечение и сайты от уязвимостей открывающим доступ к финансовым махинациям и прочим противоправным действиям. Из этих статей вы сможете узнать все что для этого необходимо. Вооружившись этой информацией, вы поймете роль и важность безопасности начиная от цикла веб-разработки вплоть до размещения вашего контента. 

+ +
+
Конфиденциальность, целостность и доступность
+
Статья описывает фундаментальные понятия по главным задачам безопасности
+
Уязвимости
+
Определяет основные категории уязвимостей и рассказывает о их существовании в программном обеспечении
+
Угрозы
+
Вкратце знакомит с основными принципами угроз
+
Контроль безопасности 
+
Определяет основные категории контроля безопасности и рассказывает о их потенциальных слабостях
+
Безопасность TCP/IP
+
Обзор TCP/IP модели, с упором на вопросы безопасности для SSL
+
+ +

Смотрите так же

+ + + +

{{QuickLinksWithSubpages("/en-US/docs/Web/Security")}}

diff --git a/files/ru/orphaned/web/svg/attribute/onload/index.html b/files/ru/orphaned/web/svg/attribute/onload/index.html new file mode 100644 index 0000000000..b6a5d49ea2 --- /dev/null +++ b/files/ru/orphaned/web/svg/attribute/onload/index.html @@ -0,0 +1,5 @@ +--- +title: onload +slug: Web/SVG/Attribute/onload +--- +

Link not exist

diff --git a/files/ru/orphaned/xml_in_mozilla/index.html b/files/ru/orphaned/xml_in_mozilla/index.html new file mode 100644 index 0000000000..aea3fbcb61 --- /dev/null +++ b/files/ru/orphaned/xml_in_mozilla/index.html @@ -0,0 +1,56 @@ +--- +title: XML in Mozilla +slug: XML_in_Mozilla +--- +

Поведение метода length объекта XML в браузерах IE и Mozilla

+

Непредвиденное поведение метода определяющего количество элементов в коллекции в браузере Mozilla.

+

Имеем XML документ с разным количеством вложенных элементов, пример:

+

<root>

+
+

   <books>

+
+

      <title></title>

+
+

      <aftor></aftor>

+
+

      <page></page>

+
+

      <note>

+
+

         <first></first>

+
+

         <second></second>

+
+

      </note>

+
+

       <note>

+
+

         <first></first>

+
+

         <second></second>

+
+

      </note>

+
+

   </books>

+
+

   <books>

+
+

      <title></title>

+
+

      <aftor></aftor>

+
+

      <page></page>

+
+

      <note>

+
+

         <first></first>

+
+

         <second></second>

+
+

      </note>

+
+

   </books>

+
+

</root>

+

 

+

Казалось, при определении количества дочерних элементов у элемента <root> должны получить - 2, а получаем вместо этого количество вложений элемнтов в XML файле - 5, причём в IE данный метод (length) ведёт себя корректно. Ищу пути решения образовавшегося вопроса, если у кого-то есть предложения, буду рад узнать. Заранее спасибо.

diff --git a/files/ru/orphaned/xpcnativewrapper/index.html b/files/ru/orphaned/xpcnativewrapper/index.html new file mode 100644 index 0000000000..c12a434e12 --- /dev/null +++ b/files/ru/orphaned/xpcnativewrapper/index.html @@ -0,0 +1,108 @@ +--- +title: XPCNativeWrapper +slug: XPCNativeWrapper +tags: + - DOM + - XPCNativeWrapper + - Безопасность + - Расширения +--- +

 

+

XPCNativeWrapper позволяет так обернуть объект, чтобы доступ к нему был безопасен для привилегированного кода. Эта обёртка может быть использована во всех версиях, хотя её поведение слегка изменилось начиная с Firefox 1.5 (Gecko 1.8). Информацию о поведении XPCNativeWrapper в Firefox версий младше 1.5 можно получить из статьи о XPCNativeWrapper в MozillaZine KnowledgeBase. Эта же статья посвящена XPCNativeWrapper в Firefox версий 1.5 и выше.

+

Что делает XPCNativeWrapper

+

An XPCNativeWrapper limits access to the properties and methods of the object it wraps. The only properties and methods accessible through an XPCNativeWrapper are those that are defined in IDL or defined by DOM Level 0 (though some DOM Level 0 properties and methods do not work on an XPCNativeWrapper). In particular, properties added to an object via JavaScript are not exposed by an XPCNativeWrapper for this object, and nor are getters and setters defined with __defineGetter__ and __defineSetter__. The intent is to allow safe access to the IDL-defined methods of the object.

+

Please make sure to read the known bugs section, especially when writing code targeted at a range of 1.5.0.x Firefox releases.

+

Типы XPCNativeWrapper

+

There are three different types of XPCNativeWrapper in Firefox 1.5. All three types wrap a possibly-unsafe object and provide safe access to its properties and methods.

+

The differences in behavior between the three types of XPCNativeWrapper are determined by two characteristics an XPCNativeWrapper wrapper can have. An XPCNativeWrapper can be explicit (or the opposite, implicit) and can be deep (or the opposite, shallow). The type of wrapper created is determined by the way it was created as follows:

+ +
Created by Explicit/Implicit Deep/Shallow
Protected script accessing an untrusted object Implicit Deep
Constructor called with string arguments Explicit Shallow
Constructor called with no string arguments Explicit Deep
+

Explicit vs. Implicit

+

The difference in behavior between explicit and implicit XPCNativeWrapper is that a property access on an implicit XPCNativeWrapper from script that is not protected is NOT safe. The property access will be forwarded through to the wrappedJSObject of the XPCNativeWrapper.

+

This means that scripts that are not protected don't need to worry about bugs arising because other code hands them an implicit XPCNativeWrapper. On the other hand, such scripts do need to watch out for unsafe object access.

+

Property access on an explicit XPCNativeWrapper is safe no matter whether the caller is protected.

+

Deep vs. Shallow

+

The difference in behavior between deep and shallow XPCNativeWrapper is that when a property is accessed or a function is called on a deep wrapper the return value will be wrapped in a XPCNativeWrapper of its own. The new XPCNativeWrapper will also be deep and it will be explicit if and only if the XPCNativeWrapper whose property is accessed was explicit. By contrast, when a property is accessed or a function is called on a shallow wrapper, the return value may be an unsafe object.

+

For example, say we are given three instances of XPCNativeWrapper for the same window object. Let us call them deepExplicitWindow, deepImplicitWindow and shallowWindow. Then we have:

+
var doc1 = deepExplicitWindow.document;
+// doc1 is now a deep explicit XPCNativeWrapper for
+// the document object.  Accessing doc1.open(), say, is safe.
+
+
var doc2 = deepImplicitWindow.document;
+// If the caller has xpcnativewrappers=yes set, doc2 is now a deep
+// implicit XPCNativeWrapper for the document object.
+// Otherwise doc2 is now the unsafe document object, since the
+// property access was simply passed along to the unsafe window object.
+
+
var doc3 = shallowWindow.document;
+// doc3 is now the unsafe document object.
+
+

Создание объектов XPCNativeWrapper

+

Существует три различных способа создания объекта XPCNativeWrapper; по одному способу на каждый из трёх типов.

+

Protected script accessing an untrusted object

+

Any time a protected script accesses an untrusted object it will get back an implicit deep XPCNativeWrapper. Accessing properties of this XPCNativeWrapper is safe from protected scripts.

+

A wrapper created in this way will stick around as long as the object being wrapped does and accessing an object twice in a row will give the same XPCNativeWrapper.

+
What is a protected script?
+

In Firefox versions 1.5 through 1.5.0.5, a script is protected or not protected based solely on its URI. A script is protected only if its URI starts with a known protected prefix; scripts not loaded by URI (e.g. JavaScript-implemented components) are not protected. The protected prefixes in Firefox 1.5 are determined by the Chrome Registry.

+

By default, all content packages are protected. This means that all URIs that start "chrome://<package name>/content/" (for any package) are protected. Individual packages can override this using a flag in their chrome manifest file.

+

Starting with Firefox 1.5.0.6, JavaScript-implemented components are protected scripts. So a script is protected if it's either loaded from a URI which starts with a protected prefix or is a JavaScript-implemented component.

+
What is an untrusted object?
+

All objects are either trusted or untrusted. An object is trusted if any of the following hold:

+
  1. Its parent (__parent__ property in JavaScript) is a trusted object.
  2. It is the root scope object for a JavaScript component.
  3. It is the window object for a trusted window.
  4. +
+

Since all DOM objects in a window have the window on their __parent__ chain, they will be trusted if and only if their window is trusted.

+
What is a trusted window?
+

Whether a window is trusted depends on its container. A window is trusted if any of the following holds:

+
  1. It is a top-level window (e.g. <xul:window>, <xul:dialog>, or some URI passed to the -chrome command-line flag).
  2. Its parent is trusted, and one of the following three options holds:
    1. It is not loaded in a <xul:iframe> or <xul:browser>.
    2. The <xul:iframe> or <xul:browser> loading it doesn't have a "type" attribute.
    3. The value of the "type" attribute of the <xul:iframe> or <xul:browser> loading it is not "content" and does not start with "content-".
  3. +
+

Note that whether a window is trusted does not depend on the URI loaded in the window. So for example, the following would create trusted windows when used inside a document whose window is already trusted:

+
  • <xul:browser>
  • <xul:browser type="chrome">
  • <xul:browser type="rabid_dog">
  • <xul:iframe type="foofy">
  • <html:iframe>
  • <html:iframe type="content">
  • +
+

The following would not create trusted windows:

+
  • <xul:browser type="content">
  • <xul:iframe type="content-primary">
  • +
+

Further note that any child window of an untrusted window is automatically untrusted.

+
What happens when a script accesses an object?
+

The table below describes what happens when a script accesses an object, and how the wrapper is involved.

+ +
Script Object Effects
Protected Trusted No wrapper is created and therefore the script gets full access to the object.
Protected Untrusted An implicit deep XPCNativeWrapper is created.
Unprotected Trusted No wrapper is created, just as in the protected/trusted case.
Unprotected Untrusted No wrapper is created, just as in the protected/trusted case.
+

XPCNativeWrapper constructor call with string arguments

+

For example:

+
var contentWinWrapper = new XPCNativeWrapper(content,
+                                             "document");
+
+

This creates an explicit shallow XPCNativeWrapper. This syntax has been kept for compatibility with versions prior to Firefox 1.5. While all properties of the contentWinWrapper object can now be safely accessed, the return values of these properties are NOT safe to access (just like in versions prior to Firefox 1.5), since the XPCNativeWrapper is shallow. So to compare the content document title to the current content selection, one must do:

+
var winWrapper = new XPCNativeWrapper(content, "document",
+                                      "getSelection()");
+var docWrapper = new XPCNativeWrapper(winWrapper.document,
+                                      "title");
+return docWrapper.title == winWrapper.getSelection();
+
+

just like in versions before Firefox 1.5. Note that the "getSelection()" argument is not strictly needed here; if the code is not intended for use with Firefox versions before 1.5 it can be removed. A single string argument after the object being wrapped is all that is required for Firefox 1.5 to create this type of XPCNativeWrapper.

+

XPCNativeWrapper constructor call with no string arguments

+

For example:

+
var contentWinWrapper = new XPCNativeWrapper(content);
+
+

This creates an explicit deep XPCNativeWrapper. Accessing properties of this XPCNativeWrapper is safe, and the return values will also be wrapped in explicit deep XPCNativeWrapper objects.

+

Setting "expando" properties on XPCNativeWrapper

+

It is possible to set "expando" properties (properties with names that don't correspond to IDL-defined properties) on XPCNativeWrapper objects. If this is done, then chrome will be able to see these expando properties, but content will not be able to. There is no safe way to set an expando property from chrome and have it be readable from content.

+

XPCNativeWrapper lifetime

+

Explicit XPCNativeWrapper objects exist while they are referenced. Creating a new explicit XPCNativeWrapper for the same possibly-unsafe object will create a new wrapper object; something to watch out for when setting "expando" properties

+

Implicit XPCNativeWrapper objects have the same lifetime as the object they're wrapping.

+

Accessing unsafe properties

+

If unsafe access to a property is required for some reason, this can be accomplished via the wrappedJSObject property of the wrapper. For example, if docWrapper is a wrapper for doc, then

+
docWrapper.wrappedJSObject.prop
+
+

is the same as

+
doc.prop
+
+

Известные ошибки

+

Известны две ошибки реализации XPCNativeWrapper в версиях 1.5.0.x:

+
  1. Firefox с версии 1.5 по версию 1.5.0.4 содержит {{ Bug(337095) }}, в результате чего в некоторых случаях для защищённых скриптов не создаются обёртки. А именно, если из защищённого скрипта происходит обращение к свойству или вызов функции, которые возвращают недоверенный (untrusted) объект, обёртка будет создана. Однако, если функция в защищённом скрипте вызывается из C++, и в качестве аргумента этой функции передаётся недоверенный объект, обёртка не будет создана. Поэтому функции, которые могут быть вызваны подобным образом, должны сами производить обёртывание. Эта ошибка исправлена в Firefox версии 1.5.0.5 и выше.
  2. Firefox с версии 1.5 по версию 1.5.0.5 содержит {{ Bug(345991) }}, в результате чего компоненты написанные на JavaScript не могут быть защищёнными скриптами. Эта ошибка исправлена в Firefox версии 1.5.0.6 и выше.
  3. +
+

Limitations of XPCNativeWrapper

+

There are some commonly used properties and coding styles that cannot be used with XPCNativeWrapper. Specifically:

+
  1. Assigning to or reading an on* property on an XPCNativeWrapper of a DOM node or Window object will throw an exception. (Use addEventListener instead, and use "event.preventDefault();" in your handler if you used "return false;" before.)
  2. Access to frames by window name (e.g. window.frameName) does not work on an XPCNativeWrapper
  3. document.all does not work on an XPCNativeWrapper for a document.
  4. Access to named items by name does not work on an XPCNativeWrapper for an HTML document. For example, if you have a <form name="foo"> and docWrapper is a wrapper for the HTML document doc then doc.foo is an HTMLFormElement while docWrapper.foo is undefined. Code that wishes to do this could use docWrapper.forms.namedItem("foo") instead.
  5. Access to nodes by id doesn't work on an XPCNativeWrapper for an HTML document. getElementById should be used instead.
  6. Access to inputs by name doesn't work on an XPCNativeWrapper for an HTML form. Code that wishes to do this should use form.elements.namedItem("inputname").
  7. Access to elements by name doesn't work on an XPCNativeWrapper for an HTMLCollection. Code that wishes to do this should use the namedItem() method. Note that namedItem only returns the first input element with the name, even if there are multiple elements (e.g. radio buttons) with the same name in the form.
  8. Calling methods implemented by NPAPI plugins through the XPCNativeWrapper for the corresponding node does not work.
  9. Getting or setting properties implemented by NPAPI plugins though the XPCNativeWrapper for the corresponding node does not work.
  10. Calling methods implemented via XBL bindings attached to a node through an XPCNativeWrapper for that node does not work.
  11. Getting or setting properties implemented via XBL bindings attached to a node through an XPCNativeWrapper for that node does not work.
  12. Enumerating the properties of an XPCNativeWrapper via "for (var p in wrapper)" does not enumerate the IDL-defined properties.
  13. Object.prototype is not on the prototype chain of an XPCNativeWrapper. As a result, various Object.prototype properties are undefined on an XPCNativeWrapper (to be precise, these are __proto__, __parent__, __count__, toSource, toLocaleString, valueOf, watch, unwatch, hasOwnProperty, isPrototypeOf, propertyIsEnumerable, __defineGetter__, __defineSetter__, __lookupGetter__, and __lookupSetter__).
  14. There is no support for the importXPCNative method the old XPCNativeWrapper implementation used to have.
  15. Accessing standard classes (such as Function) through an XPCNativeWrapper will not work. To create functions and objects with a particular window's parent, use that window's eval function.
  16. +
+

Avoid Common Pitfalls in Greasemonkey has an elaborate explanation for some of these limitations (in context of Greasemonkey scripts).

+

{{ languages( { "en": "en/XPCNativeWrapper", "fr": "fr/XPCNativeWrapper", "it": "it/XPCNativeWrapper" } ) }}

diff --git a/files/ru/orphaned/xpcom/index.html b/files/ru/orphaned/xpcom/index.html new file mode 100644 index 0000000000..ee75427939 --- /dev/null +++ b/files/ru/orphaned/xpcom/index.html @@ -0,0 +1,16 @@ +--- +title: XPCOM +slug: XPCOM +tags: + - XPCOM +--- +
Введение в XPCOM
+

Перевод статей с портала IBM developerWorks: Part I, Part II, Part III, Part IV & V

+
+

XPCOM это кросс-платформенный компонент объектной модели, похожий на Microsoft COM. Он имеет несколько привязок языка, позволяя XPCOM компонентам быть использованным и реализованным на JavaScript, Java, Python и в дополнениях к С++. Интерфейсы в XPCOM определены в IDL диалекте и называются XPIDL.
+
+XPCOM сама обеспечивает набор базовых компонентов и классов, например, файлов и управления памятью, потоков, базовых структур данных (строки, массивы, варианты) и т.д. Большинство компонентов XPCOM не являются частью этого базового набора и предоставляются другим частям платформ (например, Gecko или Necko) или приложения или даже расширения.

+

Categories

+

Interwiki Language Links

+

 

+

{{ languages( { "en": "en/XPCOM", "es": "es/XPCOM", "fr": "fr/XPCOM", "it": "it/XPCOM", "ja": "ja/XPCOM", "ko": "ko/XPCOM", "pl": "pl/XPCOM", "zh-cn": "cn/XPCOM" } ) }}

diff --git "a/files/ru/orphaned/\320\262\320\265\320\261-\321\201\321\202\320\260\320\275\320\264\320\260\321\200\321\202\321\213/index.html" "b/files/ru/orphaned/\320\262\320\265\320\261-\321\201\321\202\320\260\320\275\320\264\320\260\321\200\321\202\321\213/index.html" new file mode 100644 index 0000000000..993ff92019 --- /dev/null +++ "b/files/ru/orphaned/\320\262\320\265\320\261-\321\201\321\202\320\260\320\275\320\264\320\260\321\200\321\202\321\213/index.html" @@ -0,0 +1,14 @@ +--- +title: Веб-стандарты +slug: Веб-стандарты +--- +

Веб-стандарты, как следует из их названия, являются стандартами в области веб-технологий. Эти стандарты являются рекомендациями для разработчиков программного обеспечения и для веб-мастеров. Служат веб-стандарты для того, чтобы, с одной стороны, пользователи ПО без проблем и неудобств могли пользоваться сетью интернет, а с другой стороны, для того, чтобы разработчики программного обеспечения или веб-мастера были уверены в работоспособности своих продуктов.

+

Исторически сложилось так, что в начале 90-х годов XX века развязалась так называемая "война браузеров" между компанией Netscape и Microsoft. Суть войны заключалась в том, что разработчики веб-браузеров стремились привнести в продукты своих разработок собственные новые функции, но при этом совершенно не заботились о совместимости технологий и не согласовывали свои действия с разработчиками конкурирующей компании. По этой причине начало возрастать недовольство как среди людей, создающих сайты, так и среди людей, пользующихся сетью интернет - ведь сайты, которые были написаны специально для Netscape Navigator крайне плохо работали в Microsoft Intrnet Explorer и наоборот посредством Internet Explorer почти невозможно было просматривать сайт, написанный для Netscape Navigator.

+

В 1994 году в Массачусетском технологическом институте при поддержке CERN, DARPA и Европейской Комиссии появилась организация World Wide Web Consortcium или, сокращенно, W3C. Целью консорциума по сей день является упорядочивание всех веб-технологий для того, чтобы обеспечить их доступность как можно большему числу людей всего мира.

+

Начиная, примерно, с 2000 года все крупные производители программного обеспечения для сети интернет стараются придерживаться стандартов W3C для того, чтобы обеспечить своим продуктам максимальную эффективность и совместимость с большинством веб-ресурсов. Результат работы консорциума по стандартизации веб-технологий на сегодняшний день очень значителен и выражается в том, что веб-технологии получают все большее распространение в нашем мире и упрощают многим жизнь.

+

Ссылки

+

Официальный сайт W3C (англ.): http://www.w3.org

+

Официальные учебные пособия W3C (англ.): http://www.w3schools.com/

+

Web Standards Group: http://webstandardsgroup.org/

+

Российское крыло Web Standards Group: http://web-standards.ru/

+

Web Standards Project: http://www.webstandards.org/

diff --git "a/files/ru/orphaned/\320\262\320\276\320\277\321\200\320\276\321\201\321\213_\320\261\320\265\320\267_\320\276\321\202\320\262\320\265\321\202\320\276\320\262/index.html" "b/files/ru/orphaned/\320\262\320\276\320\277\321\200\320\276\321\201\321\213_\320\261\320\265\320\267_\320\276\321\202\320\262\320\265\321\202\320\276\320\262/index.html" new file mode 100644 index 0000000000..bd39637d9a --- /dev/null +++ "b/files/ru/orphaned/\320\262\320\276\320\277\321\200\320\276\321\201\321\213_\320\261\320\265\320\267_\320\276\321\202\320\262\320\265\321\202\320\276\320\262/index.html" @@ -0,0 +1,8 @@ +--- +title: Вопросы без ответов +slug: Вопросы_без_ответов +tags: + - Оставить вопрос + - Список вопросов +--- +

Здесь Вы можете оставить свой вопрос, на который Вы не нашли ответа. После того, как мы найдём на него ответ, вопрос будет перемещён на страницу Часто Задаваемых Вопросов.

diff --git "a/files/ru/orphaned/\320\264\320\270\320\275\320\260\320\274\320\270\321\207\320\265\321\201\320\272\320\270_\320\270\320\267\320\274\320\265\320\275\321\217\320\265\320\274\321\213\320\271_\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\214\321\201\320\272\320\270\320\271_\320\270\320\275\321\202\320\265\321\200\321\204\320\265\320\271\321\201_\320\275\320\260_xul/index.html" "b/files/ru/orphaned/\320\264\320\270\320\275\320\260\320\274\320\270\321\207\320\265\321\201\320\272\320\270_\320\270\320\267\320\274\320\265\320\275\321\217\320\265\320\274\321\213\320\271_\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\214\321\201\320\272\320\270\320\271_\320\270\320\275\321\202\320\265\321\200\321\204\320\265\320\271\321\201_\320\275\320\260_xul/index.html" new file mode 100644 index 0000000000..418fbc826a --- /dev/null +++ "b/files/ru/orphaned/\320\264\320\270\320\275\320\260\320\274\320\270\321\207\320\265\321\201\320\272\320\270_\320\270\320\267\320\274\320\265\320\275\321\217\320\265\320\274\321\213\320\271_\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\214\321\201\320\272\320\270\320\271_\320\270\320\275\321\202\320\265\321\200\321\204\320\265\320\271\321\201_\320\275\320\260_xul/index.html" @@ -0,0 +1,68 @@ +--- +title: Динамически изменяемый пользовательский интерфейс на XUL +slug: Динамически_изменяемый_пользовательский_интерфейс_на_XUL +tags: + - DOM + - Extensions + - XUL +--- +

В этой статье обсуждается управление XUL интерфейсами с использованием DOM и других API. Здесь объясняется принцип документов DOM, приводится несколько простых примеров использования вызовов DOM для выполнения простейших манипуляций с документом, после чего приводится пример, демонстрирующий работу с анонимным XBL содержимым с использованием методов, специфичных для Mozilla.

+

Эта статья написана как для начинающих, так и для разработчиков среднего уровня подготовки. Предполагается, что у читателя есть базовые знания по XUL и JavaScript. Возможно вы захотие прочитать некоторые вводные документы по DOM, такие как статья Об объектной модели документа или вводная страница Gecko DOM Reference.

+

Введение

+

Как вы знаете, XUL — это язык, основанный на XML, который использовался в различных приложениях, основанных на Mozilla, таких как Firefox и Thunderbird, для описания пользовательского интерфейса. В XUL приложениях JavaScript объявляет поведение, используя DOM APIs для доступа к XUL документу.

+

Так что же такое Document Object Model APIs?

+

Это интерфейсы, которые используются при любом взаимодействии скрипта и документа. Если вы когда-либо писали скрипт, который взаимодействует с XUL (или HTML) документом, то вы уже использовали DOM-вызовы. Пожалуй, наиболее известным DOM методом является document.getElementById(), который возвращает элемент с заданным id. Возможно, вы использовали и другие DOM-вызовы, такие как element.setAttribute(), или, если вы писали расширения, метод addEventListener(). Все они объявлены в DOM.

+

Существуют также DOM-методы, которые создают, перемещают или удаляют элементы из документа. Они будут продемонстрированы позже в этом параграфе. А сейчас давайте поймем, что такое document.

+

Что такое document?

+

Document — это структура данных, которой можно управлять через DOM APIs. Логической структурой каждого объекта document является дерево с узлами-элементами, атрибутами, комментариями и т.д. Используйте инструмент DOM Inspector, чтобы увидеть древовидное представление любого объекта document.

+

Можно считать, что document — это представление в памяти правильного HTML или хорошо сформированного XML, как, например, xhtml или XUL.

+

Важно запомнить, что разные страницы (и даже различные экземпляры одной страницы) соответствуют разным документам. Каждое XUL-окно имеет имеет свой собственный отдельный document. Более того, в одном окне может быть несколько различных объектов document, если используется <iframe>, <browser> или <tabbrowser>. Вы должны быть уверены, что все время управляете именно тем (а не иным) объектом document (больше информации можно найти в разделе Working with windows in chrome code). Если ваш скрипт подключается с использованием тэга <script>, то свойство document ссылается на DOM document, который содержит скрипт.

+

Пример: Использование методов DOM

+

Этот параграф демонстрирует использование DOM-методов appendChild(), createElement(), insertBefore(), и removeChild().

+

Удаление всех дочерних элементов

+

Этот пример удаляет все элементы, дочерние для элемента с id=someElement из текущего document'а, с использованием метода removeChild() который удаляет первый дочерний элемент до тех пор, пока их не останется совсем.

+

Заметьте, что hasChildNodes() и firstChild являются также частью DOM API.

+
var element = document.getElementById("someElement");
+  while(element.hasChildNodes()){
+    element.removeChild(element.firstChild);
+  }
+
+

Вставка элементов в меню

+

Этот пример добавляет два новых элемента меню к <menupopup>: в начало и в конец. Здесь используется метод document.createElementNS() для создания элементов и insertBefore() с appendChild() для вставки созданных xml элементов в документ.

+

Замечания:

+
    +
  • document.createElementNS() создает элемент, но не добавляет ничего в document. Необходимо воспользоваться другим DOM-методом, таким как appendChild() для вставки только что созданного элемента в document.
  • +
  • appendChild() добавляет узел после других узлов, а insertBefore() вставляет узел перед узлом, указанным во втором параметре.
  • +
+
function createMenuItem(aLabel) {
+  const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+  var item = document.createElementNS(XUL_NS, "menuitem"); // Создаем новый элемент меню XUL
+  item.setAttribute("label", aLabel);
+  return item;
+}
+var popup = document.getElementById("myPopup"); // элемент <menupopup>
+var first = createMenuItem("First item");
+var last = createMenuItem("Last item");
+popup.insertBefore(first, popup.firstChild);
+popup.appendChild(last);
+
+

Вы также можете использовать appendChild() и insertBefore() для передвигания существующих элементов. Например, вы можете подвинуть элемент "First item" в конец popup'а, добавив эту строчку последней:

+
popup.appendChild(first);
+
+

Этот оператор удалит узел из его текущего места и заново вставит его в конец popup'а.

+

Анонимное содержимое (XBL)

+

XBL — это язык, используемый в Mozilla для объявления новых виджетов. Виджеты, объявленные в XBL можно выбирать для объявления некоторого содержимого, объединенного в связку с помощью граничного элемента. Такое содержимое называется анонимное содержимое и оно не доступно через обычную модель DOM. (подкорректируйте, я не понял смысла).

+

Вместо этого вам необходимо использовать методы интерфейса nsIDOMDocumentXBL. Например:

+
// Выбирает первый анонимный дочерний элемент для заданного
+document.getAnonymousNodes(node)[0];
+
+// Возвращает NodeList анонимных элементов с атрибутом anonid равным el1
+document.getAnonymousElementByAttribute(node, "anonid", "el1");
+
+

См. getAnonymousNodes и getAnonymousElementByAttribute в XBL-справочнике.

+

Если вы достали анонимный узел, то дальше можно использовать обычные DOM-методы для работы с остальными элементами этой связки.

+

Смотри также

+ diff --git "a/files/ru/orphaned/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/index.html" "b/files/ru/orphaned/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/index.html" new file mode 100644 index 0000000000..b86149b9b8 --- /dev/null +++ "b/files/ru/orphaned/\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\321\214/index.html" @@ -0,0 +1,18 @@ +--- +title: Доступность +slug: Доступность +tags: + - Accessibility +--- +

 

+
+

"Доступность чаще всего используется, чтобы описать средства обслуживания или удобства, чтобы помочь людям с неполными способностями (инвалидам). Это может быть Шрифт Брайля (обозначения для слепых), скаты для инвалидного кресла, звуковые сигналы в пешеходных переходах, контурах прохода, дизайн вебсайта, и так далее..." {{ Ref(1) }}

+
+ +

Документация

Введение
Software Accessibility Today
Доступность программного обеспечения прошла значительные усовершенствования за прошлые два десятилетия. Эта статья рассматривает продвижение и технологию, как оно развивалось.
Dive into Accessibility
Эта книга отвечает на два вопроса. Первый - "Почему я должен делать мой сайт более доступным?" Второй - "Как я могу сделать мой сайт более доступным?"
Accessible Web Page Authoring
Хорошая статья о "Доступности для веб-сайта", от IBM.
Guidelines
Accessibility:Architecture
Как иерархия доступности выполнена в Mozilla
Building accessible custom components in XUL
Как использовать Технику доступности DHTML чтобы сделать ваши XUL компоненты доступными.
Accessible XUL Authoring Guidelines
When authored according to these guidelines, XUL is capable of generating accessible user interfaces. Coders, reviewers, designers and QA engineers should be familiar with these guidelines.
Key-navigable custom DHTML widgets, in Mozilla and IE
Until now, web developers who want to make their styled <div> and <span> based widgets keyboard accessible have lacked the proper techniques. Keyboard accessibility is part of the minimum accessibility requirements of which any web developer should be aware.
Building XULRunner with Python
How to build XULRunner with Python on Windows. Then comtypes gives access to MSAA and IAccessible2
References
AT APIs Implementation by Gecko
Shows how Gecko handles ATK, IAccessible2, MSAA and Universal Access API
ARIA: Accessible Rich Internet Applications
ARIA, formerly known as DHTML accessibility, allows desktop-style widgets such as tree views, menu bars and spreadsheets which are accessible both with the keyboard and assistive technologies such as screen readers, screen magnifiers and alternative input devices. It also allows authors describe live changes on a web page, to help screen readers know when to announce those changes. See also the report on upcoming support for AJAX:WAI ARIA Live Regions.
Accessibility XForms References
Shows how XForms controls are mapped to accessible tree

View All...

Community

  • View Mozilla forums...

{{ DiscussionList("support-accessibility", "mozilla.support.accessibility") }}

Tools

View All...

Web Development, Web Standards, XUL
+<hr> +

{{ Note(1) }} Wikipedia entry for Accessibility

+

Categories

+

Interwiki Language Links

+

 

+

{{ languages( { "es": "es/Accesibilidad", "fr": "fr/Accessibilit\u00e9", "ja": "ja/Accessibility", "pl": "pl/Dost\u0119pno\u015b\u0107" } ) }}

diff --git "a/files/ru/orphaned/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\276\320\272_\321\201\321\201\321\213\320\273\320\272\320\270/index.html" "b/files/ru/orphaned/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\276\320\272_\321\201\321\201\321\213\320\273\320\272\320\270/index.html" new file mode 100644 index 0000000000..633d7eb6a3 --- /dev/null +++ "b/files/ru/orphaned/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\276\320\272_\321\201\321\201\321\213\320\273\320\272\320\270/index.html" @@ -0,0 +1,15 @@ +--- +title: Заголовок ссылки +slug: Заголовок_ссылки +--- +

Это моя страничка для работы +Кроме того мне нужно разместить здесь фотьографии + +

+

НОВАЯ ЗЕМЛЯ

+

Изображение:Example/Users/macintosh/Desktop/РАБОТА ОБЩАЯ 2006/ForWEB/ForWEB-Images/0.jpg.jpg +Медиа:Example.ogg +

Вставляйте сюда ОБЯЗАТЕЛЬНО формулу</E=mc2>
+<nowiki>именно сюда Вставляйте сюда неотформатированный текст.</nowiki>
+--Piligrimnew153 16:48, 4 декабря 2006 (PST)доктор Бааз 05 декабря 2006
+----
diff --git "a/files/ru/orphaned/\320\272\320\276\320\275\321\202\321\200\320\276\320\273\321\214_\320\272\320\260\321\207\320\265\321\201\321\202\320\262\320\260/index.html" "b/files/ru/orphaned/\320\272\320\276\320\275\321\202\321\200\320\276\320\273\321\214_\320\272\320\260\321\207\320\265\321\201\321\202\320\262\320\260/index.html" new file mode 100644 index 0000000000..c5059d89f6 --- /dev/null +++ "b/files/ru/orphaned/\320\272\320\276\320\275\321\202\321\200\320\276\320\273\321\214_\320\272\320\260\321\207\320\265\321\201\321\202\320\262\320\260/index.html" @@ -0,0 +1,6 @@ +--- +title: Контроль качества +slug: Контроль_качества +--- +


+
Эта страница не содержит текста. Измените MDN добавив статью.

diff --git "a/files/ru/orphaned/\320\273\320\276\320\272\320\260\320\273\320\270\320\267\320\260\321\206\320\270\321\217/index.html" "b/files/ru/orphaned/\320\273\320\276\320\272\320\260\320\273\320\270\320\267\320\260\321\206\320\270\321\217/index.html" new file mode 100644 index 0000000000..0f723d6f82 --- /dev/null +++ "b/files/ru/orphaned/\320\273\320\276\320\272\320\260\320\273\320\270\320\267\320\260\321\206\320\270\321\217/index.html" @@ -0,0 +1,5 @@ +--- +title: Локализация +slug: Локализация +--- +

Локализация - это процесс перевода пользовательского интерфейса программного обеспечения с одного языка на другой и адаптации в соответствии с особенностями иностранной культуры. Данный ресурс расскажет о создании базирующихся на технологиях Mozilla локализованных приложений и расширений.

diff --git "a/files/ru/orphaned/\320\275\320\260\321\201\321\202\321\200\320\276\320\271\320\272\320\260_\321\201\321\200\320\265\320\264\321\213_\321\200\320\260\320\267\321\200\320\260\320\261\320\276\321\202\320\272\320\270_\321\200\320\260\321\201\321\210\320\270\321\200\320\265\320\275\320\270\320\271/index.html" "b/files/ru/orphaned/\320\275\320\260\321\201\321\202\321\200\320\276\320\271\320\272\320\260_\321\201\321\200\320\265\320\264\321\213_\321\200\320\260\320\267\321\200\320\260\320\261\320\276\321\202\320\272\320\270_\321\200\320\260\321\201\321\210\320\270\321\200\320\265\320\275\320\270\320\271/index.html" new file mode 100644 index 0000000000..14cfda019e --- /dev/null +++ "b/files/ru/orphaned/\320\275\320\260\321\201\321\202\321\200\320\276\320\271\320\272\320\260_\321\201\321\200\320\265\320\264\321\213_\321\200\320\260\320\267\321\200\320\260\320\261\320\276\321\202\320\272\320\270_\321\200\320\260\321\201\321\210\320\270\321\200\320\265\320\275\320\270\320\271/index.html" @@ -0,0 +1,81 @@ +--- +title: Настройка среды разработки расширений +slug: Настройка_среды_разработки_расширений +tags: + - Расширения +--- +

В этой статье приводится несколько советов о том, как настроить ваше приложение Mozilla для удобной работы над расширениями.

+ +

Профиль для разработки

+ +

Чтобы избежать возможных потерь личных данных при разработке собственных расширений, рекомендуется создать отдельный профиль и проводить в нем все тестирования.

+ +

Для того, чтобы создать новый профиль в Firefox, достаточно запустить его с ключом "-ProfileManager", т.е.

+ +
firefox -ProfileManager
+
+ +

для Linux или

+ +
Win+R (или Пуск->Выполнить)
+start "" "%ProgramFiles%\Mozilla Firefox\firefox.exe" -ProfileManager
+
+ +

для Windows.

+ +

После создания профиля (назовем его myDevProfile) можно запустить Firefox, указав ключ "-P myDevProfile". Профиль по умолчанию называется "default". Таким образом, для удобства запуска можно создать 2 ярлыка (символические ссылки) на Firefox с ключами "-P <profileName>".

+ +

Однако обычно нельзя запустить 2 копии Firefox с разными профилями. Чтобы сделать это укажите при запуске дополнительно ключ "-no-remote".

+ +

Настройки Firefox для разработки

+ +

Наверно, вы знаете о возможности настроить Firefox детально с помощью about:config. Если нет, рекомендуем вам прочитать статью конфигурационных файлов.

+ +

Итак, вот настройки, которые облегчат разработку расширений под Firefox.

+ +
    +
  • javascript.options.showInConsole = true. Вывод ошибок в файлах chrome в консоль ошибок.
  • +
+ +

при редактировании здесь учтите также номер предлагаемой опции в последней секции

+ +
    +
  • nglayout.debug.disable_xul_cache = true. Отключение кеширования XUL. Вы сможете видеть изменения в интерфейсе окон и диалогов без перезагрузки браузера (к оверлеям не относится). Чтобы это заработало, вы должны использовать папки, а не jar'ы.
  • +
  • browser.dom.window.dump.enabled = true. Позволяет использовать dump("string") для вывода в стандартную консоль. Можно также использовать en:nsIConsoleService из привелигированного скрипта.
  • +
  • javascript.options.strict = true. Обеспечит вывод предупреждений JavaScript в консоль ошибок. Учтите, что, так как большинство разработчиков отключают эту опцию, вы будете видеть предупреждения о проблемах в коде других скриптов вдобавок к своим. Можете попробовать использовать Console2.
  • +
  • extensions.logging.enabled = true. Вывод более детальной информации о проблемах установки и обновления расширения.
  • +
+ +

Расширения для разработки

+ + + +

Отдельное хранение кода расширения

+ +

Чтобы не переустанавливать расширение при каждом изменении и не опасаться случайного удаления кода при его деинсталляции, можно поместить ваш код в отдельное место.

+ +
    +
  1. Найдите папку с вашим профилем. Если вы не создавали его специально, браузер использует профиль по умолчанию. Как найти папку с профилем.
  2. +
  3. Откройте папку extensions. Если ее нет, создайте ее.
  4. +
  5. Создайте новый текстовый файл и поместите в него лишь путь к вашему расширению (напр., C:\extensions\my_extension\ для Windows или ~/extensions/my_extension/ для Unix/Linux). Сохраните файл под именем, одинаковым с id вашего расширения.
  6. +
+ +

Примечания:

+ +
    +
  • Не забудьте конечный слеш.
  • +
  • Возможно возникновение проблем из-за знаков нижнего подчеркивания в названии; если так вышло, измените его.
  • +
+ +

Использование папок, а не JAR'ов

+ +

Учитывая предыдущий пункт, можно, поместив свой код в отдельное место, не упаковывать его. Это облегчит разработку вообще и позволит воспользоваться 2-й опцией в предлагаемых настройках.

diff --git "a/files/ru/orphaned/\320\277\320\265\321\200\320\265\321\205\320\276\320\264_\321\201_internet_explorer_\320\275\320\260_mozilla/index.html" "b/files/ru/orphaned/\320\277\320\265\321\200\320\265\321\205\320\276\320\264_\321\201_internet_explorer_\320\275\320\260_mozilla/index.html" new file mode 100644 index 0000000000..c24c37d79d --- /dev/null +++ "b/files/ru/orphaned/\320\277\320\265\321\200\320\265\321\205\320\276\320\264_\321\201_internet_explorer_\320\275\320\260_mozilla/index.html" @@ -0,0 +1,10 @@ +--- +title: Переход с Internet Explorer на Mozilla +slug: Переход_с_Internet_Explorer_на_Mozilla +--- +

Введение

+

Когда Netscape запустила броузер Mozilla, было решено поддерживать стандарт W3C. В результате, Mozilla не полностью совместима с Netscape Navigator 4.x и Microsoft Internet Explorer; например, Mozilla не поддерживает <layer>, я расскажу об этом позже. Броузеры, такие как Internet Explorer 4, были разработаны до утверждения стандарта W3C, и имеют много индивидуальных особенностей. В этом ключе, я опишу особенности Mozilla, с поддержкой строгого стиля HTML в сочетании с Internet Explorer и другими используемыми броузерами.

+

Впрочем я опишу как нестандартизованные технологии, такие как XMLHttpRequest, так и богатые возможности представления текста, которые Mozilla поддерживает согласно стандарту W3C. Они включают:

+
  • HTML 4.01, XHTML 1.0 и XHTML 1.1
  • Каскадные таблицы стилей (CSS): CSS 1, CSS 2.1 и частично CSS 3
  • Объектная модель документа (DOM): DOM 1, DOM 2 и частично DOM 3
  • Математический язык разметки: MathML 2.0
  • Расширяемый язык разметки (XML): XML 1.0, Пространство имен в XML, Associating Style Sheets with XML Documents 1.0, Fragment Identifier for XML
  • XSL Традиционно: XSLT 1.0
  • XML Часть языка: XPath 1.0
  • Resource Description Framework: RDF
  • Simple Object Access Protocol: SOAP 1.1
  • ECMA-262, revision 3 (JavaScript 1.5): ECMA-262
  • +
+

 

diff --git "a/files/ru/orphaned/\321\201\320\261\320\276\321\200\320\272\320\260_\320\270_\321\203\321\201\321\202\320\260\320\275\320\276\320\262\320\272\320\260/index.html" "b/files/ru/orphaned/\321\201\320\261\320\276\321\200\320\272\320\260_\320\270_\321\203\321\201\321\202\320\260\320\275\320\276\320\262\320\272\320\260/index.html" new file mode 100644 index 0000000000..0da2e7ca31 --- /dev/null +++ "b/files/ru/orphaned/\321\201\320\261\320\276\321\200\320\272\320\260_\320\270_\321\203\321\201\321\202\320\260\320\275\320\276\320\262\320\272\320\260/index.html" @@ -0,0 +1,34 @@ +--- +title: Сборка и установка +slug: Сборка_и_установка +--- +
Важно: Не начинайте сборку без предварительной конфигурации!
+

Сборка

+

Для сборки продуктов Mozilla Вам потребуется программный пакет GNU make. Никакой другой компилятор типа "make" не подходит для решения задачи компиляции продуктов Mozilla. На операционных системах Windows, MacOS X и GNU/Linux используйте "make" для запуска компилятора GNU make, на других non-GNU UNIX-подобных используйте "gmake".

+

После того, как Вы скачали исходный код Mozilla, убедитесь в том, что Вы сконфигурировали его для сборки так, как описано на странице Конфигурация параметров сборки.

+

Для того, чтобы приступить к компиляции, на ОС Windows, MacOS X или GNU/Linux, убедитесь, что Вы находитесь в самой верхней директории исходного кода Mozilla, после чего выполните команду:

+
make -f client.mk build
+
Важно: в MacOS X, путь к директории с исходным кодом Mozilla, не должен содержать пробелов в именах папок!
+

Для запуска компиляции на большинстве non-GNU UNIX-подобных операционных системах, выполните команду:

+
gmake -f client.mk build
+
+

Если Вы хотите собрать программу не в автоматическом режиме, а вручную, то перейдите в Вашу объектную директорию и выполните последовательно команды:

+
./configure
+
+make #для Windows, MacOS X или Linux
+
+gmake #для non-GNU UNIX-подобных ОС
+
+

Запуск новой сборки

+

Теперь Вы можете запустить свою сборку непосредственно из директории, где она была скомпилирована. Для этого, перейдите в директорию:

+
@OBJDIR@/dist/bin #
+
+

И запустите на выполнение:

+
firefox      #для Linux это скрипт запуска
+firefox.exe  #для Windows
+
+

Сборка пакета или инсталлятора

+

Поскольку запуск программы из директории с исходным кодом и скомпилированными модулями и объектами не очень удобен. Да и перенести исполняемый файл, не потеряв его работоспособность нельзя. Для того, чтобы собрать инсталлятор для OS Windows или пакет для UNIX-подобных операционных систем, выполните в объектной директории команду:

+
make package    #для Linux, MacOS X b UNIX-ов
+make installer  #для OS Windows
+
diff --git "a/files/ru/orphaned/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\321\200\320\260\321\201\321\210\320\270\321\200\320\265\320\275\320\270\321\217/index.html" "b/files/ru/orphaned/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\321\200\320\260\321\201\321\210\320\270\321\200\320\265\320\275\320\270\321\217/index.html" new file mode 100644 index 0000000000..f5a8d14f6f --- /dev/null +++ "b/files/ru/orphaned/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\321\200\320\260\321\201\321\210\320\270\321\200\320\265\320\275\320\270\321\217/index.html" @@ -0,0 +1,274 @@ +--- +title: Создание расширения +slug: Создание_расширения +tags: + - Extensions +--- +

Введение

+ +

Этот краткий курс касается построения простейшего расширения для Firefox, которое будет добавлять в строку статуса надпись "Hello, World!".

+ +
Примечание: Расширение создаваемое в этой статье не будет работать в версиях Firefox в которых нет статичной строки состояния (Firefox 4 и выше). Более релевантную статью вы можете найти в руководстве Школьный учебник по XUL в разделе Приступая к работе с расширениями Firefox.
+ +

Что нужно знать для начала работы

+ +

Система разработки расширений спроектирована таким образом, что для начала разработки собственного расширения не требуется быть профессиональным программистом. Как бы то ни было, это программирование, поэтому желательно иметь некое представление о принципах работы компьютерных программ вообще и, в частности, быть знакомым с XML. Вообще желательно знание также JavaScript и CSS, однако в этой статье оно вам не понадобится.

+ +

Создание проекта расширения

+ +

Расширения состоят из нескольких файлов и для корректной его работы необходимо придерживаться определенных правил их расположения в директориях. Вот структура типичного расширения:

+ +
/myExtension:
+              /install.rdf
+              /components/*
+              /defaults/
+              /defaults/preferences/*.js
+              /plugins/*
+              /chrome.manifest
+              /chrome/icons/default/*
+              /chrome/
+              /chrome/content/
+
+ +

Впрочем, в вашем расширении необязательно должны быть все эти папки. Сейчас мы создадим схожий каркас для нашего расширения. Для начала создадим папку для его хранения (напр. C:\extensions\my_extension\ для Windows или ~/extensions/my_extension/ для Unix/Linux). Эта папка будет корневой. Создайте в ней подпапку chrome, а в последней - папку content.

+ +

Теперь создайте в корневой папке 2 пустых файла: chrome.manifest и install.rdf.

+ +

Итак, сейчас мы имеем такую структуру расширения:

+ +
<ext path>/
+          install.rdf
+          chrome.manifest
+          chrome/
+             content/
+
+ +

Для облегчения дальнейшей разработки и тестирования рекомендуем настроить Firefox для разработки расширения.

+ +

Создание скрипта ("манифеста") установки

+ +

Откройте файл install.rdf в текстовом редакторе и поместите в него следующее:

+ +
<?xml version="1.0"?>
+
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+
+  <Description about="urn:mozilla:install-manifest">
+    <em:id>sample@example.net</em:id>
+    <em:version>1.0</em:version>
+    <em:type>2</em:type>
+
+    <!-- Target Application this extension can install into,
+         with minimum and maximum supported versions. -->
+    <em:targetApplication>
+      <Description>
+        <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
+        <em:minVersion>1.5</em:minVersion>
+        <em:maxVersion>2.0.0.*</em:maxVersion>
+      </Description>
+    </em:targetApplication>
+
+    <!-- Front End MetaData -->
+    <em:name>sample</em:name>
+    <em:description>A test extension</em:description>
+    <em:creator>Your Name Here</em:creator>
+    <em:homepageURL>http://www.example.com/</em:homepageURL>
+  </Description>
+</RDF>
+
+ +

Как видите, этот файл имеет вид XML-файла. Полное описание необходимых и возможных параметров есть здесь, сейчас же отметим лишь, что этот файл предназначен для общего описания расширения, например, уникальный идентификатор расширения, его версию, имя, автора, информацию о совместимости и т.п. Назначение многих параметров понятно из их названия. Что необходимо знать сейчас:

+ +
    +
  • sample@example.net - уникальный идентификатор вашего расширения. Это может быть адрес электронной почты (как здесь) или GUID. Обратите внимание, что адрес может быть несуществующим, главное, чтобы он был уникальным.
  • +
+ +
    +
  • 2 - указывает, что это именно расширение (связано с тем, что такие же манифесты создаются для тем и плагинов).
  • +
+ +
    +
  • {ec8030f7-c20a-464f-9b0e-13a3a9e97384} - идентификатор Firefox'а (конечно, он одинаковый для всех расширений).
  • +
+ +
    +
  • 1.5 - минимальная версия Firefox, с которой будет работать ваше приложение. Обратите внимание, что указать здесь какой-либо номер не значит автоматически сделать расширение работающим с этой версией. Это лишь означает, что вы, как разработчик, утверждаете, что расширение будет работать с ней, а вот будет ли так, зависит только от вас.
  • +
+ +
    +
  • 2.0.0.* - максимальный номер версии Firefox. * означает, что включаются все версии, имеющие вид 2.0.0.x, где x - любое число.
  • +
+ +

Расширение браузера с помощью XUL

+ +

Интерфейс Firefox написан на XUL и JavaScript. XUL - это язык, основанный на XML. Он отвечает за визуальную часть интерфейса. JavaScript реализует функциональность через привязку к действиям пользователя.

+ +

Так как визуально браузер строится на XUL, то, следовательно, он весь представляется в виде XML-файла. Вы можете посмотреть на него (это будет полезно для четкого понимания своих дальнейших действий). Зайдите в папку установки Firefox, откройте там папку chrome. В ней будет browser.jar. Несмотря на расширение, этот файл - обычный zip-архив. Внутри него вы найдете файл content/browser/browser.xul. Открыв его, можно полюбоваться на общую структуру визуальной части браузера. Пусть вас не смущает большое количество непонятных пока строк - во всем разберетесь позже. Собственно, корневым узлом этого XML-файла являетcя элемент window, содержащиеся в нем узлы - это отдельные элементы интерфейса. Например, вы можете найти кнопку обновления страницы (поищите узел с id="reload-button") или пункт меню "Правка" (id="edit-menu").

+ +

Так вот, суть расширения интерфейса браузера состоит в том, что мы берем некий узел из браузера, описываем его в своем файле с необходимыми нам изменениями, например, добавляя к нему новые дочерние узлы. Таким образом можно добавить новые кнопки в панель инструментов (или создать новую панель и поместить ее в нужное место), добавить новый пункт меню (как рядом со "Справкой" так и в подменю, скажем, "Инструменты" (Tools)). Это технология называется en:XUL Overlays.

+ +

В нашем случае мы добавим новый элемент в строку статуса. В файле browser.xul можно найти узел с id="status-bar". Это и есть строка статуса. В этом узле есть несколько дочерних узлов. Добавим к ним наш, который будет описывать новую панель. Создайте файл, назовите его, скажем, sample.xul и поместите в папку chrome/content. Внесите туда такой код:

+ +
<?xml version="1.0"?>
+<overlay id="sample"
+         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <statusbar id="status-bar">
+  <statusbarpanel id="my-panel" label="Hello, World"/>
+ </statusbar>
+</overlay>
+
+ +

Здесь <statusbar> с id="status-bar" является "точкой склейки" (merge point), т.е. узлом, который мы намереваемся изменить. <statusbarpanel> - новый виджет, который мы добавляем в <statusbar>.

+ +

URI Chrome

+ +

XUL-файлы (вроде того, который мы только что создали) загружаются через URI протокола chrome://. Вместо того, чтобы каждый раз определять место установки Firefox'а и загружать файлы через file://, можно загружать их через chrome://, не беспокоясь об их истинном положении на диске.

+ +

Так, окно браузера, которое мы недавно просматривали, находится по адресу chrome://browser/content/browser.xul. Можете попробовать ввести его в адресную строку и посмотреть на результат.

+ +

URI хрома состоит из нескольких частей:

+ +
    +
  • протокол chrome говорит, что необходимо классифицировать и обработать содежимое файла как хром.
  • +
  • название пакета (в данном случае, это browser), указывающий на "сверток" (bundle) компонентов интерфейса. Это название уникально для каждого приложения/расширения.
  • +
  • тип запрашиваемых данных. Есть три типа: content (XUL, JavaScript, XBL Bindings и др., т.е. компоненты, формирующие вид и поведение интерфейса), locale (DTD, файлы propeties и т.п., производящие локализацию интерфейса) и skin (CSS и изображения для формирования темы интерфейса).
  • +
  • файл для загрузки.
  • +
+ +

Так, например, chrome://foo/skin/bar.png загружает файл bar.png из секции skin пакета foo.

+ +

Создание манифеста chrome

+ +

Для хорошего понимания манифеста просмотрите статью en:Chrome Manifest

+ +

Откройте chrome.manifest, созданный нами ранее и добавьте в него следующее:

+ +
content     sample    chrome/content/
+
+ +

Не забудьте завершающий слеш.

+ +

Эта строка объявляет

+ +
    +
  1. тип данных в пакете chrome,
  2. +
  3. название пакета (используйте лишь строчные буквы),
  4. +
  5. путь к файлам пакета.
  6. +
+ +

Таким образом, здесь мы говорим, что файлы типа content для пакета sample можно найти в chrome/content (путь относительно местоположения chrome.manifest).

+ +

Сохраните файл. Позже, при запуске Firefox, пакет chrome вашего расширения будет зарегистрирован с помощью этого файла.

+ +

Регистрация оверлея

+ +

Для того, чтобы Firefox понял, что у нас есть оверлей и мы хотим наложить его на окно браузера, необходимо зарегистрировать оверлей через все тот же chrome.manifest. Добавляем в него строку

+ +
overlay chrome://browser/content/browser.xul chrome://sample/content/sample.xul
+
+ +

Это говорит Firefox'у, что нужно объединить sample.xul и browser.xul

+ +

Тестирование

+ +

Для начала необходимо уведомить Firefox о нашем расширении. Раньше (еще во времена Firefox 1.0) необходимо было упаковать расширение как en:XPI и установить через интерфейс браузера. Теперь же достаточно просто указать Firefox'у, где находится папка с вашим расширением - и он будет подключать его каждый раз при загрузке.

+ +

Итак, ваши действия:

+ +
    +
  1. Найдите папку с вашим профилем. Если вы не создавали его специально, браузер использует профиль по умолчанию.
    + Как найти папку с профилем.
  2. +
  3. Откройте папку extensions. Если ее нет, создайте ее.
  4. +
  5. Создайте новый текстовый файл и поместите в него лишь путь к вашему расширению (напр., C:\extensions\my_extension\ для Windows или ~/extensions/my_extension/ для Unix/Linux). Сохраните файл под именем, одинаковым с id вашего расширения.
  6. +
+ +

Примечания:

+ +
    +
  • Не забудьте завершающий слеш.
  • +
  • Возможно возникновение проблем из-за знаков нижнего подчеркивания в названии; если так вышло измените его.
  • +
+ +

Теперь вы готовы к тестированию вашего расширения. Запустите Firefox. Он увидит ссылку к вашему расширению и установит его. Если все прошло успешно, вы увидите надпись "Hello, World!" в строке статуса справа. Для внесения изменений достаточно править xul-файлы и перезапустить Firefox.

+ +

Упаковка расширения

+ +

Теперь можно упаковать расширение для его дальнейшего распространиения и установки.

+ +

Создайте zip-архив из содержания корневой папки вашего расширения (но не архивируйте саму папку). Переименуйте файл, чтобы он имел расширение ".xpi". Вот и все. Для установки достаточно перетащить файл на окно браузера.

+ +

Установка с веб-страницы

+ +

Есть несколько способов это сделать. Можно разместить прямую ссылку на xpi-файл. Однако предпочтительным является InstallTrigger method, как более удобный для пользователей.

+ +

Сайт расширений addons.mozilla.org

+ +

Сайт расширений Mozilla (http://addons.mozilla.org) является местом, где вы можете бесплатно разместить свое расширение. Сайт является надежным и удобным местом для распространения своих расширений: достаточно лишь зарегистрироваться - и вы сможете загружать свои файлы на сервер.

+ +

Регистрирование расширения в реестре Windows

+ +

В Windows информация о расширении может быть добавлена в реестр. Это дает дополнительный возможности при установке расширений. Поробнее об этом читайте здесь.

+ +

Узнайте больше об оверлеях XUL

+ +

В настоящем руководстве была затронута лишь крохотная часть всех возможностей модифицирования интерфейса с помощью XUL. Чтобы узнать больше, смотрите документацию XUL.

+ +

Локализация

+ +

Для поддержки более чем одного языка необходимо отделить локализуемые строки от основного содержания с помощью сущностей (entities) и "свертков строк" (string bundles). Гораздо проще делать это в течение разработки расширения, чем после.

+ +

Информация о локализации хранится в подпапке locale папки chrome (т.е. рядос с папкой content). В этой папке необходимо разместить столько папок, сколько локализаций вы намерены сделать. Обычной практикой является называть папки стандартными названиями локалей: скажем, папку с английской локализацией - en-US, русской - ru-RU и т.п., что, впрочем, не является обязательным. Теперь создайте в каждой из папок файл somename.ent (или anothername.dtd) (имя одинаково во всех папках локализаций) и заполните его соответствующим образом (показано ниже).

+ +

Локализуем наше расширение на русский и английский языки. После создания 2 папок (назовем их ru-RU и en-US), создаем в каждой из них файл (пусть myStatusBar.ent) Поместите в тот файл, который в папке с английской локализацией, следующую строку:

+ +
<!ENTITY statusbarpanel.label "Hello, World!">
+
+ +

А в тот, который будет локализовать на русский язык, соответственно

+ +
<!ENTITY statusbarpanel.label "Привет, мир!">
+
+ +

Сохраните оба файла. Теперь необходимо зарегистрировать локализации. Для этого добавим в chrome.manifest следующие строки:

+ +
locale sample en-US chrome/locale/en-US/
+locale sample ru-RU chrome/locale/ru-RU/
+
+ +

Теперь для использования локализации достаточно добавить в начало (однако после xml-объявления) xul-файла строку

+ +
<!DOCTYPE window SYSTEM "chrome://sample/locale/myStatusBar.ent">
+
+ +

где window - это названия корневого элемента xul-документа (в нашем случае это overlay).

+ +

Для использования сущностей измените ваш xul-файл так, чтобы атрибут label у новой statusbarpanel был равен "&statusbarpanel.label;".

+ +

Исследование браузера

+ +

Гораздо более простым (и эффективным) способом исследования браузера является использование DOM Inspector'а. Он позволяет полностью изучить структуру документа, загруженного в браузер. Так, например, можно загрузить вышеописанным способом browser.xul, просмотреть все его узлы и найти подходящий для наложения оверлея. Или же можно просматривать структуру своего расширения.

+ +

Отладка расширений

+ +

Инструменты для анализа расширений

+ + + +

Отладочная распечатка

+ + + +

Дополнительная информация

+ + diff --git "a/files/ru/orphaned/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\321\200\320\260\321\201\321\210\320\270\321\200\320\265\320\275\320\270\321\217/\320\275\320\260\321\201\321\202\321\200\320\276\320\271\320\272\320\260_firefox_\320\264\320\273\321\217_\321\200\320\260\320\267\321\200\320\260\320\261\320\276\321\202\320\272\320\270/index.html" "b/files/ru/orphaned/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\321\200\320\260\321\201\321\210\320\270\321\200\320\265\320\275\320\270\321\217/\320\275\320\260\321\201\321\202\321\200\320\276\320\271\320\272\320\260_firefox_\320\264\320\273\321\217_\321\200\320\260\320\267\321\200\320\260\320\261\320\276\321\202\320\272\320\270/index.html" new file mode 100644 index 0000000000..790d74ed18 --- /dev/null +++ "b/files/ru/orphaned/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\321\200\320\260\321\201\321\210\320\270\321\200\320\265\320\275\320\270\321\217/\320\275\320\260\321\201\321\202\321\200\320\276\320\271\320\272\320\260_firefox_\320\264\320\273\321\217_\321\200\320\260\320\267\321\200\320\260\320\261\320\276\321\202\320\272\320\270/index.html" @@ -0,0 +1,25 @@ +--- +title: Настройка Firefox для разработки +slug: Создание_расширения/Настройка_Firefox_для_разработки +--- +

Перед созданием собственного расширения рекомендуется для этого настроить Firefox. Нужно это для того, чтобы не потерять важные данные и не сбить настройки на повседневном профиле браузера из-за неудачного опыта с расширением.

+

Создание экспериментального профиля

+

В Firefox имеется очень удобный менеджер профилей. С его помощью мы и создадим экспериментальный профиль на котором будем испытывать наши расширения.

+

Для того, чтобы вызвать менеджер профилей:

+
  • В Microsoft Windows:
  • +
+
  1. Нажмите кнопку "Пуск".
  2. Выберите пункт "Выполнить".
  3. Введите в строку "firefox -p" (без кавычек).
  4. +
+
  • В Linux:
  • +
+
  1. Откройте терминал.
  2. Введите "firefox -p".
  3. +
+

В открывшемся окне менеджера профилей нажмите кнопку "Создать". Далее следуйте инструкциям в менеджере. Он Вам предложит ввести для нового профиля название, для нашего пусть будет "Develop" (это уже на Ваше усмотрение), а так же предложит выбрать папку, где будет наш профиль храниться. Для папки экспериментального профиля подойдет открытое и, главное, доступное место, потому что может потребоваться в нем что-нибудь изменить руками или добавить какой-нибудь файл.

+

После того, как профиль создан, нажимаем на "Запуск Firefox". После запуска браузера вводим в адресную строку "about:config" и нажимаем Enter. На это браузер нам выдаст окно с предупреждением о возможности испортить программу, мы пообещаем ему быть осторожными.

+

В открывшемся меню Вы увидите множество строк с настройками браузера. Но в настройках "по умолчанию" вписаны не все нужные нам строки - ведь в повседневной жизни они не нужны. Для полноценной настройки экспериментального профиля Firefox следует добавить в настройки некоторые параметры. Для этого достаточно нажать правую кнопку мыши в любом месте списка и выбрать из контекстного меню пункт "Создать" --> "Логичкеское".

+
  • javascript.options.showInConsole = true - запись ошибок в файлах chrome в консоль ошибок (англ.).
  • nglayout.debug.disable_xul_cache = true - выключение кеширования xul-объектов. При внесении изменений в окна и диалоги не потребуется перезапуск браузера. Однако, работает только при использовании простых папок, а не jar-архивов. Внесение же изменеий в xul-оверлэи все таки потребует перезапуска браузера.
  • browser.dom.window.dump.enabled = true - позволяет выводить в стандартную консоль состояние дампа. Для получения информации смотри window.dump (англ.)
  • javascript.options.strict = true - принудительный вывод в консоль всех предупреждений JavaScript.
  • extensions.logging.enabled = true - вывод информации об инсталляции и обновлении в консоль ошибок.
  • +
+

Расширения разработчика

+

При создании собственных расширений могут быть очень полезными следующие дополнения для Firefox:

+ diff --git "a/files/ru/orphaned/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\321\200\320\260\321\201\321\210\320\270\321\200\320\265\320\275\320\270\321\217/\320\275\320\260\321\201\321\202\321\200\320\276\320\271\320\272\320\260_firefox_\320\264\320\273\321\217_\321\200\320\260\320\267\321\200\320\260\320\261\320\276\321\202\320\272\320\270_\321\200\320\260\321\201\321\210\320\270\321\200\320\265\320\275\320\270\320\271/index.html" "b/files/ru/orphaned/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\321\200\320\260\321\201\321\210\320\270\321\200\320\265\320\275\320\270\321\217/\320\275\320\260\321\201\321\202\321\200\320\276\320\271\320\272\320\260_firefox_\320\264\320\273\321\217_\321\200\320\260\320\267\321\200\320\260\320\261\320\276\321\202\320\272\320\270_\321\200\320\260\321\201\321\210\320\270\321\200\320\265\320\275\320\270\320\271/index.html" new file mode 100644 index 0000000000..2ee5466f3e --- /dev/null +++ "b/files/ru/orphaned/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\321\200\320\260\321\201\321\210\320\270\321\200\320\265\320\275\320\270\321\217/\320\275\320\260\321\201\321\202\321\200\320\276\320\271\320\272\320\260_firefox_\320\264\320\273\321\217_\321\200\320\260\320\267\321\200\320\260\320\261\320\276\321\202\320\272\320\270_\321\200\320\260\321\201\321\210\320\270\321\200\320\265\320\275\320\270\320\271/index.html" @@ -0,0 +1,15 @@ +--- +title: Настройка Firefox для разработки расширений +slug: Создание_расширения/Настройка_Firefox_для_разработки_расширений +--- +

Прежде чем начать разработку расширения, желательно настроить для этого Firefox. Нужно это для того, чтобы не потерять нужные данные и не сбить настройки в повседневном профиле Firefox.

+

Создание экспериментального профиля Firefox

+

Firefox хранит свои настройки в так называемом профиле. Профиль это папка, содержащая файлы в которых и хранятся настройки программы, файлы расширений, локальный кеш браузера, информация о сессиях, файлы пользовательских закладок и прочее.

+

Для того, чтобы не пришлось восстанавливать свои настройки после неудачного эксперимента с расширением, предлагается (на Ваше усмотрение, конечно) сделать профиль, который будет служить специально для разработки расширений и в нем будут внесен ряд небольших, но полезных изменений в глобальных настройках браузера.

+

Для создания профиля в Microsoft Windows сделайте следующее:

+
  • Закройте все окна Firefox
  • Нажмите кнопку "Пуск"
  • Выберите меню "Выполнить"
  • Впишите в строку  "Путь_к_папке\с_программой\firefox.exe -no-remote -P имя_профиля"
  • +
+

Для создания профиля в Linux сделайте следующее:

+
  • Откройте терминал
  • Введите там следующее "firefox -no-remote -p имя_профиля"
  • +
+

Это должно запустить программу уже с новым профилем. По умолчанию в нем ничего не установлено и все настройки находятся в состоянии "по умолчанию".

diff --git "a/files/ru/orphaned/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\321\200\320\260\321\201\321\210\320\270\321\200\320\265\320\275\320\270\321\217_\320\264\320\273\321\217_firefox_\321\201_\320\270\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265\320\274_mozilla_build_system/index.html" "b/files/ru/orphaned/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\321\200\320\260\321\201\321\210\320\270\321\200\320\265\320\275\320\270\321\217_\320\264\320\273\321\217_firefox_\321\201_\320\270\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265\320\274_mozilla_build_system/index.html" new file mode 100644 index 0000000000..b6fbfd6e87 --- /dev/null +++ "b/files/ru/orphaned/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\321\200\320\260\321\201\321\210\320\270\321\200\320\265\320\275\320\270\321\217_\320\264\320\273\321\217_firefox_\321\201_\320\270\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265\320\274_mozilla_build_system/index.html" @@ -0,0 +1,6 @@ +--- +title: Создание расширения для Firefox с использованием Mozilla Build System +slug: Создание_расширения_для_Firefox_с_использованием_Mozilla_Build_System +--- +

Существует специальное расширение для создания новых расширений для Firefox. +

{{ languages( { "en": "en/Creating_Custom_Firefox_Extensions_with_the_Mozilla_Build_System", "it": "it/Creare_Estensioni_personalizzate_per_Firefox_con_il_sistema_di_sviluppo_di_Mozilla", "ja": "ja/Creating_Custom_Firefox_Extensions_with_the_Mozilla_Build_System" } ) }} diff --git "a/files/ru/orphaned/\321\201\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\260\321\217_\320\270\320\275\321\204\320\276\321\200\320\274\320\260\321\206\320\270\321\217_\320\277\320\276_gecko_dom/index.html" "b/files/ru/orphaned/\321\201\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\260\321\217_\320\270\320\275\321\204\320\276\321\200\320\274\320\260\321\206\320\270\321\217_\320\277\320\276_gecko_dom/index.html" new file mode 100644 index 0000000000..91f9a7bee9 --- /dev/null +++ "b/files/ru/orphaned/\321\201\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\260\321\217_\320\270\320\275\321\204\320\276\321\200\320\274\320\260\321\206\320\270\321\217_\320\277\320\276_gecko_dom/index.html" @@ -0,0 +1,81 @@ +--- +title: Справочная информация по Gecko DOM +slug: Справочная_информация_по_Gecko_DOM +tags: + - NeedsTechnicalReview + - Справочная_информация_по_Gecko_DOM +--- +

Содержание справочной информации по Gecko DOM. +

+

Предисловие

+ +

Введение

+ +

Справочная информация по DOM element

+ +

Справочная информация по DOM window

+ +

Справочная информация по DOM document

+ +

Справочная информация по DOM event

+ +

Справочная информация по DOM style

+ +

Справочная информация по DOM range

+ +

Справочная информация по DOM selection

+ +

Интерфейс элемента HTML Form

+ +

Интерфейс элемента HTML Table

+ +

Примеры использования DOM

+ +{{ languages( { "fr": "fr/Reference_du_DOM_Gecko", "ja": "ja/\u0421\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u0430\u044f_\u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f_\u043f\u043e_Gecko_DOM", "ko": "ko/\u0421\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u0430\u044f_\u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f_\u043f\u043e_Gecko_DOM", "pl": "pl/Dokumentacja_Gecko_DOM", "zh-cn": "cn/Gecko_DOM_??" } ) }} diff --git "a/files/ru/orphaned/\321\201\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\260\321\217_\320\270\320\275\321\204\320\276\321\200\320\274\320\260\321\206\320\270\321\217_\320\277\320\276_gecko_dom/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265/index.html" "b/files/ru/orphaned/\321\201\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\260\321\217_\320\270\320\275\321\204\320\276\321\200\320\274\320\260\321\206\320\270\321\217_\320\277\320\276_gecko_dom/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265/index.html" new file mode 100644 index 0000000000..e2b49f348b --- /dev/null +++ "b/files/ru/orphaned/\321\201\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\260\321\217_\320\270\320\275\321\204\320\276\321\200\320\274\320\260\321\206\320\270\321\217_\320\277\320\276_gecko_dom/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265/index.html" @@ -0,0 +1,224 @@ +--- +title: Введение +slug: Справочная_информация_по_Gecko_DOM/Введение +--- +

В этом разделе представлено краткое концептуальное введение в DOM: что это такое, как он предоставляет структуру для HTML и XML-документов, как вы можете получить к нему доступ, и как этот API представляет справочную информацию и примеры.

+ +

Что такое DOM?

+ +

Document Object Model (DOM) - это программный интерфейс для HTML и XML-документов. Он представляет страницу, чтобы программы могли изменять структуру, стиль и содержание документа. DOM отображает страницу ввиде узлов и объектов. Таким образом, языки программирования могут взаимодействовать со страницей.

+ +

Веб-страница - это документ. Этот документ можно либо отобразить в окне браузера, либо в качестве источника HTML. Но в обоих случаях это один и тот же документ. Объектная модель документа (DOM) представляет этот же документ, таким образом, чтобы им можно было манипулировать. DOM представляет собой объектно-ориентированное представление веб-страницы, которое может быть модифицировано с помощью скриптовых языков, таких как JavaScript.

+ +

Стандарты W3C DOM и WHATWG DOM реализованы в большинстве современных браузеров. Многие браузеры расширяют стандарт, поэтому следует проявлять осторожность при использовании их в Интернете, где к документам могут обращаться различные браузеры с различными DOM.

+ +

Например, стандарт DOM указывает, что метод getElementsByTagName в коде ниже должен возвращать список всех <p> элементов в документе:

+ +
var paragraphs = document.getElementsByTagName("P");
+// paragraphs[0] первый <p>-элемент
+// paragraphs[1] второй <p>-элемент и т.д.
+alert(paragraphs[0].nodeName);
+
+ +

Все свойства, методы и события, доступные для управления и создания веб-страниц, организованы в объекты (например, объект документа, который представляет сам документ (document), объект таблица (table), который реализует специальный интерфейс DOM HTMLTableElement для доступа к таблицам HTML и т. д. ). Эта документация предоставляет по-объектную справку по DOM, реализованную в браузерах на базе Gecko.

+ +

DOM и JavaScript

+ +

Краткий пример выше, как и почти все примеры в этом руководстве, - это JavaScript. То есть, он написан на JavaScript, но он использует DOM для доступа к документу и его элементам. DOM не является языком программирования, но без него язык JavaScript не имел бы никаких моделей или понятия о веб-страницах, HTML и XML документах, и об их составных частях (например, элементах). Каждый элемент в документе - документ в целом, секция документа head, таблицы внутри документа, заголовки таблиц, текст внутри ячеек таблицы - являются частью объектной модели документа для этого документа, поэтому к ним можно получить доступ и манипулировать ним с помощью DOM и скриптового языка, такого как JavaScript.

+ +

В начале JavaScript и DOM были тесно переплетены, но в конечном итоге они превратились в отдельные сущности. Содержимое страницы хранится в DOM и может быть доступно и обработано через JavaScript, так что мы можем написать приблизительно такое уравнение:

+ +

API (HTML или XML страницы) = DOM + JS (скриптовый язык)

+ +

DOM был разработан, чтобы быть независимым от любого конкретного языка программирования, делая структурное представление документа доступным из единого согласованного API. Хотя мы ориентируемся исключительно на JavaScript в этой справочной документации, реализации DOM могут быть созданы для любого языка, как демонстрирует этот пример Python:

+ +
# Python DOM example
+import xml.dom.minidom as m
+doc = m.parse("C:\\Projects\\Py\\chap1.xml");
+doc.nodeName # DOM property of document object;
+p_list = doc.getElementsByTagName("para");
+
+ +

Для получения дополнительной информации о том, какие технологии используются для написания JavaScript в Интернете, см.  обзор технологий JavaScript.

+ +

Как получить доступ к DOM?

+ +

Вам не нужно делать что-то особенное, чтобы начать использовать DOM. Различные браузеры имеют различные реализации DOM, и эти реализации демонстрируют различную степень соответствия действующему стандарту DOM (тема, которую мы пытаемся избежать в этой документации), но каждый веб-браузер использует некоторую объектную модель документа, чтобы сделать веб-страницы доступными для скрипта.

+ +

Когда вы создаете код, независимо от того, встроен ли он в элемент <script> или включен в веб-страницу с помощью инструкции по загрузке скрипта извне, вы можете сразу начать использовать API для элементов document или window  для манипулирования самим документом или получить его дочерние элементы, которые являются различными элементами веб-страницы. Ваше программирование DOM может быть достаточно простым, как, например, следующий код, который выводит предупреждающее сообщение используя функцию alert() из объекта window, или может использовать более сложные методы DOM для создания нового контента, как в более длинном примере ниже.

+ +

Следующий пример кода JavaScript буде выводить предупреждение, когда загрузка документа завершена (и когда весь DOM доступен для использования).

+ +
<body onload="window.alert('Welcome to my home page!');">
+
+ +

Эта функция создает новый элемент H1, добавляет в него текст и, затем, добавляет H1 в дерево данного документа:

+ +
<html>
+  <head>
+    <script>
+       // запускает эту функцию, когда документ загружен
+       window.onload = function() {
+
+         // создает пару элементов на пустой веб-странице
+         var heading = document.createElement("h1");
+         var heading_text = document.createTextNode("Big Head!");
+         heading.appendChild(heading_text);
+         document.body.appendChild(heading);
+      }
+    </script>
+  </head>
+  <body>
+  </body>
+</html>
+
+ +

Важные типы данных

+ +

Эта руководство пытается описать различные объекты и типы данных как можно проще. Но есть много различных типов данных, которые передаются через API, о которых вы должны знать. Для простоты, примеры синтаксиса в этом руководстве по API обычно назвывают узловые элементы - элементами element, массивам узлов, такие как nodeList, - также элементами element, а аттрибуты узлов attribute именуются просто аттрибутам.

+ +

Следующая таблица кратко описывает эти типы данных.

+ + + + + + + + + + + + + + + + + + + + + + + + +
documentКогда элемент возвращает объект типа document (например,  свойство элемента ownerDocument возвращает document, к которому он принадлежит), этот элемент является корневым объектом документа document. Глава Руководство по DOM document описывает объект document.
elementelement refers to an element or a node of type element returned by a member of the DOM API. Rather than saying, for example, that the document.createElement() method returns an object reference to a node, we just say that this method returns the element that has just been created in the DOM. element objects implement the DOM Element interface and also the more basic Node interface, both of which are included together in this reference.
nodeListA nodeList is an array of elements, like the kind that is returned by the method document.getElementsByTagName(). Items in a nodeList are accessed by index in either of two ways: +
    +
  • list.item(1)
  • +
  • list[1]
  • +
+ These two are equivalent. In the first, item() is the single method on the nodeList object. The latter uses the typical array syntax to fetch the second item in the list.
attributeWhen an attribute is returned by a member (e.g., by the createAttribute() method), it is an object reference that exposes a special (albeit small) interface for attributes. Attributes are nodes in the DOM just like elements are, though you may rarely use them as such.
namedNodeMapA namedNodeMap is like an array, but the items are accessed by name or index, though this latter case is merely a convenience for enumeration, as they are in no particular order in the list. A namedNodeMap has an item() method for this purpose, and you can also add and remove items from a namedNodeMap.
+ +

Интерфейсы DOM

+ +

This guide is about the objects and the actual things you can use to manipulate the DOM hierarchy. There are many points where understanding how these work can be confusing. For example, the object representing the HTML form element gets its name property from the HTMLFormElement interface but its className property from the HTMLElement interface. In both cases, the property you want is simply in that form object.

+ +

Но взаимосвязь между объектами и интерфейсами, которые они реализуют в DOM, может сбить с толку, и поэтому этот раздел пытается немного рассказать о реальных интерфейсах в спецификации DOM и о том, как они становятся доступными.

+ +

Интерфейсы и Объекты

+ +

Many objects borrow from several different interfaces. The table object, for example, implements a specialized HTML Table Element Interface, which includes such methods as createCaption and insertRow. But since it's also an HTML element, table implements the Element interface described in the DOM element Reference chapter. And finally, since an HTML element is also, as far as the DOM is concerned, a node in the tree of nodes that make up the object model for an HTML or XML page, the table object also implements the more basic Node interface, from which Element derives.

+ +

When you get a reference to a table object, as in the following example, you routinely use all three of these interfaces interchangeably on the object, perhaps without knowing it.

+ +
var table = document.getElementById("table");
+var tableAttrs = table.attributes; // Node/Element interface
+for (var i = 0; i < tableAttrs.length; i++) {
+  // HTMLTableElement interface: border attribute
+  if(tableAttrs[i].nodeName.toLowerCase() == "border")
+    table.border = "1";
+}
+// HTMLTableElement interface: summary attribute
+table.summary = "note: increased border";
+
+ +

Ключевые Интерфесы в DOM

+ +

This section lists some of the most commonly-used interfaces in the DOM. The idea is not to describe what these APIs do here but to give you an idea of the sorts of methods and properties you will see very often as you use the DOM. These common APIs are used in the longer examples in the DOM Examples chapter at the end of this book.

+ +

Document и window объекты являются объектами, интерфейсы которых наиболее  часто используются при программировании DOM. Простыми словами, объект window  представляет собой что-то вроде браузера, а объект document корень самого документа. Element наследуется от общего интерфейса Node, и вместе эти два интерфейса предоставляют множество методов и свойств, которые вы используете для отдельных элементов. Эти элементы также могут иметь определенные интерфейсы для обработки данных, которые хранятся в этих элементах, как в примере объекта tableв предыдущем разделе.

+ +

Ниже приведен краткий список общих API-интерфейсов в сценариях веб-страниц и XML-страниц с использованием DOM.

+ + + +

Тестирование DOM API

+ +

This document provides samples for every interface that you can use in your own web development. In some cases, the samples are complete HTML pages, with the DOM access in a <script> element, the interface (e.g, buttons) necessary to fire up the script in a form, and the HTML elements upon which the DOM operates listed as well. When this is the case, you can cut and paste the example into a new HTML document, save it, and run the example from the browser.

+ +

There are some cases, however, when the examples are more concise. To run examples that only demonstrate the basic relationship of the interface to the HTML elements, you may want to set up a test page in which interfaces can be easily accessed from scripts. The following very simple web page provides a <script> element in the header in which you can place functions that test the interface, a few HTML elements with attributes that you can retrieve, set, or otherwise manipulate, and the web user interface necessary to call those functions from the browser.

+ +

You can use this test page or create a similar one to test the DOM interfaces you are interested in and see how they work on the browser platform. You can update the contents of the test() function as needed, create more buttons, or add elements as necessary.

+ +
<html>
+  <head>
+    <title>DOM Tests</title>
+    <script type="application/javascript">
+    function setBodyAttr(attr, value){
+      if (document.body) eval('document.body.'+attr+'="'+value+'"');
+      else notSupported();
+    }
+    </script>
+  </head>
+  <body>
+    <div style="margin: .5in; height: 400;">
+      <p><b><tt>text</tt></b></p>
+      <form>
+        <select onChange="setBodyAttr('text',
+        this.options[this.selectedIndex].value);">
+          <option value="black">black
+          <option value="darkblue">darkblue
+        </select>
+        <p><b><tt>bgColor</tt></b></p>
+        <select onChange="setBodyAttr('bgColor',
+        this.options[this.selectedIndex].value);">
+          <option value="white">white
+          <option value="lightgrey">gray
+        </select>
+        <p><b><tt>link</tt></b></p>
+        <select onChange="setBodyAttr('link',
+        this.options[this.selectedIndex].value);">
+          <option value="blue">blue
+          <option value="green">green
+        </select>  <small>
+        <a href="http://www.brownhen.com/dom_api_top.html" id="sample">
+        (sample link)</a></small><br>
+      </form>
+      <form>
+        <input type="button" value="version" onclick="ver()" />
+      </form>
+    </div>
+  </body>
+</html>
+
+ +

To test a lot of interfaces in a single page-for example, a "suite" of properties that affect the colors of a web page-you can create a similar test page with a whole console of buttons, textfields, and other HTML elements. The following screenshot gives you some idea of how interfaces can be grouped together for testing.

+ +
+
Схема 0.1 Sample DOM Test Page
+Image:DOM_Ref_Introduction_to_the_DOM.gif
+ +

In this example, the dropdown menus dynamically update such DOM-accessible aspects of the web page as its background color (bgColor), the color of the hyperlinks (aLink), and color of the text (text). However you design your test pages, testing the interfaces as you read about them is an important part of learning how to use the DOM effectively.

+ + + + diff --git "a/files/ru/orphaned/\321\201\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\260\321\217_\320\270\320\275\321\204\320\276\321\200\320\274\320\260\321\206\320\270\321\217_\320\277\320\276_gecko_dom/\320\277\321\200\320\265\320\264\320\270\321\201\320\273\320\276\320\262\320\270\320\265/index.html" "b/files/ru/orphaned/\321\201\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\260\321\217_\320\270\320\275\321\204\320\276\321\200\320\274\320\260\321\206\320\270\321\217_\320\277\320\276_gecko_dom/\320\277\321\200\320\265\320\264\320\270\321\201\320\273\320\276\320\262\320\270\320\265/index.html" new file mode 100644 index 0000000000..6d891324fa --- /dev/null +++ "b/files/ru/orphaned/\321\201\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\260\321\217_\320\270\320\275\321\204\320\276\321\200\320\274\320\260\321\206\320\270\321\217_\320\277\320\276_gecko_dom/\320\277\321\200\320\265\320\264\320\270\321\201\320\273\320\276\320\262\320\270\320\265/index.html" @@ -0,0 +1,64 @@ +--- +title: Предисловие +slug: Справочная_информация_по_Gecko_DOM/Предисловие +--- +

 

+ +

О предисловии

+ +

В этом параграфе описывается руководство в целом: для кого оно, как представлена информация, и как вы можете использовать примеры статьи в своих собственных разработках.

+ +

Заметьте, что этот документ находится на стадии разработки и на данный момент не является полным списком всех DOM-методов и свойств доступных в Gecko. Тем не менее, каждый параграф документа является полным для описываемого объекта. Как только справочная информация к различным API станет доступной, она будет добавлена.

+ +

Для кого эта статья

+ +

Читатель должен быть веб-разработчиком или продвинутым веб-пользователем и иметь представление об устройстве веб-страниц. Эта статья не предполагает знакомства читателя с DOM, XML, веб-сервисами, веб-стандартами и даже с JavaScript, языком, через который DOM доступен читателю. Но подразумевается знакомство с HTML, разметкой, базовой структурой веб-страниц, браузерами и таблицами стилей.

+ +

Здесь представлен вводный материал с большим количеством примеров и хорошо организованными объяснениями, который должен пригодиться начинающим и продвинутым разработчикам. Эта статья является не только руководством для начинающих. В основном этот документ является справочным руководством по API.

+ +

Что такое Gecko?

+ +

Mozilla, Firefox, Netscape 6+ и другие основанные на Mozilla браузеры имеют одинаковые реализации DOM, поскольку все они основаны на одном движке. naturally, it applies only to products based on the same version of Gecko, but it's tricky to explain

+ +

Gecko — программный компонент всех этих браузеров, который отвечает за синтаксический разбор HTML, внешний вид страниц, объектную модель документа и даже рендеринг интерфейсов приложений. Gecko является быстрым, совместимым со стандартами движком рендеринга, который обеспечивает поддержку стандартов W3C DOM и похожую на DOM (но не стандартизированную) модель документа браузера в контексте веб-страницы и интерфейса приложения.

+ +

Хотя интерфейс приложения и содержимое, отображаемое браузером во многом различны, DOM обрабатывает их одинаково, как иерархию узлов.(commenting this incomplete sentence out for now...) The tree structure of the DOM (which in its application to the user

+ +

Синтаксис API

+ +

Каждое описание в справочнике по API включает синтаксис, входные и выходные данные, пример использования, дополнительные замечания и ссылку на соответствующую спецификацию.

+ +

Как правило атрибуты только-для-чтения имеют однострочный синтаксис, поскольку им нельзя присвоить значения и они могут быть только прочитаны. Пример использования атрибута только-для-чтения availHeight объекта screen выглядит примерно так:

+ +
Image:Preface2.gif
+ +

Это означает, что вы можете использовать свойство только в правой части операции присваивания; атрибуты, которым можно присвоить значение, приведены в примере:

+ +
Image:Prefacea.gif
+ +

В основном, данные и методы описываемых объектов, будут приводиться в примерах в контексте простых типов, таких как element для всех элементов, document для объектов верхнего уровня, table для объекта TABLE и т.д. (см. Важные типы данных для информации о типах данных).

+ +

Использование примеров

+ +

Большинство примеров в этом справочнике являются самодостаточными файлами, которые можно использовать просто копируя и вставляя их в новый файл, а затем открывая в браузере. Другие же являются фрагментами кода. Их вы сможете запустить только поместив в функции. Например свойство window.document может быть получено в теле функции, которая вызывается нажатием соответствующей кнопки:

+ +
<html>
+
+<script>
+function testWinDoc() {
+
+  doc= window.document;
+
+  alert(doc.title);
+
+}
+</script>
+
+<button onclick="testWinDoc();">test document property</button>
+
+</html>
+
+ +

Похожие функции и страницы можно сделать для методов и свойств объектов, которые еще недоступны к использованию. См. параграф Тестирование DOM API для введения в средства тестирования, которые вы можете использовать для большого количества различных API.

+ +

{{ languages( { "fr": "fr/R\u00e9f\u00e9rence_du_DOM_Gecko/Pr\u00e9face", "ja": "ja/Gecko_DOM_Reference/Preface", "ko": "ko/Gecko_DOM_Reference/Preface", "pl": "pl/Dokumentacja_Gecko_DOM/Przedmowa", "zh-cn": "cn/Gecko_DOM_\u53c2\u8003/Preface" } ) }}

diff --git "a/files/ru/orphaned/\321\201\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\260\321\217_\320\270\320\275\321\204\320\276\321\200\320\274\320\260\321\206\320\270\321\217_\320\277\320\276_gecko_dom/\320\277\321\200\320\270\320\274\320\265\321\200\321\213/index.html" "b/files/ru/orphaned/\321\201\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\260\321\217_\320\270\320\275\321\204\320\276\321\200\320\274\320\260\321\206\320\270\321\217_\320\277\320\276_gecko_dom/\320\277\321\200\320\270\320\274\320\265\321\200\321\213/index.html" new file mode 100644 index 0000000000..6d2319c182 --- /dev/null +++ "b/files/ru/orphaned/\321\201\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\260\321\217_\320\270\320\275\321\204\320\276\321\200\320\274\320\260\321\206\320\270\321\217_\320\277\320\276_gecko_dom/\320\277\321\200\320\270\320\274\320\265\321\200\321\213/index.html" @@ -0,0 +1,5 @@ +--- +title: Примеры +slug: Справочная_информация_по_Gecko_DOM/Примеры +--- +

This page has no content. Enrich MDC by contributing.

diff --git "a/files/ru/orphaned/\321\202\320\265\320\274\321\213/index.html" "b/files/ru/orphaned/\321\202\320\265\320\274\321\213/index.html" new file mode 100644 index 0000000000..32b62868e6 --- /dev/null +++ "b/files/ru/orphaned/\321\202\320\265\320\274\321\213/index.html" @@ -0,0 +1,14 @@ +--- +title: Темы +slug: Темы +--- +

 

+
Введение
+Введение в разработку тем для Firefox.
+
Темы представляют из себя "шкурки" для различных приложений Mozilla. Они позволяют быстро изменить вид пользовательского интерфейса и персонализовать его на ваш вкус. Тема поможет легко изменить цвет пользовательского интерфейса или внешний вид вцелом.
+ +

Documentation

Creating a Skin for Firefox
An introduction to creating new themes for Firefox.
Making Sure Your Theme Works with RTL Locales
How to make sure your theme will look right with Hebrew, Arabic, Persian and Urdu locales.
Theme Packaging
How to package themes for Firefox and Thunderbird.

Theme changes between Firefox 3.0 and 3.1
Theme changes between Firefox 2.0 and 3.0
Theme changes between Firefox 1.5 and 2.0
A comprehensive list of theme changes between the 1.5 and 2.0 releases of Firefox
Theme changes from Firefox 1.0 to 1.5 (forum post)
A forum post at MozillaZine outlining the basic theme-related changes between Firefox 1.0 and 1.5.
First steps in theme design
A somewhat aged article discussing theme design for Firefox.

View All...

Community

  • View Mozilla forums...

{{ DiscussionList("dev-themes", "mozilla.dev.themes") }}

Tools

View All...

CSS
+

Categories

+

Interwiki Language Links

+

 

+

{{ languages( { "de": "de/Themes", "es": "es/Temas", "fr": "fr/Th\u00e8mes", "ja": "ja/Themes", "pl": "pl/Motywy", "zh-cn": "cn/\u4e3b\u9898", "zh-tw": "zh_tw/\u4f48\u666f\u4e3b\u984c" } ) }}

diff --git a/files/ru/plugins/roadmap/index.html b/files/ru/plugins/roadmap/index.html new file mode 100644 index 0000000000..d50a948963 --- /dev/null +++ b/files/ru/plugins/roadmap/index.html @@ -0,0 +1,71 @@ +--- +title: План поддержки плагинов в Firefox +slug: Plugins/План +translation_of: Plugins/Roadmap +--- +

Плагины — проблема безопасности и производительности для пользователей Firefox. NPAPI плагины являются устаревшей технологией, и Mozilla движется к Вебу, в котором они не нужны. Последний оставшийся NPAPI плагин — Adobe Flash, который выпустил план по окончанию срока поддержки. Для поддержки воздержания от использования Flash, Firefox, вместе с другими браузерами, работает над тем, чтобы постепенно и аккуратно избавиться от использования и зависимости от Flash. Ниже представлен план, рассказывающий о том, что будет происходить с поддержкой плагинов в Firefox.

+ +

План

+ +
+
Июнь 2016
+
Начиная с Firefox 47 в Июне 2016, все плагины, отличные от Adobe Flash, теперь активируются только по клику. Пользователи сами выбирают, каким сайта разрешено активировать каждый плагин. К тому же, в 64-битной версии Firefox для Windows поддерживается только Flash плагин.
+
Март 2017
+
Начиная с Firefox 52 в Марте 2017, плагины, отличные от Adobe Flash, больше не поддерживаются в Firefox. Версия Firefox Extended Support Release 52 продолжит поддерживать все плагины, включая Flash, до начала 2018.
+
Август 2017
+
Начиная с Firefox 55 в Августе 2017, пользователи смогут выбрать, каким сайта разрешено активировать Flash плагин. У пользователей появится надстройка, разрешающая запуск Flash, для каждого сайта отдельно. Это изменение будет введится постепенно, начиная с Августа и Сентября 2017.
+
+ В целях повышения безопасности и улучшения производительности, Mozilla будет вести список сайтов, которые не могу использовать никакие плагины.
+
Сентябрь 2017
+
Начиная с Firefox 56 в Сентябре 2017, в Firefox для Android будет удалена поддержка всех плагинов ({{bug(1381916)}}).
+
2019
+
В Сентябре 2019, в Firefox 69 будет удалена надстройка во Flash под названием "Всегда включен", теперь мы будет всегда спрашивать ваше разрешение, прежде чем запустить плагин на сайте.
+
2020
+
В начале 2020, поддержка Flash будет полностью удалена из обычной версии Firefox. Firefox Extended Support Release (ESR) будет поддерживатть Flash до конца 2020.
+
2021
+
Когда Adobe прекратит выпускать обновления безопасности для Flash, в конце 2020, Firefox больше не будет поддерживать этот плагин.
+
+ +

Смотрите также

+ +

Mozilla Firefox

+ + + +

Adobe Flash

+ + + +

Google Chrome

+ + + +

Microsoft Edge и Internet Explorer

+ + + +

Apple Safari

+ + diff --git "a/files/ru/plugins/\320\277\320\273\320\260\320\275/index.html" "b/files/ru/plugins/\320\277\320\273\320\260\320\275/index.html" deleted file mode 100644 index d50a948963..0000000000 --- "a/files/ru/plugins/\320\277\320\273\320\260\320\275/index.html" +++ /dev/null @@ -1,71 +0,0 @@ ---- -title: План поддержки плагинов в Firefox -slug: Plugins/План -translation_of: Plugins/Roadmap ---- -

Плагины — проблема безопасности и производительности для пользователей Firefox. NPAPI плагины являются устаревшей технологией, и Mozilla движется к Вебу, в котором они не нужны. Последний оставшийся NPAPI плагин — Adobe Flash, который выпустил план по окончанию срока поддержки. Для поддержки воздержания от использования Flash, Firefox, вместе с другими браузерами, работает над тем, чтобы постепенно и аккуратно избавиться от использования и зависимости от Flash. Ниже представлен план, рассказывающий о том, что будет происходить с поддержкой плагинов в Firefox.

- -

План

- -
-
Июнь 2016
-
Начиная с Firefox 47 в Июне 2016, все плагины, отличные от Adobe Flash, теперь активируются только по клику. Пользователи сами выбирают, каким сайта разрешено активировать каждый плагин. К тому же, в 64-битной версии Firefox для Windows поддерживается только Flash плагин.
-
Март 2017
-
Начиная с Firefox 52 в Марте 2017, плагины, отличные от Adobe Flash, больше не поддерживаются в Firefox. Версия Firefox Extended Support Release 52 продолжит поддерживать все плагины, включая Flash, до начала 2018.
-
Август 2017
-
Начиная с Firefox 55 в Августе 2017, пользователи смогут выбрать, каким сайта разрешено активировать Flash плагин. У пользователей появится надстройка, разрешающая запуск Flash, для каждого сайта отдельно. Это изменение будет введится постепенно, начиная с Августа и Сентября 2017.
-
- В целях повышения безопасности и улучшения производительности, Mozilla будет вести список сайтов, которые не могу использовать никакие плагины.
-
Сентябрь 2017
-
Начиная с Firefox 56 в Сентябре 2017, в Firefox для Android будет удалена поддержка всех плагинов ({{bug(1381916)}}).
-
2019
-
В Сентябре 2019, в Firefox 69 будет удалена надстройка во Flash под названием "Всегда включен", теперь мы будет всегда спрашивать ваше разрешение, прежде чем запустить плагин на сайте.
-
2020
-
В начале 2020, поддержка Flash будет полностью удалена из обычной версии Firefox. Firefox Extended Support Release (ESR) будет поддерживатть Flash до конца 2020.
-
2021
-
Когда Adobe прекратит выпускать обновления безопасности для Flash, в конце 2020, Firefox больше не будет поддерживать этот плагин.
-
- -

Смотрите также

- -

Mozilla Firefox

- - - -

Adobe Flash

- - - -

Google Chrome

- - - -

Microsoft Edge и Internet Explorer

- - - -

Apple Safari

- - diff --git a/files/ru/toolkit_api/index.html b/files/ru/toolkit_api/index.html deleted file mode 100644 index 48d33c6e3a..0000000000 --- a/files/ru/toolkit_api/index.html +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: Toolkit API (Инструментарий АПИ) -slug: Toolkit_API -tags: - - Toolkit API ---- -

Mozilla Toolkit это набор программных интерфейсов (APIs) собранных на базе Gecko которые обеспечивают продвинутые службы на базе XUL приложенияй. Эти службы включают:

-
  • Менеджер профиля
  • Chrome регистрация
  • История просмотра
  • Расширения и Управление темами
  • Служба обновления приложения
  • Безопасный режим
  • -
-

Официальное руководство

- -

Дополнительная информация

-

Следующие страницы разработчика содержат примеры и обсуждение конкретных тем

-

XUL; XUL Overlays; Developing Extensions; XULRunner; Developing Themes; DOM; RDF; Storage; Creating Help Documentation

-

Categories

-

Interwiki Language Links

-

{{ languages( { "ca": "ca/API_del_Toolkit", "es": "es/API_del_Toolkit", "fr": "fr/API_du_toolkit", "it": "it/Toolkit_API", "ja": "ja/Toolkit_API", "ko": "ko/Toolkit_API", "pl": "pl/Toolkit_API" } ) }}

diff --git a/files/ru/tools/accessibility_inspector/index.html b/files/ru/tools/accessibility_inspector/index.html new file mode 100644 index 0000000000..a375a027ae --- /dev/null +++ b/files/ru/tools/accessibility_inspector/index.html @@ -0,0 +1,166 @@ +--- +title: Инспектор доступности +slug: Tools/Инспектор_доступности +translation_of: Tools/Accessibility_inspector +--- +
{{ToolsSidebar}}
+ +

Инспектор доступности предоставляет средства для доступа к важной информации, предоставляемой вспомогательным технологиям на текущей странице, через дерево доступности, позволяя вам проверить, что отсутствует или иным образом требует внимания. В этой статье вы узнаете основные функции инспектора доступности и способы его использования.

+ +

Очень краткое руководство по доступности

+ +

Доступность - это средство, позволяющее использовать ваши сайты как можно большему числу людей. Это означает, что вы стараетесь изо всех сил не ограничивать кого-либо в доступе к информации из-за какой-либо имеющейся инвалидности, или любых других личных особенностей, таких как используемое устройство, скорости их сетевого подключения или их географического местоположения или языка.

+ +

Здесь мы в основном говорим о том, чтобы донести информацию людям с нарушениями зрения - это делается с помощью API доступности, доступных внутри веб-браузеров, которые раскрывают информацию о том, какие роли играют разные элементы на вашей странице (например, они являются текстом или кнопками, ссылками, элементами форм и т. д.?).

+ +

Семантические элементы DOM имеют роли, назначенные им по умолчанию, которые имеют свое предназначение. Иногда приходится использовать некоторую не семантическую разметку (например, {{htmlelement ("div")}}) для создания сложного настраиваемого элемента управления, а элемент управления не будет иметь роль по умолчанию, которая отражает его назначение. В такой ситуации вы можете использовать атрибуты роли WAI-ARIA для обозначения своих собственных ролей.

+ +

Роли и другая информация, предоставляемая API-интерфейсами браузера, представлена в иерархической структуре, называемой деревом доступности. Это немного похоже на дерево DOM, за исключением того, что оно содержит более ограниченный набор элементов и немного другую информацию о них.

+ +

Вспомогательные технологии, такие как скринридеры, используют эту информацию, чтобы узнать, что находится на веб-странице и сообщают своим пользователям и  это позволяет им взаимодействовать со страницей. Инспектор доступности также использует эту информацию для обеспечения возможностей для отладки доступности в DevTools.

+ +

Доступ к инспектору доступности

+ +

The accessibility inspector (available since Firefox 61) is not shown by default in the DevTools. To turn it on, you need to go to DevTools Settings (press F1, or go to the "three dots" menu and choose Settings) and check the Accessibility checkbox under the Default Developer Tools heading. This will cause the Accessibility tab to appear in the main DevTools display, which can be clicked on to display the accessibility panel:

+ +

Accessibility tab in firefox devtools, turned off, with a button labeled Turn On Accessibility Features

+ +

Initially the DevTools accessibility features are turned off (unless you've already got them turned on in another browser tab, or got the Firefox accessibility engine started already, e.g., you might be a screenreader user or tester). This is because the accessibility engine runs in the background when the accessibility features are turned on. While it’s running, it slows performance and takes up memory; therefore it interferes with the metrics from other panels such as Memory and Performance as well as overall browser performance. For this reason you should keep it turned off when you aren't specifically using it.

+ +

You can turn the features on using the Turn On Accessibility Features button.

+ +

Once the panel content loads, you can then turn it off again using the Turn Off Accessibility Features button available in the top-left corner, unless you have the accessibility engine running previously to operate a screenreader, in which case this button will be disabed.

+ +
+

Note: If are using the accessibility features in multiple tabs, turning them off in one tab turns them off in all tabs.

+
+ +

Особенности панели доступности

+ +

The enabled accessibility panel looks like so:

+ +

Accessibility tab in firefox devtools, turned on, showing two information panels plus a button labeled Turn Off Accessibility Features

+ +

On the left-hand side, there is a tree diagram representing all the items in the accessibility tree for the current page. Items with nested children have arrows that can be clicked to reveal the children, so you can move deeper into the hierarchy. Each item has two properties listed:

+ +
    +
  • Role — the role this item has on the page (e.g., pushbutton, or footer). This can be either a default role provided by the browser, or a role given to it via a WAI-ARIA role attribute.
  • +
  • Name — the name this item has on the page. Where this comes from depends on the element; for example, the name of most text elements is simply their textContent, whereas form elements' names are the contents of their associated {{htmlelement("label")}}.
  • +
+ +

On the right-hand side, you can see further information about the currently selected item. The listed properties are as follows:

+ +
    +
  • name — the item's name, as described above.
  • +
  • role — the item's role, as described above.
  • +
  • actions — a list of the actions that can be performed on the item, for example a pushbutton would have "Press" listed, while a link would have "Jump" listed.
  • +
  • value — the value of the item. This can mean different things depending on the type of item; for example, a form input (role: entry) would have a value of whatever is entered in the input, whereas a link's value would be the URL in the corresponding <a> element's href.
  • +
  • DOMNode — the type of DOM node that the item in the accessibility tree represents. You can click on the "target" icon that comes after it to select the node in the Page Inspector. Hovering over the "target" icon highlights the DOM node in the page content.
    + DOMNode property in accessibility inspector with target icon highlighted
  • +
  • description — any further description provided on the element, usually by the content of a title attribute.
  • +
  • help — this is not implemented in Gecko, so it always returns an empty string. This will be removed from the inspector in Firefox 62 ({{bug(1467643)}}).
  • +
  • keyboardShortcut — any keyboard shortcut that is available to activate the element, as specified in an accessKey attribute. Note that this works correctly as of Firefox 62 ({{bug("1467381")}}).
  • +
  • childCount — the number of child items the current item has in the accessibility tree hierarchy.
  • +
  • indexInParent — an index value indicating what number child the item is, inside its parent. If the item is the first item inside its parent, it has a value of 0. If it is the second, it has a value of 1. And so on.
  • +
  • states — a list of the different accessibility-relevant states that can apply to the current item. For example, one of the links in one demo has states of focusable, linked, selectable text, opaque, enabled, and sensitive. For a full list of internal states, see Gecko states.
  • +
  • attributes — a list of all the accessibility-relevant attributes that are applied to the item. This can include style-related attributes such as margin-left and text-indent, and other useful states for accessibility information, such as draggable and level (e.g., what heading level is it, in the case of headings). For a full list of possible attributes, see Gecko object attributes.
  • +
+ +
+

Note: The exposed information is the same across all platforms — the inspector exposes Gecko's accessibility tree, rather than information from the platform accessibility layer.

+
+ +

Keyboard controls

+ +

The Accessibility tab is fully keyboard-accessible:

+ +
    +
  • You can tab between the Turn Off Accessibility Features button and left and right panels.
  • +
  • When one of the panels is focused, you can move the focus up and down items using the up and down arrow keys, and use the left and right arrow keys to expand and collapse expandable rows (e.g., different hierarchy levels of the accessibility tree).
  • +
+ +

Вывод дерева доступности в JSON-формате

+ +

You can print the contents of the accessibility tree to json by right-clicking on an entry in the Accessibility tab and selecting Print to json:

+ +

+ +

When you do, you will get a new tab with the selected accessibility tree loaded into the JSON viewer:

+ +

+ +

Once opened, you can save or copy the data as necessary. The JSON viewer can also show you the raw json data on a separate tab in the viewer.

+ +

Известные связанные особенности

+ +

When the accessibility features are turned on, there are a number of useful additional features available in the DevTools, which are detailed below:

+ +

Context menu options

+ +

An extra context menu option is added, both for the general context menu on the web page when right/Ctrl + clicking a UI feature, and the HTML pane of the page inspector when right/Ctrl + clicking a DOM element:

+ +

context menu in the browser viewport, with a highlighted option: Inspect Accessibility Properties

+ +

context menu in the DOM inspector, with a highlighted option: Show Accessibility Properties

+ +

When you choose the Inspect Accessibility Properties/Show Accessibility Properties context menu options, the Accessibility tab is immediately opened to show the corresponding accessibility tree item and its properties.

+ +
+

Note: Some DOM elements do not have accessibility properties — in such a case, the Inspect Accessibility Properties/Show Accessibility Properties context menu item is grayed out.

+
+ +

Выделение элементов интерфейса

+ +

In the Accessibility tab, when the mouse hovers over accessibility items, you can see a semi-transparent highlight appear over the UI items they relate to, if appropriate. The role and name of the item will be shown in a small information bar. This is useful for determining how the items in the accessibility tree relate to the UI items on the actual page.

+ +

In the following example, you can see that the image has been highlighted and its role, graphic, and name, "Road, Asphalt, Sky, Clouds, Fall" appears in the information bar above it.

+ +

+ +

Цветовой контраст

+ +

Contrast ratio information is particularly useful when you are designing the color palette for your website because if the contrast is not sufficient, readers with visual impairments such as color blindness will be unable to read the text. The Web Content Accessibility Guidelines (WCAG) 2.0 defines 4.5:1 as the minimum suggested contrast ratio between the foreground and background colors for smaller text on a web page. For example:

+ +

+ +

The color contrast in the image above is 2.77, potentially not enough contrast to make it easy to read. Notice the warning symbol that indicates that the contrast fails to meet the acceptable contrast ratio. Compare that to the following:

+ +

+ +

In this example, the contrast is 12.63. This time the number is followed by AAA and a checkmark in green, indicating that the text has a contrast ratio of 7:1 or more, meaning it meets the criteria for enhanced contrast, or Level AAA.

+ +

Accessibility picker

+ +

In a similar way to the Page Inspector HTML pane picker, when the Accessibility tab's picker button is pressed you can then hover and select UI items in the current page, and the corresponding accessible object is highlighted in the accessibility tree.

+ +

The accessibility tab picker differs in look slightly from the Page Inspector HTML pane picker, as shown below:

+ +

highlighted dom inspector picker button, with a tooltip saying Pick an element from the page

+ +

highlighted accessibility inspector button, with a tooltip saying Pick accessible object from the page

+ +

When you "perform a pick", you see the accessibility object highlighted in the accessibility tree, and the picker is then deactivated. Note, however, that if you hold the Shift key down when "performing a pick", you can "preview" the accessibility object in the tree (and its properties in the right-hand pane), but then continue picking as many times as you like (the picker does not get cancelled) until you release the Shift key.

+ +

When the picker is activated, you can also deactivate it by pressing the picker button a second time, or pressing the Esc key.

+ +

Типичное использование

+ +

The accessibility inspector is very useful for spotting accessibility problems at a glance. For a start, you can investigate items that don't have a proper text equivalent — images without alt text and form elements without proper labels have a name property of null, for example.

+ +

A form input highlighted in the UI, with information about it shown in the accessibility inspector to reveal that it has no label — it has a name property of null

+ +

It is also very handy for verifying semantics — you can use the Inspect Accessibility Properties context menu option to quickly see whether an item has the correct role set on it (e.g., whether a button is really a button, or whether a link is really a link).

+ +

A UI element that looks like a button, with information about it shown in the accessibility inspector to reveal that it isn't a button, it is a section element. It has a name property of null

+ +

Смотри также

+ + + +
 
diff --git a/files/ru/tools/add-ons/dom_inspector/index.html b/files/ru/tools/add-ons/dom_inspector/index.html deleted file mode 100644 index 0e2c41dc29..0000000000 --- a/files/ru/tools/add-ons/dom_inspector/index.html +++ /dev/null @@ -1,57 +0,0 @@ ---- -title: DOM Inspector -slug: Tools/Add-ons/DOM_Inspector -translation_of: Tools/Add-ons/DOM_Inspector ---- -
{{ToolsSidebar}}

Инспектор DOM (также известный как DOMi) — инструмент для разработчиков, используемый для проверки, просмотра и редактирования объектной модели документа - обычных веб-страниц или XUL windows. По иерархии DOM можно перемещаться с помощью двух окон, отображающих целый ряд различных представлений документа и всех вложенных в него узлов.

- -
-

Этот инструмент является дополнением для приложений, основанных на XUL, таких как Firefox и Thunderbird. Если вы ищете инспектор DOM, который встроен в Firefox, обратитесь к разделу документации Инспектор страницы.

-
- -

Документация

- -
-
Введение в инспектор DOM
-
Руководствоваться учебник, который поможет вам начать работу с DOM Inspector.
-
- -
-
FAQ инспектор DOM
-
Ответы на общие вопросы по DOM Inspector.
-
- -
-
страницы на MozillaZine
-
Более подробную информацию о DOM Inspector.
-
как скомпилировать инспектор DOM
-
Сообщение в блоге на здание инспектор DOM от источника.
-
- -

Получение инспектор DOM

- -
-
Firefox и Thunderbird
-
Вы можете скачать и установить Инспектор DOM на веб-сайте AMO. (Thunderbird пользователей, использующих AMO в Firefox следует сохранить ссылку установки, или посетить страницу Инспектор DOM для Thunderbird).
-
- -
-
Thunderbird 2
-
Инспектор DOM для Thunderbird 2 доступен из Дополнений для Thunderbird. Или настройте Thunderbird сами со следующими параметрами:
-
- -
ac_add_options --enable-extensions="default inspector"
-ac_add_options --enable-inspector-apis
- -
-
Mozilla Suite и SeaMonkey
-
Выберите Инструменты > Веб-разработка > Инспектор DOM. Вы также можете установить боковую панель через Правка > Настройки > Дополнительно > Инспектор DOM, затем просто откройте панель инспектора DOM и посетите любой веб-сайт.
-
- -

Отчет об ошибке в DOM Inspector

- -

Использовать удобно именованный раздел компонент «Инспектор DOM» в Bugzilla.

- -

Чтобы узнать о тех, кто знает код DOM Inspector и где он живет, см. листинг модуля DOM Inspector.

- -

{{ languages( { "es": "es/DOM_Inspector", "it": "it/DOM_Inspector", "fr": "fr/Inspecteur_DOM", "ja": "ja/DOM_Inspector", "ko": "ko/DOM_Inspector", "pl": "pl/Inspektor_DOM" } ) }}

diff --git a/files/ru/tools/add-ons/index.html b/files/ru/tools/add-ons/index.html deleted file mode 100644 index ab408aeb18..0000000000 --- a/files/ru/tools/add-ons/index.html +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: Add-ons -slug: Tools/Add-ons -tags: - - NeedsTranslation - - TopicStub -translation_of: Tools/Add-ons ---- -
{{ToolsSidebar}}

Developer tools that are not built into Firefox, but ship as separate add-ons.

- -
-
WebSocket Monitor
-
Examine the data exchanged in a WebSocket connection.
-
 
-
diff --git a/files/ru/tools/browser_console/index.html b/files/ru/tools/browser_console/index.html new file mode 100644 index 0000000000..487bc2eb5e --- /dev/null +++ b/files/ru/tools/browser_console/index.html @@ -0,0 +1,180 @@ +--- +title: Консоль браузера +slug: Tools/Консоль_браузера +tags: + - Tools + - Web Development + - Браузер + - Отладка + - 'веб-разработка:инструменты' + - консоль +translation_of: Tools/Browser_Console +--- +
{{ToolsSidebar}}

Консоль браузера — как Веб-консоль, но для работы со всем браузером, а не с отдельной его вкладкой.

+ +

То есть, она протоколирует такую же информацию, что и Веб-консоль: сетевые запросы, ошибки и предупреждения JavaScript и CSS, ошибки и предупреждения о безопасности, и информационные сообщения, выдаваемые непосредственно кодом JavaScript. Однако она протоколирует эту информацию не только для одной вкладки с контентом, но для всех вкладок с контентом, для дополнений, и для кода самого браузера.

+ +

Если вы хотите использовать и другие инструменты, доступные в обычном наборе инструментов веб-разработки, с кодом дополнений или браузера, вам может пригодиться Панель инструментов браузера.

+ +

В Консоли браузера можно также выполнять и выражения JavaScript. But while the Web Console executes code in the page window scope, the Browser Console executes them in the scope of the browser's chrome window. This means you can interact with all the browser's tabs using the gBrowser global, and even with the XUL used to specify the browser's user interface.

+ +
+

Внимание: начиная с Firefox 30, командная строка Консоли браузера (куда вставляются выражения JavaScript) по умолчанию выключена. Чтобы её включить, присвойте настройке about:config devtools.chrome.enabled значение true, либо поставьте галочку «Включить инструменты отладки browser chrome и дополнений» (начиная с Firefox 40) / «Включить отладку chrome и дополнений» (по Firefox 38.0.5 включительно) в настройках панели инструментов разработчика.

+
+ +

Открытие Консоли браузера

+ +

Консоль браузера можно открыть двумя способами:

+ +
    +
  1. из меню: выбрать «Консоль браузера» из меню Разработка в меню Firefox (или меню Инструменты, если оно включено или на OS X)
  2. +
  3. с клавиатуры: нажать Ctrl+Shift+J (или Cmd+Shift+J на Mac).
  4. +
+ +

Note that until Firefox 38, if the Browser Console has become hidden by a normal Firefox window and you select it again, either from the menu or from the keyboard, then it will be closed. From Firefox 38 onwards, this instead has the effect of switching the focus back to the Browser Console, which is more likely to be what you wanted.

+ +

You can also start the Browser Console by launching Firefox from the command line and passing the -jsconsole argument:

+ +
/Applications/FirefoxAurora.app/Contents/MacOS/firefox-bin -jsconsole
+ +

The Browser Console looks like this:

+ +

+ +

You can see that the Browser Console looks and behaves very much like the Web Console:

+ + + +

Browser Console logging

+ +

The Browser console logs the same sorts of messages as the Web Console:

+ + + +

However, it displays such messages from:

+ +
    +
  • web content hosted by all browser tabs
  • +
  • the browser's own code
  • +
  • add-ons.
  • +
+ +

Messages from add-ons

+ +

The Browser Console displays messages logged by all Firefox add-ons.

+ +

Console.jsm

+ +

To use the console API from a traditional or bootstrapped add-on, get it from the Console module.

+ +

One exported symbol from Console.jsm is "console". Below is an example of how to acess it, which adds a message to the Browser Console.

+ +
Components.utils.import("resource://gre/modules/devtools/Console.jsm");
+console.log("Hello from Firefox code"); //output messages to the console
+ +

Learn more:

+ + + +

HUDService

+ +

There is also the HUDService which allows access to the Browse Console. The module is available at Mozilla Cross-Reference. We see we can not only access the Browser Console but also Web Console.

+ +

Here is an example on how to clear the contents of the Browser console:

+ +
Components.utils.import("resource://gre/modules/devtools/Loader.jsm");
+var HUDService = devtools.require("devtools/webconsole/hudservice");
+
+var hud = HUDService.getBrowserConsole();
+hud.jsterm.clearOutput(true);
+ +

If you would like to access the content document of the Browser Console this can be done with the HUDService. This example here makes it so that when you mouse over the "Clear" button it will clear the Browser Console:

+ +
Components.utils.import("resource://gre/modules/devtools/Loader.jsm");
+var HUDService = devtools.require("devtools/webconsole/hudservice");
+
+var hud = HUDService.getBrowserConsole();
+
+var clearBtn = hud.chromeWindow.document.querySelector('.webconsole-clear-console-button');
+clearBtn.addEventListener('mouseover', function() {
+  hud.jsterm.clearOutput(true);
+}, false);
+ +

Bonus Features Available

+ +

For Add-on SDK add-ons, the console API is available automatically. Here's an example add-on that just logs an error when the user clicks a widget:

+ +
widget = require("sdk/widget").Widget({
+  id: "an-error-happened",
+  label: "Error!",
+  width: 40,
+  content: "Error!",
+  onClick: logError
+});
+
+function logError() {
+  console.error("something went wrong!");
+}
+ +

If you build this as an XPI file, then open the Browser Console, then open the XPI file in Firefox and install it, you'll see a widget labeled "Error!" in the Add-on bar:

+ +

Click the icon. You'll see output like this in the Browser Console:

+ +

+ +

For Add-on SDK-based add-ons only, the message is prefixed with the name of the add-on ("log-error"), making it easy to find all messages from this add-on using the "Filter output" search box. By default, only error messages are logged to the console, although you can change this in the browser's preferences.

+ +

Browser Console command line

+ +
+

From Firefox 30, the Browser Console command line is disabled by default. To enable it set the devtools.chrome.enabled preference to true in about:config, or set the "Enable chrome debugging" option in the developer tool settings.

+
+ +

Like the Web Console, the command line interpreter enables you to evaluate JavaScript expressions in real time:Also like the Web Console's command line interpreter, this command line supports autocomplete, history, and various keyboard shortcuts and helper commands. If the result of a command is an object, you can click on the object to see its details.

+ +

But while the Web Console executes code in the scope of the content window it's attached to, the browser console executes code in the scope of the chrome window of the browser. You can confirm this by evaluating window:

+ +

+ +

This means you can control the browser: opening, closing tabs and windows and changing the content that they host, and modify the browser's UI by creating, changing and removing XUL elements.

+ +

Controlling the browser

+ +

The command line interpreter gets access to the tabbrowser object, through the gBrowser global, and that enables you to control the browser through the command line. Try running this code in the Browser Console's command line (remember that to send multiple lines to the Browser Console, use Shift+Enter):

+ +
var newTabBrowser = gBrowser.getBrowserForTab(gBrowser.selectedTab);
+newTabBrowser.addEventListener("load", function() {
+  newTabBrowser.contentDocument.body.innerHTML = "<h1>this page has been eaten</h1>";
+}, true);
+newTabBrowser.contentDocument.location.href = "https://mozilla.org/";
+ +

It adds a listener to the currently selected tab's load event that will eat the new page, then loads a new page.

+ +

Modifying the browser UI

+ +

Since the global window object is the browser's chrome window, you can also modify the browser's user interface. On Windows, the following code will add a new item to the browser's main menu:

+ +
var parent = window.document.getElementById("appmenuPrimaryPane");
+var makeTheTea = gBrowser.ownerDocument.defaultView.document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "menuitem");
+makeTheTea.setAttribute("label", "A nice cup of tea?");
+parent.appendChild(makeTheTea);
+ +

On OS X, this similar code will add a new item to the "Tools" menu:

+ +
var parent = window.document.getElementById("menu_ToolsPopup");
+var makeTheTea = gBrowser.ownerDocument.defaultView.document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "menuitem");
+makeTheTea.setAttribute("label", "A nice cup of tea?");
+parent.appendChild(makeTheTea);
+ +

diff --git a/files/ru/tools/debugger/how_to/debug_eval_sources/index.html b/files/ru/tools/debugger/how_to/debug_eval_sources/index.html new file mode 100644 index 0000000000..29224f2590 --- /dev/null +++ b/files/ru/tools/debugger/how_to/debug_eval_sources/index.html @@ -0,0 +1,36 @@ +--- +title: Отладка кода внутри eval +slug: Tools/Debugger/How_to/Отладка_кода_внутри_eval +tags: + - Отладка +translation_of: Tools/Debugger/How_to/Debug_eval_sources +--- +
{{ToolsSidebar}}
+

Доступно, начиная с Firefox 36.

+
+ +

В Firefox версии 36 или старше доступна отладка кода, выполняемого с помощью eval() или конструктора Function.

+ +

Чтобы воспользоваться этой возможностью, используйте директиву //# sourceURL 

+ +
var button = document.getElementById("clickme");
+button.addEventListener("click", evalFoo, false);
+
+var script = "function foo() {" +
+             "  console.log('called foo');" +
+             "}" +
+             "foo();//# sourceURL=my-foo.js";
+
+function evalFoo() {
+  eval(script);
+}
+ +

Такой код присвоит исполняемому скрипту имя "my-foo.js".

+ +

Как только скрипт из строки script будет выполнен, он станет доступен в дебаггере как отдельный источник, а также будет доступен к отладке, как код из любого другого источника. Кроме этого, появится возможность, представить код в удобочитаемом виде:

+ +

+ +

Это имя также будет использоваться в стеке вызовов функций, доступном в веб-консоли.

+ +

Начиная с Firefox 40, оператор debugger; также останавливает дебаггер в безымянных источниках выполнения.

diff --git a/files/ru/tools/debugger/how_to/pretty-print_a_minified_file/index.html b/files/ru/tools/debugger/how_to/pretty-print_a_minified_file/index.html new file mode 100644 index 0000000000..e224f9d591 --- /dev/null +++ b/files/ru/tools/debugger/how_to/pretty-print_a_minified_file/index.html @@ -0,0 +1,10 @@ +--- +title: Работа с минифицированным кодом +slug: Tools/Debugger/How_to/Работа_с_минифицированным_кодом +translation_of: Tools/Debugger/How_to/Pretty-print_a_minified_file +--- +
{{ToolsSidebar}}

Чтобы представить минифицированный код в удобочитаемом виде, откройте его, а затем нажмите на иконку с фигурными скобками:

+ +

Файл будет преобразован в более комфортное человеческому глазу представление, благодаря добавлению отсутствующих отступов:

+ +

Вы можете настроить отладчик на автоматическое представление обнаруженных минифицированных исходников в удобочитаемом виде в настройках отладчика.

diff --git "a/files/ru/tools/debugger/how_to/\320\276\321\202\320\273\320\260\320\264\320\272\320\260_\320\272\320\276\320\264\320\260_\320\262\320\275\321\203\321\202\321\200\320\270_eval/index.html" "b/files/ru/tools/debugger/how_to/\320\276\321\202\320\273\320\260\320\264\320\272\320\260_\320\272\320\276\320\264\320\260_\320\262\320\275\321\203\321\202\321\200\320\270_eval/index.html" deleted file mode 100644 index 29224f2590..0000000000 --- "a/files/ru/tools/debugger/how_to/\320\276\321\202\320\273\320\260\320\264\320\272\320\260_\320\272\320\276\320\264\320\260_\320\262\320\275\321\203\321\202\321\200\320\270_eval/index.html" +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: Отладка кода внутри eval -slug: Tools/Debugger/How_to/Отладка_кода_внутри_eval -tags: - - Отладка -translation_of: Tools/Debugger/How_to/Debug_eval_sources ---- -
{{ToolsSidebar}}
-

Доступно, начиная с Firefox 36.

-
- -

В Firefox версии 36 или старше доступна отладка кода, выполняемого с помощью eval() или конструктора Function.

- -

Чтобы воспользоваться этой возможностью, используйте директиву //# sourceURL 

- -
var button = document.getElementById("clickme");
-button.addEventListener("click", evalFoo, false);
-
-var script = "function foo() {" +
-             "  console.log('called foo');" +
-             "}" +
-             "foo();//# sourceURL=my-foo.js";
-
-function evalFoo() {
-  eval(script);
-}
- -

Такой код присвоит исполняемому скрипту имя "my-foo.js".

- -

Как только скрипт из строки script будет выполнен, он станет доступен в дебаггере как отдельный источник, а также будет доступен к отладке, как код из любого другого источника. Кроме этого, появится возможность, представить код в удобочитаемом виде:

- -

- -

Это имя также будет использоваться в стеке вызовов функций, доступном в веб-консоли.

- -

Начиная с Firefox 40, оператор debugger; также останавливает дебаггер в безымянных источниках выполнения.

diff --git "a/files/ru/tools/debugger/how_to/\321\200\320\260\320\261\320\276\321\202\320\260_\321\201_\320\274\320\270\320\275\320\270\321\204\320\270\321\206\320\270\321\200\320\276\320\262\320\260\320\275\320\275\321\213\320\274_\320\272\320\276\320\264\320\276\320\274/index.html" "b/files/ru/tools/debugger/how_to/\321\200\320\260\320\261\320\276\321\202\320\260_\321\201_\320\274\320\270\320\275\320\270\321\204\320\270\321\206\320\270\321\200\320\276\320\262\320\260\320\275\320\275\321\213\320\274_\320\272\320\276\320\264\320\276\320\274/index.html" deleted file mode 100644 index e224f9d591..0000000000 --- "a/files/ru/tools/debugger/how_to/\321\200\320\260\320\261\320\276\321\202\320\260_\321\201_\320\274\320\270\320\275\320\270\321\204\320\270\321\206\320\270\321\200\320\276\320\262\320\260\320\275\320\275\321\213\320\274_\320\272\320\276\320\264\320\276\320\274/index.html" +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: Работа с минифицированным кодом -slug: Tools/Debugger/How_to/Работа_с_минифицированным_кодом -translation_of: Tools/Debugger/How_to/Pretty-print_a_minified_file ---- -
{{ToolsSidebar}}

Чтобы представить минифицированный код в удобочитаемом виде, откройте его, а затем нажмите на иконку с фигурными скобками:

- -

Файл будет преобразован в более комфортное человеческому глазу представление, благодаря добавлению отсутствующих отступов:

- -

Вы можете настроить отладчик на автоматическое представление обнаруженных минифицированных исходников в удобочитаемом виде в настройках отладчика.

diff --git a/files/ru/tools/page_inspector/how_to/edit_fonts/index.html b/files/ru/tools/page_inspector/how_to/edit_fonts/index.html new file mode 100644 index 0000000000..24b490e3d3 --- /dev/null +++ b/files/ru/tools/page_inspector/how_to/edit_fonts/index.html @@ -0,0 +1,24 @@ +--- +title: Просмотр шрифтов +slug: Tools/Page_Inspector/How_to/Просмотр_шрифтов +tags: + - Guide + - Инспектор + - инструменты +translation_of: Tools/Page_Inspector/How_to/Edit_fonts +--- +
{{ToolsSidebar}}

Всплывающая подсказка у font-family

+ +

Если навести указатель на свойство font-family на вкладке «Правила», всплывёт подсказка с примером написанным соответствующим шрифтом:

+ +

+ +

Вкладка «Шрифты»

+ +

Режим просмотра шрифтов показывает все шрифты, используемые выбранным элементом. Заметьте, что он показывает шрифты, используемые на вашей системе, и они могут отличаться от шрифтов, указанных в CSS:

+ +

Скриншот вкладки Шрифты инспектора Nightly 2014-04-26 40.0a1.ru.linux-x86_64.

+ +

Образец шрифта по умолчанию «Abc», но до Firefox 36 он был contenteditable и свободно редактировался.

+ +

 

diff --git a/files/ru/tools/page_inspector/how_to/examine_event_listeners/index.html b/files/ru/tools/page_inspector/how_to/examine_event_listeners/index.html new file mode 100644 index 0000000000..c5ea101f0b --- /dev/null +++ b/files/ru/tools/page_inspector/how_to/examine_event_listeners/index.html @@ -0,0 +1,28 @@ +--- +title: Исследовать Event Listeners +slug: Tools/Page_Inspector/How_to/Исследовать_event_listeners +tags: + - Инспектор + - Руководство + - инструменты +translation_of: Tools/Page_Inspector/How_to/Examine_event_listeners +--- +
{{ToolsSidebar}}

Начиная с Firefox 33 вы увидите значок «ev» в области HTML, напротив элементов, у которых есть связаные с ними Event Listeners:

+ +

+ +

Нажмите на иконку, затем вы увидите всплывающее окно со списком всех Event Listeners, связанных с этим элементом:Каждая строка содержит:

+ +
    +
  • кнопка паузы: щелкните на нее, чтобы перейти к "event Listener" в Отладчик, где вы сможете установить контрольную точку в нем
  • +
  • название события
  • +
  • название и номер строки обработчика: нажмите, чтобы увидеть функцию обработчика во всплывающем окне
  • +
  • метка, указывающая, является ли событие высплывающим
  • +
  • метка, указывающая систему, которая определяет событие. Firefox может отображать: + +
  • +
diff --git a/files/ru/tools/page_inspector/how_to/open_the_inspector/index.html b/files/ru/tools/page_inspector/how_to/open_the_inspector/index.html new file mode 100644 index 0000000000..a4e0927d76 --- /dev/null +++ b/files/ru/tools/page_inspector/how_to/open_the_inspector/index.html @@ -0,0 +1,19 @@ +--- +title: Открытие Инспектора +slug: Tools/Page_Inspector/How_to/Otkrytie_Inspektora +tags: + - Guide + - Инспектор + - инструменты +translation_of: Tools/Page_Inspector/How_to/Open_the_Inspector +--- +
{{ToolsSidebar}}

Есть два основных способа открытия Инспектора:

+ +
    +
  • без выбора элемента: выберите пункт «Инспектор» в меню «Разработка» или «Веб-разработка», или нажмите соответствующее клавиатурное сокращение.
  • +
  • с выбранным элементом: щёлкните правой кнопкой мыши элемент на веб-странице и выберите «Исследовать элемент».
  • +
+ +

Инспектор появится в нижней части окна браузера:

+ +

Чтобы начать первые шаги по Инспектору, см. UI tour.

diff --git a/files/ru/tools/page_inspector/how_to/otkrytie_inspektora/index.html b/files/ru/tools/page_inspector/how_to/otkrytie_inspektora/index.html deleted file mode 100644 index a4e0927d76..0000000000 --- a/files/ru/tools/page_inspector/how_to/otkrytie_inspektora/index.html +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Открытие Инспектора -slug: Tools/Page_Inspector/How_to/Otkrytie_Inspektora -tags: - - Guide - - Инспектор - - инструменты -translation_of: Tools/Page_Inspector/How_to/Open_the_Inspector ---- -
{{ToolsSidebar}}

Есть два основных способа открытия Инспектора:

- -
    -
  • без выбора элемента: выберите пункт «Инспектор» в меню «Разработка» или «Веб-разработка», или нажмите соответствующее клавиатурное сокращение.
  • -
  • с выбранным элементом: щёлкните правой кнопкой мыши элемент на веб-странице и выберите «Исследовать элемент».
  • -
- -

Инспектор появится в нижней части окна браузера:

- -

Чтобы начать первые шаги по Инспектору, см. UI tour.

diff --git a/files/ru/tools/page_inspector/how_to/select_an_element/index.html b/files/ru/tools/page_inspector/how_to/select_an_element/index.html new file mode 100644 index 0000000000..16db872b70 --- /dev/null +++ b/files/ru/tools/page_inspector/how_to/select_an_element/index.html @@ -0,0 +1,29 @@ +--- +title: Выбор элемента +slug: Tools/Page_Inspector/How_to/Vybor_elementa +tags: + - Guide + - Инспектор + - инструменты +translation_of: Tools/Page_Inspector/How_to/Select_an_element +--- +
{{ToolsSidebar}}

{{EmbedYouTube("y2LcsxE2pR0")}}

+ +

Если Вы открыли Инспектор нажатием на «Исследовать элемент», элемент уже будет выбран.

+ +

В противном случае, когда вы будете перемещать мышь по странице, элемент под курсором мыши будет подсвечиваться, а подсказка будет содержать его HTML-тег, атрибуты class и/или ID, а также размер.  Одновременно в левой панели Инспектора появится HTML-код элемента в его контексте:

+ +

С версии Firefox 39 можно использовать клавиши со стрелками для перехода между выбранными элементами:

+ +
    +
  • Налево: подсветить элемент родительский текущему.
  • +
  • Направо: подсветить элемент дочерний текущему, или (если у текущего нет дочерних) следующий элемент одного родителя с текущим, или (если и сиблингов/сестринских нет) следующий узел в дереве.
  • +
+ +

Это особенно полезно когда элемент и его родитель отображаются на одном и том же пространстве экрана, так что трудно выбрать один из них мышью.

+ +

Нажатие на подсвеченный элемент выбирает его.  Когда элемент выбран, в HTML pane [en] в левой части Инспектора подсвечивается его разметка, а в CSS pane [en] в правой части Инспектора выводится информация о его стилях:

+ +

+ +

Есть два способа выбрать другой элемент: или щёлкните его разметку в HTML pane, или нажмите "Select element" button [en], а потом щёлкните по элементу на веб-странице.

diff --git a/files/ru/tools/page_inspector/how_to/vybor_elementa/index.html b/files/ru/tools/page_inspector/how_to/vybor_elementa/index.html deleted file mode 100644 index 16db872b70..0000000000 --- a/files/ru/tools/page_inspector/how_to/vybor_elementa/index.html +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: Выбор элемента -slug: Tools/Page_Inspector/How_to/Vybor_elementa -tags: - - Guide - - Инспектор - - инструменты -translation_of: Tools/Page_Inspector/How_to/Select_an_element ---- -
{{ToolsSidebar}}

{{EmbedYouTube("y2LcsxE2pR0")}}

- -

Если Вы открыли Инспектор нажатием на «Исследовать элемент», элемент уже будет выбран.

- -

В противном случае, когда вы будете перемещать мышь по странице, элемент под курсором мыши будет подсвечиваться, а подсказка будет содержать его HTML-тег, атрибуты class и/или ID, а также размер.  Одновременно в левой панели Инспектора появится HTML-код элемента в его контексте:

- -

С версии Firefox 39 можно использовать клавиши со стрелками для перехода между выбранными элементами:

- -
    -
  • Налево: подсветить элемент родительский текущему.
  • -
  • Направо: подсветить элемент дочерний текущему, или (если у текущего нет дочерних) следующий элемент одного родителя с текущим, или (если и сиблингов/сестринских нет) следующий узел в дереве.
  • -
- -

Это особенно полезно когда элемент и его родитель отображаются на одном и том же пространстве экрана, так что трудно выбрать один из них мышью.

- -

Нажатие на подсвеченный элемент выбирает его.  Когда элемент выбран, в HTML pane [en] в левой части Инспектора подсвечивается его разметка, а в CSS pane [en] в правой части Инспектора выводится информация о его стилях:

- -

- -

Есть два способа выбрать другой элемент: или щёлкните его разметку в HTML pane, или нажмите "Select element" button [en], а потом щёлкните по элементу на веб-странице.

diff --git "a/files/ru/tools/page_inspector/how_to/\320\270\321\201\321\201\320\273\320\265\320\264\320\276\320\262\320\260\321\202\321\214_event_listeners/index.html" "b/files/ru/tools/page_inspector/how_to/\320\270\321\201\321\201\320\273\320\265\320\264\320\276\320\262\320\260\321\202\321\214_event_listeners/index.html" deleted file mode 100644 index c5ea101f0b..0000000000 --- "a/files/ru/tools/page_inspector/how_to/\320\270\321\201\321\201\320\273\320\265\320\264\320\276\320\262\320\260\321\202\321\214_event_listeners/index.html" +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: Исследовать Event Listeners -slug: Tools/Page_Inspector/How_to/Исследовать_event_listeners -tags: - - Инспектор - - Руководство - - инструменты -translation_of: Tools/Page_Inspector/How_to/Examine_event_listeners ---- -
{{ToolsSidebar}}

Начиная с Firefox 33 вы увидите значок «ev» в области HTML, напротив элементов, у которых есть связаные с ними Event Listeners:

- -

- -

Нажмите на иконку, затем вы увидите всплывающее окно со списком всех Event Listeners, связанных с этим элементом:Каждая строка содержит:

- -
    -
  • кнопка паузы: щелкните на нее, чтобы перейти к "event Listener" в Отладчик, где вы сможете установить контрольную точку в нем
  • -
  • название события
  • -
  • название и номер строки обработчика: нажмите, чтобы увидеть функцию обработчика во всплывающем окне
  • -
  • метка, указывающая, является ли событие высплывающим
  • -
  • метка, указывающая систему, которая определяет событие. Firefox может отображать: - -
  • -
diff --git "a/files/ru/tools/page_inspector/how_to/\320\277\321\200\320\276\321\201\320\274\320\276\321\202\321\200_\321\210\321\200\320\270\321\204\321\202\320\276\320\262/index.html" "b/files/ru/tools/page_inspector/how_to/\320\277\321\200\320\276\321\201\320\274\320\276\321\202\321\200_\321\210\321\200\320\270\321\204\321\202\320\276\320\262/index.html" deleted file mode 100644 index 24b490e3d3..0000000000 --- "a/files/ru/tools/page_inspector/how_to/\320\277\321\200\320\276\321\201\320\274\320\276\321\202\321\200_\321\210\321\200\320\270\321\204\321\202\320\276\320\262/index.html" +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: Просмотр шрифтов -slug: Tools/Page_Inspector/How_to/Просмотр_шрифтов -tags: - - Guide - - Инспектор - - инструменты -translation_of: Tools/Page_Inspector/How_to/Edit_fonts ---- -
{{ToolsSidebar}}

Всплывающая подсказка у font-family

- -

Если навести указатель на свойство font-family на вкладке «Правила», всплывёт подсказка с примером написанным соответствующим шрифтом:

- -

- -

Вкладка «Шрифты»

- -

Режим просмотра шрифтов показывает все шрифты, используемые выбранным элементом. Заметьте, что он показывает шрифты, используемые на вашей системе, и они могут отличаться от шрифтов, указанных в CSS:

- -

Скриншот вкладки Шрифты инспектора Nightly 2014-04-26 40.0a1.ru.linux-x86_64.

- -

Образец шрифта по умолчанию «Abc», но до Firefox 36 он был contenteditable и свободно редактировался.

- -

 

diff --git a/files/ru/tools/page_inspector/keyboard_shortcuts/index.html b/files/ru/tools/page_inspector/keyboard_shortcuts/index.html new file mode 100644 index 0000000000..ae162ef628 --- /dev/null +++ b/files/ru/tools/page_inspector/keyboard_shortcuts/index.html @@ -0,0 +1,13 @@ +--- +title: Клавиатурные сокращения +slug: Tools/Page_Inspector/Сочетания_клавиш +tags: + - Инспектор + - инструменты +translation_of: Tools/Page_Inspector/Keyboard_shortcuts +--- +
{{ToolsSidebar}}

{{ Page ("ru/docs/tools/Keyboard_shortcuts", "page-inspector") }}

+ +

Глобальные сокращения

+ +

{{ Page ("ru/docs/tools/Keyboard_shortcuts", "all-toolbox-tools") }}

diff --git "a/files/ru/tools/page_inspector/\321\201\320\276\321\207\320\265\321\202\320\260\320\275\320\270\321\217_\320\272\320\273\320\260\320\262\320\270\321\210/index.html" "b/files/ru/tools/page_inspector/\321\201\320\276\321\207\320\265\321\202\320\260\320\275\320\270\321\217_\320\272\320\273\320\260\320\262\320\270\321\210/index.html" deleted file mode 100644 index ae162ef628..0000000000 --- "a/files/ru/tools/page_inspector/\321\201\320\276\321\207\320\265\321\202\320\260\320\275\320\270\321\217_\320\272\320\273\320\260\320\262\320\270\321\210/index.html" +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: Клавиатурные сокращения -slug: Tools/Page_Inspector/Сочетания_клавиш -tags: - - Инспектор - - инструменты -translation_of: Tools/Page_Inspector/Keyboard_shortcuts ---- -
{{ToolsSidebar}}

{{ Page ("ru/docs/tools/Keyboard_shortcuts", "page-inspector") }}

- -

Глобальные сокращения

- -

{{ Page ("ru/docs/tools/Keyboard_shortcuts", "all-toolbox-tools") }}

diff --git a/files/ru/tools/performance/index.html b/files/ru/tools/performance/index.html new file mode 100644 index 0000000000..ba11369101 --- /dev/null +++ b/files/ru/tools/performance/index.html @@ -0,0 +1,95 @@ +--- +title: Производительность +slug: Tools/Производительность +translation_of: Tools/Performance +--- +
{{ToolsSidebar}}

Инструмент даёт Вам понять общую отзывчивость вашего сайта,  JavaScript и общее представление о разметке. С помощью инструмента производительности Вы создадите запись или профиль своего сайта за определенный промежуток времени. Затем, инструмент покажет Вам действия браузера и график смены частоты кадров, поверх профиля, рендера Вашего сайта.

+ +

Вы получите четыре набора инструментов для более подробного изучения аспектов профиля:

+ +
    +
  •  Waterfall (Водопад) показывает различные операции браузера, например, выполняет макет, JavaScript, перерисовывает и собирает мусор
  • +
  • Call Tree (Дерево вызова) показывает функции JavaScript, в которых браузер провел большую часть своего времени
  • +
  • Flame Chart (Пламенный График) показывает стек вызовов JavaScript над конечной записью.
  • +
  • Allocations. В этом представлении отображаются распределения кучи, сделанные вашим кодом в ходе записи. Это представление появляется только в том случае, если вы отметили «Записать выделение» в настройках инструмента «Производительность».
  • +
+ +

{{EmbedYouTube("WBmttwfA_k8")}}

+ +
+

Приступая к работе

+ +
+
+
+
UI Tour (Пользовательский интерфейс)
+
+

Чтобы найти свой вариант производительности инструмента, вот краткий обзор пользовательского интерфейса UI.

+
+
+
+ +
+
+
How to (Как)
+
Основные задачи: откройте инструмент создать, сохранить, загрузить и настроить записи.
+
+
+
+ +
+

Компоненты инструмента производительности

+ +
+
+
+
Frame rate (Частота кадров)
+
Исследование Вашего сайта на отзывчивость.
+
Call Tree (Дерево вызовов)
+
Поиск узких мест Вашего сайта на JavaScript.
+
+
+ +
+
+
Waterfall (Водопад)
+
Исследует работу браузера на взаимодействие пользователей с Вашим сайтом.
+
Flame Chart (Диаграмма)
+
Обзор выполнения функций JavaScript во времени.
+
Allocations (Распределение)
+
Просмотр распределений сделанных вашим кодом во время записи.
+
 
+
 
+
+
+
+ +
+

Сценарии

+ +
+
+
+
Animating CSS properties (Свойства анимации CSS)
+
Использует водопад чтобы понять как браузер обновляет страницу, и как меняя разные свойства CSS можно улучшить производительность.
+
 
+
+
+ +
+
+
Intensive JavaScript (Интенсивный JS)
+
Использует частоту кадров и инструменты водопада для выделения проблем с производительностью, вызванные длительной загрузкой JavaScript и каким образом с помощью инструментов разработчика  возможно исправить ситуацию.
+
+
+
+ +

 

+ +
+
+
 
+
+
+ +

 

diff --git a/files/ru/tools/performance/waterfall/index.html b/files/ru/tools/performance/waterfall/index.html new file mode 100644 index 0000000000..1531a44a10 --- /dev/null +++ b/files/ru/tools/performance/waterfall/index.html @@ -0,0 +1,386 @@ +--- +title: Waterfall +slug: Tools/Производительность/Waterfall +translation_of: Tools/Performance/Waterfall +--- +
{{ToolsSidebar}}
+

Водопад (Waterfall) дает вам представление о различных процессах, которые происходят внутри браузера, когда вы открывайте ваш сайт или запускаете ваше приложение. Он основан на идее разделения всех происходящих внутри браузера процессов на различные типы  - запуск JavaScript, обновление layout и так далее - и что в любой момент времени браузрер выполняет один из этих процессов.

+ +

Поэтому если вы увидите признаки проблем с производительностью  - например, падения частоты кадров - вы можете запустить Waterfall, чтобы увидеть, что делает браузер в этот момент.

+
+ +

+ +

Ось X это ось времени. Записанные операции и вызванные маркеры отображаются в виде горизонтальных прямоуголников, расположенных в виде водопада, чтобы подчеркнуть последовательность выполнения внутри браузера.

+ +

При выборе маркера вы увидите подробную информацию о нем на панели справа. В этой панели вы сможете узнать продолжительность и другую специфичную для конктреного типа процесса инофрмацию .

+ +

Markers

+ +

The markers for operations are color-coded and labeled. The following operations are recorded:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Name and descriptionColorDetailed information
+

DOM Event

+ +

JavaScript code that's executed in response to a DOM event.

+
+
+
Event Type
+
For example, "click" or "message".
+
+ +
+
Event Phase
+
For example, "Target" or "Capture".
+
+
+

JavaScript functions executed in the page are labeled with the reason the function was called:

+ +

Script Tag
+ setInterval
+ setTimeout
+ requestAnimationFrame
+ Promise Callback
+ Promise Init
+ Worker
+ JavaScript URI
+ Event Handler

+
+
+
Stack
+
Call stack, with links to functions.
+
+
+

Parse HTML

+ +

Time spent parsing the page's HTML.

+
+
+
Stack
+
Call stack, with links to functions.
+
+
+

Parse XML

+ +

Time spent parsing the page's XML.

+
+
+
Stack
+
Call stack, with links to functions.
+
+
+

Recalculate Style

+ +

Calculating the computed styles that apply to page elements.

+
+
+
Restyle Hint
+
A string indicating what kind of restyling is needed. The hint may be any of:
+ Self
+ Subtree
+ LaterSiblings
+ CSSTransitions
+ CSSAnimations
+ SVGAttrAnimations
+ StyleAttribute
+ StyleAttribute_Animations
+ Force
+ ForceDescendants
+
+
+

Layout

+ +

Calculating the position and size of page elements. This operation is sometimes called "reflow".

+
 
+

Paint

+ +

Drawing pixels to the screen.

+
 
+

GC Event

+ +

Garbage collection event. Non-incremental GC events are labeled "(Non-incremental)".

+
+
+
Reason
+
A string the indicating the reason GC was performed.
+
Non-incremental Reason
+
If the GC event was non-incremental, a string the indicating the reason non-incremental GC was performed.
+
+
+

Console

+ +

The period between matching calls to console.time() and console.timeEnd().

+
+
+
Timer name
+
The argument passed to the console functions.
+
Stack at start
+
Call stack console.time(), with links to functions.
+
Stack at End
+
(New in Firefox 41). Call stack at console.timeEnd(). If this is inside a callback from a Promise, this will also show the "Async stack".
+
+
+

Timestamp

+ +

A single call to console.timeStamp().

+
+
+
Label
+
The argument passed to timeStamp().
+
+
+ +

The markers, and their colors, are the same in the Waterfall tool as in the Waterfall overview, making is easy to correlate from one to the other.

+ +

Filtering markers

+ +

You can control which markers are displayed using a button in the Toolbar:

+ +

+ +

Waterfall patterns

+ +

Exactly what you'll see in the Waterfall is very dependent on the kind of thing your site is doing: JavaScript-heavy sites will have a lot of orange, while visually dynamic sites will have a lot of purple and green. But there are common patterns which can alert you to possible performance problems.

+ +

Rendering waterfall

+ +

One pattern that you'll often see in the Waterfall view is something like this:

+ +

+ +

This is a visualization of the basic algorithm the browser uses to update the page in response to some event:

+ +
    +
  1. JavaScript Function Call: some event - for example, a DOM event - causes some JavaScript in the page to run. The JavaScript changes some of the page's DOM or CSSOM.
  2. +
  3. Recalculate Style: if the browser thinks the computed styles for page elements have changed, it must then recalculate them.
  4. +
  5. Layout: next, the browser uses the computed styles to figure out the position and geometry for the elements. This operation is labeled "layout" but is also sometimes called "reflow".
  6. +
  7. Paint: finally, the browser needs to repaint the elements to the screen. One last step is not shown in this sequence: the page may be split into layers, which are painted independently and then combined in a process called "Composition".
  8. +
+ +

This sequence needs to fit into a single frame, since the screen isn't updated until it is complete. It's commonly accepted that 60 frames per second is the rate at which animations will appear smooth. For a rate of 60 frames per second, that gives the browser 16.7 milliseconds to execute the complete flow.

+ +

Importantly for responsiveness, the browser doesn't always have to go through every step:

+ +
    +
  • CSS animations update the page without having to run any JavaScript.
  • +
  • Not all CSS property changes cause a reflow. Changing properties that can alter an object's geometry and position, such as width, display, font-size, or top, will cause a reflow. However, changing properties that don't alter geometry or position, such as color or opacity, will not.
  • +
  • Not all CSS property changes cause a repaint. In particular, if you animate an element using the transform property, the browser will use a separate layer for the transformed element, and doesn't even have to repaint when the element is moved: the new position of the element is handled in composition.
  • +
+ +

The Animating CSS properties article shows how animating different CSS properties can give different performance outcomes, and how the Waterfall can help signal that.

+ +

Blocking JavaScript

+ +

By default, a site's JavaScript is executed in the same thread that the browser uses for layout updates, repaints, DOM events, and so on. This means that long-running JavaScript functions can cause unresponsiveness (jank): animations may not be smooth, or the site might even freeze.

+ +

Using the frame rate tool and the Waterfall together, it's easy to see when long-running JavaScript is causing responsiveness problems. In the screenshot below, we've zoomed in on a JS function that's caused a drop in the frame rate:

+ +

+ +

The Intensive JavaScript article shows how the Waterfall can highlight responsiveness problems caused by long JavaScript functions, and how you can use asynchronous methods to keep the main thread responsive.

+ +

Expensive paints

+ +

Some paint effects, such as box-shadow, can be expensive, especially if you are applying them in a transition where the browser has to calculate them in every frame. If you're seeing drops in the frame rate, especially during graphically-intensive operations and transitions, check the Waterfall for long green markers.

+ +

Garbage collection

+ +

Red markers in the Waterfall represent garbage collection (GC) events, in which SpiderMonkey (the JavaScript engine in Firefox) walks the heap looking for memory that's no longer reachable and subsequently releasing it. GC is relevant to performance because while it's running the JavaScript engine must be paused, so your program is suspended and will be completely unresponsive.

+ +

To help reduce the length of pauses, SpiderMonkey implements incremental GC: this means that it can perform garbage collection in fairly small increments, letting the program run in between. Sometimes, though, it needs to perform a full non-incremental collection, and the program has to wait for it to finish.

+ +

When the Waterfall records a GC marker it indicates:

+ +
    +
  • whether the GC was incremental or not
  • +
  • the reason the GC was performed
  • +
  • if the GC was non-incremental, the reason it was non-incremental
  • +
+ +

In trying to avoid GC events, and especially non-incremental GC events, it's wise not to try to optimize for the specific implementation of the JavaScript engine. SpiderMonkey uses a complex set of heuristics to determine when GC is needed, and when non-incremental GC in particular is needed. In general, though:

+ +
    +
  • GC is needed when a lot of memory is being allocated
  • +
  • non-incremental GC is usually needed when the memory allocation rate is high enough that SpiderMonkey may run out of memory during incremental GC
  • +
+ +

Adding markers with the console API

+ +

Two markers are directly controlled by console API calls: "Console" and "Timestamp".

+ +

Console markers

+ +

These enable you to mark a specific section of the recording.

+ +

To make a console marker, call console.time() at the start of the section, and console.timeEnd() at the end. These functions take an argument which is used to name the section.

+ +

For example, suppose we have code like this:

+ +
var iterations = 70;
+var multiplier = 1000000000;
+
+function calculatePrimes() {
+
+  console.time("calculating...");
+
+  var primes = [];
+  for (var i = 0; i < iterations; i++) {
+    var candidate = i * (multiplier * Math.random());
+    var isPrime = true;
+    for (var c = 2; c <= Math.sqrt(candidate); ++c) {
+      if (candidate % c === 0) {
+          // not prime
+          isPrime = false;
+          break;
+       }
+    }
+    if (isPrime) {
+      primes.push(candidate);
+    }
+  }
+
+  console.timeEnd("calculating...");
+
+  return primes;
+}
+ +

The Waterfall's output will look something like this:

+ +

+ +

The marker is labeled with the argument you passed to console.time(), and when you select the marker, you can see the program stack in the right-hand sidebar.

+ +

Async stack

+ +

New in Firefox 41.

+ +

Starting in Firefox 41, the right-hand sidebar will also show the stack at the end of the period: that is, at the point console.timeEnd() was called. If console.timeEnd() was called from the resolution of a Promise, it will also display "(Async: Promise)", under which it will show the "async stack": that is, the call stack at the point the promise was made.

+ +

For example, consider code like this:

+ +
var timerButton = document.getElementById("timer");
+timerButton.addEventListener("click", handleClick, false);
+
+function handleClick() {
+  console.time("timer");
+  runTimer(1000).then(timerFinished);
+}
+
+function timerFinished() {
+  console.timeEnd("timer");
+  console.log("ready!");
+}
+
+function runTimer(t) {
+  return new Promise(function(resolve) {
+    setTimeout(resolve, t);
+  });
+}
+ +

The Waterfall will display a marker for the period between time() and timeEnd(), and if you select it, you'll see the async stack in the sidebar:

+ +

+ +

Timestamp markers

+ +

Timestamps enable you to mark an instant in the recording.

+ +

To make a timestamp marker, call console.timeStamp(). You can pass an argument to label the timestamp.

+ +

For example, suppose we adapt the code above to make a timestamp every 10 iterations of the loop, labeled with the iteration number:

+ +
var iterations = 70;
+var multiplier = 1000000000;
+
+function calculatePrimes() {
+  console.time("calculating...");
+
+  var primes = [];
+  for (var i = 0; i < iterations; i++) {
+
+    if (i % 10 == 0) {
+      console.timeStamp(i.toString());
+    }
+
+    var candidate = i * (multiplier * Math.random());
+    var isPrime = true;
+    for (var c = 2; c <= Math.sqrt(candidate); ++c) {
+      if (candidate % c === 0) {
+          // not prime
+          isPrime = false;
+          break;
+       }
+    }
+    if (isPrime) {
+      primes.push(candidate);
+    }
+  }
+  console.timeEnd("calculating...");
+  return primes;
+}
+ +

In the Waterfall you'll now see something like this:

+ +

+ +

 

diff --git a/files/ru/tools/profiler/index.html b/files/ru/tools/profiler/index.html deleted file mode 100644 index 10e4254907..0000000000 --- a/files/ru/tools/profiler/index.html +++ /dev/null @@ -1,169 +0,0 @@ ---- -title: Профилирование JavaScript -slug: Tools/Profiler -tags: - - Firefox - - Отладка - - Профайлер - - Профилирование - - Руководство - - инструменты -translation_of: Tools/Performance -translation_of_original: Tools/Profiler ---- -
{{ToolsSidebar}}

Используйте средства профилирования, чтобы находить узкие места в своём JavaScript коде.  Профайлер периодически проверяет состояние стека вызовов JavaScript и составляет статистику на основе полученных в результате измерения величин.

- -

Вы можете запустить профайлер выбрав «Profiler»  из меню «Web Develeper». Для операционных систем Linux и OS X данное меню находится в меню «Tools», в Windows его можно вызвать из меню «Firefox».

- -

В открывшемся меню уже будет выбран профайлер.

- -

 

- -

Семплирующие профайлеры

- -

 

- -

Профайлер JavaScript — сэмплирующий профайлер. Это означает, что он периодически собирает информацию о состоянии интерпретатора JavaScript, сохраняет стек выполняющегося на момент сэмплирования кода. Статистически, число образцов полученных во время выполнения какой-либо функции, соответствует количеству времени, которое браузер проводит выполняя её, таким образом вы можете находить узкие места в своём коде.

- -

Рассмотрим следующую программу в качестве примера:

- -
function doSomething() {
-  var x = getTheValue();
-  x = x + 1;                   // -> sample A
-  logTheValue(x);
-}
-
-function getTheValue() {
-  return 5;
-}
-
-function logTheValue(x) {
- console.log(x);               // -> sample B, sample C
-}
-
-doSomething();
- -

Допустим мы запустили данную программу с активным профайлером, и во время её выполнения, профайлер взял три сэмпла, в местах указанных комментариями.

- -

Они все взяты внутри doSomething(), но вторые два внутри функции logTheValue() вызванной doSomething(). В результате получим профиль состоящий из трёх записей:

- -
Sample A: doSomething()
-Sample B: doSomething() > logTheValue()
-Sample C: doSomething() > logTheValue()
- -

Конечно этих данных недостаточно, чтобы сделать какие-то выводы, но с гораздо большим количеством сэмплов, мы поймём, что узким местом в нашей программе является logTheValue().

- -

 

- -

Создание профиля

- -

Нажмите кнопку stopwatch в профайлере, чтобы начать сбор сэмплов. Кнопка stopwatch подсвечена, если профайлер активен. Кликните на ней ещё раз и сохраните новый профиль:

- -

 

- -

- -

Новый профиль будет открыт автоматически при нажатии "Stop".

- -

- -

Панель разделена на две части:

- -
    -
  • Левая сторона содержит список всех записанных профилей и позволяет загрузить любой из них. Ниже находятся две кнопки: stopwatch позволяет записать новый профиль, в то время как import... позволяет импортировать ранее сохраненные данные. Когда профиль выбран, вы можете сохранить его данные как файл в формате JSON нажав на кнопке Save.
  • -
  • Правая сторона показывает текущий загруженный профиль.
  • -
- -

 

- -

Анализируем профиль

- -

 

- -

Профиль разделён на две части:

- - - -

График профилирования

- -

График профилирования располагается в верхней части экрана профиля.

- -

- -

Горизонтальная ось это время, а вертикальная — размер стека вызовов на текущий сэмпл. Стек вызовов представляет количество активных функций  на момент сэмплирования.
- Красные сэмплы на графике говорят о том, что браузер был недоступен на тот момент и пользователь мог наблюдать паузы в анимации и отклике браузера. Если профиль содержит красные образцы,  их следует разбить на несколько событий и рассмотреть  используя requestAnimationFrame и Workers.

- -

Подсветив определённый участок в профиле рамкой, можно исследовать его более детально:

- -

- -

В таком случае, над графиком появится новая кнопка с надписью вида: "Sample Range [AAA, BBB]". Нажав на неё, можно приблизить рассматриваемый участок и детально его рассмотреть.

- -

- -

Детали профилирования

- -

Детали профилирования расположены в нижней части экрана профиля:

- -

- -

Когда вы впервые открываете новый сэмпл, панель сэмплов содержит единственную строку «(total)»,  как на скриншоте ниже. Если кликнуть на стрелке следующей за надписью «(total)», вы увидилте список всех функций верхнего уровня которые находятся в сэмпле.

- -


-

- -

Время выполнения (Running time) показывает число сэмплов в которых присутствует данная функция1 , далее следует процент появления функции в остальных сэмплах профиля.  Первая сверху строка показывает, что в профиле 2021 сэмпл, вторая строка показывает, что 1914 или 94.7% из них содержат в себе функцию detectImage().

- -

Self показывает количество сэмплов полученное во время выполнения самой функции, а не функции её вызвавшей. В примере выше  doSomething() имеет время выполнения (Running time) равное 3 (сэмпл A, B и C), но значение Self равно единице (sample A).

- -

Третий столбец содержит имена функций, а также имена файлов и номера строк (для локальных функций) или полное/доменное имя (для внешних). Функции серого цвета — встроенные функции браузера, чёрные — JavaScript загруженный страницей. Если вы переместите курсор мыши вдоль строк, то обнаружите справа от имён функций стрелочку: кликните по ней и увидите исходный код функции.

- -

 

- -

Раскрываем древо вызовов

- -

 

- -

В строке, если какие-либо сэмплы были взяты в функции вызванной другой функцией (т. е. Если время выполнения (Running time) больше чем Self для заданной строки) — появляется стрелочка слева от имени функции, дающая возможность раскрыть древо вызовов.

- -

Для примера приведённого выше, полностью раскрытое древо вызовов будет выглядеть следующим образом:

- - - - - - - - - - - - - - - - - - - -
Running TimeSelf 
3            100%1doSomething()
2              67%2logTheValue()
- -

Более реалистичный пример: на скриншоте ниже,  на второй строке видно 1914 сэмпла взятых внутри функции detectImage(). Но все сэмплы были получены  внутри функции названной detectImage() (Self равно нулю). Мы можем развернуть древо вызовов чтобы определить какая из функций на самом деле выполнялась когда было взято большинство сэмплов:

- -

- -

Далее можно сделать вывод, что 6 сэмплов было взято во время выполнения detectAtScale(), 12 во время getRect() и так далее.

- -

Примечания

- -
    -
  1.   Если функция вызывается несколько раз из различных источников, в выводе профайлера представлена она будет так же несколько раз. Так структуры вроде forEach будут появляться несколько раз в древе вызовов. - -

     

    -
  2. -
- -

 

diff --git a/files/ru/tools/release_notes/index.html b/files/ru/tools/release_notes/index.html deleted file mode 100644 index ba7f7887f2..0000000000 --- a/files/ru/tools/release_notes/index.html +++ /dev/null @@ -1,128 +0,0 @@ ---- -title: Замечания к релизу -slug: Tools/Release_notes -translation_of: Mozilla/Firefox/Releases -translation_of_original: Tools/Release_notes ---- -
{{ToolsSidebar}}

Firefox 48

- -

Главное:

- - - -

Другие исправления багов

- -

Firefox 32

- -

Highlights:

- - - -

More details:

- -
    -
  • HiDPI images added to the tools
  • -
  • Nodes that have display:none are shown differently in the Inspector
  • -
- -

All devtools bugs fixed between Firefox 31 and Firefox 32.

- -

Firefox 31

- -

Highlights:

- - - -

More details:

- - - -

All devtools bugs fixed between Firefox 30 and Firefox 31.

- -

Firefox 30

- -

Highlights:

- - - -

More details:

- - - -

All devtools bugs fixed between Firefox 29 and Firefox 30.

- -

Firefox 29

- -

Firefox 29 Hacks post. Highlights:

- - - -

Firefox 28

- -

Firefox 28 Hacks post. Highlights:

- - - -

Firefox 27

- -

Firefox 27 Hacks post. Highlights:

- - diff --git a/files/ru/tools/responsive_design_mode/index.html b/files/ru/tools/responsive_design_mode/index.html new file mode 100644 index 0000000000..e5acc43af0 --- /dev/null +++ b/files/ru/tools/responsive_design_mode/index.html @@ -0,0 +1,100 @@ +--- +title: Режим адаптивного дизайна +slug: Tools/Responsive_Design_View +tags: + - Design + - Firefox + - Guide + - Tools + - Web Development + - 'l10n:priority' + - Дизайн + - адаптивный дизайн + - инструменты разработки +translation_of: Tools/Responsive_Design_Mode +--- +
{{ToolsSidebar}}
+ +

Адаптивные дизайны (Responsive designs)  адаптируются к различным размерам экрана, чтобы обеспечить подходящее отображение для различных видов устройств, таких как мобильные телефоны или планшеты. Режим адаптивного дизайна даёт легкую возможность увидеть, как ваш сайт или веб-приложение будет выглядеть на экранах разных размеров.

+ +

{{EmbedYouTube("LBcE72sG2s8")}}

+ +

Скриншот ниже показывает страницу мобильной версии Википедии, отображаемой при размере области контента 320 на 480.

+ +

Окно Firefox, в области содержимого которого показывается короткая панель инструментов и маленькая область содержимого, в которой показана статья «мобильной» Википедии «Вода» соответственно размеру маленькой области.Режим адаптивного дизайна удобен тем, что можно быстро и точно изменять размер области содержимого.

+ +

Конечно, можно просто изменить размер окна браузера: но этим вы уменьшите и все остальные вкладки, что может очень затруднить использование браузера.

+ +

В режиме адаптивного дизайна можно ходить по страницам в изменённой области содержимого как и обычно.

+ +

Включение и выключение

+ +

Есть три способа включения режима адаптивного дизайна:

+ + + +

и три способа выключить режим адаптивного дизайна:

+ +
    +
  • снова выбрать пункт меню «Режим адаптивного дизайна» или «Адаптивный дизайн»;
  • +
  • кликнуть кнопку «Выйти» («закрыть») в верхнем левом углу окна режима;
  • +
  • Нажать Ctrl + Shift + M, (or Cmd + Opt + M on OS X). До Firefox 34, Escape тоже закрывала Режим адаптивного дизайна.
  • +
+ +

Изменение размера

+ +

Изменить размер области содержимого можно двумя способами:

+ + + +

При использовании перетаскивания можно удерживать клавишу Control (command на Max OS X), чтобы изменение шло медленнее. Это помогает установить размер точнее.

+ +
+

Элементы управления режимом

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + +
ВыйтиЗакрыть Режим адаптивного дизайна и вернуться к нормальному просмотру
Выбрать размер +

Выбрать из ряда комбинаций ширины и высоты, или определить свои собственные.

+ +

Начиная с Firefox 33, показываемые здесь числа можно редактировать на месте, так что можно легко определять собственные измерения.

+
ПовернутьПереключить экран между книжной и альбомной ориентацией.
+

Симулировать события прикосновения

+
+

Включить / выключить симуляцию сенсорных событий: когда она включена, события мыши переводятся в touch events.

+
+

Скриншот

+
Сделать скриншот (снимок) области содержимого.
+
+ +

 

diff --git a/files/ru/tools/responsive_design_view/index.html b/files/ru/tools/responsive_design_view/index.html deleted file mode 100644 index e5acc43af0..0000000000 --- a/files/ru/tools/responsive_design_view/index.html +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: Режим адаптивного дизайна -slug: Tools/Responsive_Design_View -tags: - - Design - - Firefox - - Guide - - Tools - - Web Development - - 'l10n:priority' - - Дизайн - - адаптивный дизайн - - инструменты разработки -translation_of: Tools/Responsive_Design_Mode ---- -
{{ToolsSidebar}}
- -

Адаптивные дизайны (Responsive designs)  адаптируются к различным размерам экрана, чтобы обеспечить подходящее отображение для различных видов устройств, таких как мобильные телефоны или планшеты. Режим адаптивного дизайна даёт легкую возможность увидеть, как ваш сайт или веб-приложение будет выглядеть на экранах разных размеров.

- -

{{EmbedYouTube("LBcE72sG2s8")}}

- -

Скриншот ниже показывает страницу мобильной версии Википедии, отображаемой при размере области контента 320 на 480.

- -

Окно Firefox, в области содержимого которого показывается короткая панель инструментов и маленькая область содержимого, в которой показана статья «мобильной» Википедии «Вода» соответственно размеру маленькой области.Режим адаптивного дизайна удобен тем, что можно быстро и точно изменять размер области содержимого.

- -

Конечно, можно просто изменить размер окна браузера: но этим вы уменьшите и все остальные вкладки, что может очень затруднить использование браузера.

- -

В режиме адаптивного дизайна можно ходить по страницам в изменённой области содержимого как и обычно.

- -

Включение и выключение

- -

Есть три способа включения режима адаптивного дизайна:

- - - -

и три способа выключить режим адаптивного дизайна:

- -
    -
  • снова выбрать пункт меню «Режим адаптивного дизайна» или «Адаптивный дизайн»;
  • -
  • кликнуть кнопку «Выйти» («закрыть») в верхнем левом углу окна режима;
  • -
  • Нажать Ctrl + Shift + M, (or Cmd + Opt + M on OS X). До Firefox 34, Escape тоже закрывала Режим адаптивного дизайна.
  • -
- -

Изменение размера

- -

Изменить размер области содержимого можно двумя способами:

- - - -

При использовании перетаскивания можно удерживать клавишу Control (command на Max OS X), чтобы изменение шло медленнее. Это помогает установить размер точнее.

- -
-

Элементы управления режимом

- -

- - - - - - - - - - - - - - - - - - - - - - - - -
ВыйтиЗакрыть Режим адаптивного дизайна и вернуться к нормальному просмотру
Выбрать размер -

Выбрать из ряда комбинаций ширины и высоты, или определить свои собственные.

- -

Начиная с Firefox 33, показываемые здесь числа можно редактировать на месте, так что можно легко определять собственные измерения.

-
ПовернутьПереключить экран между книжной и альбомной ориентацией.
-

Симулировать события прикосновения

-
-

Включить / выключить симуляцию сенсорных событий: когда она включена, события мыши переводятся в touch events.

-
-

Скриншот

-
Сделать скриншот (снимок) области содержимого.
-
- -

 

diff --git a/files/ru/tools/rulers/index.html b/files/ru/tools/rulers/index.html new file mode 100644 index 0000000000..c8d17fffac --- /dev/null +++ b/files/ru/tools/rulers/index.html @@ -0,0 +1,24 @@ +--- +title: Линейки +slug: Tools/Линейки +translation_of: Tools/Rulers +--- +
{{ToolsSidebar}}

Новое в Firefox 40.

+ +

Начиная с Firefox 40, можно отобразить горизонтальную и вертикальную линейки на странице:

+ +

Единица измерения - пиксели (точки, px).

+ +

Есть два способа включить линейки:

+ +
    +
  • используя команду rulers (линейки) в Developer Toolbar's (shift+f2)
  • +
  • использовать специально назначенную кнопку на тулбаре. По умолчанию эта кнопка не отображается, чтобы она стала видна нужно отметить галочку в разделе "Available Toolbox Buttons" ("Доступные кнопки инструментов") в Настройках.
  • +
+ +

Нужно помнить при пользованиями линейками:

+ +
    +
  • Команда включения линеек должна быть вызвана снова на новой вкладке и после каждого обновления страницы.
  • +
  • Команда не является постоянно активной.
  • +
diff --git a/files/ru/tools/web_console/opening_the_web_console/index.html b/files/ru/tools/web_console/opening_the_web_console/index.html deleted file mode 100644 index 41f3e760cc..0000000000 --- a/files/ru/tools/web_console/opening_the_web_console/index.html +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: Opening the Web Console -slug: Tools/Web_Console/Opening_the_Web_Console -translation_of: Tools/Web_Console/UI_Tour ---- -
{{ToolsSidebar}}

To open the Web Console:

- -
    -
  • either select "Web Console" from the Web Developer submenu in the Firefox Menu (or Tools menu if you display the menu bar or are on Mac OS X)
  • -
  • or press the CtrlShiftK (CommandOptionK on OS X) keyboard shortcut.
  • -
- -

The Toolbox will appear at the bottom of the browser window, with the Web Console activated (it's just called "Console" in the DevTools toolbar):

- -

- -

The Web Console's interface is split into three horizontal sections:

- -
    -
  • Toolbar: along the top is a toolbar containing buttons with labels like "Net", "CSS", and "JS". This toolbar is used to filter which messages are displayed
  • -
  • Command Line: along the bottom is a command line that you can use to enter JavaScript expressions
  • -
  • Message Display Pane: in between the toolbar and the command line, and occupying most of the window, is the space in which the Web Console displays messages
  • -
diff --git a/files/ru/tools/web_console/ui_tour/index.html b/files/ru/tools/web_console/ui_tour/index.html new file mode 100644 index 0000000000..41f3e760cc --- /dev/null +++ b/files/ru/tools/web_console/ui_tour/index.html @@ -0,0 +1,23 @@ +--- +title: Opening the Web Console +slug: Tools/Web_Console/Opening_the_Web_Console +translation_of: Tools/Web_Console/UI_Tour +--- +
{{ToolsSidebar}}

To open the Web Console:

+ +
    +
  • either select "Web Console" from the Web Developer submenu in the Firefox Menu (or Tools menu if you display the menu bar or are on Mac OS X)
  • +
  • or press the CtrlShiftK (CommandOptionK on OS X) keyboard shortcut.
  • +
+ +

The Toolbox will appear at the bottom of the browser window, with the Web Console activated (it's just called "Console" in the DevTools toolbar):

+ +

+ +

The Web Console's interface is split into three horizontal sections:

+ +
    +
  • Toolbar: along the top is a toolbar containing buttons with labels like "Net", "CSS", and "JS". This toolbar is used to filter which messages are displayed
  • +
  • Command Line: along the bottom is a command line that you can use to enter JavaScript expressions
  • +
  • Message Display Pane: in between the toolbar and the command line, and occupying most of the window, is the space in which the Web Console displays messages
  • +
diff --git "a/files/ru/tools/\320\270\320\275\321\201\320\277\320\265\320\272\321\202\320\276\321\200_\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\320\270/index.html" "b/files/ru/tools/\320\270\320\275\321\201\320\277\320\265\320\272\321\202\320\276\321\200_\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\320\270/index.html" deleted file mode 100644 index a375a027ae..0000000000 --- "a/files/ru/tools/\320\270\320\275\321\201\320\277\320\265\320\272\321\202\320\276\321\200_\320\264\320\276\321\201\321\202\321\203\320\277\320\275\320\276\321\201\321\202\320\270/index.html" +++ /dev/null @@ -1,166 +0,0 @@ ---- -title: Инспектор доступности -slug: Tools/Инспектор_доступности -translation_of: Tools/Accessibility_inspector ---- -
{{ToolsSidebar}}
- -

Инспектор доступности предоставляет средства для доступа к важной информации, предоставляемой вспомогательным технологиям на текущей странице, через дерево доступности, позволяя вам проверить, что отсутствует или иным образом требует внимания. В этой статье вы узнаете основные функции инспектора доступности и способы его использования.

- -

Очень краткое руководство по доступности

- -

Доступность - это средство, позволяющее использовать ваши сайты как можно большему числу людей. Это означает, что вы стараетесь изо всех сил не ограничивать кого-либо в доступе к информации из-за какой-либо имеющейся инвалидности, или любых других личных особенностей, таких как используемое устройство, скорости их сетевого подключения или их географического местоположения или языка.

- -

Здесь мы в основном говорим о том, чтобы донести информацию людям с нарушениями зрения - это делается с помощью API доступности, доступных внутри веб-браузеров, которые раскрывают информацию о том, какие роли играют разные элементы на вашей странице (например, они являются текстом или кнопками, ссылками, элементами форм и т. д.?).

- -

Семантические элементы DOM имеют роли, назначенные им по умолчанию, которые имеют свое предназначение. Иногда приходится использовать некоторую не семантическую разметку (например, {{htmlelement ("div")}}) для создания сложного настраиваемого элемента управления, а элемент управления не будет иметь роль по умолчанию, которая отражает его назначение. В такой ситуации вы можете использовать атрибуты роли WAI-ARIA для обозначения своих собственных ролей.

- -

Роли и другая информация, предоставляемая API-интерфейсами браузера, представлена в иерархической структуре, называемой деревом доступности. Это немного похоже на дерево DOM, за исключением того, что оно содержит более ограниченный набор элементов и немного другую информацию о них.

- -

Вспомогательные технологии, такие как скринридеры, используют эту информацию, чтобы узнать, что находится на веб-странице и сообщают своим пользователям и  это позволяет им взаимодействовать со страницей. Инспектор доступности также использует эту информацию для обеспечения возможностей для отладки доступности в DevTools.

- -

Доступ к инспектору доступности

- -

The accessibility inspector (available since Firefox 61) is not shown by default in the DevTools. To turn it on, you need to go to DevTools Settings (press F1, or go to the "three dots" menu and choose Settings) and check the Accessibility checkbox under the Default Developer Tools heading. This will cause the Accessibility tab to appear in the main DevTools display, which can be clicked on to display the accessibility panel:

- -

Accessibility tab in firefox devtools, turned off, with a button labeled Turn On Accessibility Features

- -

Initially the DevTools accessibility features are turned off (unless you've already got them turned on in another browser tab, or got the Firefox accessibility engine started already, e.g., you might be a screenreader user or tester). This is because the accessibility engine runs in the background when the accessibility features are turned on. While it’s running, it slows performance and takes up memory; therefore it interferes with the metrics from other panels such as Memory and Performance as well as overall browser performance. For this reason you should keep it turned off when you aren't specifically using it.

- -

You can turn the features on using the Turn On Accessibility Features button.

- -

Once the panel content loads, you can then turn it off again using the Turn Off Accessibility Features button available in the top-left corner, unless you have the accessibility engine running previously to operate a screenreader, in which case this button will be disabed.

- -
-

Note: If are using the accessibility features in multiple tabs, turning them off in one tab turns them off in all tabs.

-
- -

Особенности панели доступности

- -

The enabled accessibility panel looks like so:

- -

Accessibility tab in firefox devtools, turned on, showing two information panels plus a button labeled Turn Off Accessibility Features

- -

On the left-hand side, there is a tree diagram representing all the items in the accessibility tree for the current page. Items with nested children have arrows that can be clicked to reveal the children, so you can move deeper into the hierarchy. Each item has two properties listed:

- -
    -
  • Role — the role this item has on the page (e.g., pushbutton, or footer). This can be either a default role provided by the browser, or a role given to it via a WAI-ARIA role attribute.
  • -
  • Name — the name this item has on the page. Where this comes from depends on the element; for example, the name of most text elements is simply their textContent, whereas form elements' names are the contents of their associated {{htmlelement("label")}}.
  • -
- -

On the right-hand side, you can see further information about the currently selected item. The listed properties are as follows:

- -
    -
  • name — the item's name, as described above.
  • -
  • role — the item's role, as described above.
  • -
  • actions — a list of the actions that can be performed on the item, for example a pushbutton would have "Press" listed, while a link would have "Jump" listed.
  • -
  • value — the value of the item. This can mean different things depending on the type of item; for example, a form input (role: entry) would have a value of whatever is entered in the input, whereas a link's value would be the URL in the corresponding <a> element's href.
  • -
  • DOMNode — the type of DOM node that the item in the accessibility tree represents. You can click on the "target" icon that comes after it to select the node in the Page Inspector. Hovering over the "target" icon highlights the DOM node in the page content.
    - DOMNode property in accessibility inspector with target icon highlighted
  • -
  • description — any further description provided on the element, usually by the content of a title attribute.
  • -
  • help — this is not implemented in Gecko, so it always returns an empty string. This will be removed from the inspector in Firefox 62 ({{bug(1467643)}}).
  • -
  • keyboardShortcut — any keyboard shortcut that is available to activate the element, as specified in an accessKey attribute. Note that this works correctly as of Firefox 62 ({{bug("1467381")}}).
  • -
  • childCount — the number of child items the current item has in the accessibility tree hierarchy.
  • -
  • indexInParent — an index value indicating what number child the item is, inside its parent. If the item is the first item inside its parent, it has a value of 0. If it is the second, it has a value of 1. And so on.
  • -
  • states — a list of the different accessibility-relevant states that can apply to the current item. For example, one of the links in one demo has states of focusable, linked, selectable text, opaque, enabled, and sensitive. For a full list of internal states, see Gecko states.
  • -
  • attributes — a list of all the accessibility-relevant attributes that are applied to the item. This can include style-related attributes such as margin-left and text-indent, and other useful states for accessibility information, such as draggable and level (e.g., what heading level is it, in the case of headings). For a full list of possible attributes, see Gecko object attributes.
  • -
- -
-

Note: The exposed information is the same across all platforms — the inspector exposes Gecko's accessibility tree, rather than information from the platform accessibility layer.

-
- -

Keyboard controls

- -

The Accessibility tab is fully keyboard-accessible:

- -
    -
  • You can tab between the Turn Off Accessibility Features button and left and right panels.
  • -
  • When one of the panels is focused, you can move the focus up and down items using the up and down arrow keys, and use the left and right arrow keys to expand and collapse expandable rows (e.g., different hierarchy levels of the accessibility tree).
  • -
- -

Вывод дерева доступности в JSON-формате

- -

You can print the contents of the accessibility tree to json by right-clicking on an entry in the Accessibility tab and selecting Print to json:

- -

- -

When you do, you will get a new tab with the selected accessibility tree loaded into the JSON viewer:

- -

- -

Once opened, you can save or copy the data as necessary. The JSON viewer can also show you the raw json data on a separate tab in the viewer.

- -

Известные связанные особенности

- -

When the accessibility features are turned on, there are a number of useful additional features available in the DevTools, which are detailed below:

- -

Context menu options

- -

An extra context menu option is added, both for the general context menu on the web page when right/Ctrl + clicking a UI feature, and the HTML pane of the page inspector when right/Ctrl + clicking a DOM element:

- -

context menu in the browser viewport, with a highlighted option: Inspect Accessibility Properties

- -

context menu in the DOM inspector, with a highlighted option: Show Accessibility Properties

- -

When you choose the Inspect Accessibility Properties/Show Accessibility Properties context menu options, the Accessibility tab is immediately opened to show the corresponding accessibility tree item and its properties.

- -
-

Note: Some DOM elements do not have accessibility properties — in such a case, the Inspect Accessibility Properties/Show Accessibility Properties context menu item is grayed out.

-
- -

Выделение элементов интерфейса

- -

In the Accessibility tab, when the mouse hovers over accessibility items, you can see a semi-transparent highlight appear over the UI items they relate to, if appropriate. The role and name of the item will be shown in a small information bar. This is useful for determining how the items in the accessibility tree relate to the UI items on the actual page.

- -

In the following example, you can see that the image has been highlighted and its role, graphic, and name, "Road, Asphalt, Sky, Clouds, Fall" appears in the information bar above it.

- -

- -

Цветовой контраст

- -

Contrast ratio information is particularly useful when you are designing the color palette for your website because if the contrast is not sufficient, readers with visual impairments such as color blindness will be unable to read the text. The Web Content Accessibility Guidelines (WCAG) 2.0 defines 4.5:1 as the minimum suggested contrast ratio between the foreground and background colors for smaller text on a web page. For example:

- -

- -

The color contrast in the image above is 2.77, potentially not enough contrast to make it easy to read. Notice the warning symbol that indicates that the contrast fails to meet the acceptable contrast ratio. Compare that to the following:

- -

- -

In this example, the contrast is 12.63. This time the number is followed by AAA and a checkmark in green, indicating that the text has a contrast ratio of 7:1 or more, meaning it meets the criteria for enhanced contrast, or Level AAA.

- -

Accessibility picker

- -

In a similar way to the Page Inspector HTML pane picker, when the Accessibility tab's picker button is pressed you can then hover and select UI items in the current page, and the corresponding accessible object is highlighted in the accessibility tree.

- -

The accessibility tab picker differs in look slightly from the Page Inspector HTML pane picker, as shown below:

- -

highlighted dom inspector picker button, with a tooltip saying Pick an element from the page

- -

highlighted accessibility inspector button, with a tooltip saying Pick accessible object from the page

- -

When you "perform a pick", you see the accessibility object highlighted in the accessibility tree, and the picker is then deactivated. Note, however, that if you hold the Shift key down when "performing a pick", you can "preview" the accessibility object in the tree (and its properties in the right-hand pane), but then continue picking as many times as you like (the picker does not get cancelled) until you release the Shift key.

- -

When the picker is activated, you can also deactivate it by pressing the picker button a second time, or pressing the Esc key.

- -

Типичное использование

- -

The accessibility inspector is very useful for spotting accessibility problems at a glance. For a start, you can investigate items that don't have a proper text equivalent — images without alt text and form elements without proper labels have a name property of null, for example.

- -

A form input highlighted in the UI, with information about it shown in the accessibility inspector to reveal that it has no label — it has a name property of null

- -

It is also very handy for verifying semantics — you can use the Inspect Accessibility Properties context menu option to quickly see whether an item has the correct role set on it (e.g., whether a button is really a button, or whether a link is really a link).

- -

A UI element that looks like a button, with information about it shown in the accessibility inspector to reveal that it isn't a button, it is a section element. It has a name property of null

- -

Смотри также

- - - -
 
diff --git "a/files/ru/tools/\320\272\320\276\320\275\321\201\320\276\320\273\321\214_\320\261\321\200\320\260\321\203\320\267\320\265\321\200\320\260/index.html" "b/files/ru/tools/\320\272\320\276\320\275\321\201\320\276\320\273\321\214_\320\261\321\200\320\260\321\203\320\267\320\265\321\200\320\260/index.html" deleted file mode 100644 index 487bc2eb5e..0000000000 --- "a/files/ru/tools/\320\272\320\276\320\275\321\201\320\276\320\273\321\214_\320\261\321\200\320\260\321\203\320\267\320\265\321\200\320\260/index.html" +++ /dev/null @@ -1,180 +0,0 @@ ---- -title: Консоль браузера -slug: Tools/Консоль_браузера -tags: - - Tools - - Web Development - - Браузер - - Отладка - - 'веб-разработка:инструменты' - - консоль -translation_of: Tools/Browser_Console ---- -
{{ToolsSidebar}}

Консоль браузера — как Веб-консоль, но для работы со всем браузером, а не с отдельной его вкладкой.

- -

То есть, она протоколирует такую же информацию, что и Веб-консоль: сетевые запросы, ошибки и предупреждения JavaScript и CSS, ошибки и предупреждения о безопасности, и информационные сообщения, выдаваемые непосредственно кодом JavaScript. Однако она протоколирует эту информацию не только для одной вкладки с контентом, но для всех вкладок с контентом, для дополнений, и для кода самого браузера.

- -

Если вы хотите использовать и другие инструменты, доступные в обычном наборе инструментов веб-разработки, с кодом дополнений или браузера, вам может пригодиться Панель инструментов браузера.

- -

В Консоли браузера можно также выполнять и выражения JavaScript. But while the Web Console executes code in the page window scope, the Browser Console executes them in the scope of the browser's chrome window. This means you can interact with all the browser's tabs using the gBrowser global, and even with the XUL used to specify the browser's user interface.

- -
-

Внимание: начиная с Firefox 30, командная строка Консоли браузера (куда вставляются выражения JavaScript) по умолчанию выключена. Чтобы её включить, присвойте настройке about:config devtools.chrome.enabled значение true, либо поставьте галочку «Включить инструменты отладки browser chrome и дополнений» (начиная с Firefox 40) / «Включить отладку chrome и дополнений» (по Firefox 38.0.5 включительно) в настройках панели инструментов разработчика.

-
- -

Открытие Консоли браузера

- -

Консоль браузера можно открыть двумя способами:

- -
    -
  1. из меню: выбрать «Консоль браузера» из меню Разработка в меню Firefox (или меню Инструменты, если оно включено или на OS X)
  2. -
  3. с клавиатуры: нажать Ctrl+Shift+J (или Cmd+Shift+J на Mac).
  4. -
- -

Note that until Firefox 38, if the Browser Console has become hidden by a normal Firefox window and you select it again, either from the menu or from the keyboard, then it will be closed. From Firefox 38 onwards, this instead has the effect of switching the focus back to the Browser Console, which is more likely to be what you wanted.

- -

You can also start the Browser Console by launching Firefox from the command line and passing the -jsconsole argument:

- -
/Applications/FirefoxAurora.app/Contents/MacOS/firefox-bin -jsconsole
- -

The Browser Console looks like this:

- -

- -

You can see that the Browser Console looks and behaves very much like the Web Console:

- - - -

Browser Console logging

- -

The Browser console logs the same sorts of messages as the Web Console:

- - - -

However, it displays such messages from:

- -
    -
  • web content hosted by all browser tabs
  • -
  • the browser's own code
  • -
  • add-ons.
  • -
- -

Messages from add-ons

- -

The Browser Console displays messages logged by all Firefox add-ons.

- -

Console.jsm

- -

To use the console API from a traditional or bootstrapped add-on, get it from the Console module.

- -

One exported symbol from Console.jsm is "console". Below is an example of how to acess it, which adds a message to the Browser Console.

- -
Components.utils.import("resource://gre/modules/devtools/Console.jsm");
-console.log("Hello from Firefox code"); //output messages to the console
- -

Learn more:

- - - -

HUDService

- -

There is also the HUDService which allows access to the Browse Console. The module is available at Mozilla Cross-Reference. We see we can not only access the Browser Console but also Web Console.

- -

Here is an example on how to clear the contents of the Browser console:

- -
Components.utils.import("resource://gre/modules/devtools/Loader.jsm");
-var HUDService = devtools.require("devtools/webconsole/hudservice");
-
-var hud = HUDService.getBrowserConsole();
-hud.jsterm.clearOutput(true);
- -

If you would like to access the content document of the Browser Console this can be done with the HUDService. This example here makes it so that when you mouse over the "Clear" button it will clear the Browser Console:

- -
Components.utils.import("resource://gre/modules/devtools/Loader.jsm");
-var HUDService = devtools.require("devtools/webconsole/hudservice");
-
-var hud = HUDService.getBrowserConsole();
-
-var clearBtn = hud.chromeWindow.document.querySelector('.webconsole-clear-console-button');
-clearBtn.addEventListener('mouseover', function() {
-  hud.jsterm.clearOutput(true);
-}, false);
- -

Bonus Features Available

- -

For Add-on SDK add-ons, the console API is available automatically. Here's an example add-on that just logs an error when the user clicks a widget:

- -
widget = require("sdk/widget").Widget({
-  id: "an-error-happened",
-  label: "Error!",
-  width: 40,
-  content: "Error!",
-  onClick: logError
-});
-
-function logError() {
-  console.error("something went wrong!");
-}
- -

If you build this as an XPI file, then open the Browser Console, then open the XPI file in Firefox and install it, you'll see a widget labeled "Error!" in the Add-on bar:

- -

Click the icon. You'll see output like this in the Browser Console:

- -

- -

For Add-on SDK-based add-ons only, the message is prefixed with the name of the add-on ("log-error"), making it easy to find all messages from this add-on using the "Filter output" search box. By default, only error messages are logged to the console, although you can change this in the browser's preferences.

- -

Browser Console command line

- -
-

From Firefox 30, the Browser Console command line is disabled by default. To enable it set the devtools.chrome.enabled preference to true in about:config, or set the "Enable chrome debugging" option in the developer tool settings.

-
- -

Like the Web Console, the command line interpreter enables you to evaluate JavaScript expressions in real time:Also like the Web Console's command line interpreter, this command line supports autocomplete, history, and various keyboard shortcuts and helper commands. If the result of a command is an object, you can click on the object to see its details.

- -

But while the Web Console executes code in the scope of the content window it's attached to, the browser console executes code in the scope of the chrome window of the browser. You can confirm this by evaluating window:

- -

- -

This means you can control the browser: opening, closing tabs and windows and changing the content that they host, and modify the browser's UI by creating, changing and removing XUL elements.

- -

Controlling the browser

- -

The command line interpreter gets access to the tabbrowser object, through the gBrowser global, and that enables you to control the browser through the command line. Try running this code in the Browser Console's command line (remember that to send multiple lines to the Browser Console, use Shift+Enter):

- -
var newTabBrowser = gBrowser.getBrowserForTab(gBrowser.selectedTab);
-newTabBrowser.addEventListener("load", function() {
-  newTabBrowser.contentDocument.body.innerHTML = "<h1>this page has been eaten</h1>";
-}, true);
-newTabBrowser.contentDocument.location.href = "https://mozilla.org/";
- -

It adds a listener to the currently selected tab's load event that will eat the new page, then loads a new page.

- -

Modifying the browser UI

- -

Since the global window object is the browser's chrome window, you can also modify the browser's user interface. On Windows, the following code will add a new item to the browser's main menu:

- -
var parent = window.document.getElementById("appmenuPrimaryPane");
-var makeTheTea = gBrowser.ownerDocument.defaultView.document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "menuitem");
-makeTheTea.setAttribute("label", "A nice cup of tea?");
-parent.appendChild(makeTheTea);
- -

On OS X, this similar code will add a new item to the "Tools" menu:

- -
var parent = window.document.getElementById("menu_ToolsPopup");
-var makeTheTea = gBrowser.ownerDocument.defaultView.document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "menuitem");
-makeTheTea.setAttribute("label", "A nice cup of tea?");
-parent.appendChild(makeTheTea);
- -

diff --git "a/files/ru/tools/\320\273\320\270\320\275\320\265\320\271\320\272\320\270/index.html" "b/files/ru/tools/\320\273\320\270\320\275\320\265\320\271\320\272\320\270/index.html" deleted file mode 100644 index c8d17fffac..0000000000 --- "a/files/ru/tools/\320\273\320\270\320\275\320\265\320\271\320\272\320\270/index.html" +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: Линейки -slug: Tools/Линейки -translation_of: Tools/Rulers ---- -
{{ToolsSidebar}}

Новое в Firefox 40.

- -

Начиная с Firefox 40, можно отобразить горизонтальную и вертикальную линейки на странице:

- -

Единица измерения - пиксели (точки, px).

- -

Есть два способа включить линейки:

- -
    -
  • используя команду rulers (линейки) в Developer Toolbar's (shift+f2)
  • -
  • использовать специально назначенную кнопку на тулбаре. По умолчанию эта кнопка не отображается, чтобы она стала видна нужно отметить галочку в разделе "Available Toolbox Buttons" ("Доступные кнопки инструментов") в Настройках.
  • -
- -

Нужно помнить при пользованиями линейками:

- -
    -
  • Команда включения линеек должна быть вызвана снова на новой вкладке и после каждого обновления страницы.
  • -
  • Команда не является постоянно активной.
  • -
diff --git "a/files/ru/tools/\320\277\321\200\320\276\320\270\320\267\320\262\320\276\320\264\320\270\321\202\320\265\320\273\321\214\320\275\320\276\321\201\321\202\321\214/index.html" "b/files/ru/tools/\320\277\321\200\320\276\320\270\320\267\320\262\320\276\320\264\320\270\321\202\320\265\320\273\321\214\320\275\320\276\321\201\321\202\321\214/index.html" deleted file mode 100644 index ba11369101..0000000000 --- "a/files/ru/tools/\320\277\321\200\320\276\320\270\320\267\320\262\320\276\320\264\320\270\321\202\320\265\320\273\321\214\320\275\320\276\321\201\321\202\321\214/index.html" +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: Производительность -slug: Tools/Производительность -translation_of: Tools/Performance ---- -
{{ToolsSidebar}}

Инструмент даёт Вам понять общую отзывчивость вашего сайта,  JavaScript и общее представление о разметке. С помощью инструмента производительности Вы создадите запись или профиль своего сайта за определенный промежуток времени. Затем, инструмент покажет Вам действия браузера и график смены частоты кадров, поверх профиля, рендера Вашего сайта.

- -

Вы получите четыре набора инструментов для более подробного изучения аспектов профиля:

- -
    -
  •  Waterfall (Водопад) показывает различные операции браузера, например, выполняет макет, JavaScript, перерисовывает и собирает мусор
  • -
  • Call Tree (Дерево вызова) показывает функции JavaScript, в которых браузер провел большую часть своего времени
  • -
  • Flame Chart (Пламенный График) показывает стек вызовов JavaScript над конечной записью.
  • -
  • Allocations. В этом представлении отображаются распределения кучи, сделанные вашим кодом в ходе записи. Это представление появляется только в том случае, если вы отметили «Записать выделение» в настройках инструмента «Производительность».
  • -
- -

{{EmbedYouTube("WBmttwfA_k8")}}

- -
-

Приступая к работе

- -
-
-
-
UI Tour (Пользовательский интерфейс)
-
-

Чтобы найти свой вариант производительности инструмента, вот краткий обзор пользовательского интерфейса UI.

-
-
-
- -
-
-
How to (Как)
-
Основные задачи: откройте инструмент создать, сохранить, загрузить и настроить записи.
-
-
-
- -
-

Компоненты инструмента производительности

- -
-
-
-
Frame rate (Частота кадров)
-
Исследование Вашего сайта на отзывчивость.
-
Call Tree (Дерево вызовов)
-
Поиск узких мест Вашего сайта на JavaScript.
-
-
- -
-
-
Waterfall (Водопад)
-
Исследует работу браузера на взаимодействие пользователей с Вашим сайтом.
-
Flame Chart (Диаграмма)
-
Обзор выполнения функций JavaScript во времени.
-
Allocations (Распределение)
-
Просмотр распределений сделанных вашим кодом во время записи.
-
 
-
 
-
-
-
- -
-

Сценарии

- -
-
-
-
Animating CSS properties (Свойства анимации CSS)
-
Использует водопад чтобы понять как браузер обновляет страницу, и как меняя разные свойства CSS можно улучшить производительность.
-
 
-
-
- -
-
-
Intensive JavaScript (Интенсивный JS)
-
Использует частоту кадров и инструменты водопада для выделения проблем с производительностью, вызванные длительной загрузкой JavaScript и каким образом с помощью инструментов разработчика  возможно исправить ситуацию.
-
-
-
- -

 

- -
-
-
 
-
-
- -

 

diff --git "a/files/ru/tools/\320\277\321\200\320\276\320\270\320\267\320\262\320\276\320\264\320\270\321\202\320\265\320\273\321\214\320\275\320\276\321\201\321\202\321\214/waterfall/index.html" "b/files/ru/tools/\320\277\321\200\320\276\320\270\320\267\320\262\320\276\320\264\320\270\321\202\320\265\320\273\321\214\320\275\320\276\321\201\321\202\321\214/waterfall/index.html" deleted file mode 100644 index 1531a44a10..0000000000 --- "a/files/ru/tools/\320\277\321\200\320\276\320\270\320\267\320\262\320\276\320\264\320\270\321\202\320\265\320\273\321\214\320\275\320\276\321\201\321\202\321\214/waterfall/index.html" +++ /dev/null @@ -1,386 +0,0 @@ ---- -title: Waterfall -slug: Tools/Производительность/Waterfall -translation_of: Tools/Performance/Waterfall ---- -
{{ToolsSidebar}}
-

Водопад (Waterfall) дает вам представление о различных процессах, которые происходят внутри браузера, когда вы открывайте ваш сайт или запускаете ваше приложение. Он основан на идее разделения всех происходящих внутри браузера процессов на различные типы  - запуск JavaScript, обновление layout и так далее - и что в любой момент времени браузрер выполняет один из этих процессов.

- -

Поэтому если вы увидите признаки проблем с производительностью  - например, падения частоты кадров - вы можете запустить Waterfall, чтобы увидеть, что делает браузер в этот момент.

-
- -

- -

Ось X это ось времени. Записанные операции и вызванные маркеры отображаются в виде горизонтальных прямоуголников, расположенных в виде водопада, чтобы подчеркнуть последовательность выполнения внутри браузера.

- -

При выборе маркера вы увидите подробную информацию о нем на панели справа. В этой панели вы сможете узнать продолжительность и другую специфичную для конктреного типа процесса инофрмацию .

- -

Markers

- -

The markers for operations are color-coded and labeled. The following operations are recorded:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name and descriptionColorDetailed information
-

DOM Event

- -

JavaScript code that's executed in response to a DOM event.

-
-
-
Event Type
-
For example, "click" or "message".
-
- -
-
Event Phase
-
For example, "Target" or "Capture".
-
-
-

JavaScript functions executed in the page are labeled with the reason the function was called:

- -

Script Tag
- setInterval
- setTimeout
- requestAnimationFrame
- Promise Callback
- Promise Init
- Worker
- JavaScript URI
- Event Handler

-
-
-
Stack
-
Call stack, with links to functions.
-
-
-

Parse HTML

- -

Time spent parsing the page's HTML.

-
-
-
Stack
-
Call stack, with links to functions.
-
-
-

Parse XML

- -

Time spent parsing the page's XML.

-
-
-
Stack
-
Call stack, with links to functions.
-
-
-

Recalculate Style

- -

Calculating the computed styles that apply to page elements.

-
-
-
Restyle Hint
-
A string indicating what kind of restyling is needed. The hint may be any of:
- Self
- Subtree
- LaterSiblings
- CSSTransitions
- CSSAnimations
- SVGAttrAnimations
- StyleAttribute
- StyleAttribute_Animations
- Force
- ForceDescendants
-
-
-

Layout

- -

Calculating the position and size of page elements. This operation is sometimes called "reflow".

-
 
-

Paint

- -

Drawing pixels to the screen.

-
 
-

GC Event

- -

Garbage collection event. Non-incremental GC events are labeled "(Non-incremental)".

-
-
-
Reason
-
A string the indicating the reason GC was performed.
-
Non-incremental Reason
-
If the GC event was non-incremental, a string the indicating the reason non-incremental GC was performed.
-
-
-

Console

- -

The period between matching calls to console.time() and console.timeEnd().

-
-
-
Timer name
-
The argument passed to the console functions.
-
Stack at start
-
Call stack console.time(), with links to functions.
-
Stack at End
-
(New in Firefox 41). Call stack at console.timeEnd(). If this is inside a callback from a Promise, this will also show the "Async stack".
-
-
-

Timestamp

- -

A single call to console.timeStamp().

-
-
-
Label
-
The argument passed to timeStamp().
-
-
- -

The markers, and their colors, are the same in the Waterfall tool as in the Waterfall overview, making is easy to correlate from one to the other.

- -

Filtering markers

- -

You can control which markers are displayed using a button in the Toolbar:

- -

- -

Waterfall patterns

- -

Exactly what you'll see in the Waterfall is very dependent on the kind of thing your site is doing: JavaScript-heavy sites will have a lot of orange, while visually dynamic sites will have a lot of purple and green. But there are common patterns which can alert you to possible performance problems.

- -

Rendering waterfall

- -

One pattern that you'll often see in the Waterfall view is something like this:

- -

- -

This is a visualization of the basic algorithm the browser uses to update the page in response to some event:

- -
    -
  1. JavaScript Function Call: some event - for example, a DOM event - causes some JavaScript in the page to run. The JavaScript changes some of the page's DOM or CSSOM.
  2. -
  3. Recalculate Style: if the browser thinks the computed styles for page elements have changed, it must then recalculate them.
  4. -
  5. Layout: next, the browser uses the computed styles to figure out the position and geometry for the elements. This operation is labeled "layout" but is also sometimes called "reflow".
  6. -
  7. Paint: finally, the browser needs to repaint the elements to the screen. One last step is not shown in this sequence: the page may be split into layers, which are painted independently and then combined in a process called "Composition".
  8. -
- -

This sequence needs to fit into a single frame, since the screen isn't updated until it is complete. It's commonly accepted that 60 frames per second is the rate at which animations will appear smooth. For a rate of 60 frames per second, that gives the browser 16.7 milliseconds to execute the complete flow.

- -

Importantly for responsiveness, the browser doesn't always have to go through every step:

- -
    -
  • CSS animations update the page without having to run any JavaScript.
  • -
  • Not all CSS property changes cause a reflow. Changing properties that can alter an object's geometry and position, such as width, display, font-size, or top, will cause a reflow. However, changing properties that don't alter geometry or position, such as color or opacity, will not.
  • -
  • Not all CSS property changes cause a repaint. In particular, if you animate an element using the transform property, the browser will use a separate layer for the transformed element, and doesn't even have to repaint when the element is moved: the new position of the element is handled in composition.
  • -
- -

The Animating CSS properties article shows how animating different CSS properties can give different performance outcomes, and how the Waterfall can help signal that.

- -

Blocking JavaScript

- -

By default, a site's JavaScript is executed in the same thread that the browser uses for layout updates, repaints, DOM events, and so on. This means that long-running JavaScript functions can cause unresponsiveness (jank): animations may not be smooth, or the site might even freeze.

- -

Using the frame rate tool and the Waterfall together, it's easy to see when long-running JavaScript is causing responsiveness problems. In the screenshot below, we've zoomed in on a JS function that's caused a drop in the frame rate:

- -

- -

The Intensive JavaScript article shows how the Waterfall can highlight responsiveness problems caused by long JavaScript functions, and how you can use asynchronous methods to keep the main thread responsive.

- -

Expensive paints

- -

Some paint effects, such as box-shadow, can be expensive, especially if you are applying them in a transition where the browser has to calculate them in every frame. If you're seeing drops in the frame rate, especially during graphically-intensive operations and transitions, check the Waterfall for long green markers.

- -

Garbage collection

- -

Red markers in the Waterfall represent garbage collection (GC) events, in which SpiderMonkey (the JavaScript engine in Firefox) walks the heap looking for memory that's no longer reachable and subsequently releasing it. GC is relevant to performance because while it's running the JavaScript engine must be paused, so your program is suspended and will be completely unresponsive.

- -

To help reduce the length of pauses, SpiderMonkey implements incremental GC: this means that it can perform garbage collection in fairly small increments, letting the program run in between. Sometimes, though, it needs to perform a full non-incremental collection, and the program has to wait for it to finish.

- -

When the Waterfall records a GC marker it indicates:

- -
    -
  • whether the GC was incremental or not
  • -
  • the reason the GC was performed
  • -
  • if the GC was non-incremental, the reason it was non-incremental
  • -
- -

In trying to avoid GC events, and especially non-incremental GC events, it's wise not to try to optimize for the specific implementation of the JavaScript engine. SpiderMonkey uses a complex set of heuristics to determine when GC is needed, and when non-incremental GC in particular is needed. In general, though:

- -
    -
  • GC is needed when a lot of memory is being allocated
  • -
  • non-incremental GC is usually needed when the memory allocation rate is high enough that SpiderMonkey may run out of memory during incremental GC
  • -
- -

Adding markers with the console API

- -

Two markers are directly controlled by console API calls: "Console" and "Timestamp".

- -

Console markers

- -

These enable you to mark a specific section of the recording.

- -

To make a console marker, call console.time() at the start of the section, and console.timeEnd() at the end. These functions take an argument which is used to name the section.

- -

For example, suppose we have code like this:

- -
var iterations = 70;
-var multiplier = 1000000000;
-
-function calculatePrimes() {
-
-  console.time("calculating...");
-
-  var primes = [];
-  for (var i = 0; i < iterations; i++) {
-    var candidate = i * (multiplier * Math.random());
-    var isPrime = true;
-    for (var c = 2; c <= Math.sqrt(candidate); ++c) {
-      if (candidate % c === 0) {
-          // not prime
-          isPrime = false;
-          break;
-       }
-    }
-    if (isPrime) {
-      primes.push(candidate);
-    }
-  }
-
-  console.timeEnd("calculating...");
-
-  return primes;
-}
- -

The Waterfall's output will look something like this:

- -

- -

The marker is labeled with the argument you passed to console.time(), and when you select the marker, you can see the program stack in the right-hand sidebar.

- -

Async stack

- -

New in Firefox 41.

- -

Starting in Firefox 41, the right-hand sidebar will also show the stack at the end of the period: that is, at the point console.timeEnd() was called. If console.timeEnd() was called from the resolution of a Promise, it will also display "(Async: Promise)", under which it will show the "async stack": that is, the call stack at the point the promise was made.

- -

For example, consider code like this:

- -
var timerButton = document.getElementById("timer");
-timerButton.addEventListener("click", handleClick, false);
-
-function handleClick() {
-  console.time("timer");
-  runTimer(1000).then(timerFinished);
-}
-
-function timerFinished() {
-  console.timeEnd("timer");
-  console.log("ready!");
-}
-
-function runTimer(t) {
-  return new Promise(function(resolve) {
-    setTimeout(resolve, t);
-  });
-}
- -

The Waterfall will display a marker for the period between time() and timeEnd(), and if you select it, you'll see the async stack in the sidebar:

- -

- -

Timestamp markers

- -

Timestamps enable you to mark an instant in the recording.

- -

To make a timestamp marker, call console.timeStamp(). You can pass an argument to label the timestamp.

- -

For example, suppose we adapt the code above to make a timestamp every 10 iterations of the loop, labeled with the iteration number:

- -
var iterations = 70;
-var multiplier = 1000000000;
-
-function calculatePrimes() {
-  console.time("calculating...");
-
-  var primes = [];
-  for (var i = 0; i < iterations; i++) {
-
-    if (i % 10 == 0) {
-      console.timeStamp(i.toString());
-    }
-
-    var candidate = i * (multiplier * Math.random());
-    var isPrime = true;
-    for (var c = 2; c <= Math.sqrt(candidate); ++c) {
-      if (candidate % c === 0) {
-          // not prime
-          isPrime = false;
-          break;
-       }
-    }
-    if (isPrime) {
-      primes.push(candidate);
-    }
-  }
-  console.timeEnd("calculating...");
-  return primes;
-}
- -

In the Waterfall you'll now see something like this:

- -

- -

 

diff --git a/files/ru/using_firefox_1.5_caching/index.html b/files/ru/using_firefox_1.5_caching/index.html deleted file mode 100644 index 2db6fe3556..0000000000 --- a/files/ru/using_firefox_1.5_caching/index.html +++ /dev/null @@ -1,210 +0,0 @@ ---- -title: Использование кэширования в Firefox 1.5 -slug: Using_Firefox_1.5_caching -translation_of: Mozilla/Firefox/Releases/1.5/Using_Firefox_1.5_caching ---- -
{{FirefoxSidebar}}

 

- -

Введение

- -

Firefox 1.5 использует кэширование целых Web-страниц, включая их JavaScript-состояния, в рамках сессии браузера. Переходы по посещённым страницам вперёд-назад не требуют загрузки страниц, а JavaScript-состояния сохраняются. Эта функция, обозначаемая иногда как bfcache (Back-Forward Cache), делает навигацию по страницам очень быстрой. Такое кэшированное состояние сохраняется, пока пользователь не закроет браузер.

- -

Есть случаи, в которых Firefox не кэширует страницы. Вот некоторые обычные программные причины того, что страница не кэширована:

- -
    -
  • страница использует обработчик unload или beforeunload;
  • -
  • страница устанавливает заголовок «cache-control: no-store».
  • -
  • доступ к сайту происходит по протоколу HTTPS, а страница устанавливает по меньшей мере один из следующих заголовков: -
      -
    • «Cache-Control: no-cache»
    • -
    • «Pragma: no-cache»
    • -
    • с заголовком «Expires: 0» or «Expires» со значением даты, лежащим в прошлом относительно значению заголовка «Date» (если только не указан также заголовок «Cache-Control: max-age=»);
    • -
    -
  • -
  • страница не полностью загрузилась, когда пользователь ушёл с неё, или имеет прерванные сетевые запросы по другим причинам (например, XMLHttpRequest));
  • -
  • страница имеет работающие IndexedDB-транзакции;
  • -
  • страница верхнего уровня содержит фреймы (например, {{ HTMLElement("iframe") }}), которые не кэшируются по одной из перечисленных здесь причин;
  • -
  • страница находится в фрейме и пользователь загружает новую страницу в этот фрейм (в этом случае, когда пользователь уходит со с этой страницы, последнее загруженное в фреймы содержимое есть то, что закэшировано).
  • -
- -

Эта новая функция кэширования меняет поведение загрузки страницы, так что Web-авторы могут захотеть:

- -
    -
  • узнать, когда на страницу происходит переход (когда она загружается из пользовательского кэша);
  • -
  • определить поведение страницы, когда пользователь уходит со страницы (позволяя всё же странице быть закэшированной).
  • -
- -

Это позволяют сделать два новых события браузера.

- -

Новые события браузера

- -

Если вы используете эти новые события, ваши страницы продолжат правильно отображаться в других браузерах (мы протестировали старые версии Firefox, Internet Explorer, Opera и Safari), а при загрузке в Firefox 1.5 добавится новая функциональность кэширования.

- -

Примечание: по состоянию на октябрь 2009 года разработческие версии Safari добавили поддержку этих новых событий (см. webkit-баг).

- -

Стандартное поведение для Web-страниц следующее:

- -
    -
  1. Пользователь переходит на страницу.
  2. -
  3. По мере загрузки страницы выполняются инлайновые скрипты.
  4. -
  5. Как только страница загрузилась, срабатывает обработчик onload.
  6. -
- -

Некоторые страницы включают четвёртый шаг. Если страница использует обработчик unload или beforeunload handler, он срабатывает прежде чем пользователь уходит со страницы. Если присутствует обработчик unload, эта страница не будет кэширована.

- -

Когда пользователь переходит на кэшированную страницу, инлайновые скрипты и обработчик onload не запускаются (шаги 2 и 3), так как в большинстве случаев эффекты этих скриптов были сохранены.

- -

Если страница содержит скрипты или иное поведение, запускаемое в течение загрузки, которое вы хотите продолжить выполнять каждый раз, когда пользователь заходит на страницу, или если вы хотите знать, когда пользователь заходит на кэшированную страницу, используйте новое событие pageshow.

- -

Если у вас есть поведение, запускаемое, когда пользователь уходит со страницы, но вы хотите воспользоваться новой функциональностью кэширования, и поэтому не хотите использовать обработчик unload, используйте новое событие pagehide.

- -

Событие pageshow

- -

Это событие работает так же, как событие load, но срабатывает каждый раз при загрузке страницы (в то время как событие load в Firefox 1.5 не срабатывает, когда страница загружается из кэша). При первой загрузке страницы событие pageshow срабатывает сразу после события load. Событие pageshow использует булевское свойство persisted, которое выставляется в false при начальной загрузке. Оно выставляется в true, если это не начальная загрузка (то есть когда страница уже кэширована).

- -

Выполняйте любой JavaScript-код, который должен отработать при каждой загрузке страницы, при срабатывании событий pageshow.

- -

Вызывая JavaScript-функции в обработчике события pageshow, вы можете обеспечить их вызов при загрузке страницы в браузерах, отличных от Firefox 1.5, вызывая этот обработчик в обработчике события load, как показано в примере ниже.

- -

Событие pagehide

- -

Если вы хотите определить поведение, которое происходит, когда пользователь уходит со страницы, но не хотите использовать событие unload (что воспрепятствовало бы кэшированию страницы), вы можете использовать новое событие pagehide. Как и pageshow, событие pagehide использует булевское свойство persisted. Оно выставляется в false, если страница не кэширована в браузере, а в true,— если кэширована. Когда это свойство выставлено в false, обработчик unload, если он есть, вызывается сразу после события pagehide.

- -

Firefox 1.5 пытается имитировать события загрузки в том же порядке, в каком они срабатывают при начальной загрузке страницы. Фреймы обрабатываются таким же образом, что и документ верхнего уровня. Если страница содержит фреймы, то при загрузке кэшированной страницы:

- -
    -
  • События pageshow из каждого фрейма срабатывают перед событием pageshow в главном документе.
  • -
  • Когда пользователь уходит с кэшированной страницы, событие pagehide из каждого фрейма срабатывает перед событием pagehide в главном документе.
  • -
  • Для навигации, происходящей внутри отдельного фрейма, события срабатывают только в затронутом фрейме.
  • -
- -

Кэширование страницы несмотря на обработчики unload и beforeunload

- -

Если вы хотите использовать события unload или beforeunload, сохранив кэширование страницы, вы можете просто удалить эти события в обработчике события и восстановить их в обработчике pageshow, если возвращаетесь на эту страницу:

- -
window.addEventListener('pageshow', PageShowHandler, false);
-window.addEventListener('unload', UnloadHandler, false);
-
-function PageShowHandler() {
-	window.addEventListener('unload', UnloadHandler, false);
-}
-
-function UnloadHandler() {
-	window.removeEventListener('unload', UnloadHandler, false);
-}
-
- -

Пример кода

- -

Приведённый ниже пример реализует страницу, которая использует обработчики load и pageshow. Поведение этой страницы следующее:

- -
    -
  • В браузерах, отличных от Firefox 1.5, при каждой загрузке страницы происходит следующее: событие load вызывает функцию onLoad, которая вызывает функцию onPageShow (а также дополнительную функцию).
  • -
- -
    -
  • В Firefox 1.5 при первой загрузке страницы событие load работает так же, как и в других браузерах. Кроме того, срабатывает событие pageshow, и, так как persisted установлено в false, не предпринимается никаких дополнительных действий.
  • -
- -
    -
  • В Firefox 1.5 при загрузке страницы из кэша срабатывает только событие pageshow. Так как persisted установлено в true, вызывается только JavaScript-код в функции onPageShow.
  • -
- -

В этом примере:

- -
    -
  • Страница вычисляет и обображает текущие дату и время каждый раз при загрузке. Это вычисление включает секунды и миллисекунды, так что вы легко можете протестировать функциональность.
  • -
  • Курсор помещается в поле Name при первой загрузке страницы. В Firefox 1.5 при возвращении на страницу курсор остаётся в том поле, где он был, когда пользователь ушёл со страницы. В других браузерах курсор опять помещается в поле Name.
  • -
- -
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
-   "http://www.w3.org/TR/html4/loose.dtd">
-<HTML>
-<head>
-<title>Order query : Firefox 1.5 Example</title>
-<style type="text/css">
-body, p {
-	font-family: Verdana, sans-serif;
-	font-size: 12px;
-   	}
-</style>
-<script type="text/javascript">
-function onLoad() {
-	loadOnlyFirst();
-	onPageShow();
-}
-
-function onPageShow() {
-//вычисление текущего времени
-	var currentTime= new Date();
-	var year=currentTime.getFullYear();
-	var month=currentTime.getMonth()+1;
-	var day=currentTime.getDate();
-	var hour=currentTime.getHours();
-	var min=currentTime.getMinutes();
-	var sec=currentTime.getSeconds();
-	var mil=currentTime.getMilliseconds();
-	var displayTime = (month + "/" + day + "/" + year + " " +
-		hour + ":" + min + ":" + sec + ":" + mil);
-	document.getElementById("timefield").value=displayTime;
-}
-
-function loadOnlyFirst() {
-	document.zipForm.name.focus();
-}
-</script>
-</head>
-<body onload="onLoad();" onpageshow="if (event.persisted) onPageShow();">
-<h2>Order query</h2>
-
-<form name="zipForm" action="http://www.example.com/formresult.html" method="get">
-<label for="timefield">Date and time:</label>
-<input type="text" id="timefield"><br>
-<label for="name">Name:</label>
-<input type="text" id="name"><br>
-<label for="address">Email address:</label>
-<input type="text" id="address"><br>
-<label for="order">Order number:</label>
-<input type="text" id="order"><br>
-<input type="submit" name="submit" value="Submit Query">
-</form>
-</body>
-</html>
-
- -

Напротив, если приведённая выше страница не слушает событие pageshow и выполняет все вычисления в обработчике события load (если код написан так, как показано в примере ниже), как положение курсора, так и дата/время в Firefox 1.5 будут кэшированы, когда пользователь when the user navigated away from the page. When the user returned to the page, the cached date/time would display.

- -
<script>
-function onLoad() {
-	loadOnlyFirst();
-
-//calculate current time
-	var currentTime= new Date();
-	var year = currentTime.getFullYear();
-	var month = currentTime.getMonth()+1;
-	var day = currentTime.getDate();
-	var hour=currentTime.getHours();
-	var min=currentTime.getMinutes();
-	var sec=currentTime.getSeconds();
-	var mil=currentTime.getMilliseconds();
-	var displayTime = (month + "/" + day + "/" + year + " " +
-		hour + ":" + min + ":" + sec + ":" + mil);
-	document.getElementById("timefield").value=displayTime;
-}
-
-function loadOnlyFirst() {
-	document.zipForm.name.focus();
-}
-</script>
-</head>
-
-<body onload="onLoad();">
-
- -

Developing Firefox extensions

- -

Firefox 1.5 extensions need to allow for this caching functionality. If you are developing a Firefox extension that you want to be compatible with both 1.5 and earlier versions, make sure that it listens for the load event for triggers that can be cached and listens for the pageshow event for triggers that shouldn’t be cached.

- -

For instance, the Google Toolbar for Firefox should listen for the load event for the autolink function and to the pageshow event for the PageRank function in order to be compatible with both 1.5 and earlier versions.

- -

{{ languages( { "it": "it/Usare_il_caching_di_Firefox_1.5", "de": "de/Benutzen_des_Zwischenspeichers_in_Firefox_1.5_(caching)", "fr": "fr/Utilisation_du_cache_de_Firefox_1.5", "ja": "ja/Using_Firefox_1.5_caching" } ) }}

diff --git "a/files/ru/web/accessibility/\320\262\320\265\320\261-\321\200\320\260\320\267\321\200\320\260\320\261\320\276\321\202\320\272\320\260/index.html" "b/files/ru/web/accessibility/\320\262\320\265\320\261-\321\200\320\260\320\267\321\200\320\260\320\261\320\276\321\202\320\272\320\260/index.html" deleted file mode 100644 index ce48a75de2..0000000000 --- "a/files/ru/web/accessibility/\320\262\320\265\320\261-\321\200\320\260\320\267\321\200\320\260\320\261\320\276\321\202\320\272\320\260/index.html" +++ /dev/null @@ -1,51 +0,0 @@ ---- -title: Веб-разработка -slug: Web/Accessibility/Веб-разработка -tags: - - ARIA - - Web Development - - XUL - - доступность -translation_of: Web/Accessibility -translation_of_original: Web/Accessibility/Web_Development ---- -

Здесь ссылки на более подробную информацию для разработчиков о доступности (accessibility) в Веб и в XUL.

- - - - - - - - -
-

Доступность в Вебе

- -
-
ARIA для разработчиков
-
ARIA позволяет делать доступным динамический HTML-контент. Examples are live content regions and JavaScript widgets.
-
Keyboard-navigable JavaScript widgets
-
До недавнего времени у веб-разработчиков, желавших сделать свои виджеты на основе <div>, <span> и стилей доступными с клавиатуры, не было the proper techniques. Управляемость с клавиатуры — одно из минимальных требований accessibility, о которых должен знать каждый разработчик.
-
- -

Доступность XUL

- -
-
 
-
Building accessible custom components in XUL
-
How to use DHTML Accessibility techniques to add accessibility to your custom XUL components.
-
Accessible XUL authoring guidelines
-
When authored according to these guidelines, XUL is capable of generating accessible user interfaces. Coders, reviewers, designers and QA engineers should be familiar with these guidelines.
-
-
-

Внешние ресурсы

- -
-
Dive into Accessibility
-
Эта книга отвечает на два вопроса. Первый — «Зачем мне делать мой сайт более доступным?» Второй — «Как мне сделать мой сайт более доступным?»
-
Accessible Web Page Authoring
-
A handy web accessibility checklist, from IBM.
-
-
- -

 

diff --git a/files/ru/web/api/audiocontext/createpanner/index.html b/files/ru/web/api/audiocontext/createpanner/index.html deleted file mode 100644 index 0a4d5db32b..0000000000 --- a/files/ru/web/api/audiocontext/createpanner/index.html +++ /dev/null @@ -1,211 +0,0 @@ ---- -title: AudioContext.createPanner() -slug: Web/API/AudioContext/createPanner -translation_of: Web/API/BaseAudioContext/createPanner ---- -

{{ APIRef("Web Audio API") }}

- -
-

Метод createPanner() интерфейса {{ domxref("AudioContext") }} применяется для создания нового {{domxref("PannerNode")}}, который используется для размещения аудиопотока в виртуальном 3D пространстве.

-
- -

The panner node is spatialized in relation to the AudioContext's {{domxref("AudioListener") }} (defined by the {{domxref("AudioContext.listener") }} attribute), which represents the position and orientation of the person listening to the audio.

- -

Синтаксис

- -
var audioCtx = new AudioContext();
-var panner = audioCtx.createPanner();
- -

Возврат

- -

A {{domxref("PannerNode")}}.

- -

Пример

- -
-
Ниже можно увидеть пример использования {{domxref("AudioListener")}}, {{domxref("PannerNode")}} и метода createPanner() для управления пространством объемного звука. Обычно определяется положение в трехмерном пространстве, изначально занимаемое слушателем (listener) и источником звука (panner), а затем, при использовании приложения, обновляется позиция одного из них или обоих. Например, вы можете перемещать персонажа внутри игрового мира, и желательно чтобы передача звука изменялась реалистично, по мере приближения или отдаления персонажа относительно источника звука, вроде стереопроигрывателя. В этом примере можно видеть, что все это управляется функциями moveRight(), moveLeft(), и т.п., которые устанавливают новые значения для положения паннера через функцию PositionPanner().
- -
 
- -
-
-
Чтобы увидеть полную реализацию ознакомьтесь с нашим примером panner-node (просмотрите весь список примеров) — эта демонстрация перенесет вас в 2.5D "Room of metal" (2,5-мерную "металлическую комнату"), где можно проиграть трек на бумбоксе и затем походить вокруг него и посмотреть как изменяется звук!
- -
 
-
-
-
- -

Note how we have used some feature detection to either give the browser the newer property values (like {{domxref("AudioListener.forwardX")}}) for setting position, etc. if it supports those, or older methods (like {{domxref("AudioListener.setOrientation()")}}) if it still supports those but not the new properties.

- -
// set up listener and panner position information
-// установка сведений о слушателе (listener) и положении panner'а
-var WIDTH = window.innerWidth;
-var HEIGHT = window.innerHeight;
-
-var xPos = Math.floor(WIDTH/2);
-var yPos = Math.floor(HEIGHT/2);
-var zPos = 295;
-
-// define other variables (определяем другие переменные)
-
-var AudioContext = window.AudioContext || window.webkitAudioContext;
-var audioCtx = new AudioContext();
-
-var panner = audioCtx.createPanner();
-panner.panningModel = 'HRTF';
-panner.distanceModel = 'inverse';
-panner.refDistance = 1;
-panner.maxDistance = 10000;
-panner.rolloffFactor = 1;
-panner.coneInnerAngle = 360;
-panner.coneOuterAngle = 0;
-panner.coneOuterGain = 0;
-
-if(panner.orientationX) {
-  panner.orientationX.value = 1;
-  panner.orientationY.value = 0;
-  panner.orientationZ.value = 0;
-} else {
-  panner.setOrientation(1,0,0);
-}
-
-var listener = audioCtx.listener;
-
-if(listener.forwardX) {
-  listener.forwardX.value = 0;
-  listener.forwardY.value = 0;
-  listener.forwardZ.value = -1;
-  listener.upX.value = 0;
-  listener.upY.value = 1;
-  listener.upZ.value = 0;
-} else {
-  listener.setOrientation(0,0,-1,0,1,0);
-}
-
-var source;
-
-var play = document.querySelector('.play');
-var stop = document.querySelector('.stop');
-
-var boomBox = document.querySelector('.boom-box');
-
-var listenerData = document.querySelector('.listener-data');
-var pannerData = document.querySelector('.panner-data');
-
-leftBound = (-xPos) + 50;
-rightBound = xPos - 50;
-
-xIterator = WIDTH/150;
-
-// listener will always be in the same place for this demo
-// в этом демо слушатель всегда находится на одном и том же месте
-
-if(listener.positionX) {
-  listener.positionX.value = xPos;
-  listener.positionY.value = yPos;
-  listener.positionZ.value = 300;
-} else {
-  listener.setPosition(xPos,yPos,300);
-}
-
-listenerData.innerHTML = 'Listener data: X ' + xPos + ' Y ' + yPos + ' Z ' + 300;
-
-// panner will move as the boombox graphic moves around on the screen
-// паннер будет перемещаться по экрану за перемещением бумбокса
-function positionPanner() {
-  if(panner.positionX) {
-    panner.positionX.value = xPos;
-    panner.positionY.value = yPos;
-    panner.positionZ.value = zPos;
-  } else {
-    panner.setPosition(xPos,yPos,zPos);
-  }
-  pannerData.innerHTML = 'Panner data: X ' + xPos + ' Y ' + yPos + ' Z ' + zPos;
-}
- -
-

In terms of working out what position values to apply to the listener and panner, to make the sound appropriate to what the visuals are doing on screen, there is quite a bit of fiddly math involved, but you will soon get used to it with a bit of experimentation.

-
- -

Specifications

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-createPanner-PannerNode', 'createPanner()')}}{{Spec2('Web Audio API')}} 
- -

Browser compatibility

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome(10.0)}}{{property_prefix("webkit")}}{{CompatVersionUnknown}}{{CompatGeckoDesktop(25.0)}} {{CompatNo}}15.0{{property_prefix("webkit")}}
- 22 (unprefixed)
6.0{{property_prefix("webkit")}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidEdgeFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari MobileChrome for Android
Basic support{{CompatUnknown}}{{CompatVersionUnknown}}26.01.2{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}33.0
-
- -

See also

- - diff --git a/files/ru/web/api/audiocontext/currenttime/index.html b/files/ru/web/api/audiocontext/currenttime/index.html deleted file mode 100644 index 51370701f4..0000000000 --- a/files/ru/web/api/audiocontext/currenttime/index.html +++ /dev/null @@ -1,97 +0,0 @@ ---- -title: AudioContext.currentTime -slug: Web/API/AudioContext/currentTime -translation_of: Web/API/BaseAudioContext/currentTime ---- -

{{ APIRef("AudioContext") }}

-
-

Поле currentTime принадлежит {{ domxref("AudioContext") }} и возвращает время с момента создания AudioContext. Может использоваться при планировании воспроизведения или визуализации.  Поле currentTime является не перезаписываемым и не может быть остановлено или сброшено.

-
-

Синтаксис

-
var audioCtx = new AudioContext();
-console.log(audioCtx.currentTime);
-

Тип данных

-

A double.

-

Примеры

-
-

Примечание: для большего понимания реализации Web Audio, посмотрите наши Web Audio Demos на MDN Github repo, like panner-node. Попробуйте ввести audioCtx.currentTime в консоли вашего браузера.

-
-
var AudioContext = window.AudioContext || window.webkitAudioContext;
-var audioCtx = new AudioContext();
-// Older webkit/blink browsers require a prefix
-
-...
-
-console.log(audioCtx.currentTime);
-
-

Specifications

- - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-currentTime', 'currentTime')}}{{Spec2('Web Audio API')}} 
-

Browser compatibility

-
- {{CompatibilityTable}}
-
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome(10.0)}}{{property_prefix("webkit")}}{{CompatGeckoDesktop(25.0)}} {{CompatNo}}15.0{{property_prefix("webkit")}}
- 22 (unprefixed)
6.0{{property_prefix("webkit")}}
-
-
- - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari MobileChrome for Android
Basic support{{CompatUnknown}}26.01.2{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}33.0
-
-

See also

- diff --git a/files/ru/web/api/audiocontext/decodeaudiodata/index.html b/files/ru/web/api/audiocontext/decodeaudiodata/index.html deleted file mode 100644 index faae982eae..0000000000 --- a/files/ru/web/api/audiocontext/decodeaudiodata/index.html +++ /dev/null @@ -1,220 +0,0 @@ ---- -title: AudioContext.decodeAudioData() -slug: Web/API/AudioContext/decodeAudioData -tags: - - API -translation_of: Web/API/BaseAudioContext/decodeAudioData ---- -

{{ APIRef("Web Audio API") }}

- -
-

The decodeAudioData() method of the {{ domxref("AudioContext") }} Interface is used to asynchronously decode audio file data contained in an {{domxref("ArrayBuffer")}}. In this case the ArrayBuffer is usually loaded from an {{domxref("XMLHttpRequest")}}'s response attribute after setting the responseType to arraybuffer. The decoded AudioBuffer is resampled to the AudioContext's sampling rate, then passed to a callback or promise.

-
- -

This is the preferred method of creating an audio source for Web Audio API from an audio track.

- -

Syntax

- -

Older callback syntax:

- -
audioCtx.decodeAudioData(audioData, function(decodedData) {
-  // use the dec​oded data here
-});
- -

Newer promise-based syntax:

- -
audioCtx.decodeAudioData(audioData).then(function(decodedData) {
-  // use the decoded data here
-});
- -

Example

- -

In this section we will first cover the older callback-based system and then the newer promise-based syntax.

- -

Older callback syntax

- -

In this example, the getData() function uses XHR to load an audio track, setting the responseType of the request to arraybuffer so that it returns an array buffer as its response that we then store in the audioData variable . We then pass this buffer into a decodeAudioData() function; the success callback takes the successfully decoded PCM data, puts it into an {{ domxref("AudioBufferSourceNode") }} created using {{ domxref("AudioContext.createBufferSource()") }}, connects the source to the {{domxref("AudioContext.destination") }} and sets it to loop.

- -

The buttons in the example simply run getData() to load the track and start it playing, and stop it playing, respectively. When the stop() method is called on the source, the source is cleared out.

- -
-

Note: You can run the example live (or view the source.)

-
- -
// define variables
-
-var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
-var source;
-
-var pre = document.querySelector('pre');
-var myScript = document.querySelector('script');
-var play = document.querySelector('.play');
-var stop = document.querySelector('.stop');
-
-// use XHR to load an audio track, and
-// decodeAudioData to decode it and stick it in a buffer.
-// Then we put the buffer into the source
-
-function getData() {
-  source = audioCtx.createBufferSource();
-  var request = new XMLHttpRequest();
-
-  request.open('GET', 'viper.ogg', true);
-
-  request.responseType = 'arraybuffer';
-
-
-  request.onload = function() {
-    var audioData = request.response;
-
-    audioCtx.decodeAudioData(audioData, function(buffer) {
-        source.buffer = buffer;
-
-        source.connect(audioCtx.destination);
-        source.loop = true;
-      },
-
-      function(e){"Error with decoding audio data" + e.err});
-
-  }
-
-  request.send();
-}
-
-// wire up buttons to stop and play audio
-
-play.onclick = function() {
-  getData();
-  source.start(0);
-  play.setAttribute('disabled', 'disabled');
-}
-
-stop.onclick = function() {
-  source.stop(0);
-  play.removeAttribute('disabled');
-}
-
-
-// dump script to pre element
-
-pre.innerHTML = myScript.innerHTML;
- -

New promise-based syntax

- -
ctx.decodeAudioData(compressedBuffer).then(function(decodedData) {
- // use the decoded data here
-});
- -

Parameters

- -
-
ArrayBuffer
-
An ArrayBuffer containing the audio data to be decoded, usually grabbed from an {{domxref("XMLHttpRequest")}}'s response attribute after setting the responseType to arraybuffer.
-
DecodeSuccessCallback
-
A callback function to be invoked when the decoding successfully finishes. The single argument to this callback is an AudioBuffer representing the decoded PCM audio data. Usually you'll want to put the decoded data into an {{domxref("AudioBufferSourceNode")}}, from which it can be played and manipulated how you want.
-
DecodeErrorCallback
-
An optional error callback, to be invoked if an error occurs when the audio data is being decoded.
-
- -

Returns

- -

An {{domxref("AudioBuffer") }} representing the decoded PCM audio data.

- -

Specifications

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-decodeAudioData-Promise-AudioBuffer--ArrayBuffer-audioData-DecodeSuccessCallback-successCallback-DecodeErrorCallback-errorCallback', 'decodeAudioData()')}}{{Spec2('Web Audio API')}} 
- -

Browser compatibility

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome(10.0)}}{{property_prefix("webkit")}}{{CompatGeckoDesktop(25.0)}} {{CompatNo}}15.0{{property_prefix("webkit")}}
- 22 (unprefixed)
6.0{{property_prefix("webkit")}}
Promise-based syntax{{CompatChrome(49.0)}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidAndroid WebviewFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari MobileChrome for Android
Basic support{{CompatUnknown}}{{CompatVersionUnknown}}26.01.2{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatChrome(33.0)}}
Promise-based syntax{{CompatUnknown}}{{CompatChrome(49.0)}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatUnknown}}{{CompatUnknown}}{{CompatChrome(49.0)}}
-
- -

See also

- - diff --git a/files/ru/web/api/baseaudiocontext/createpanner/index.html b/files/ru/web/api/baseaudiocontext/createpanner/index.html new file mode 100644 index 0000000000..0a4d5db32b --- /dev/null +++ b/files/ru/web/api/baseaudiocontext/createpanner/index.html @@ -0,0 +1,211 @@ +--- +title: AudioContext.createPanner() +slug: Web/API/AudioContext/createPanner +translation_of: Web/API/BaseAudioContext/createPanner +--- +

{{ APIRef("Web Audio API") }}

+ +
+

Метод createPanner() интерфейса {{ domxref("AudioContext") }} применяется для создания нового {{domxref("PannerNode")}}, который используется для размещения аудиопотока в виртуальном 3D пространстве.

+
+ +

The panner node is spatialized in relation to the AudioContext's {{domxref("AudioListener") }} (defined by the {{domxref("AudioContext.listener") }} attribute), which represents the position and orientation of the person listening to the audio.

+ +

Синтаксис

+ +
var audioCtx = new AudioContext();
+var panner = audioCtx.createPanner();
+ +

Возврат

+ +

A {{domxref("PannerNode")}}.

+ +

Пример

+ +
+
Ниже можно увидеть пример использования {{domxref("AudioListener")}}, {{domxref("PannerNode")}} и метода createPanner() для управления пространством объемного звука. Обычно определяется положение в трехмерном пространстве, изначально занимаемое слушателем (listener) и источником звука (panner), а затем, при использовании приложения, обновляется позиция одного из них или обоих. Например, вы можете перемещать персонажа внутри игрового мира, и желательно чтобы передача звука изменялась реалистично, по мере приближения или отдаления персонажа относительно источника звука, вроде стереопроигрывателя. В этом примере можно видеть, что все это управляется функциями moveRight(), moveLeft(), и т.п., которые устанавливают новые значения для положения паннера через функцию PositionPanner().
+ +
 
+ +
+
+
Чтобы увидеть полную реализацию ознакомьтесь с нашим примером panner-node (просмотрите весь список примеров) — эта демонстрация перенесет вас в 2.5D "Room of metal" (2,5-мерную "металлическую комнату"), где можно проиграть трек на бумбоксе и затем походить вокруг него и посмотреть как изменяется звук!
+ +
 
+
+
+
+ +

Note how we have used some feature detection to either give the browser the newer property values (like {{domxref("AudioListener.forwardX")}}) for setting position, etc. if it supports those, or older methods (like {{domxref("AudioListener.setOrientation()")}}) if it still supports those but not the new properties.

+ +
// set up listener and panner position information
+// установка сведений о слушателе (listener) и положении panner'а
+var WIDTH = window.innerWidth;
+var HEIGHT = window.innerHeight;
+
+var xPos = Math.floor(WIDTH/2);
+var yPos = Math.floor(HEIGHT/2);
+var zPos = 295;
+
+// define other variables (определяем другие переменные)
+
+var AudioContext = window.AudioContext || window.webkitAudioContext;
+var audioCtx = new AudioContext();
+
+var panner = audioCtx.createPanner();
+panner.panningModel = 'HRTF';
+panner.distanceModel = 'inverse';
+panner.refDistance = 1;
+panner.maxDistance = 10000;
+panner.rolloffFactor = 1;
+panner.coneInnerAngle = 360;
+panner.coneOuterAngle = 0;
+panner.coneOuterGain = 0;
+
+if(panner.orientationX) {
+  panner.orientationX.value = 1;
+  panner.orientationY.value = 0;
+  panner.orientationZ.value = 0;
+} else {
+  panner.setOrientation(1,0,0);
+}
+
+var listener = audioCtx.listener;
+
+if(listener.forwardX) {
+  listener.forwardX.value = 0;
+  listener.forwardY.value = 0;
+  listener.forwardZ.value = -1;
+  listener.upX.value = 0;
+  listener.upY.value = 1;
+  listener.upZ.value = 0;
+} else {
+  listener.setOrientation(0,0,-1,0,1,0);
+}
+
+var source;
+
+var play = document.querySelector('.play');
+var stop = document.querySelector('.stop');
+
+var boomBox = document.querySelector('.boom-box');
+
+var listenerData = document.querySelector('.listener-data');
+var pannerData = document.querySelector('.panner-data');
+
+leftBound = (-xPos) + 50;
+rightBound = xPos - 50;
+
+xIterator = WIDTH/150;
+
+// listener will always be in the same place for this demo
+// в этом демо слушатель всегда находится на одном и том же месте
+
+if(listener.positionX) {
+  listener.positionX.value = xPos;
+  listener.positionY.value = yPos;
+  listener.positionZ.value = 300;
+} else {
+  listener.setPosition(xPos,yPos,300);
+}
+
+listenerData.innerHTML = 'Listener data: X ' + xPos + ' Y ' + yPos + ' Z ' + 300;
+
+// panner will move as the boombox graphic moves around on the screen
+// паннер будет перемещаться по экрану за перемещением бумбокса
+function positionPanner() {
+  if(panner.positionX) {
+    panner.positionX.value = xPos;
+    panner.positionY.value = yPos;
+    panner.positionZ.value = zPos;
+  } else {
+    panner.setPosition(xPos,yPos,zPos);
+  }
+  pannerData.innerHTML = 'Panner data: X ' + xPos + ' Y ' + yPos + ' Z ' + zPos;
+}
+ +
+

In terms of working out what position values to apply to the listener and panner, to make the sound appropriate to what the visuals are doing on screen, there is quite a bit of fiddly math involved, but you will soon get used to it with a bit of experimentation.

+
+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-createPanner-PannerNode', 'createPanner()')}}{{Spec2('Web Audio API')}} 
+ +

Browser compatibility

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome(10.0)}}{{property_prefix("webkit")}}{{CompatVersionUnknown}}{{CompatGeckoDesktop(25.0)}} {{CompatNo}}15.0{{property_prefix("webkit")}}
+ 22 (unprefixed)
6.0{{property_prefix("webkit")}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidEdgeFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari MobileChrome for Android
Basic support{{CompatUnknown}}{{CompatVersionUnknown}}26.01.2{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}33.0
+
+ +

See also

+ + diff --git a/files/ru/web/api/baseaudiocontext/currenttime/index.html b/files/ru/web/api/baseaudiocontext/currenttime/index.html new file mode 100644 index 0000000000..51370701f4 --- /dev/null +++ b/files/ru/web/api/baseaudiocontext/currenttime/index.html @@ -0,0 +1,97 @@ +--- +title: AudioContext.currentTime +slug: Web/API/AudioContext/currentTime +translation_of: Web/API/BaseAudioContext/currentTime +--- +

{{ APIRef("AudioContext") }}

+
+

Поле currentTime принадлежит {{ domxref("AudioContext") }} и возвращает время с момента создания AudioContext. Может использоваться при планировании воспроизведения или визуализации.  Поле currentTime является не перезаписываемым и не может быть остановлено или сброшено.

+
+

Синтаксис

+
var audioCtx = new AudioContext();
+console.log(audioCtx.currentTime);
+

Тип данных

+

A double.

+

Примеры

+
+

Примечание: для большего понимания реализации Web Audio, посмотрите наши Web Audio Demos на MDN Github repo, like panner-node. Попробуйте ввести audioCtx.currentTime в консоли вашего браузера.

+
+
var AudioContext = window.AudioContext || window.webkitAudioContext;
+var audioCtx = new AudioContext();
+// Older webkit/blink browsers require a prefix
+
+...
+
+console.log(audioCtx.currentTime);
+
+

Specifications

+ + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-currentTime', 'currentTime')}}{{Spec2('Web Audio API')}} 
+

Browser compatibility

+
+ {{CompatibilityTable}}
+
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome(10.0)}}{{property_prefix("webkit")}}{{CompatGeckoDesktop(25.0)}} {{CompatNo}}15.0{{property_prefix("webkit")}}
+ 22 (unprefixed)
6.0{{property_prefix("webkit")}}
+
+
+ + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari MobileChrome for Android
Basic support{{CompatUnknown}}26.01.2{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}33.0
+
+

See also

+ diff --git a/files/ru/web/api/baseaudiocontext/decodeaudiodata/index.html b/files/ru/web/api/baseaudiocontext/decodeaudiodata/index.html new file mode 100644 index 0000000000..faae982eae --- /dev/null +++ b/files/ru/web/api/baseaudiocontext/decodeaudiodata/index.html @@ -0,0 +1,220 @@ +--- +title: AudioContext.decodeAudioData() +slug: Web/API/AudioContext/decodeAudioData +tags: + - API +translation_of: Web/API/BaseAudioContext/decodeAudioData +--- +

{{ APIRef("Web Audio API") }}

+ +
+

The decodeAudioData() method of the {{ domxref("AudioContext") }} Interface is used to asynchronously decode audio file data contained in an {{domxref("ArrayBuffer")}}. In this case the ArrayBuffer is usually loaded from an {{domxref("XMLHttpRequest")}}'s response attribute after setting the responseType to arraybuffer. The decoded AudioBuffer is resampled to the AudioContext's sampling rate, then passed to a callback or promise.

+
+ +

This is the preferred method of creating an audio source for Web Audio API from an audio track.

+ +

Syntax

+ +

Older callback syntax:

+ +
audioCtx.decodeAudioData(audioData, function(decodedData) {
+  // use the dec​oded data here
+});
+ +

Newer promise-based syntax:

+ +
audioCtx.decodeAudioData(audioData).then(function(decodedData) {
+  // use the decoded data here
+});
+ +

Example

+ +

In this section we will first cover the older callback-based system and then the newer promise-based syntax.

+ +

Older callback syntax

+ +

In this example, the getData() function uses XHR to load an audio track, setting the responseType of the request to arraybuffer so that it returns an array buffer as its response that we then store in the audioData variable . We then pass this buffer into a decodeAudioData() function; the success callback takes the successfully decoded PCM data, puts it into an {{ domxref("AudioBufferSourceNode") }} created using {{ domxref("AudioContext.createBufferSource()") }}, connects the source to the {{domxref("AudioContext.destination") }} and sets it to loop.

+ +

The buttons in the example simply run getData() to load the track and start it playing, and stop it playing, respectively. When the stop() method is called on the source, the source is cleared out.

+ +
+

Note: You can run the example live (or view the source.)

+
+ +
// define variables
+
+var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
+var source;
+
+var pre = document.querySelector('pre');
+var myScript = document.querySelector('script');
+var play = document.querySelector('.play');
+var stop = document.querySelector('.stop');
+
+// use XHR to load an audio track, and
+// decodeAudioData to decode it and stick it in a buffer.
+// Then we put the buffer into the source
+
+function getData() {
+  source = audioCtx.createBufferSource();
+  var request = new XMLHttpRequest();
+
+  request.open('GET', 'viper.ogg', true);
+
+  request.responseType = 'arraybuffer';
+
+
+  request.onload = function() {
+    var audioData = request.response;
+
+    audioCtx.decodeAudioData(audioData, function(buffer) {
+        source.buffer = buffer;
+
+        source.connect(audioCtx.destination);
+        source.loop = true;
+      },
+
+      function(e){"Error with decoding audio data" + e.err});
+
+  }
+
+  request.send();
+}
+
+// wire up buttons to stop and play audio
+
+play.onclick = function() {
+  getData();
+  source.start(0);
+  play.setAttribute('disabled', 'disabled');
+}
+
+stop.onclick = function() {
+  source.stop(0);
+  play.removeAttribute('disabled');
+}
+
+
+// dump script to pre element
+
+pre.innerHTML = myScript.innerHTML;
+ +

New promise-based syntax

+ +
ctx.decodeAudioData(compressedBuffer).then(function(decodedData) {
+ // use the decoded data here
+});
+ +

Parameters

+ +
+
ArrayBuffer
+
An ArrayBuffer containing the audio data to be decoded, usually grabbed from an {{domxref("XMLHttpRequest")}}'s response attribute after setting the responseType to arraybuffer.
+
DecodeSuccessCallback
+
A callback function to be invoked when the decoding successfully finishes. The single argument to this callback is an AudioBuffer representing the decoded PCM audio data. Usually you'll want to put the decoded data into an {{domxref("AudioBufferSourceNode")}}, from which it can be played and manipulated how you want.
+
DecodeErrorCallback
+
An optional error callback, to be invoked if an error occurs when the audio data is being decoded.
+
+ +

Returns

+ +

An {{domxref("AudioBuffer") }} representing the decoded PCM audio data.

+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-decodeAudioData-Promise-AudioBuffer--ArrayBuffer-audioData-DecodeSuccessCallback-successCallback-DecodeErrorCallback-errorCallback', 'decodeAudioData()')}}{{Spec2('Web Audio API')}} 
+ +

Browser compatibility

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome(10.0)}}{{property_prefix("webkit")}}{{CompatGeckoDesktop(25.0)}} {{CompatNo}}15.0{{property_prefix("webkit")}}
+ 22 (unprefixed)
6.0{{property_prefix("webkit")}}
Promise-based syntax{{CompatChrome(49.0)}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidAndroid WebviewFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari MobileChrome for Android
Basic support{{CompatUnknown}}{{CompatVersionUnknown}}26.01.2{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatChrome(33.0)}}
Promise-based syntax{{CompatUnknown}}{{CompatChrome(49.0)}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatUnknown}}{{CompatUnknown}}{{CompatChrome(49.0)}}
+
+ +

See also

+ + diff --git a/files/ru/web/api/canvas_api/tutorial/applying_styles_and_colors/index.html b/files/ru/web/api/canvas_api/tutorial/applying_styles_and_colors/index.html new file mode 100644 index 0000000000..2c9eeaae78 --- /dev/null +++ b/files/ru/web/api/canvas_api/tutorial/applying_styles_and_colors/index.html @@ -0,0 +1,726 @@ +--- +title: Применение стилей и цветов +slug: Web/API/Canvas_API/Tutorial/Применение_стилей_и_цветов +translation_of: Web/API/Canvas_API/Tutorial/Applying_styles_and_colors +--- +
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_shapes", "Web/API/Canvas_API/Tutorial/Drawing_text")}}
+ +
+

В главе о рисовании фигур, мы использовали для линий и заполнения только стили по умолчанию. Здесь мы будем исследовать опции canvas, которые мы имеем в нашем распоряжении, чтобы сделать наши рисунки немного более привлекательными. Вы узнаете, как добавлять различные цвета, стили линий, градиенты, узоры и тени вашим рисункам.

+
+ +

Цвета

+ +

До сих пор мы видели только методы рисования контекста. Если мы хотим применить цвета к фигуре, то есть два важных свойства, которые мы можем использовать: fillStyle и strokeStyle.

+ +
+
{{domxref("CanvasRenderingContext2D.fillStyle", "fillStyle = color")}}
+
Устанавливает стиль для фона фигур.
+
{{domxref("CanvasRenderingContext2D.strokeStyle", "strokeStyle = color")}}
+
Устанавливает стиль контура фигуры. 
+
+ +

color может быть цветом, (строка, представленная в CSS {{cssxref("<color>")}}), градиентом или паттерном. Градиенты и паттерны мы рассмотрим позже. По умолчанию цвет фона и контура  — черный (значение CSS цвета  #000000).

+ +
+

На заметку: Когда вы устанавливаете  значения strokeStyle и/или fillStyle, то новое значение становится стандартным для всех фигур, которые будут нарисованы с этого момента. Когда вам нужен другой цвет, вы должны перезаписать значение в fillStyle или в strokeStyle для каждой фигуры.

+
+ +

Чтобы строка color считалась валидной, она должна соответствовать CSS {{cssxref("<color>")}}. Далее приведены примеры того, как можно по-разному задать один и тот же цвет. 

+ +
// these all set the fillStyle to 'orange'
+
+ctx.fillStyle = "orange";
+ctx.fillStyle = "#FFA500";
+ctx.fillStyle = "rgb(255,165,0)";
+ctx.fillStyle = "rgba(255,165,0,1)";
+
+ +

Пример fillStyle

+ +

В этом примере мы опять воспользуемся двойным циклом, чтобы нарисовать сетку из прямоугольников, каждый из которых имеет свой цвет. Окончательное изображение должно иметь вид, как показано на скриншоте. Здесь не происходит ничего сверхъестественного. Мы используем две переменные i и j для генерации уникального RGB цвета для каждого квадрата и изменяем только красные и зеленые значения. Синий канал представляет собой фиксированное значение. Путем изменения каналов вы можете генерировать всю палитру. Увеличив количество шагов вы можете достигнуть такого вида палитры, какая используется в Photoshop.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  for (var i=0;i<6;i++){
+    for (var j=0;j<6;j++){
+      ctx.fillStyle = 'rgb(' + Math.floor(255-42.5*i) + ',' +
+                       Math.floor(255-42.5*j) + ',0)';
+      ctx.fillRect(j*25,i*25,25,25);
+    }
+  }
+}
+ + + +

Результат выглядит так:

+ +

{{EmbedLiveSample("Пример_fillStyle", 160, 160, "https://mdn.mozillademos.org/files/5417/Canvas_fillstyle.png")}}

+ +

Пример strokeStyle

+ +

Этот пример похож на предыдущий, но мы используем свойство strokeStyle чтобы изменить цвета очертаний фигур. Так же мы используем метод arc() для рисования окружностей вместо квадратов.

+ +
  function draw() {
+    var ctx = document.getElementById('canvas').getContext('2d');
+    for (var i=0;i<6;i++){
+      for (var j=0;j<6;j++){
+        ctx.strokeStyle = 'rgb(0,' + Math.floor(255-42.5*i) + ',' +
+                         Math.floor(255-42.5*j) + ')';
+        ctx.beginPath();
+        ctx.arc(12.5+j*25,12.5+i*25,10,0,Math.PI*2,true);
+        ctx.stroke();
+      }
+    }
+  }
+
+ + + +

Результат выглядит так:

+ +

{{EmbedLiveSample("Пример_strokeStyle", "180", "180", "https://mdn.mozillademos.org/files/253/Canvas_strokestyle.png")}}

+ +

Прозрачность

+ +

В дополнении к рисованию непрозрачных фигур, мы также можем рисовать прозрачные (полупрозрачные) фигуры.  Это делается через установку свойства globalAlpha или задачи полупрозрачного цвета фона или контура.

+ +
+
{{domxref("CanvasRenderingContext2D.globalAlpha", "globalAlpha = transparencyValue")}}
+
Для применения, указывается значения прозрачности для всех будущих фигур, что будут нарисованы на canvas. Значение полупрозрачности могут быть между 0.0 (полная прозрачность) и 1.0 (полная непрозрачность). Значение 1.0 (полная непрозрачность) установлено по умолчанию.
+
+ +

Свойство globalAlpha может быть использовано, если вы хотите рисовать формы с одинаковой прозрачностью, но в иной ситуации, обычно устанавливают прозрачность индивидуально к каждой форме, когда указывают их цвет.

+ +

Так как свойства strokeStyle и fillStyle принимают цветовые значения rgba через CSS, мы можем использовать следующее обозначение  для назначения прозрачных цветов.

+ +
// Assigning transparent colors to stroke and fill style
+
+ctx.strokeStyle = "rgba(255,0,0,0.5)";
+ctx.fillStyle = "rgba(255,0,0,0.5)";
+
+ +

Функция rgba() похожа на функцию rgb(), но имеет один дополнительный параметр. Последний параметр устанавливает значение прозрачности для конкретного цвета. Действующий диапозон значений находится между 0.0 (полная прозрачность) и 1.0 (полная непрозрачность).

+ +

Пример globalAlpha

+ +

В данном примере мы нарисуем фон и четыре квадрата с различными цветами.  Сверху изображения будет выведен набор полупрозрачных кругов. Установим свойство globalAlpha значением 0.2, которое будет использовано для всех последующих форм. Каждый шаг цикла рисует круг с большим радиусом. По окончанию получим радиальный градиент. Накладывая еще больше кругов друг на друга, мы фактически сможем уменьшить прозрачность ранее нарисованных кругов. Увеличив счетчик итераций, при этом рисуя еще круги, мы сможем добиться исчезновение центра изображения.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  // фон изображения
+  ctx.fillStyle = '#FD0';
+  ctx.fillRect(0,0,75,75);
+  ctx.fillStyle = '#6C0';
+  ctx.fillRect(75,0,75,75);
+  ctx.fillStyle = '#09F';
+  ctx.fillRect(0,75,75,75);
+  ctx.fillStyle = '#F30';
+  ctx.fillRect(75,75,75,75);
+  ctx.fillStyle = '#FFF';
+
+  // устанавливаем значение прозрачности
+  ctx.globalAlpha = 0.2;
+
+  // Рисуем полупрозрачные круги
+  for (i=0;i<7;i++){
+    ctx.beginPath();
+    ctx.arc(75,75,10+10*i,0,Math.PI*2,true);
+    ctx.fill();
+  }
+}
+ + + +

{{EmbedLiveSample("Пример_globalAlpha", "180", "180", "https://mdn.mozillademos.org/files/232/Canvas_globalalpha.png")}}

+ +

Пример использования rgba()

+ +

В этом втором примере мы делаем что-то похожее на предыдущее, но вместо рисования кругов друг над другом, я рисовал маленькие прямоугольники с увеличением непрозрачности. Использование rgba() добавляет контроля и гибкости, поскольку мы можем индивидуально настраивать стиль заливки и штриха.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+
+  // Нарисовать фон
+  ctx.fillStyle = 'rgb(255,221,0)';
+  ctx.fillRect(0,0,150,37.5);
+  ctx.fillStyle = 'rgb(102,204,0)';
+  ctx.fillRect(0,37.5,150,37.5);
+  ctx.fillStyle = 'rgb(0,153,255)';
+  ctx.fillRect(0,75,150,37.5);
+  ctx.fillStyle = 'rgb(255,51,0)';
+  ctx.fillRect(0,112.5,150,37.5);
+
+  // Нарисовать полупрозрачные прямоугольники
+  for (var i=0;i<10;i++){
+    ctx.fillStyle = 'rgba(255,255,255,'+(i+1)/10+')';
+    for (var j=0;j<4;j++){
+      ctx.fillRect(5+i*14,5+j*37.5,14,27.5);
+    }
+  }
+}
+ + + +

{{EmbedLiveSample("Пример_использования_rgba()", "180", "180", "https://mdn.mozillademos.org/files/246/Canvas_rgba.png")}}

+ +

Стили линий

+ +

Есть несколько свойств, которые позволяют нам стилизовать линии.

+ +
+
{{domxref("CanvasRenderingContext2D.lineWidth", "lineWidth = value")}}
+
Устанавливает ширину линий, рисуемых в будущем.
+
{{domxref("CanvasRenderingContext2D.lineCap", "lineCap = type")}}
+
Устанавливает внешний вид концов линий.
+
{{domxref("CanvasRenderingContext2D.lineJoin", "lineJoin = type")}}
+
Устанавливает внешний вид «углов», где встречаются линии.
+
{{domxref("CanvasRenderingContext2D.miterLimit", "miterLimit = value")}}
+
Устанавливает ограничение на митру, когда две линии соединяются под острым углом, чтобы вы могли контролировать её толщину.
+
{{domxref("CanvasRenderingContext2D.getLineDash", "getLineDash()")}}
+
Возвращает текущий массив тире штриховки, содержащий четное число неотрицательных чисел.
+
{{domxref("CanvasRenderingContext2D.setLineDash", "setLineDash(segments)")}}
+
Устанавливает текущий пунктир линии.
+
{{domxref("CanvasRenderingContext2D.lineDashOffset", "lineDashOffset = value")}}
+
Указывает, где следует начинать тире массива в строке.
+
+ +

Вы лучше поймете, что они делают, глядя на приведенные ниже примеры.

+ +

Пример lineWidth

+ +

Это свойство задает толщину текущей строки. Значения должны быть положительными. По умолчанию для этого значения установлено 1.0 единицы.

+ +

Ширина линии - это толщина хода, центрированного по данному пути. Другими словами, область, которая нарисована, простирается до половины ширины линии по обе стороны пути. Поскольку координаты холста не напрямую ссылаются на пиксели, особое внимание следует уделять получению четких горизонтальных и вертикальных линий.

+ +

В приведенном ниже примере 10 прямых линий рисуются с увеличением ширины линий. Линия в крайнем левом углу - 1.0 единицы. Тем не менее, толщина левой и всех других линий нечетной ширины не выглядят четкими из-за позиционирования пути.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  for (var i = 0; i < 10; i++){
+    ctx.lineWidth = 1+i;
+    ctx.beginPath();
+    ctx.moveTo(5+i*14,5);
+    ctx.lineTo(5+i*14,140);
+    ctx.stroke();
+  }
+}
+
+ + + +

{{EmbedLiveSample("Пример_lineWidth", "180", "180", "https://mdn.mozillademos.org/files/239/Canvas_linewidth.png")}}

+ +

Получение четких строк требует понимания путей сглаживания. На рисунках ниже представлена сетка координат холста. Квадраты между сетками являются фактическими экранными пикселями. В первом изображении сетки ниже прямоугольник от (2, 1) до (5, 5) заполняется. Вся область между ними (светло-красный) падает на границы пикселей, поэтому полученный заполненный прямоугольник будет иметь четкие края.

+ +

+ +

Если вы рассмотрите путь от (3, 1) до (3, 5) с толщиной строки 1.0, вы получите ситуацию во втором изображении. Фактическая заполняемая область, (синяя), распространяется только наполовину в пикселях по обе стороны пути. Приблизительно это означает, что частично затенённые пиксели приводят к заполнению всей области (светло-голубой и синей) цветом, только наполовину темным, чем фактический цвет штриха. Это то, что происходит с линией шириной 1.0 в предыдущем примере кода.

+ +

Чтобы исправить это, вы должны быть более точными при создании пути. Зная, что линия шириной 1.0 занимает половину единицы по обе стороны пути, создание пути от (3.5, 1) до (3.5, 5) приведёт к ситуации в третьем изображении - ширина линии 1.0 закончится верно, точно заполняя вертикальную линию с одним пикселем.

+ +
+

Примечание: Имейте в виду, что в нашем примере с вертикальной линией позиция Y по-прежнему ссылается на целочисленную позицию сетки - иначе мы увидели бы пиксели с половинным охватом в конечных точках (также обратите внимание, что это поведение зависит от текущего стиля lineCap,  значение по умолчанию - butt; вы можете вычислить согласованные штрихи с полупиксельными координатами для линий с нечетной шириной, установив стиль lineCap в square, чтобы внешняя граница вокруг конечной точки линии автоматически расширялась, охватывая весь пиксель в точку).

+ +

Также обратите внимание, что затронуты только начальные и конечные  точки пути: если путь закрыт с помощью closePath(), - нет начальной и конечной точки; вместо этого все конечные точки в пути подключены к их прикрепленному предыдущему и следующему сегментам и при текущей настройке стиля lineJoin в значении по умолчанию - miter, с эффектом автоматического расширения внешних границ подключенных сегментов до их точки пересечения - обработанный ход будет точно покрывать полные пиксели с центром в каждой конечной точке, если эти связанные сегменты горизонтальны и/или вертикальны). См. следующие два раздела, демонстрирующие эти дополнительные стили.

+
+ +

Для линий с четной шириной каждая половина заканчивается как целое количество пикселей, поэтому вам нужен путь, который находится между пикселями (то есть (3,1) - (3,5)), вместо середины пикселей.

+ +

Хотя это и необычно, когда изначально работаешь с масштабируемой 2D-графикой, обращая внимание на сетку пикселей и положение путей, но вы убедитесь, что ваши рисунки будут выглядеть правильно, независимо от масштабирования или любых других преобразований. Вертикальная линия ширины 1,0, построенная таким образом, станет четкой 2-пиксельной линией при увеличении на 2 и появится в правильном положении.

+ +

Пример lineCap

+ +

Свойство lineCap определяет, как выводятся конечные точки каждой строки. Для этого свойства есть три возможных значения: butt, round и square. По умолчанию для этого свойства установлено значение butt.

+ +

+ +
+
butt
+
Концы линий соответствуют крайним точкам.
+
round
+
Концы линий округлены.
+
square
+
Концы линий описаны квадратом с равной шириной и половиной высоты толщины линии.
+
+ +

В этом примере мы проведем три строки, каждая из которых имеет другое значение для свойства lineCap. Я также добавил два руководства, чтобы увидеть точные различия между ними. Каждая из этих линий начинается и заканчивается именно на этих направляющих.

+ +

Строка слева использует butt опцию по умолчанию. Вы заметите, что она полностью очищена от направляющих. Второй вариант -  round опция. Это добавляет полукруг к концу, который имеет радиус, равный половине ширины линии. Строка справа использует square опцию. Это добавляет поле с равной шириной и половиной высоты толщины линии.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  var lineCap = ['butt','round','square'];
+
+  // Draw guides
+  ctx.strokeStyle = '#09f';
+  ctx.beginPath();
+  ctx.moveTo(10,10);
+  ctx.lineTo(140,10);
+  ctx.moveTo(10,140);
+  ctx.lineTo(140,140);
+  ctx.stroke();
+
+  // Draw lines
+  ctx.strokeStyle = 'black';
+  for (var i=0;i<lineCap.length;i++){
+    ctx.lineWidth = 15;
+    ctx.lineCap = lineCap[i];
+    ctx.beginPath();
+    ctx.moveTo(25+i*50,10);
+    ctx.lineTo(25+i*50,140);
+    ctx.stroke();
+  }
+}
+
+ + + +

{{EmbedLiveSample("Пример_lineCap", "180", "180", "https://mdn.mozillademos.org/files/236/Canvas_linecap.png")}}

+ +

Пример lineJoin

+ +

Свойство lineJoin определяет, как соединяются два сегмента (линий, дуг или кривых) с ненулевой длиной в форме (вырожденные сегменты с нулевой длиной, заданные конечные точки и контрольные точки находятся точно в том же положении - пропущены).

+ +

Для этого свойства есть три возможных значения: round, bevel и miter. По умолчанию для этого свойства установлено значение miter. Обратите внимание, что настройка lineJoin не действует, если два связанных сегмента имеют одно и то же направление, потому что в этом случае не будет добавлена ​​область соединения.

+ +

+ +
+
round
+
Радиус заполняемой части для скругленных углов равен половине ширины линии. центр этого радиуса совпадает с концами подключенных сегментов.
+
bevel
+
Заполняет дополнительную треугольную область между общей конечной точкой подключенных сегментов и отдельными внешними прямоугольными углами каждого сегмента. 
+
miter
+
Подключенные сегменты соединяются путем расширения их внешних краев для соединения в одной точке с эффектом заполнения дополнительной области в форме пастилки. Эта настройка выполняется с помощью свойства miterLimit, которое объясняется ниже.
+
+ +

В приведенном ниже примере показаны три разных пути, демонстрирующие каждый из этих трех свойств lineJoin; результат - выше. 

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  var lineJoin = ['round','bevel','miter'];
+  ctx.lineWidth = 10;
+  for (var i=0;i<lineJoin.length;i++){
+    ctx.lineJoin = lineJoin[i];
+    ctx.beginPath();
+    ctx.moveTo(-5,5+i*40);
+    ctx.lineTo(35,45+i*40);
+    ctx.lineTo(75,5+i*40);
+    ctx.lineTo(115,45+i*40);
+    ctx.lineTo(155,5+i*40);
+    ctx.stroke();
+  }
+}
+
+ + + +

{{EmbedLiveSample("Пример_lineJoin", "180", "180", "https://mdn.mozillademos.org/files/237/Canvas_linejoin.png")}}

+ +

Демонстрация свойства miterLimit

+ +

Как вы видели в предыдущем примере, при объединении двух строк с опцией miter внешние края двух соединительных линий расширены до точки, где они встречаются. Для линий, которые находятся под большими углами друг с другом, эта точка находится недалеко от внутренней точки соединения. Однако, поскольку углы между каждой линией уменьшаются, расстояние (длина меча) между этими точками увеличивается экспоненциально.

+ +

Свойство miterLimit определяет, как далеко можно установить внешнюю точку соединения из внутренней точки подключения. Если две линии превышают это значение, вместо этого получается привязка конуса. Обратите внимание, что максимальная длина митра является произведением ширины линии, измеренной в текущей системе координат, значением этого свойства miterLimit (значение по умолчанию 10,0 в HTML {{HTMLElement("canvas")}}), поэтому miterLimit может устанавливаться независимо от текущей шкалы дисплея или любых аффинных преобразований путей: она влияет только на эффективно визуализированную форму ребер линии.

+ +

Точнее, предел митры является максимально допустимым отношением длины расширения (в холсте HTML он измеряется между внешним углом соединенных краев линии и общей конечной точкой соединительных сегментов, указанными на пути), до половины ширины линии. Его можно равнозначно определить как максимально допустимое отношение расстояния между внутренней и внешней точками перехода краев к общей ширине линии. Затем он равен косекансу с половиной минимального внутреннего угла соединительных сегментов, ниже которого не будет создано ни одного соединения митра, а только скос соединяется:

+ +
    +
  • miterLimit = max miterLength / lineWidth = 1 / sin ( min θ / 2 )
  • +
  • Предел митры по умолчанию, равный 10,0, разделит все митры углов, острее примерно 11 градусов.
  • +
  • Предел митры, равный √2 ≈ 1.4142136 (rounded up) сгладит миты для всех острых углов, поддерживая митры только для тупых или прямых углов.
  • +
  • Предел митры, равный 1,0, действителен, но отключит все миты.
  • +
  • Значения ниже 1.0 являются недопустимыми для предела митры.
  • +
+ +

Вот небольшая демонстрация, в которой вы можете динамически установить miterLimit и посмотреть, как это влияет на фигуры на холсте. Синие линии показывают, где начальная и конечная точки для каждой из линий в шаблоне зигзага.

+ +

Если вы укажете в этой демонстрации значение miterLimit ниже 4.2, ни один из видимых углов не присоединится к расширению митры, но только с небольшим скосом рядом с синими линиями; с отметкой miterLimit выше 10, большинство углов в этой демонстрации должны соединяться с митрой, удаленной от синих линий, высота которой уменьшается между углами слева направо, потому что они соединяются с растущими углами; с промежуточными значениями углы с левой стороны будут соединяться только с скосом рядом с синими линиями, а углы с правой стороны с удлинителем митры (также с уменьшающейся высотой).

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+
+  // Clear canvas
+  ctx.clearRect(0,0,150,150);
+
+  // Draw guides
+  ctx.strokeStyle = '#09f';
+  ctx.lineWidth   = 2;
+  ctx.strokeRect(-5,50,160,50);
+
+  // Set line styles
+  ctx.strokeStyle = '#000';
+  ctx.lineWidth = 10;
+
+  // check input
+  if (document.getElementById('miterLimit').value.match(/\d+(\.\d+)?/)) {
+    ctx.miterLimit = parseFloat(document.getElementById('miterLimit').value);
+  } else {
+    alert('Value must be a positive number');
+  }
+
+  // Draw lines
+  ctx.beginPath();
+  ctx.moveTo(0,100);
+  for (i=0;i<24;i++){
+    var dy = i%2==0 ? 25 : -25 ;
+    ctx.lineTo(Math.pow(i,1.5)*2,75+dy);
+  }
+  ctx.stroke();
+  return false;
+}
+
+ + + +

{{EmbedLiveSample("Демонстрация_свойства_miterLimit", "400", "180", "https://mdn.mozillademos.org/files/240/Canvas_miterlimit.png")}}

+ +

Использование штрихов

+ +

Метод setLineDash и свойство lineDashOffset задают шаблон штрихов для линий. Метод setLineDash принимает список чисел, который определяет расстояния для попеременного рисования линии и разрыва, а свойство lineDashOffset устанавливает смещение, с которого начинается шаблон.

+ +

В этом примере мы создаем эффект походных муравьев. Это техника анимации, часто встречающаяся в инструментах выбора программ компьютерной графики. Это помогает пользователю отличить границу выделения от фона изображения, анимируя границу. В следующей части этого руководства вы узнаете, как сделать эту и другие основные анимации.

+ + + +
var ctx = document.getElementById('canvas').getContext('2d');
+var offset = 0;
+
+function draw() {
+  ctx.clearRect(0,0, canvas.width, canvas.height);
+  ctx.setLineDash([4, 2]);
+  ctx.lineDashOffset = -offset;
+  ctx.strokeRect(10,10, 100, 100);
+}
+
+function march() {
+  offset++;
+  if (offset > 16) {
+    offset = 0;
+  }
+  draw();
+  setTimeout(march, 20);
+}
+
+march();
+ +

{{EmbedLiveSample("Используемый штрих", "120", "120", "https://mdn.mozillademos.org/files/9853/marching-ants.png")}}

+ +

Градиенты

+ +

Just like any normal drawing program, we can fill and stroke shapes using linear and radial gradients. We create a {{domxref("CanvasGradient")}} object by using one of the following methods. We can then assign this object to the fillStyle or strokeStyle properties.

+ +
+
{{domxref("CanvasRenderingContext2D.createLinearGradient", "createLinearGradient(x1, y1, x2, y2)")}}
+
Creates a linear gradient object with a starting point of (x1, y1) and an end point of (x2, y2).
+
{{domxref("CanvasRenderingContext2D.createRadialGradient", "createRadialGradient(x1, y1, r1, x2, y2, r2)")}}
+
Creates a radial gradient. The parameters represent two circles, one with its center at (x1, y1) and a radius of r1, and the other with its center at (x2, y2) with a radius of r2.
+
+ +

For example:

+ +
var lineargradient = ctx.createLinearGradient(0, 0, 150, 150);
+var radialgradient = ctx.createRadialGradient(75, 75, 0, 75, 75, 100);
+
+ +

Once we've created a CanvasGradient object we can assign colors to it by using the addColorStop() method.

+ +
+
{{domxref("CanvasGradient.addColorStop", "gradient.addColorStop(position, color)")}}
+
Creates a new color stop on the gradient object. The position is a number between 0.0 and 1.0 and defines the relative position of the color in the gradient, and the color argument must be a string representing a CSS {{cssxref("<color>")}}, indicating the color the gradient should reach at that offset into the transition.
+
+ +

You can add as many color stops to a gradient as you need. Below is a very simple linear gradient from white to black.

+ +
var lineargradient = ctx.createLinearGradient(0,0,150,150);
+lineargradient.addColorStop(0, 'white');
+lineargradient.addColorStop(1, 'black');
+
+ +

Пример createLinearGradient

+ +

In this example, we'll create two different gradients. As you can see here, both the strokeStyle and fillStyle properties can accept a canvasGradient object as valid input.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+
+  // Create gradients
+  var lingrad = ctx.createLinearGradient(0,0,0,150);
+  lingrad.addColorStop(0, '#00ABEB');
+  lingrad.addColorStop(0.5, '#fff');
+  lingrad.addColorStop(0.5, '#26C000');
+  lingrad.addColorStop(1, '#fff');
+
+  var lingrad2 = ctx.createLinearGradient(0,50,0,95);
+  lingrad2.addColorStop(0.5, '#000');
+  lingrad2.addColorStop(1, 'rgba(0,0,0,0)');
+
+  // assign gradients to fill and stroke styles
+  ctx.fillStyle = lingrad;
+  ctx.strokeStyle = lingrad2;
+
+  // draw shapes
+  ctx.fillRect(10,10,130,130);
+  ctx.strokeRect(50,50,50,50);
+
+}
+
+ + + +

The first is a background gradient. As you can see, we assigned two colors at the same position. You do this to make very sharp color transitions—in this case from white to green. Normally, it doesn't matter in what order you define the color stops, but in this special case, it does significantly. If you keep the assignments in the order you want them to appear, this won't be a problem.

+ +

In the second gradient, we didn't assign the starting color (at position 0.0) since it wasn't strictly necessary, because it will automatically assume the color of the next color stop. Therefore, assigning the black color at position 0.5 automatically makes the gradient, from the start to this stop, black.

+ +

{{EmbedLiveSample("Пример_createLinearGradient", "180", "180", "https://mdn.mozillademos.org/files/235/Canvas_lineargradient.png")}}

+ +

Пример createRadialGradient

+ +

In this example, we'll define four different radial gradients. Because we have control over the start and closing points of the gradient, we can achieve more complex effects than we would normally have in the "classic" radial gradients we see in, for instance, Photoshop (that is, a gradient with a single center point where the gradient expands outward in a circular shape).

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+
+  // Create gradients
+  var radgrad = ctx.createRadialGradient(45,45,10,52,50,30);
+  radgrad.addColorStop(0, '#A7D30C');
+  radgrad.addColorStop(0.9, '#019F62');
+  radgrad.addColorStop(1, 'rgba(1,159,98,0)');
+
+  var radgrad2 = ctx.createRadialGradient(105,105,20,112,120,50);
+  radgrad2.addColorStop(0, '#FF5F98');
+  radgrad2.addColorStop(0.75, '#FF0188');
+  radgrad2.addColorStop(1, 'rgba(255,1,136,0)');
+
+  var radgrad3 = ctx.createRadialGradient(95,15,15,102,20,40);
+  radgrad3.addColorStop(0, '#00C9FF');
+  radgrad3.addColorStop(0.8, '#00B5E2');
+  radgrad3.addColorStop(1, 'rgba(0,201,255,0)');
+
+  var radgrad4 = ctx.createRadialGradient(0,150,50,0,140,90);
+  radgrad4.addColorStop(0, '#F4F201');
+  radgrad4.addColorStop(0.8, '#E4C700');
+  radgrad4.addColorStop(1, 'rgba(228,199,0,0)');
+
+  // draw shapes
+  ctx.fillStyle = radgrad4;
+  ctx.fillRect(0,0,150,150);
+  ctx.fillStyle = radgrad3;
+  ctx.fillRect(0,0,150,150);
+  ctx.fillStyle = radgrad2;
+  ctx.fillRect(0,0,150,150);
+  ctx.fillStyle = radgrad;
+  ctx.fillRect(0,0,150,150);
+}
+
+ + + +

In this case, we've offset the starting point slightly from the end point to achieve a spherical 3D effect. It's best to try to avoid letting the inside and outside circles overlap because this results in strange effects which are hard to predict.

+ +

The last color stop in each of the four gradients uses a fully transparent color. If you want to have a nice transition from this to the previous color stop, both colors should be equal. This isn't very obvious from the code because it uses two different CSS color methods as a demonstration, but in the first gradient #019F62 = rgba(1,159,98,1).

+ +

{{EmbedLiveSample("Пример_createRadialGradient", "180", "180", "https://mdn.mozillademos.org/files/244/Canvas_radialgradient.png")}}

+ +

Шаблоны

+ +

В одном из предыдущих примеров мы использовали несколько циклов, чтобы создать шаблон из повторяющихся изображений. Однако, есть более простой способ сделать подобное - метод createPattern().

+ +
+
{{domxref("CanvasRenderingContext2D.createPattern", "createPattern(image, type)")}}
+
Создает и возвращает новый canvas объект - шаблон (pattern). image - {{domxref("CanvasImageSource")}} (то есть {{domxref ("HTMLImageElement")}}, другой холст, элемент {{HTMLElement ("video")}} или подобный  объект. type - строка, указывающая, как использовать image.
+
+ +

Тип указывает, как использовать image для создания шаблона и должен быть одним из следующих значений:

+ +
+
repeat
+
Повторяет изображение в вертикальном и горизонтальном направлениях.
+
repeat-x
+
Повторяет изображение по горизонтали, но не по вертикали.
+
repeat-y
+
Повторяет изображение по вертикали, но не по горизонтали.
+
no-repeat
+
Не повторяет изображение. Используется только один раз.
+
+ +

Мы используем этот метод, чтобы создать {{domxref("CanvasPattern")}} объект, который очень похож на методы градиента, рассмотренные ранее. Как только мы создали шаблон, мы можем назначить ему свойства fillStyle или strokeStyle. Например:

+ +
var img = new Image();
+img.src = 'someimage.png';
+var ptrn = ctx.createPattern(img,'repeat');
+
+ +
+

Примечание: По аналогии с методом drawImage(), вы должны убедиться, что изображение, которое вы используете, загружено до вызова этого метода. Иначе шаблон может быть отрисован некорректно.

+
+ +

Пример createPattern

+ +

In this last example, we'll create a pattern to assign to the fillStyle property. The only thing worth noting is the use of the image's onload handler. This is to make sure the image is loaded before it is assigned to the pattern.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+
+  // create new image object to use as pattern
+  var img = new Image();
+  img.src = 'https://mdn.mozillademos.org/files/222/Canvas_createpattern.png';
+  img.onload = function(){
+
+    // create pattern
+    var ptrn = ctx.createPattern(img,'repeat');
+    ctx.fillStyle = ptrn;
+    ctx.fillRect(0,0,150,150);
+
+  }
+}
+
+ + + +

{{EmbedLiveSample("Пример_createPattern", "180", "180", "https://mdn.mozillademos.org/files/222/Canvas_createpattern.png")}}

+ +

Тени

+ +

Using shadows involves just four properties:

+ +
+
{{domxref("CanvasRenderingContext2D.shadowOffsetX", "shadowOffsetX = float")}}
+
Indicates the horizontal distance the shadow should extend from the object. This value isn't affected by the transformation matrix. The default is 0.
+
{{domxref("CanvasRenderingContext2D.shadowOffsetY", "shadowOffsetY = float")}}
+
Indicates the vertical distance the shadow should extend from the object. This value isn't affected by the transformation matrix. The default is 0.
+
{{domxref("CanvasRenderingContext2D.shadowBlur", "shadowBlur = float")}}
+
Indicates the size of the blurring effect; this value doesn't correspond to a number of pixels and is not affected by the current transformation matrix. The default value is 0.
+
{{domxref("CanvasRenderingContext2D.shadowColor", "shadowColor = color")}}
+
A standard CSS color value indicating the color of the shadow effect; by default, it is fully-transparent black.
+
+ +

The properties shadowOffsetX and shadowOffsetY indicate how far the shadow should extend from the object in the X and Y directions; these values aren't affected by the current transformation matrix. Use negative values to cause the shadow to extend up or to the left, and positive values to cause the shadow to extend down or to the right. These are both 0 by default.

+ +

The shadowBlur property indicates the size of the blurring effect; this value doesn't correspond to a number of pixels and is not affected by the current transformation matrix. The default value is 0.

+ +

The shadowColor property is a standard CSS color value indicating the color of the shadow effect; by default, it is fully-transparent black.

+ +
+

Note: Shadows are only drawn for source-over compositing operations.

+
+ +

Пример текста с тенью

+ +

This example draws a text string with a shadowing effect.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+
+  ctx.shadowOffsetX = 2;
+  ctx.shadowOffsetY = 2;
+  ctx.shadowBlur = 2;
+  ctx.shadowColor = "rgba(0, 0, 0, 0.5)";
+
+  ctx.font = "20px Times New Roman";
+  ctx.fillStyle = "Black";
+  ctx.fillText("Sample String", 5, 30);
+}
+
+ + + +

{{EmbedLiveSample("Пример_текста_с_тенью", "180", "100", "https://mdn.mozillademos.org/files/2505/shadowed-string.png")}}

+ +

We will look at the font property and fillText method in the next chapter about drawing text.

+ +

Canvas fill rules

+ +

When using fill (or {{domxref("CanvasRenderingContext2D.clip", "clip")}} and {{domxref("CanvasRenderingContext2D.isPointInPath", "isPointinPath")}}) you can optionally provide a fill rule algorithm by which to determine if a point is inside or outside a path and thus if it gets filled or not. This is useful when a path intersetcs itself or is nested.
+
+ Two values are possible:

+ + + +

In this example we are using the evenodd rule.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  ctx.beginPath();
+  ctx.arc(50, 50, 30, 0, Math.PI*2, true);
+  ctx.arc(50, 50, 15, 0, Math.PI*2, true);
+  ctx.fill("evenodd");
+}
+ + + +

{{EmbedLiveSample("Canvas_fill_rules", "110", "110", "https://mdn.mozillademos.org/files/9855/fill-rule.png")}}

+ +

{{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_shapes", "Web/API/Canvas_API/Tutorial/Drawing_text")}}

diff --git a/files/ru/web/api/canvas_api/tutorial/basic_animations/index.html b/files/ru/web/api/canvas_api/tutorial/basic_animations/index.html new file mode 100644 index 0000000000..a47b8b734e --- /dev/null +++ b/files/ru/web/api/canvas_api/tutorial/basic_animations/index.html @@ -0,0 +1,308 @@ +--- +title: Простые анимации +slug: Web/API/Canvas_API/Tutorial/Основы_анимации +tags: + - HTML + - HTML5 + - Графика + - Обучение + - Средний уровень + - Холст +translation_of: Web/API/Canvas_API/Tutorial/Basic_animations +--- +
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Compositing", "Web/API/Canvas_API/Tutorial/Advanced_animations")}}
+ +
+

Поскольку для управления элементами {{HTMLElement ("canvas")}} используется JavaScript, не составляет труда сделать (интерактивные) анимации. В этой главе мы рассмотрим, как делаются некоторые базовые анимации.

+
+ +

Вероятно, самым большим ограничением является то, что когда фигура нарисована, её уже нельзя двигать. Чтобы изобразить движение нам нужно перерисовать фигуру и всё, что было нарисовано до неё. Перерисовка сложных кадров занимает много времени, и производительность сильно зависит от скорости компьютера, на котором она выполняется.

+ +

Основные шаги анимации

+ +

Ниже перечислены необходимые шаги для того, чтобы нарисовать кадр:

+ +
    +
  1. Очистить canvas
    + Если фигура, которую вы собираетесь нарисовать, не занимает всю площадь canvas (как фон, например), то всё что было нарисовано ранее необходимо стереть. Проще всего это сделать при помощи метода {{domxref("CanvasRenderingContext2D.clearRect", "clearRect()")}}.
  2. +
  3. Сохранить изначальное состояние canvas
    + Если вы изменяете любые настройки (такие как стили, трансформации и т.п.), которые затрагивают состояние canvas и вы хотите убедиться, что оригинальное состояние используется каждый раз, когда был отрисован кадр, то вам следует сохранить это оригинальное состояние.
  4. +
  5. Нарисовать анимированные фигуры
    + Шаг на котором вы собственно отрисовываете кадр.
  6. +
  7. Восстановить состояние canvas
    + Если вы сохраняли состояние, восстановите его, прежде чем отрисовывать новый кадр.
  8. +
+ +

Управление анимацией

+ +

Фигуры отрисовываются на canvas либо напрямую — при помощи методов canvas, либо с помощью сторонних функций. В нормальной ситуации результат станет виден на canvas после окончания выполнения скрипта. К примеру, цикл for использовать для анимации нельзя. 

+ +

Это значит, нужен способ выполнения функций отрисовки через интервалы времени. Есть два способа для управления такой анимацией.

+ +

Запланированные обновления

+ +

Первый — это функции {{domxref("window.setInterval()")}}, {{domxref("window.setTimeout()")}}, и {{domxref("window.requestAnimationFrame()")}}, которые могут быть использованы для вызова некоторой функции, через заданный промежуток времени.

+ +
+
{{domxref("WindowTimers.setInterval", "setInterval(function, delay)")}}
+
Начинает периодически исполнять функцию function каждые delay миллисекунд.
+
{{domxref("WindowTimers.setTimeout", "setTimeout(function, delay)")}}
+
Запускает выполнение указанной функции function через delay миллисекунд.
+
{{domxref("Window.requestAnimationFrame()", "requestAnimationFrame(callback)")}}
+
Сообщает браузеру, что вы хотите выполнить анимацию, и запрашивает, чтобы браузер вызвал указанную функцию callback для обновления анимации перед следующей перерисовкой.
+
+ +

Если вы не планируете никакого взаимодействия с пользователем, вы можете использовать функцию setInterval() , которая многократно выполняет, предоставленный ей код. Если же вы планиуете создать игру, в которой контроль анимации осуществляется мышью или клавиатурой, то необходимо использовать  setTimeout(). Установив {{domxref("EventListener")}}, вы можете перехватываете любые действия пользователя и запустить соответствующие функции анимации.

+ +
+

В примерах ниже мы будем использовать функцию {{domxref("window.requestAnimationFrame()")}} для контроля анимации. Функция requestAnimationFrame является более эффективной для создания анимации, так как новая итерация вызывается, когда система готова к отрисовке нового кадра. Количество вызовов в секунду примерно равно 60 и уменьшается, когда вкладка неактивна. Для более подробного изучения цикла анимации, особенно для игр, прочитайте статью Анатомия видеоигр В Зоне разработке игр.

+
+ +

Анимированная солнечная система

+ +

В этом примере анимируется небольшая модель солнечной системы.

+ +
var sun = new Image();
+var moon = new Image();
+var earth = new Image();
+function init(){
+  sun.src = 'https://mdn.mozillademos.org/files/1456/Canvas_sun.png';
+  moon.src = 'https://mdn.mozillademos.org/files/1443/Canvas_moon.png';
+  earth.src = 'https://mdn.mozillademos.org/files/1429/Canvas_earth.png';
+  window.requestAnimationFrame(draw);
+}
+
+function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+
+  ctx.globalCompositeOperation = 'destination-over';
+  ctx.clearRect(0,0,300,300); // clear canvas
+
+  ctx.fillStyle = 'rgba(0,0,0,0.4)';
+  ctx.strokeStyle = 'rgba(0,153,255,0.4)';
+  ctx.save();
+  ctx.translate(150,150);
+
+  // Earth
+  var time = new Date();
+  ctx.rotate( ((2*Math.PI)/60)*time.getSeconds() + ((2*Math.PI)/60000)*time.getMilliseconds() );
+  ctx.translate(105,0);
+  ctx.fillRect(0,-12,50,24); // Shadow
+  ctx.drawImage(earth,-12,-12);
+
+  // Moon
+  ctx.save();
+  ctx.rotate( ((2*Math.PI)/6)*time.getSeconds() + ((2*Math.PI)/6000)*time.getMilliseconds() );
+  ctx.translate(0,28.5);
+  ctx.drawImage(moon,-3.5,-3.5);
+  ctx.restore();
+
+  ctx.restore();
+
+  ctx.beginPath();
+  ctx.arc(150,150,105,0,Math.PI*2,false); // Earth orbit
+  ctx.stroke();
+
+  ctx.drawImage(sun,0,0,300,300);
+
+  window.requestAnimationFrame(draw);
+}
+
+init();
+
+ + + +

{{EmbedLiveSample("An_animated_solar_system", "310", "310", "https://mdn.mozillademos.org/files/202/Canvas_animation1.png")}}

+ +

Анимированные часы

+ +

В этом примере создаются анимированные часы, показывающие правильное время.

+ +
function clock(){
+  var now = new Date();
+  var ctx = document.getElementById('canvas').getContext('2d');
+  ctx.save();
+  ctx.clearRect(0,0,150,150);
+  ctx.translate(75,75);
+  ctx.scale(0.4,0.4);
+  ctx.rotate(-Math.PI/2);
+  ctx.strokeStyle = "black";
+  ctx.fillStyle = "white";
+  ctx.lineWidth = 8;
+  ctx.lineCap = "round";
+
+  // Hour marks
+  ctx.save();
+  for (var i=0;i<12;i++){
+    ctx.beginPath();
+    ctx.rotate(Math.PI/6);
+    ctx.moveTo(100,0);
+    ctx.lineTo(120,0);
+    ctx.stroke();
+  }
+  ctx.restore();
+
+  // Minute marks
+  ctx.save();
+  ctx.lineWidth = 5;
+  for (i=0;i<60;i++){
+    if (i%5!=0) {
+      ctx.beginPath();
+      ctx.moveTo(117,0);
+      ctx.lineTo(120,0);
+      ctx.stroke();
+    }
+    ctx.rotate(Math.PI/30);
+  }
+  ctx.restore();
+
+  var sec = now.getSeconds();
+  var min = now.getMinutes();
+  var hr  = now.getHours();
+  hr = hr>=12 ? hr-12 : hr;
+
+  ctx.fillStyle = "black";
+
+  // write Hours
+  ctx.save();
+  ctx.rotate( hr*(Math.PI/6) + (Math.PI/360)*min + (Math.PI/21600)*sec )
+  ctx.lineWidth = 14;
+  ctx.beginPath();
+  ctx.moveTo(-20,0);
+  ctx.lineTo(80,0);
+  ctx.stroke();
+  ctx.restore();
+
+  // write Minutes
+  ctx.save();
+  ctx.rotate( (Math.PI/30)*min + (Math.PI/1800)*sec )
+  ctx.lineWidth = 10;
+  ctx.beginPath();
+  ctx.moveTo(-28,0);
+  ctx.lineTo(112,0);
+  ctx.stroke();
+  ctx.restore();
+
+  // Write seconds
+  ctx.save();
+  ctx.rotate(sec * Math.PI/30);
+  ctx.strokeStyle = "#D40000";
+  ctx.fillStyle = "#D40000";
+  ctx.lineWidth = 6;
+  ctx.beginPath();
+  ctx.moveTo(-30,0);
+  ctx.lineTo(83,0);
+  ctx.stroke();
+  ctx.beginPath();
+  ctx.arc(0,0,10,0,Math.PI*2,true);
+  ctx.fill();
+  ctx.beginPath();
+  ctx.arc(95,0,10,0,Math.PI*2,true);
+  ctx.stroke();
+  ctx.fillStyle = "rgba(0,0,0,0)";
+  ctx.arc(0,0,3,0,Math.PI*2,true);
+  ctx.fill();
+  ctx.restore();
+
+  ctx.beginPath();
+  ctx.lineWidth = 14;
+  ctx.strokeStyle = '#325FA2';
+  ctx.arc(0,0,142,0,Math.PI*2,true);
+  ctx.stroke();
+
+  ctx.restore();
+
+  window.requestAnimationFrame(clock);
+}
+
+window.requestAnimationFrame(clock);
+ + + +

{{EmbedLiveSample("An_animated_clock", "180", "180", "https://mdn.mozillademos.org/files/203/Canvas_animation2.png")}}

+ +

Зацикленная панорама

+ +

В этом примере панорама прокручивается слева направо. Мы используем фото национального парка Йосемити взятое из Википедии, но вы можете использовать любое изображение, большее элемента canvas.

+ +
var img = new Image();
+
+// User Variables - customize these to change the image being scrolled, its
+// direction, and the speed.
+
+img.src = 'https://mdn.mozillademos.org/files/4553/Capitan_Meadows,_Yosemite_National_Park.jpg';
+var CanvasXSize = 800;
+var CanvasYSize = 200;
+var speed = 30; //lower is faster
+var scale = 1.05;
+var y = -4.5; //vertical offset
+
+// Main program
+
+var dx = 0.75;
+var imgW;
+var imgH;
+var x = 0;
+var clearX;
+var clearY;
+var ctx;
+
+img.onload = function() {
+    imgW = img.width*scale;
+    imgH = img.height*scale;
+    if (imgW > CanvasXSize) { x = CanvasXSize-imgW; } // image larger than canvas
+    if (imgW > CanvasXSize) { clearX = imgW; } // image larger than canvas
+    else { clearX = CanvasXSize; }
+    if (imgH > CanvasYSize) { clearY = imgH; } // image larger than canvas
+    else { clearY = CanvasYSize; }
+    //Get Canvas Element
+    ctx = document.getElementById('canvas').getContext('2d');
+    //Set Refresh Rate
+    return setInterval(draw, speed);
+}
+
+function draw() {
+    //Clear Canvas
+    ctx.clearRect(0,0,clearX,clearY);
+    //If image is <= Canvas Size
+    if (imgW <= CanvasXSize) {
+        //reset, start from beginning
+        if (x > (CanvasXSize)) { x = 0; }
+        //draw aditional image
+        if (x > (CanvasXSize-imgW)) { ctx.drawImage(img,x-CanvasXSize+1,y,imgW,imgH); }
+    }
+    //If image is > Canvas Size
+    else {
+        //reset, start from beginning
+        if (x > (CanvasXSize)) { x = CanvasXSize-imgW; }
+        //draw aditional image
+        if (x > (CanvasXSize-imgW)) { ctx.drawImage(img,x-imgW+1,y,imgW,imgH); }
+    }
+    //draw image
+    ctx.drawImage(img,x,y,imgW,imgH);
+    //amount to move
+    x += dx;
+}
+
+ +

Заметьте, что ширина и высота должны совпадать  со значениями CanvasXZSize и CanvasYSize.

+ +
<canvas id="canvas" width="800" height="200"></canvas>
+ +

{{EmbedLiveSample("A_looping_panorama", "830", "230")}}

+ +

Другие примеры

+ +
+
A basic ray-caster
+
Хороший пример того, как сделать управляемую анимацию с клавиатуры.
+
Advanced animations
+
Мы рассмотрим некоторые продвинутые методы анимации и физику в следующей главе.
+
+ +

{{PreviousNext("Web/API/Canvas_API/Tutorial/Compositing", "Web/API/Canvas_API/Tutorial/Advanced_animations")}}

diff --git a/files/ru/web/api/canvas_api/tutorial/compositing/index.html b/files/ru/web/api/canvas_api/tutorial/compositing/index.html new file mode 100644 index 0000000000..264cc7e544 --- /dev/null +++ b/files/ru/web/api/canvas_api/tutorial/compositing/index.html @@ -0,0 +1,108 @@ +--- +title: Композиция и обрезка +slug: Web/API/Canvas_API/Tutorial/Композиции +tags: + - канвас +translation_of: Web/API/Canvas_API/Tutorial/Compositing +--- +
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Transformations", "Web/API/Canvas_API/Tutorial/Basic_animations")}}
+ +
+

Во всех наших предыдущих примерах, фигуры всегда были нарисованы одна поверх другой. Это более чем достаточно для большинства ситуаций, но это ограничивает порядок, в котором построены композиционные формы. Однако, мы можем изменить это поведение, установив свойство globalCompositeOperation. Кроме того, свойства clip позволяет скрыть нежелательные части формы.

+
+ +

globalCompositeOperation

+ +

Мы можем не только рисовать новые фигуры за существующие формы, но мы также можем использовать его, чтобы замаскировать определенные участки, очистить разделы от холста (не ограничивается прямоугольниками, как{{domxref("CanvasRenderingContext2D.clearRect", "clearRect()")}} method does) и другое.

+ +
+
{{domxref("CanvasRenderingContext2D.globalCompositeOperation", "globalCompositeOperation = type")}}
+
Это задает Тип операции композиции для применения при разработке новых форм, где Тип является строкой, идентифицирующей, какие из двенадцати операций композитинг в использовании.
+
+ +

См.  примеры компоновки кода из следующих примеров.

+ +

{{EmbedLiveSample("Compositing_example", 750, 6750, "" ,"Web/API/Canvas_API/Tutorial/Compositing/Example")}}

+ +

Обрезка контуров

+ +

Отсеченный контур похож на обычную форму холста, но он действует как маска, чтобы скрыть нежелательные части фигур. Это визуализируется на изображении справа. Форма красной звезды - наша отправочная дорожка. Все, что выходит за пределы этого пути, не будет нарисовано на холсте.

+ +

Если мы сравниваем отсеченный контур со свойством globalCompositeOperation на изображении, мы видим два режима композитинга, которые достигают более или менее того же эффекта в исходном и исходном состоянии.   Наиболее важные различия между ними заключаются в том, что отсечение контура фактически  никогда не обращается к холсту и контур обрезки никогда не влияет добавление новых форм. Это делает обрезку контура идеальным для рисования нескольких фигур в ограниченной области.

+ +

В главе о рисовании форм, я назвал только stroke() и fill() методы, но есть третий способ можно использовать с контурами, так называемый clip().

+ +
+
{{domxref("CanvasRenderingContext2D.clip", "clip()")}}
+
Преобразует текущий выстраиваемый контур в отсечённый контур.
+
+ +

Используйте clip() вместо closePath() для закрытия контура и его преобразования в отсечённый контур вместо создания заполняющего  или обрамляющего контура.

+ +

По умолчанию элемент {{HTMLElement("canvas")}} использует отсечённый контур, который в точности совпадает по размеру с размером самого холста. Это означает, что никакого отсечения попросту не произойдёт.

+ +

Пример обрезки

+ +

В этом примере мы будем использовать круговую обрезку контура, чтобы ограничить рисование набора случайных звезд определенной областью.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  ctx.fillRect(0, 0, 150, 150);
+  ctx.translate(75, 75);
+
+  // Create a circular clipping path
+  ctx.beginPath();
+  ctx.arc(0, 0, 60, 0, Math.PI * 2, true);
+  ctx.clip();
+
+  // draw background
+  var lingrad = ctx.createLinearGradient(0, -75, 0, 75);
+  lingrad.addColorStop(0, '#232256');
+  lingrad.addColorStop(1, '#143778');
+
+  ctx.fillStyle = lingrad;
+  ctx.fillRect(-75, -75, 150, 150);
+
+  // draw stars
+  for (var j = 1; j < 50; j++) {
+    ctx.save();
+    ctx.fillStyle = '#fff';
+    ctx.translate(75 - Math.floor(Math.random() * 150),
+                  75 - Math.floor(Math.random() * 150));
+    drawStar(ctx, Math.floor(Math.random() * 4) + 2);
+    ctx.restore();
+  }
+
+}
+
+function drawStar(ctx, r) {
+  ctx.save();
+  ctx.beginPath();
+  ctx.moveTo(r, 0);
+  for (var i = 0; i < 9; i++) {
+    ctx.rotate(Math.PI / 5);
+    if (i % 2 === 0) {
+      ctx.lineTo((r / 0.525731) * 0.200811, 0);
+    } else {
+      ctx.lineTo(r, 0);
+    }
+  }
+  ctx.closePath();
+  ctx.fill();
+  ctx.restore();
+}
+
+ + + +

В первых нескольких строках кода мы рисуем черный прямоугольник размером с холстом в качестве фона, а затем переводим начало координат в центр. Затем мы создаем круговой обтравочный контур, рисуя дугу и вызывающий clip(). Обрезанные контуры также являются частью состояния сохранения холста. Если бы мы хотели сохранить исходный обтравочный контур, мы могли бы сохранить состояние холста перед созданием нового.

+ +

Все, что нарисовано после создания отсеченного контура, появится только внутри этого пути. Вы можете видеть это четко в линейном градиенте, который нарисован далее. После этого набирается набор из 50 случайно расположенных и масштабированных звезд, используя drawStar(). Снова звезды появляются только в пределах определенного обтравочного контура.

+ +

{{EmbedLiveSample("A_clip_example", "180", "180", "https://mdn.mozillademos.org/files/208/Canvas_clip.png")}}

+ +

{{PreviousNext("Web/API/Canvas_API/Tutorial/Transformations", "Web/API/Canvas_API/Tutorial/Basic_animations")}}

diff --git a/files/ru/web/api/canvas_api/tutorial/drawing_shapes/index.html b/files/ru/web/api/canvas_api/tutorial/drawing_shapes/index.html new file mode 100644 index 0000000000..f6ca6c23ef --- /dev/null +++ b/files/ru/web/api/canvas_api/tutorial/drawing_shapes/index.html @@ -0,0 +1,582 @@ +--- +title: Рисование фигур с помощью canvas +slug: Web/API/Canvas_API/Tutorial/Рисование_фигур +translation_of: Web/API/Canvas_API/Tutorial/Drawing_shapes +--- +
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_usage", "Web/API/Canvas_API/Tutorial/Applying_styles_and_colors")}}
+ +
+

Теперь, установив наше окружение canvas, мы можем погрузиться в детали того, как рисовать в canvas. К концу этой статьи, Вы научитесь рисовать прямоугольники, треугольники, линии, дуги и кривые, при условии что Вы хорошо знакомы с основными геометрическими фигурами. Работа с путями весьма важна, когда рисуете объекты на canvas и мы увидим как это может быть сделано.

+
+ +

Сетка

+ +

Перед тем, как мы начнем рисовать, нам нужно поговорить о сетке canvas или координатной плоскости. Наш HTML каркас из предыдущей страницы включал в себя элемент canvas 150 пикселей в ширину и 150 пикселей в высоту. Справа можно увидеть этот canvas с сеткой, накладываемой по умолчанию. Обычно 1 единица на сетке соответствует 1 пикселю на canvas. Начало координат этой сетки расположено в верхнем левом углу в координате (0,0 ). Все элементы размещены относительно этого начала. Таким образом, положение верхнего левого угла синего квадрата составляет х пикселей слева и у пикселей сверху, на координате , у). Позже в этом уроке мы увидим, как можно перевести начало координат в другое место, вращать сетку и даже масштабировать ее, но сейчас мы будем придерживаться настроек сетки по умолчанию.

+ +

Рисование прямоугольников

+ +

В отличие от {{Glossary("SVG")}}, {{HTMLElement("canvas")}} поддерживает только одну примитивную фигуру: прямоугольник. Все другие фигуры должны быть созданы комбинацией одного или большего количества контуров (paths), набором точек, соединенных в линии. К счастью в ассортименте рисования контуров у нас есть  функции, которые делают возможным составление очень сложных фигур.

+ +

Сначала рассмотрим прямоугольник. Ниже представлены три функции рисования прямоугольников в canvas:

+ +
+
{{domxref("CanvasRenderingContext2D.fillRect", "fillRect(x, y, width, height)")}}
+
Рисование заполненного прямоугольника.
+
{{domxref("CanvasRenderingContext2D.strokeRect", "strokeRect(x, y, width, height)")}}
+
Рисование прямоугольного контура.
+
{{domxref("CanvasRenderingContext2D.clearRect", "clearRect(x, y, width, height)")}}
+
Очистка  прямоугольной области, делая содержимое совершенно прозрачным.
+
+ +

Каждая из приведенных функций принимает несколько параметров: 

+ +
    +
  • xy устанавливают положение верхнего левого угла прямоугольника в canvas (относительно начала координат);
  • +
  • width(ширина) и height(высота) определяют размеры прямоугольника.
  • +
+ +

Ниже приведена функция draw(), использующая эти три функции.

+ +

Пример создания прямоугольных фигур

+ + + +
function draw() {
+  var canvas = document.getElementById('canvas');
+  if (canvas.getContext) {
+    var ctx = canvas.getContext('2d');
+
+    ctx.fillRect(25,25,100,100);
+    ctx.clearRect(45,45,60,60);
+    ctx.strokeRect(50,50,50,50);
+  }
+}
+ +

Этот пример изображен ниже.

+ +

{{EmbedLiveSample("Пример_создания_прямоугольных_фигур", 160, 160, "https://mdn.mozillademos.org/files/245/Canvas_rect.png")}}

+ +

Функция fillRect() рисует большой чёрный квадрат со стороной 100 px. Функция clearRect() вырезает квадрат 60х60 из центра, а функция strokeRect() создает прямоугольный контур 50х50 пикселей внутри очищенного квадрата.

+ +

На следующей странице мы рассмотрим две альтернативы методу clearRect(), и также увидим, как можно изменять цвет и стиль контура отображаемых фигур.

+ +

В отличие от функций создания контуров, которые будут рассмотрены в следующем разделе, все три функции создания прямоугольника сразу же отображаются на canvas.

+ +

Рисование контуров (path)

+ +

Остальные примитивные фигуры создаются контурами. Контур - это набор точек, которые, соединяясь в отрезки линий, могут образовывать различные фигуры, изогнутые или нет, разной ширины и разного цвета. Контур (или субконтур) может быть закрытым.

+ +

Создание фигур используя контуры происходит в несколько важных шагов:

+ +
    +
  1. Сначала вы создаете контур.
  2. +
  3. Затем, используя команды рисования, рисуете контур.
  4. +
  5. Потом закрываете контур.
  6. +
  7. Созданный контур вы можете обвести или залить для его отображения.
  8. +
+ +

Здесь приведены функции, которые можно использовать в описанных шагах:

+ +
+
{{domxref("CanvasRenderingContext2D.beginPath", "beginPath()")}}
+
Создает новый контур. После создания используется в дальнейшем командами рисования при построении контуров.
+
Path методы
+
Методы для установки различных контуров объекта.
+
{{domxref("CanvasRenderingContext2D.closePath", "closePath()")}}
+
Закрывает контур, так что будущие команды рисования вновь направлены контекст.
+
{{domxref("CanvasRenderingContext2D.stroke", "stroke()")}}
+
Рисует фигуру с внешней обводкой.
+
{{domxref("CanvasRenderingContext2D.fill", "fill()")}}
+
Рисует фигуру с заливкой внутренней области.
+
+ +

Первый шаг создания контура заключается в вызове функции beginPath(). Внутри содержатся контуры в виде набора суб-контуров (линии, дуги и др.), которые вместе образуют форму фигуры. Каждый вызов этого метода очищает набор, и мы можем начинать рисовать новые фигуры.

+ +
Note:  если текущий контур пуст (например, как после вызова beginPath() или на вновь созданном canvas), первой командой построения контура всегда является функция  moveTo(). Поэтому мы всегда можем установить начальную позицию рисования контура после перезагрузки.
+ +

Вторым шагом является вызов методов, определяемых видом контура, который нужно нарисовать. Их мы рассмотрим позднее.

+ +

Третий и необязательный шаг - это вызов closePath(). Этот метод пытается закрыть фигуру, рисуя прямую линию из текущей точки в начальную. Если фигура была уже закрыта или является просто точкой, то функция ничего не делает.

+ +
Note: Когда вы вызываете fill(), то каждая открытая фигура закрывается автоматически, так что вы можете не использовать closePath(). Это обстоятельство не имеет место в случае вызова stroke().
+ +

Рисование треугольника

+ +

Например, код для рисования треугольника будет выглядеть как-то так:

+ + + +
function draw() {
+  var canvas = document.getElementById('canvas');
+  if (canvas.getContext){
+    var ctx = canvas.getContext('2d');
+
+    ctx.beginPath();
+    ctx.moveTo(75,50);
+    ctx.lineTo(100,75);
+    ctx.lineTo(100,25);
+    ctx.fill();
+  }
+}
+
+ +

Результат выглядит так:

+ +

{{EmbedLiveSample("Рисование_треугольника", 110, 110, "https://mdn.mozillademos.org/files/9847/triangle.png")}}

+ +

Передвижение пера

+ +

Одна очень полезная функция, которая ничего не рисует, но связана по смыслу с вышеописанными функциями  - это moveTo(). Вы можете представить это как отрыв (подъем) пера от бумаги и его перемещение в другое место.

+ +
+
{{domxref("CanvasRenderingContext2D.moveTo", "moveTo(x, y)")}}
+
Перемещает перо в точку с координатами x и y.
+
+ +

При инициализации canvas или при вызове beginPath(), вы захотите использовать функцию moveTo() для перемещения в точку начала рисования. Можно использовать moveTo() и для рисования несвязанного(незакрытого) контура. Посмотрите на смайлик ниже.

+ +

Вы можете проверить это сами, используя участок кода ниже. Просто вставьте в функцию draw(), рассмотренную ранее.

+ + + +
function draw() {
+  var canvas = document.getElementById('canvas');
+  if (canvas.getContext){
+     var ctx = canvas.getContext('2d');
+
+    ctx.beginPath();
+    ctx.arc(75,75,50,0,Math.PI*2,true); // Внешняя окружность
+    ctx.moveTo(110,75);
+    ctx.arc(75,75,35,0,Math.PI,false);  // рот (по часовой стрелке)
+    ctx.moveTo(65,65);
+    ctx.arc(60,65,5,0,Math.PI*2,true);  // Левый глаз
+    ctx.moveTo(95,65);
+    ctx.arc(90,65,5,0,Math.PI*2,true);  // Правый глаз
+    ctx.stroke();
+  }
+}
+
+ +

Результат этого ниже:

+ +

{{EmbedLiveSample("Передвижение_пера", 160, 160, "https://mdn.mozillademos.org/files/252/Canvas_smiley.png")}}

+ +

Если вы захотите увидеть соединные линии, то можете удалить вызов moveTo().

+ +
+

Note: Подробнее о функции arc(),посмотрите {{anch("Дуги")}} .

+
+ +

Линии

+ +

Для рисования прямых линий используйте метод lineTo().

+ +
+
{{domxref("CanvasRenderingContext2D.lineTo", "lineTo(x, y)")}}
+
Рисует линию с текущей позиции до позиции, определенной x и y.
+
+ +

Этот метод принимает два аргумента x и y, которые являются координатами конечной точки линии. Начальная точка зависит от ранее нарисованных путей, причём конечная точка предыдущего пути является начальной точкой следующего и т. д. Начальная точка также может быть изменена с помощью метода moveTo().

+ +

Пример ниже рисует два треугольника, один закрашенный и другой обведен контуром.

+ + + +
function draw() {
+  var canvas = document.getElementById('canvas');
+  if (canvas.getContext){
+    var ctx = canvas.getContext('2d');
+
+    // Filled triangle
+    ctx.beginPath();
+    ctx.moveTo(25,25);
+    ctx.lineTo(105,25);
+    ctx.lineTo(25,105);
+    ctx.fill();
+
+    // Stroked triangle
+    ctx.beginPath();
+    ctx.moveTo(125,125);
+    ctx.lineTo(125,45);
+    ctx.lineTo(45,125);
+    ctx.closePath();
+    ctx.stroke();
+  }
+}
+
+ +

Отрисовка начинается с вызова beginPath(), чтобы начать рисовать путь новой фигуры. Затем мы используем метод moveTo(), чтобы переместить начальную точку в нужное положение. Ниже рисуются две линии, которые образуют две стороны треугольника.

+ +

{{EmbedLiveSample("Линии", 160, 160, "https://mdn.mozillademos.org/files/238/Canvas_lineTo.png")}}

+ +

Вы заметите разницу между закрашенным и обведенным контуром треугольниками. Это, как упоминалось выше, из-за того, что фигуры автоматически закрываются, когда путь заполнен (т. е. закрашен), но не тогда, когда он очерчен (т. е. обведен контуром). Если бы мы не учли closePath() для очерченного треугольника, тогда только две линии были бы нарисованы, а не весь треугольник.

+ +

Дуги

+ +

Для рисования дуг и окружностей, используем методы arc() и arcTo().

+ +
+
{{domxref("CanvasRenderingContext2D.arc", "arc(x, y, radius, startAngle, endAngle, anticlockwise)")}}
+
Рисуем дугу с центром в точке (x,y) радиусом radius, начиная с угла startAngle и заканчивая в endAngle в направлении против часовой стрелки anticlockwise (по умолчанию по ходу движения часовой стрелки).
+
{{domxref("CanvasRenderingContext2D.arcTo", "arcTo(x1, y1, x2, y2, radius)")}}
+
Рисуем дугу с заданными контрольными точками и радиусом, соединяя эти точки прямой линией.
+
+ +

Рассмотрим детальнее метод arc(), который имеет пять параметров: x и y — это координаты центра окружности, в которой должна быть нарисована дуга. radius — не требует пояснений. Углы startAngle и endAngle определяют начальную и конечную точки дуги в радианах вдоль кривой окружности. Отсчет происходит от оси x. Параметр anticlockwise — логическое значение, которое, если true, то рисование дуги совершается против хода часовой стрелки; иначе рисование происходит по ходу часовой стрелки.

+ +
+

Note: Углы в функции arc() измеряют в радианах, не в градусах. Для перевода градусов в радианы вы можете использовать JavaScript-выражение: radians = (Math.PI/180)*degrees.

+
+ +

Следующий пример немного сложнее, чем мы рассматривали ранее. Здесь нарисованы 12 различных дуг с разными углами и заливками.

+ +

Два for цикла размещают дуги по столбцам и строкам. Для каждой дуги, мы начинаем новый контур, вызывая beginPath(). В этом коде каждый параметр дуги для большей ясности задан в виде переменной, но вам не обязательно делать так в реальных проектах.

+ +

Координаты x и y  должны быть достаточно ясны. radius and startAngle — фиксированы. endAngle начинается со 180 градусов (полуокружность) в первой колонке и, увеличиваясь с шагом 90 градусов, достигает кульминации полноценной окружностью в последнем столбце.

+ +

Установка параметра clockwise определяет результат; в первой и третьей строках рисование дуг происходит по часовой стрелке, а во второй и четвертой - против часовой стрелки. Благодаря if-условию верхняя половина дуг образуется с контуром, (обводкой), а нижняя половина дуг - с заливкой.

+ +
+

Note: Этот пример требует немного большего холста (canvas), чем другие на этой странице: 150 x 200 pixels.

+
+ + + +
function draw() {
+  var canvas = document.getElementById('canvas');
+  if (canvas.getContext){
+    var ctx = canvas.getContext('2d');
+
+    for(var i=0;i<4;i++){
+      for(var j=0;j<3;j++){
+        ctx.beginPath();
+        var x = 25+j*50; // x coordinate
+        var y = 25+i*50; // y coordinate
+        var radius = 20; // Arc radius
+        var startAngle = 0; // Starting point on circle
+        var endAngle = Math.PI+(Math.PI*j)/2; // End point on circle
+        var anticlockwise = i%2==0 ? false : true; // clockwise or anticlockwise
+
+        ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);
+
+        if (i>1){
+          ctx.fill();
+        } else {
+          ctx.stroke();
+        }
+      }
+    }
+  }
+}
+
+ +

{{EmbedLiveSample("Дуги", 160, 210, "https://mdn.mozillademos.org/files/204/Canvas_arc.png")}}

+ +

Безье и квадратичные кривые

+ +

Следующим типом доступных контуров являются  кривые Безье, и к тому же доступны в кубическом и квадратичном вариантах. Обычно они используются при рисовании сложных составных фигур.

+ +
+
{{domxref("CanvasRenderingContext2D.quadraticCurveTo", "quadraticCurveTo(cp1x, cp1y, x, y)")}}
+
Рисуется квадратичная кривая Безье с текущей позиции пера в конечную точку с координатами x и y, используя контрольную точку с координатами cp1x и cp1y.
+
{{domxref("CanvasRenderingContext2D.bezierCurveTo", "bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)")}}
+
Рисуется кубическая кривая Безье с текущей позиции пера в конечную точку с координатами x и y, используя две контрольные точки с координатами (cp1x, cp1y) и (cp2x, cp2y).
+
+ +

Различие между ними можно увидеть на рисунке, изображенном справа. Квадратичная кривая Безье имеет стартовую и конечную точки (синие точки) и всего одну контрольную точку (красная точка), в то время как кубическая кривая Безье использует две контрольные точки.

+ +

Параметры x и y в этих двух методах являются координатами конечной точки. cp1x и cp1y — координаты первой контрольной точки, а cp2x и cp2y — координаты второй контрольной точки.

+ +

Использование квадратичных или кубических кривых Безье может быть  спорным выходом, так как в отличие от приложений векторной графики типа Adobe Illustrator, мы не имеем полной видимой обратной связи с тем, что мы делаем. Этот факт делает довольно сложным процесс рисования сложных фигур. В следующем примере мы нарисуем совсем простую составную фигуру, но, если у вас есть время и ещё больше терпения, можно создать более сложные составные фигуры.

+ +

В этом примере нет ничего слишком тяжелого. В обоих случаях мы видим последовательность кривых, рисуя которые, в результате получим составную фигуру.

+ +

Квадратичные кривые Безье

+ +

В этом примере многократно используются квадратичные кривые Безье для рисования речевой выноски.

+ + + +
function draw() {
+  var canvas = document.getElementById('canvas');
+  if (canvas.getContext) {
+    var ctx = canvas.getContext('2d');
+
+    // Quadratric curves example
+    ctx.beginPath();
+    ctx.moveTo(75,25);
+    ctx.quadraticCurveTo(25,25,25,62.5);
+    ctx.quadraticCurveTo(25,100,50,100);
+    ctx.quadraticCurveTo(50,120,30,125);
+    ctx.quadraticCurveTo(60,120,65,100);
+    ctx.quadraticCurveTo(125,100,125,62.5);
+    ctx.quadraticCurveTo(125,25,75,25);
+    ctx.stroke();
+  }
+}
+
+ +

{{EmbedLiveSample("Квадратичные_кривые_Безье", 160, 160, "https://mdn.mozillademos.org/files/243/Canvas_quadratic.png")}}

+ +

Кубические кривые Безье

+ +

В этом примере нарисовано сердце с использованием кубических кривых Безье.

+ + + +
function draw() {
+  var canvas = document.getElementById('canvas');
+  if (canvas.getContext){
+    var ctx = canvas.getContext('2d');
+
+    // Cubic curves example
+    ctx.beginPath();
+    ctx.moveTo(75,40);
+    ctx.bezierCurveTo(75,37,70,25,50,25);
+    ctx.bezierCurveTo(20,25,20,62.5,20,62.5);
+    ctx.bezierCurveTo(20,80,40,102,75,120);
+    ctx.bezierCurveTo(110,102,130,80,130,62.5);
+    ctx.bezierCurveTo(130,62.5,130,25,100,25);
+    ctx.bezierCurveTo(85,25,75,37,75,40);
+    ctx.fill();
+  }
+}
+
+ +

{{EmbedLiveSample("Cubic_Bezier_curves", 160, 160, "https://mdn.mozillademos.org/files/207/Canvas_bezier.png")}}

+ +

Прямоугольники

+ +

Все эти методы мы видели в  {{anch("Рисование прямоугольников")}}, которые рисуют прямоугольники сразу в canvas, так же есть метод rect(), который не отображает, а только добавляет контур рисования (path) заданного прямоугольника к последнему открытому контуру.

+ +
+
{{domxref("CanvasRenderingContext2D.rect", "rect(x, y, width, height)")}}
+

+ Добавляет в path прямоугольник, верхний левый угол которого указан с помощью (x, y) с вашими width и height
+
+
+ +

Когда этот метод вызван, автоматически вызывается метод moveTo() с параметрами (x, y). Другими словами, позиция курсора устанавливается в начало добавленного прямоугольника.

+ +

Создание комбинаций

+ +

До сих пор, в каждом примере использовался только один тип функции контуров для каждой фигуры.
+ Однако, нет никаких ограничений на количество или типы контуров, которые вы можете использовать для создания фигур. Давайте в этом примере объединим все вышеперечисленные  функции контуров, чтобы создать набор очень известных игровых персонажей.

+ + + +
function draw() {
+  var canvas = document.getElementById('canvas');
+  if (canvas.getContext){
+    var ctx = canvas.getContext('2d');
+
+    roundedRect(ctx,12,12,150,150,15);
+    roundedRect(ctx,19,19,150,150,9);
+    roundedRect(ctx,53,53,49,33,10);
+    roundedRect(ctx,53,119,49,16,6);
+    roundedRect(ctx,135,53,49,33,10);
+    roundedRect(ctx,135,119,25,49,10);
+
+    ctx.beginPath();
+    ctx.arc(37,37,13,Math.PI/7,-Math.PI/7,false);
+    ctx.lineTo(31,37);
+    ctx.fill();
+
+    for(var i=0;i<8;i++){
+      ctx.fillRect(51+i*16,35,4,4);
+    }
+
+    for(i=0;i<6;i++){
+      ctx.fillRect(115,51+i*16,4,4);
+    }
+
+    for(i=0;i<8;i++){
+      ctx.fillRect(51+i*16,99,4,4);
+    }
+
+    ctx.beginPath();
+    ctx.moveTo(83,116);
+    ctx.lineTo(83,102);
+    ctx.bezierCurveTo(83,94,89,88,97,88);
+    ctx.bezierCurveTo(105,88,111,94,111,102);
+    ctx.lineTo(111,116);
+    ctx.lineTo(106.333,111.333);
+    ctx.lineTo(101.666,116);
+    ctx.lineTo(97,111.333);
+    ctx.lineTo(92.333,116);
+    ctx.lineTo(87.666,111.333);
+    ctx.lineTo(83,116);
+    ctx.fill();
+
+    ctx.fillStyle = "white";
+    ctx.beginPath();
+    ctx.moveTo(91,96);
+    ctx.bezierCurveTo(88,96,87,99,87,101);
+    ctx.bezierCurveTo(87,103,88,106,91,106);
+    ctx.bezierCurveTo(94,106,95,103,95,101);
+    ctx.bezierCurveTo(95,99,94,96,91,96);
+    ctx.moveTo(103,96);
+    ctx.bezierCurveTo(100,96,99,99,99,101);
+    ctx.bezierCurveTo(99,103,100,106,103,106);
+    ctx.bezierCurveTo(106,106,107,103,107,101);
+    ctx.bezierCurveTo(107,99,106,96,103,96);
+    ctx.fill();
+
+    ctx.fillStyle = "black";
+    ctx.beginPath();
+    ctx.arc(101,102,2,0,Math.PI*2,true);
+    ctx.fill();
+
+    ctx.beginPath();
+    ctx.arc(89,102,2,0,Math.PI*2,true);
+    ctx.fill();
+  }
+}
+
+// A utility function to draw a rectangle with rounded corners.
+
+function roundedRect(ctx,x,y,width,height,radius){
+  ctx.beginPath();
+  ctx.moveTo(x,y+radius);
+  ctx.lineTo(x,y+height-radius);
+  ctx.quadraticCurveTo(x,y+height,x+radius,y+height);
+  ctx.lineTo(x+width-radius,y+height);
+  ctx.quadraticCurveTo(x+width,y+height,x+width,y+height-radius);
+  ctx.lineTo(x+width,y+radius);
+  ctx.quadraticCurveTo(x+width,y,x+width-radius,y);
+  ctx.lineTo(x+radius,y);
+  ctx.quadraticCurveTo(x,y,x,y+radius);
+  ctx.stroke();
+}
+
+ +

Конечное изображение выглядит так:

+ +

{{EmbedLiveSample("Создание_комбинаций", 160, 160, "https://mdn.mozillademos.org/files/9849/combinations.png")}}

+ +

Мы не будем подробно останавливаться на том, так как это на самом деле удивительно просто. Наиболее важные вещи, которые следует отметить, это использование свойства fillStyle в контексте рисования и использование функции утилиты (в данном случае roundedRect()). Использование функций утилиты для битов чертежа часто может быть очень полезным и сократить количество необходимого кода, а также его сложность.

+ +

Позже, в этом уроке, мы еще раз рассмотрим fillStyle, но более подробно. Здесь же мы используем его для изменения цвета заливки путей вместо цвета по умолчанию от черного до белого, а затем обратно.

+ +

Path2D объекты

+ +

Как мы видели в последнем примере, есть серия путей и команд для рисования объектов на вашем холсте. Чтобы упростить код и повысить производительность, объект {{domxref("Path2D")}}, доступный в последних версиях браузеров, позволяет вам кэшировать или записывать эти команды рисования. Вы можете быстро запускать свои пути.
+ Давайте посмотрим, как мы можем построить объект Path2D :

+ +
+
{{domxref("Path2D.Path2D", "Path2D()")}}
+
Конструктор Path2D() возвращает вновь созданный объект Path2D  необязательно с другим путем в качестве аргумента (создает копию) или необязательно со строкой, состоящей из данных пути SVG path .
+
+ +
new Path2D();     // пустой path объект
+new Path2D(path); // копирование из другого path
+new Path2D(d);    // path из SVG
+ +

Все  методы path , такие как  moveTo,  rect,  arc, или quadraticCurveTo,  итп, которые мы уже знаем, доступны для объектов Path2D

+ +

API Path2D также добавляет способ комбинирования путей с использованием метода addPath. Это может быть полезно, если вы хотите, например, создавать объекты из нескольких компонентов.

+ +
+
{{domxref("Path2D.addPath", "Path2D.addPath(path [, transform])")}}
+
Добавляет путь к текущему пути с необязательной матрицей преобразования.
+
+ +

Path2D пример

+ +

В этом примере мы создаем прямоугольник и круг. Оба они сохраняются как объект Path2D, поэтому они доступны для последующего использования. С новым API Path2D несколько методов были обновлены, чтобы при необходимости принять объект Path2D для использования вместо текущего пути. Здесь stroke и fill используются с аргументом пути, например, для рисования обоих объектов на холст.

+ + + +
function draw() {
+  var canvas = document.getElementById('canvas');
+  if (canvas.getContext){
+    var ctx = canvas.getContext('2d');
+
+    var rectangle = new Path2D();
+    rectangle.rect(10, 10, 50, 50);
+
+    var circle = new Path2D();
+    circle.moveTo(125, 35);
+    circle.arc(100, 35, 25, 0, 2 * Math.PI);
+
+    ctx.stroke(rectangle);
+    ctx.fill(circle);
+  }
+}
+
+ +

{{EmbedLiveSample("Path2D_example", 130, 110, "https://mdn.mozillademos.org/files/9851/path2d.png")}}

+ +

Использование SVG путей

+ +

Еще одна мощная функция нового Canvas Path2D API использует данные пути SVG, SVG path data, для инициализации путей на вашем холсте. Это может позволить вам передавать данные пути и повторно использовать их как в SVG, так и в холсте.

+ +

Путь перемещается в точку (M10 10), а затем горизонтально перемещается на 80 пунктов вправо (h 80), затем на 80 пунктов вниз (v 80), затем на 80 пунктов влево (h -80), а затем обратно на start (z). 
+ Этот пример можно увидеть на странице  Path2D constructor.

+ +
var p = new Path2D("M10 10 h 80 v 80 h -80 Z");
+ +
{{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_usage", "Web/API/Canvas_API/Tutorial/Applying_styles_and_colors")}}
diff --git a/files/ru/web/api/canvas_api/tutorial/drawing_text/index.html b/files/ru/web/api/canvas_api/tutorial/drawing_text/index.html new file mode 100644 index 0000000000..90915c5e09 --- /dev/null +++ b/files/ru/web/api/canvas_api/tutorial/drawing_text/index.html @@ -0,0 +1,166 @@ +--- +title: Рисование текста +slug: Web/API/Canvas_API/Tutorial/Рисование_текста +tags: + - Canvas + - Графика + - Примеры + - Рукводовство + - мануал +translation_of: Web/API/Canvas_API/Tutorial/Drawing_text +--- +
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Applying_styles_and_colors", "Web/API/Canvas_API/Tutorial/Using_images")}}
+ +
+

После того, как мы увидели в предыдущей главе, как применять стили и цвета, взглянем на написание текста в canvas.

+
+ +

Рисование текста

+ +

Контекст рендеринга canvas предоставляет два метода для рисования текста:

+ +
+
{{domxref("CanvasRenderingContext2D.fillText", "fillText(text, x, y [, maxWidth])")}}
+
Вставляет заданный текст в положении (x,y). Опционально может быть указана максимальная ширина.
+
{{domxref("CanvasRenderingContext2D.strokeText", "strokeText(text, x, y [, maxWidth])")}}
+
Вставляет контур заданного текста в положении (x,y). Опционально может быть указана максимальная ширина.
+
+ +

Пример fillText

+ +

Текст вставлен с использованием текущего fillStyle.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  ctx.font = "48px serif";
+  ctx.fillText("Hello world", 10, 50);
+}
+ + + +

{{EmbedLiveSample("A_fillText_example", 310, 110)}}

+ +

Пример strokeText

+ +

Текст вставлен с использованием текущего strokeStyle.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  ctx.font = "48px serif";
+  ctx.strokeText("Hello world", 10, 50);
+}
+ + + +

{{EmbedLiveSample("A_strokeText_example", 310, 110)}}

+ +

Стилизация текста

+ +

В примерах выше мы уже использовали свойство font для изменения размера текста. Кроме него существуют еще несколько свойств, позволяющие настроить вывод текста на canvas:

+ +
+
{{domxref("CanvasRenderingContext2D.font", "font = value")}}
+
Это основной стиль, который будет использоваться для вывода текста. Строка имеет такой же синтаксис, как CSS-свойство {{cssxref("font")}}. По умолчанию - sans-serif высотой 10px.
+
{{domxref("CanvasRenderingContext2D.textAlign", "textAlign = value")}}
+
Настройка выравнивания текста. Возможные значения: start, end, left, right или center. По умолчанию - start.
+
{{domxref("CanvasRenderingContext2D.textBaseline", "textBaseline = value")}}
+
Настройка выравнивания текста по вертикали. Возможные значения: top, hanging, middle, alphabetic, ideographic, bottom. По умолчанию - alphabetic.
+
{{domxref("CanvasRenderingContext2D.direction", "direction = value")}}
+
Направление текста. Возможные значения: ltr, rtl, inherit. По умолчанию - inherit.
+
+ +

Эти свойства могут быть вам знакомы если вы работали с CSS.

+ +

Изображение от WHATWG ниже показывает различные варианты свойства textBaseline.The top of the em square is
+roughly at the top of the glyphs in a font, the hanging baseline is
+where some glyphs like आ are anchored, the middle is half-way
+between the top of the em square and the bottom of the em square,
+the alphabetic baseline is where characters like Á, ÿ,
+f, and Ω are anchored, the ideographic baseline is
+where glyphs like 私 and 達 are anchored, and the bottom
+of the em square is roughly at the bottom of the glyphs in a
+font. The top and bottom of the bounding box can be far from these
+baselines, due to glyphs extending far outside the em square.

+ +

Пример textBaseline

+ +

Редактируя код ниже, вы можете видеть, как меняется отображение текста на canvas в реальном времени:

+ +
ctx.font = "48px serif";
+ctx.textBaseline = "hanging";
+ctx.strokeText("Hello world!", 0, 100);
+
+ + + +

{{ EmbedLiveSample('Playable_code', 700, 360) }}

+ +

Измерение ширины текста

+ +

Для измерения ширины текста (без рисования его на canvas) можно воспользоваться следующим методом:

+ +
+
{{domxref("CanvasRenderingContext2D.measureText", "measureText()")}}
+
Возвращает объект {{domxref("TextMetrics")}}, содержащий ширину текста в пикселах, до отрисовки на canvas.
+
+ +

Пример ниже показывает, как можно измерить ширину текста.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  var text = ctx.measureText("foo"); // TextMetrics object
+  text.width; // 16;
+}
+
+ +

Примечания

+ +

В ранних версиях Gecko (движок рендеринга в Firefox, Firefox OS и других приложениях Mozilla) были реализованы методы API с префиксами для рисования текста на canvas. На данный момент они устарели и уже, возможно, удалены, поэтому их правильная работа не гарантируется.

+ +

{{PreviousNext("Web/API/Canvas_API/Tutorial/Applying_styles_and_colors", "Web/API/Canvas_API/Tutorial/Using_images")}}

diff --git a/files/ru/web/api/canvas_api/tutorial/using_images/index.html b/files/ru/web/api/canvas_api/tutorial/using_images/index.html new file mode 100644 index 0000000000..3ce4b8384e --- /dev/null +++ b/files/ru/web/api/canvas_api/tutorial/using_images/index.html @@ -0,0 +1,333 @@ +--- +title: Использование изображений +slug: Web/API/Canvas_API/Tutorial/Использование_изображений +tags: + - Графика +translation_of: Web/API/Canvas_API/Tutorial/Using_images +--- +
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_text", "Web/API/Canvas_API/Tutorial/Трансформации")}}
+ +
+

До сих пор мы создавали наши собственные фигуры и применяли стили к ним. Одна из самых впечатляющих функций {{HTMLElement("canvas")}} это возможность использования изображений. Они могут быть использованы для динамического композитинга фото или как фоны графиков, для спрайтов в играх, и так далее. Внешние изображения могут быть использованы в любых поддерживаемых браузером форматах, таких как PNG, GIF, или JPEG. Вы можете даже использовать изображение, произведенное другими canvas элементами на той же странице как источник!

+
+ +

Импортирование изображений в canvas в основном состоит из 2 этапов:

+ +
    +
  1. Дав ссылку на {{domxref("HTMLImageElement")}} объект или для другого canvas элемента как источник. Также можно использовать изображение дав ссылку на URL.
  2. +
  3. Для рисования изображения на canvas используется функция drawImage().
  4. +
+ +

Давайте посмотрим как это сделать.

+ +

Использование изображений для рисования

+ +

Canvas API может использовать все перечисленные далее типы данных как источник изображения:

+ +
+
{{domxref("HTMLImageElement")}}
+
Эти изображения созданы, используя конструктор Image(), также как все{{HTMLElement("img")}} элементы.
+
{{domxref("HTMLVideoElement")}}
+
Используя HTML {{HTMLElement("video")}} элемент как источник изображения захватывает текущий кадр из видео и использует его как изображение.
+
{{domxref("HTMLCanvasElement")}}
+
Вы можете использовать другой {{HTMLElement("canvas")}} элемент как источник изображения.
+
+ +

Эти источники совместно именуемые по типу {{domxref("CanvasImageSource")}}.

+ +

Есть несколько способов, чтобы получить изображения для использования на холсте.

+ +

Использование изображений из той же страницы

+ +

Мы можем получить ссылку на изображение, на той же странице, на canvas с используя  один из способов: 

+ +
    +
  •  {{domxref("document.images")}} коллекция
  • +
  • The {{domxref("document.getElementsByTagName()")}} метод
  • +
  • Если вы знаете id конкретного изображения, который вы хотите использовать, вы можете использовать {{domxref("document.getElementById ()")}}, чтобы получить это конкретное изображение
  • +
+ +

Использование изображений из других доменов

+ +

Использование {{htmlattrxref("crossorigin", "img")}} атрибута {{HTMLElement("img")}} элемент (отображается  {{domxref("HTMLImageElement.crossOrigin")}} свойства), вы можете запросить разрешение на загрузку другого домена для использования в drawImage(). Если хостинг домен разрешает доступ к междоменному изображению, то изображение может быть использовано в вашем canvas без  without tainting it;иначе он может испортить ваш canvas.

+ +

Использование других canvas элементов

+ +

Как и с обычными изображениями, мы можем получить доступ к другим canvas элементам используя либо {{domxref("document.getElementsByTagName()")}} либо {{domxref("document.getElementById()")}} метод. Проверьте, что в canvas источнике уже что-то нарисовано, прежде чем использовать его в целевом изображении canvas.

+ +

Одним из удобных способов было бы использование второго элемента canvas  в качестве миниатюры другого большего изображения canvas.

+ +

Создание изображений с нуля

+ +

Другой способ это создать новые {{domxref("HTMLImageElement")}} объекты в нашем скрипте.  Чтобы это сделать, вы можете использовать удобный Image() конструктор:

+ +
var img = new Image();   // Создает новый элемент изображения
+img.src = 'myImage.png'; // Устанавливает путь
+
+ +

Когда этот скрипт выполнится, изображение начнет загружаться.

+ +

Если вы попытаетесь вызвать функцию drawImage() перед тем как изображение загрузится, то скрипт ничего не сделает (или, в старых браузерах, может даже выдать исключение). Поэтому вам необходимо использовать событие load, чтобы вы не пытались сделать это прежде, чем изображение загрузится:

+ +
var img = new Image();   // Создает новое изображение
+img.addEventListener("load", function() {
+  // здесь выполняет drawImage функцию
+}, false);
+img.src = 'myImage.png'; // Устанавливает источник файла
+
+ +

Если вы используете только одно стороннее изображение, то этот метод может быть хорошим примером, но если нужно следить за несколькими изображениями, то необходимо придумать что-то более умное. Хотя поиски тактики проверки загрузки изображений выходят за пределы этого обучающего курса,  вы должны об этом помнить.

+ +

Вложение изображения с помощью данных: URL

+ +

Другой возможный способ включить изображение это через data: url. Data URLs позволяет вам полностью определить изображение как Base64 кодированную строку символов прямо в ваш код.

+ +
var img = new Image();   // Создает новый элемент img
+img.src = 'data:image/gif;base64,R0lGODlhCwALAIAAAAAA3pn/ZiH5BAEAAAEALAAAAAALAAsAAAIUhA+hkcuO4lmNVindo7qyrIXiGBYAOw==';
+
+ +

Одним из преимуществ data URLs  это то что полученное изображение доступно сразу без других запросов туда-обратно на сервер. Другое потенциальное преимущество в том, что также можно инкапсулировать всё в одном файле все ваши CSS, JavaScript, HTML, и изображения, что делает его более портативным в других местах.

+ +

Некоторые недостатки этого метода в том что ваше изображение не кешировано, и для изображений с большим размером кодированние url может стать очень долгим процессом.

+ +

Использование кадров из видео

+ +

Вы также можете использовать кадры из видео представленных {{HTMLElement("video")}} элементом (даже если видео не видно). Например, если у вас есть  {{HTMLElement("video")}} элемент с  ID "myvideo", вы можете сделать:

+ +
function getMyVideo() {
+  var canvas = document.getElementById('canvas');
+  if (canvas.getContext) {
+    var ctx = canvas.getContext('2d');
+
+    return document.getElementById('myvideo');
+  }
+}
+
+ +

Эта функция вернет {{domxref("HTMLVideoElement")}} объект для этого видео, который, как мы упоминали ранее, является одним из объектов, который можно использовать как CanvasImageSource.

+ +

Рисование изображений

+ +

Как только мы получили ссылку на источник объекта изображения, мы можем использовать метод drawImage() для включения его в  canvas. Как мы увидим далее, метод drawImage() перегружен и у него есть несколько вариантов. В базовом варианте он выглядит как:

+ +
+
{{domxref("CanvasRenderingContext2D.drawImage", "drawImage(image, x, y)")}}
+
Рисует  изображение, указанное в CanvasImageSource в координатах  (x, y).
+
+ +
+

SVG изображения должны указывать ширину и высоту корневого  <svg> элемента.

+
+ +

Пример: Простой линейный график

+ +

В следующем примере, мы будем использовать внешнее изображение в качестве фона для небольшого линейного графика. Использование фонов может сделать ваш скрипт значительно меньше, потому что мы можем избежать необходимости писать код для создания фона. В этом примере мы используем только один образ, поэтому я использую обработчик событий изображения объекта загрузки для выполнения операторов рисования. drawImage() метод определяющий место фона с координатами (0, 0), которые привязаны к верхнему левому углу canvas.

+ + + +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  var img = new Image();
+  img.onload = function(){
+    ctx.drawImage(img,0,0);
+    ctx.beginPath();
+    ctx.moveTo(30,96);
+    ctx.lineTo(70,66);
+    ctx.lineTo(103,76);
+    ctx.lineTo(170,15);
+    ctx.stroke();
+  };
+  img.src = 'https://mdn.mozillademos.org/files/5395/backdrop.png';
+}
+ +

Получившийся график выглядит так:

+ +

{{EmbedLiveSample("Example_A_simple_line_graph", 220, 160, "https://mdn.mozillademos.org/files/206/Canvas_backdrop.png")}}

+ +

Изменение размеров

+ +

Второй вариант метода drawImage() добавляет два новых параметра и позволяет разместить изображение в  canvas с измененными размерами.

+ +
+
{{domxref("CanvasRenderingContext2D.drawImage", "drawImage(image, x, y, width, height)")}}
+
Это добавляет параметр ширины и высоты, которые указывают до какого размера нужно изменить изображение при рисовании его в  canvas.
+
+ +

Пример: Тайлинг изображения

+ +

В этом примере, мы будем использовать изображение в качестве обоев и повторим его в canvas несколько раз. Это может быть сделано просто через цикл, располагая измененные изображения на разных позициях. В коде внизу, первый цикл for проходит по рядам. Второй цикл for проходит по колонкам. Изображение уменьшено на треть от реального размера, которое было  50x38 пикселей.

+ +
+

Обратите внимание: Изображения могут стать размытыми, при большом увеличении или зернистыми при значительном уменьшении. Возможно, лучше всего не изменять размеры изображения, если на них есть текст, который должен остаться читаемым. 

+
+ + + +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  var img = new Image();
+  img.onload = function(){
+    for (var i=0;i<4;i++){
+      for (var j=0;j<3;j++){
+        ctx.drawImage(img,j*50,i*38,50,38);
+      }
+    }
+  };
+  img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg';
+}
+ +

Получившийся рисунок canvas выглядит так:

+ +

{{EmbedLiveSample("Example_Tiling_an_image", 160, 160, "https://mdn.mozillademos.org/files/251/Canvas_scale_image.png")}}

+ +

Нарезка

+ +

У третьего и последнего варианта метода drawImage() в дополнении к источнику изображения есть еще восемь параметров . Он позволяет нам вырезать кусок из изображения, затем изменить его размер и нарисовать его в canvas.

+ +
+
{{domxref("CanvasRenderingContext2D.drawImage", "drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)")}}
+
В данном изображении, эта функция берет фрагмент из изображения, в виде прямоугольника, левый верхний угол которого -  (sx, sy), ширина и высота -  sWidth и sHeight и рисует  в  canvas, располагая его в точке  (dx, dy) и изменяя его размер на указанные величины в  dWidth и dHeight.
+
+ +

Чтобы понять что  делает нарезка, можно посмотреть на изображение справа. Первые четыре параметра определяют местоположение и размер фрагмента исходного изображения.  Последние четыре параметра определяют прямоугольник, в который будет вписано изображение на целевом рисунке  canvas.

+ +

Нарезка может быть полезным инструментом, когда вы захотите сделать композицию.  Вы могли бы собрать все элементы в одном файле изображения и использовать этот метод для создания композиции. Например, если вы захотите сделать график, вы могли бы сделать PNG изображение, содержащее все необходимые тексты в одном файле и в зависимости от ваших данных, могли бы достаточно просто изменять график. Другим преимуществом является то, что нет необходимости загружать каждое изображение по отдельности, получив возможность увеличить скорость загрузки.

+ +

Пример: Обрамление изображения

+ +

В этом примере, мы будем использовать того же носорога, что и в предыдущем примере, но мы отрежем его голову и включим ее в рамку. Изображение рамки это 24-х битный PNG, который включает падающую тень. Так как в 24-х битные PNG изображения включается полный 8-ми битный альфа-канал, в отличие от GIF и 8-битных PNG изображений, он может быть помещен в любой фон, без беспокойства о матовом цвете. 

+ +
<html>
+ <body onload="draw();">
+   <canvas id="canvas" width="150" height="150"></canvas>
+   <div style="display:none;">
+     <img id="source" src="https://mdn.mozillademos.org/files/5397/rhino.jpg" width="300" height="227">
+     <img id="frame" src="https://mdn.mozillademos.org/files/242/Canvas_picture_frame.png" width="132" height="150">
+   </div>
+ </body>
+</html>
+
+ +
function draw() {
+  var canvas = document.getElementById('canvas');
+  var ctx = canvas.getContext('2d');
+
+  // Рисуем фрагмент
+  ctx.drawImage(document.getElementById('source'),
+                33, 71, 104, 124, 21, 20, 87, 104);
+
+  // Рисуем рамку
+  ctx.drawImage(document.getElementById('frame'),0,0);
+}
+ +

В этот раз мы применили другой способ загрузки изображения. Вместо загрузки методом создания новых {{domxref("HTMLImageElement")}} объектов, мы включили их как  {{HTMLElement("img")}} тэги прямо в наш HTML файл и из них выбрали изображения. Изображения скрыты с помощью  CSS свойства {{cssxref("display")}}, установленного в "none" для этих изображений.

+ +

{{EmbedLiveSample("Example_Framing_an_image", 160, 160, "https://mdn.mozillademos.org/files/226/Canvas_drawimage2.jpg")}}

+ +

Скрипт, сам по себе, очень простой. Каждому {{HTMLElement("img")}} присвоен атрибут ID, который  делает удобным их выбор с использованием {{domxref("document.getElementById()")}}. Потом мы просто используем функцию  drawImage(), чтобы из первого изображения вырезать фрагмент носорога и вставить его в canvas, затем рисуем рамку сверху, используя второй вызов функции drawImage().

+ +

Пример галереи искусства

+ +

В последнем примере этой главы, мы построим небольшую галлерею искусств. Галерея состоит из таблицы, включающей несколько изображений. Когда страница загрузится,  {{HTMLElement("canvas")}}  элемент вставится в каждое изображение, а вокруг будет нарисована рамка. 

+ +

В этом случае, у каждого изображения фиксированная ширина и высота, такая же, как и у рамки нарисованной вокруг них.  Вы могли бы усовершенствовать этот скрипт так, чтобы он использовал ширину и высоту изображения, чтобы рамка идеально его окружила.

+ +

Код ниже должен говорить сам за себя. Мы проходим циклом через {{domxref("document.images")}} контейнер и соответственно добавляем новые элементы  canvas. Возможно следует упомянуть для тех, кто не слишком хорошо знаком с DOM, что для этого используется {{domxref("Node.insertBefore")}} метод. insertBefore() это метод родительского узла (ячейки таблицы) элемента (изображения) перед которым мы хотим вставить наш новый узел  (элемент canvas).

+ +
<html>
+ <body onload="draw();">
+     <table>
+      <tr>
+        <td><img src="https://mdn.mozillademos.org/files/5399/gallery_1.jpg"></td>
+        <td><img src="https://mdn.mozillademos.org/files/5401/gallery_2.jpg"></td>
+        <td><img src="https://mdn.mozillademos.org/files/5403/gallery_3.jpg"></td>
+        <td><img src="https://mdn.mozillademos.org/files/5405/gallery_4.jpg"></td>
+      </tr>
+      <tr>
+        <td><img src="https://mdn.mozillademos.org/files/5407/gallery_5.jpg"></td>
+        <td><img src="https://mdn.mozillademos.org/files/5409/gallery_6.jpg"></td>
+        <td><img src="https://mdn.mozillademos.org/files/5411/gallery_7.jpg"></td>
+        <td><img src="https://mdn.mozillademos.org/files/5413/gallery_8.jpg"></td>
+      </tr>
+     </table>
+     <img id="frame" src="https://mdn.mozillademos.org/files/242/Canvas_picture_frame.png" width="132" height="150">
+ </body>
+</html>
+
+ +

И сюда какую-нибудь CSS для украшения:

+ +
body {
+  background: 0 -100px repeat-x url(https://mdn.mozillademos.org/files/5415/bg_gallery.png) #4F191A;
+  margin: 10px;
+}
+
+img {
+  display: none;
+}
+
+table {
+  margin: 0 auto;
+}
+
+td {
+  padding: 15px;
+}
+
+ +

Связывая все вместе  JavaScript рисует наши изображения в рамках:

+ +
function draw() {
+
+  // Цикл по всем изображениям
+  for (var i=0;i<document.images.length;i++){
+
+    // Не добавляет canvas для изображения рамки
+    if (document.images[i].getAttribute('id')!='frame'){
+
+      // Создает элемент canvas
+      var canvas = document.createElement('canvas');
+      canvas.setAttribute('width',132);
+      canvas.setAttribute('height',150);
+
+      // Вставляет перед изображением
+      document.images[i].parentNode.insertBefore(canvas,document.images[i]);
+
+      var ctx = canvas.getContext('2d');
+
+      // Рисует изображение в canvas
+      ctx.drawImage(document.images[i],15,20);
+
+      // Добавляет рамку
+      ctx.drawImage(document.getElementById('frame'),0,0);
+    }
+  }
+}
+ +

{{EmbedLiveSample("Art_gallery_example", 725, 400)}}

+ +

Контроль изменений размеров изображения

+ +

Как было отмечено ранее, изменение размеров изображений может привести к размытости или к шуму в процессе преобразования. Вы можете использовать контекст рисования {{domxref("CanvasRenderingContext2D.imageSmoothingEnabled", "imageSmoothingEnabled")}} свойства, чтобы контролировать использование сглаживающего алгоритма, когда изменяющиеся изображения в вашем контексте. Обычно это свойство установлено в  true, означая, что изображения будут сглажены во время изменения размеров. Вы можете отключить это свойство так:

+ +
ctx.mozImageSmoothingEnabled = false;
+ctx.webkitImageSmoothingEnabled = false;
+ctx.msImageSmoothingEnabled = false;
+ctx.imageSmoothingEnabled = false;
+
+ +

{{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_text", "Web/API/Canvas_API/Tutorial/Transformations")}}

diff --git "a/files/ru/web/api/canvas_api/tutorial/\320\270\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265_\320\270\320\267\320\276\320\261\321\200\320\260\320\266\320\265\320\275\320\270\320\271/index.html" "b/files/ru/web/api/canvas_api/tutorial/\320\270\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265_\320\270\320\267\320\276\320\261\321\200\320\260\320\266\320\265\320\275\320\270\320\271/index.html" deleted file mode 100644 index 3ce4b8384e..0000000000 --- "a/files/ru/web/api/canvas_api/tutorial/\320\270\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265_\320\270\320\267\320\276\320\261\321\200\320\260\320\266\320\265\320\275\320\270\320\271/index.html" +++ /dev/null @@ -1,333 +0,0 @@ ---- -title: Использование изображений -slug: Web/API/Canvas_API/Tutorial/Использование_изображений -tags: - - Графика -translation_of: Web/API/Canvas_API/Tutorial/Using_images ---- -
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_text", "Web/API/Canvas_API/Tutorial/Трансформации")}}
- -
-

До сих пор мы создавали наши собственные фигуры и применяли стили к ним. Одна из самых впечатляющих функций {{HTMLElement("canvas")}} это возможность использования изображений. Они могут быть использованы для динамического композитинга фото или как фоны графиков, для спрайтов в играх, и так далее. Внешние изображения могут быть использованы в любых поддерживаемых браузером форматах, таких как PNG, GIF, или JPEG. Вы можете даже использовать изображение, произведенное другими canvas элементами на той же странице как источник!

-
- -

Импортирование изображений в canvas в основном состоит из 2 этапов:

- -
    -
  1. Дав ссылку на {{domxref("HTMLImageElement")}} объект или для другого canvas элемента как источник. Также можно использовать изображение дав ссылку на URL.
  2. -
  3. Для рисования изображения на canvas используется функция drawImage().
  4. -
- -

Давайте посмотрим как это сделать.

- -

Использование изображений для рисования

- -

Canvas API может использовать все перечисленные далее типы данных как источник изображения:

- -
-
{{domxref("HTMLImageElement")}}
-
Эти изображения созданы, используя конструктор Image(), также как все{{HTMLElement("img")}} элементы.
-
{{domxref("HTMLVideoElement")}}
-
Используя HTML {{HTMLElement("video")}} элемент как источник изображения захватывает текущий кадр из видео и использует его как изображение.
-
{{domxref("HTMLCanvasElement")}}
-
Вы можете использовать другой {{HTMLElement("canvas")}} элемент как источник изображения.
-
- -

Эти источники совместно именуемые по типу {{domxref("CanvasImageSource")}}.

- -

Есть несколько способов, чтобы получить изображения для использования на холсте.

- -

Использование изображений из той же страницы

- -

Мы можем получить ссылку на изображение, на той же странице, на canvas с используя  один из способов: 

- -
    -
  •  {{domxref("document.images")}} коллекция
  • -
  • The {{domxref("document.getElementsByTagName()")}} метод
  • -
  • Если вы знаете id конкретного изображения, который вы хотите использовать, вы можете использовать {{domxref("document.getElementById ()")}}, чтобы получить это конкретное изображение
  • -
- -

Использование изображений из других доменов

- -

Использование {{htmlattrxref("crossorigin", "img")}} атрибута {{HTMLElement("img")}} элемент (отображается  {{domxref("HTMLImageElement.crossOrigin")}} свойства), вы можете запросить разрешение на загрузку другого домена для использования в drawImage(). Если хостинг домен разрешает доступ к междоменному изображению, то изображение может быть использовано в вашем canvas без  without tainting it;иначе он может испортить ваш canvas.

- -

Использование других canvas элементов

- -

Как и с обычными изображениями, мы можем получить доступ к другим canvas элементам используя либо {{domxref("document.getElementsByTagName()")}} либо {{domxref("document.getElementById()")}} метод. Проверьте, что в canvas источнике уже что-то нарисовано, прежде чем использовать его в целевом изображении canvas.

- -

Одним из удобных способов было бы использование второго элемента canvas  в качестве миниатюры другого большего изображения canvas.

- -

Создание изображений с нуля

- -

Другой способ это создать новые {{domxref("HTMLImageElement")}} объекты в нашем скрипте.  Чтобы это сделать, вы можете использовать удобный Image() конструктор:

- -
var img = new Image();   // Создает новый элемент изображения
-img.src = 'myImage.png'; // Устанавливает путь
-
- -

Когда этот скрипт выполнится, изображение начнет загружаться.

- -

Если вы попытаетесь вызвать функцию drawImage() перед тем как изображение загрузится, то скрипт ничего не сделает (или, в старых браузерах, может даже выдать исключение). Поэтому вам необходимо использовать событие load, чтобы вы не пытались сделать это прежде, чем изображение загрузится:

- -
var img = new Image();   // Создает новое изображение
-img.addEventListener("load", function() {
-  // здесь выполняет drawImage функцию
-}, false);
-img.src = 'myImage.png'; // Устанавливает источник файла
-
- -

Если вы используете только одно стороннее изображение, то этот метод может быть хорошим примером, но если нужно следить за несколькими изображениями, то необходимо придумать что-то более умное. Хотя поиски тактики проверки загрузки изображений выходят за пределы этого обучающего курса,  вы должны об этом помнить.

- -

Вложение изображения с помощью данных: URL

- -

Другой возможный способ включить изображение это через data: url. Data URLs позволяет вам полностью определить изображение как Base64 кодированную строку символов прямо в ваш код.

- -
var img = new Image();   // Создает новый элемент img
-img.src = 'data:image/gif;base64,R0lGODlhCwALAIAAAAAA3pn/ZiH5BAEAAAEALAAAAAALAAsAAAIUhA+hkcuO4lmNVindo7qyrIXiGBYAOw==';
-
- -

Одним из преимуществ data URLs  это то что полученное изображение доступно сразу без других запросов туда-обратно на сервер. Другое потенциальное преимущество в том, что также можно инкапсулировать всё в одном файле все ваши CSS, JavaScript, HTML, и изображения, что делает его более портативным в других местах.

- -

Некоторые недостатки этого метода в том что ваше изображение не кешировано, и для изображений с большим размером кодированние url может стать очень долгим процессом.

- -

Использование кадров из видео

- -

Вы также можете использовать кадры из видео представленных {{HTMLElement("video")}} элементом (даже если видео не видно). Например, если у вас есть  {{HTMLElement("video")}} элемент с  ID "myvideo", вы можете сделать:

- -
function getMyVideo() {
-  var canvas = document.getElementById('canvas');
-  if (canvas.getContext) {
-    var ctx = canvas.getContext('2d');
-
-    return document.getElementById('myvideo');
-  }
-}
-
- -

Эта функция вернет {{domxref("HTMLVideoElement")}} объект для этого видео, который, как мы упоминали ранее, является одним из объектов, который можно использовать как CanvasImageSource.

- -

Рисование изображений

- -

Как только мы получили ссылку на источник объекта изображения, мы можем использовать метод drawImage() для включения его в  canvas. Как мы увидим далее, метод drawImage() перегружен и у него есть несколько вариантов. В базовом варианте он выглядит как:

- -
-
{{domxref("CanvasRenderingContext2D.drawImage", "drawImage(image, x, y)")}}
-
Рисует  изображение, указанное в CanvasImageSource в координатах  (x, y).
-
- -
-

SVG изображения должны указывать ширину и высоту корневого  <svg> элемента.

-
- -

Пример: Простой линейный график

- -

В следующем примере, мы будем использовать внешнее изображение в качестве фона для небольшого линейного графика. Использование фонов может сделать ваш скрипт значительно меньше, потому что мы можем избежать необходимости писать код для создания фона. В этом примере мы используем только один образ, поэтому я использую обработчик событий изображения объекта загрузки для выполнения операторов рисования. drawImage() метод определяющий место фона с координатами (0, 0), которые привязаны к верхнему левому углу canvas.

- - - -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  var img = new Image();
-  img.onload = function(){
-    ctx.drawImage(img,0,0);
-    ctx.beginPath();
-    ctx.moveTo(30,96);
-    ctx.lineTo(70,66);
-    ctx.lineTo(103,76);
-    ctx.lineTo(170,15);
-    ctx.stroke();
-  };
-  img.src = 'https://mdn.mozillademos.org/files/5395/backdrop.png';
-}
- -

Получившийся график выглядит так:

- -

{{EmbedLiveSample("Example_A_simple_line_graph", 220, 160, "https://mdn.mozillademos.org/files/206/Canvas_backdrop.png")}}

- -

Изменение размеров

- -

Второй вариант метода drawImage() добавляет два новых параметра и позволяет разместить изображение в  canvas с измененными размерами.

- -
-
{{domxref("CanvasRenderingContext2D.drawImage", "drawImage(image, x, y, width, height)")}}
-
Это добавляет параметр ширины и высоты, которые указывают до какого размера нужно изменить изображение при рисовании его в  canvas.
-
- -

Пример: Тайлинг изображения

- -

В этом примере, мы будем использовать изображение в качестве обоев и повторим его в canvas несколько раз. Это может быть сделано просто через цикл, располагая измененные изображения на разных позициях. В коде внизу, первый цикл for проходит по рядам. Второй цикл for проходит по колонкам. Изображение уменьшено на треть от реального размера, которое было  50x38 пикселей.

- -
-

Обратите внимание: Изображения могут стать размытыми, при большом увеличении или зернистыми при значительном уменьшении. Возможно, лучше всего не изменять размеры изображения, если на них есть текст, который должен остаться читаемым. 

-
- - - -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  var img = new Image();
-  img.onload = function(){
-    for (var i=0;i<4;i++){
-      for (var j=0;j<3;j++){
-        ctx.drawImage(img,j*50,i*38,50,38);
-      }
-    }
-  };
-  img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg';
-}
- -

Получившийся рисунок canvas выглядит так:

- -

{{EmbedLiveSample("Example_Tiling_an_image", 160, 160, "https://mdn.mozillademos.org/files/251/Canvas_scale_image.png")}}

- -

Нарезка

- -

У третьего и последнего варианта метода drawImage() в дополнении к источнику изображения есть еще восемь параметров . Он позволяет нам вырезать кусок из изображения, затем изменить его размер и нарисовать его в canvas.

- -
-
{{domxref("CanvasRenderingContext2D.drawImage", "drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)")}}
-
В данном изображении, эта функция берет фрагмент из изображения, в виде прямоугольника, левый верхний угол которого -  (sx, sy), ширина и высота -  sWidth и sHeight и рисует  в  canvas, располагая его в точке  (dx, dy) и изменяя его размер на указанные величины в  dWidth и dHeight.
-
- -

Чтобы понять что  делает нарезка, можно посмотреть на изображение справа. Первые четыре параметра определяют местоположение и размер фрагмента исходного изображения.  Последние четыре параметра определяют прямоугольник, в который будет вписано изображение на целевом рисунке  canvas.

- -

Нарезка может быть полезным инструментом, когда вы захотите сделать композицию.  Вы могли бы собрать все элементы в одном файле изображения и использовать этот метод для создания композиции. Например, если вы захотите сделать график, вы могли бы сделать PNG изображение, содержащее все необходимые тексты в одном файле и в зависимости от ваших данных, могли бы достаточно просто изменять график. Другим преимуществом является то, что нет необходимости загружать каждое изображение по отдельности, получив возможность увеличить скорость загрузки.

- -

Пример: Обрамление изображения

- -

В этом примере, мы будем использовать того же носорога, что и в предыдущем примере, но мы отрежем его голову и включим ее в рамку. Изображение рамки это 24-х битный PNG, который включает падающую тень. Так как в 24-х битные PNG изображения включается полный 8-ми битный альфа-канал, в отличие от GIF и 8-битных PNG изображений, он может быть помещен в любой фон, без беспокойства о матовом цвете. 

- -
<html>
- <body onload="draw();">
-   <canvas id="canvas" width="150" height="150"></canvas>
-   <div style="display:none;">
-     <img id="source" src="https://mdn.mozillademos.org/files/5397/rhino.jpg" width="300" height="227">
-     <img id="frame" src="https://mdn.mozillademos.org/files/242/Canvas_picture_frame.png" width="132" height="150">
-   </div>
- </body>
-</html>
-
- -
function draw() {
-  var canvas = document.getElementById('canvas');
-  var ctx = canvas.getContext('2d');
-
-  // Рисуем фрагмент
-  ctx.drawImage(document.getElementById('source'),
-                33, 71, 104, 124, 21, 20, 87, 104);
-
-  // Рисуем рамку
-  ctx.drawImage(document.getElementById('frame'),0,0);
-}
- -

В этот раз мы применили другой способ загрузки изображения. Вместо загрузки методом создания новых {{domxref("HTMLImageElement")}} объектов, мы включили их как  {{HTMLElement("img")}} тэги прямо в наш HTML файл и из них выбрали изображения. Изображения скрыты с помощью  CSS свойства {{cssxref("display")}}, установленного в "none" для этих изображений.

- -

{{EmbedLiveSample("Example_Framing_an_image", 160, 160, "https://mdn.mozillademos.org/files/226/Canvas_drawimage2.jpg")}}

- -

Скрипт, сам по себе, очень простой. Каждому {{HTMLElement("img")}} присвоен атрибут ID, который  делает удобным их выбор с использованием {{domxref("document.getElementById()")}}. Потом мы просто используем функцию  drawImage(), чтобы из первого изображения вырезать фрагмент носорога и вставить его в canvas, затем рисуем рамку сверху, используя второй вызов функции drawImage().

- -

Пример галереи искусства

- -

В последнем примере этой главы, мы построим небольшую галлерею искусств. Галерея состоит из таблицы, включающей несколько изображений. Когда страница загрузится,  {{HTMLElement("canvas")}}  элемент вставится в каждое изображение, а вокруг будет нарисована рамка. 

- -

В этом случае, у каждого изображения фиксированная ширина и высота, такая же, как и у рамки нарисованной вокруг них.  Вы могли бы усовершенствовать этот скрипт так, чтобы он использовал ширину и высоту изображения, чтобы рамка идеально его окружила.

- -

Код ниже должен говорить сам за себя. Мы проходим циклом через {{domxref("document.images")}} контейнер и соответственно добавляем новые элементы  canvas. Возможно следует упомянуть для тех, кто не слишком хорошо знаком с DOM, что для этого используется {{domxref("Node.insertBefore")}} метод. insertBefore() это метод родительского узла (ячейки таблицы) элемента (изображения) перед которым мы хотим вставить наш новый узел  (элемент canvas).

- -
<html>
- <body onload="draw();">
-     <table>
-      <tr>
-        <td><img src="https://mdn.mozillademos.org/files/5399/gallery_1.jpg"></td>
-        <td><img src="https://mdn.mozillademos.org/files/5401/gallery_2.jpg"></td>
-        <td><img src="https://mdn.mozillademos.org/files/5403/gallery_3.jpg"></td>
-        <td><img src="https://mdn.mozillademos.org/files/5405/gallery_4.jpg"></td>
-      </tr>
-      <tr>
-        <td><img src="https://mdn.mozillademos.org/files/5407/gallery_5.jpg"></td>
-        <td><img src="https://mdn.mozillademos.org/files/5409/gallery_6.jpg"></td>
-        <td><img src="https://mdn.mozillademos.org/files/5411/gallery_7.jpg"></td>
-        <td><img src="https://mdn.mozillademos.org/files/5413/gallery_8.jpg"></td>
-      </tr>
-     </table>
-     <img id="frame" src="https://mdn.mozillademos.org/files/242/Canvas_picture_frame.png" width="132" height="150">
- </body>
-</html>
-
- -

И сюда какую-нибудь CSS для украшения:

- -
body {
-  background: 0 -100px repeat-x url(https://mdn.mozillademos.org/files/5415/bg_gallery.png) #4F191A;
-  margin: 10px;
-}
-
-img {
-  display: none;
-}
-
-table {
-  margin: 0 auto;
-}
-
-td {
-  padding: 15px;
-}
-
- -

Связывая все вместе  JavaScript рисует наши изображения в рамках:

- -
function draw() {
-
-  // Цикл по всем изображениям
-  for (var i=0;i<document.images.length;i++){
-
-    // Не добавляет canvas для изображения рамки
-    if (document.images[i].getAttribute('id')!='frame'){
-
-      // Создает элемент canvas
-      var canvas = document.createElement('canvas');
-      canvas.setAttribute('width',132);
-      canvas.setAttribute('height',150);
-
-      // Вставляет перед изображением
-      document.images[i].parentNode.insertBefore(canvas,document.images[i]);
-
-      var ctx = canvas.getContext('2d');
-
-      // Рисует изображение в canvas
-      ctx.drawImage(document.images[i],15,20);
-
-      // Добавляет рамку
-      ctx.drawImage(document.getElementById('frame'),0,0);
-    }
-  }
-}
- -

{{EmbedLiveSample("Art_gallery_example", 725, 400)}}

- -

Контроль изменений размеров изображения

- -

Как было отмечено ранее, изменение размеров изображений может привести к размытости или к шуму в процессе преобразования. Вы можете использовать контекст рисования {{domxref("CanvasRenderingContext2D.imageSmoothingEnabled", "imageSmoothingEnabled")}} свойства, чтобы контролировать использование сглаживающего алгоритма, когда изменяющиеся изображения в вашем контексте. Обычно это свойство установлено в  true, означая, что изображения будут сглажены во время изменения размеров. Вы можете отключить это свойство так:

- -
ctx.mozImageSmoothingEnabled = false;
-ctx.webkitImageSmoothingEnabled = false;
-ctx.msImageSmoothingEnabled = false;
-ctx.imageSmoothingEnabled = false;
-
- -

{{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_text", "Web/API/Canvas_API/Tutorial/Transformations")}}

diff --git "a/files/ru/web/api/canvas_api/tutorial/\320\272\320\276\320\274\320\277\320\276\320\267\320\270\321\206\320\270\320\270/index.html" "b/files/ru/web/api/canvas_api/tutorial/\320\272\320\276\320\274\320\277\320\276\320\267\320\270\321\206\320\270\320\270/index.html" deleted file mode 100644 index 264cc7e544..0000000000 --- "a/files/ru/web/api/canvas_api/tutorial/\320\272\320\276\320\274\320\277\320\276\320\267\320\270\321\206\320\270\320\270/index.html" +++ /dev/null @@ -1,108 +0,0 @@ ---- -title: Композиция и обрезка -slug: Web/API/Canvas_API/Tutorial/Композиции -tags: - - канвас -translation_of: Web/API/Canvas_API/Tutorial/Compositing ---- -
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Transformations", "Web/API/Canvas_API/Tutorial/Basic_animations")}}
- -
-

Во всех наших предыдущих примерах, фигуры всегда были нарисованы одна поверх другой. Это более чем достаточно для большинства ситуаций, но это ограничивает порядок, в котором построены композиционные формы. Однако, мы можем изменить это поведение, установив свойство globalCompositeOperation. Кроме того, свойства clip позволяет скрыть нежелательные части формы.

-
- -

globalCompositeOperation

- -

Мы можем не только рисовать новые фигуры за существующие формы, но мы также можем использовать его, чтобы замаскировать определенные участки, очистить разделы от холста (не ограничивается прямоугольниками, как{{domxref("CanvasRenderingContext2D.clearRect", "clearRect()")}} method does) и другое.

- -
-
{{domxref("CanvasRenderingContext2D.globalCompositeOperation", "globalCompositeOperation = type")}}
-
Это задает Тип операции композиции для применения при разработке новых форм, где Тип является строкой, идентифицирующей, какие из двенадцати операций композитинг в использовании.
-
- -

См.  примеры компоновки кода из следующих примеров.

- -

{{EmbedLiveSample("Compositing_example", 750, 6750, "" ,"Web/API/Canvas_API/Tutorial/Compositing/Example")}}

- -

Обрезка контуров

- -

Отсеченный контур похож на обычную форму холста, но он действует как маска, чтобы скрыть нежелательные части фигур. Это визуализируется на изображении справа. Форма красной звезды - наша отправочная дорожка. Все, что выходит за пределы этого пути, не будет нарисовано на холсте.

- -

Если мы сравниваем отсеченный контур со свойством globalCompositeOperation на изображении, мы видим два режима композитинга, которые достигают более или менее того же эффекта в исходном и исходном состоянии.   Наиболее важные различия между ними заключаются в том, что отсечение контура фактически  никогда не обращается к холсту и контур обрезки никогда не влияет добавление новых форм. Это делает обрезку контура идеальным для рисования нескольких фигур в ограниченной области.

- -

В главе о рисовании форм, я назвал только stroke() и fill() методы, но есть третий способ можно использовать с контурами, так называемый clip().

- -
-
{{domxref("CanvasRenderingContext2D.clip", "clip()")}}
-
Преобразует текущий выстраиваемый контур в отсечённый контур.
-
- -

Используйте clip() вместо closePath() для закрытия контура и его преобразования в отсечённый контур вместо создания заполняющего  или обрамляющего контура.

- -

По умолчанию элемент {{HTMLElement("canvas")}} использует отсечённый контур, который в точности совпадает по размеру с размером самого холста. Это означает, что никакого отсечения попросту не произойдёт.

- -

Пример обрезки

- -

В этом примере мы будем использовать круговую обрезку контура, чтобы ограничить рисование набора случайных звезд определенной областью.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  ctx.fillRect(0, 0, 150, 150);
-  ctx.translate(75, 75);
-
-  // Create a circular clipping path
-  ctx.beginPath();
-  ctx.arc(0, 0, 60, 0, Math.PI * 2, true);
-  ctx.clip();
-
-  // draw background
-  var lingrad = ctx.createLinearGradient(0, -75, 0, 75);
-  lingrad.addColorStop(0, '#232256');
-  lingrad.addColorStop(1, '#143778');
-
-  ctx.fillStyle = lingrad;
-  ctx.fillRect(-75, -75, 150, 150);
-
-  // draw stars
-  for (var j = 1; j < 50; j++) {
-    ctx.save();
-    ctx.fillStyle = '#fff';
-    ctx.translate(75 - Math.floor(Math.random() * 150),
-                  75 - Math.floor(Math.random() * 150));
-    drawStar(ctx, Math.floor(Math.random() * 4) + 2);
-    ctx.restore();
-  }
-
-}
-
-function drawStar(ctx, r) {
-  ctx.save();
-  ctx.beginPath();
-  ctx.moveTo(r, 0);
-  for (var i = 0; i < 9; i++) {
-    ctx.rotate(Math.PI / 5);
-    if (i % 2 === 0) {
-      ctx.lineTo((r / 0.525731) * 0.200811, 0);
-    } else {
-      ctx.lineTo(r, 0);
-    }
-  }
-  ctx.closePath();
-  ctx.fill();
-  ctx.restore();
-}
-
- - - -

В первых нескольких строках кода мы рисуем черный прямоугольник размером с холстом в качестве фона, а затем переводим начало координат в центр. Затем мы создаем круговой обтравочный контур, рисуя дугу и вызывающий clip(). Обрезанные контуры также являются частью состояния сохранения холста. Если бы мы хотели сохранить исходный обтравочный контур, мы могли бы сохранить состояние холста перед созданием нового.

- -

Все, что нарисовано после создания отсеченного контура, появится только внутри этого пути. Вы можете видеть это четко в линейном градиенте, который нарисован далее. После этого набирается набор из 50 случайно расположенных и масштабированных звезд, используя drawStar(). Снова звезды появляются только в пределах определенного обтравочного контура.

- -

{{EmbedLiveSample("A_clip_example", "180", "180", "https://mdn.mozillademos.org/files/208/Canvas_clip.png")}}

- -

{{PreviousNext("Web/API/Canvas_API/Tutorial/Transformations", "Web/API/Canvas_API/Tutorial/Basic_animations")}}

diff --git "a/files/ru/web/api/canvas_api/tutorial/\320\276\321\201\320\275\320\276\320\262\321\213_\320\260\320\275\320\270\320\274\320\260\321\206\320\270\320\270/index.html" "b/files/ru/web/api/canvas_api/tutorial/\320\276\321\201\320\275\320\276\320\262\321\213_\320\260\320\275\320\270\320\274\320\260\321\206\320\270\320\270/index.html" deleted file mode 100644 index a47b8b734e..0000000000 --- "a/files/ru/web/api/canvas_api/tutorial/\320\276\321\201\320\275\320\276\320\262\321\213_\320\260\320\275\320\270\320\274\320\260\321\206\320\270\320\270/index.html" +++ /dev/null @@ -1,308 +0,0 @@ ---- -title: Простые анимации -slug: Web/API/Canvas_API/Tutorial/Основы_анимации -tags: - - HTML - - HTML5 - - Графика - - Обучение - - Средний уровень - - Холст -translation_of: Web/API/Canvas_API/Tutorial/Basic_animations ---- -
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Compositing", "Web/API/Canvas_API/Tutorial/Advanced_animations")}}
- -
-

Поскольку для управления элементами {{HTMLElement ("canvas")}} используется JavaScript, не составляет труда сделать (интерактивные) анимации. В этой главе мы рассмотрим, как делаются некоторые базовые анимации.

-
- -

Вероятно, самым большим ограничением является то, что когда фигура нарисована, её уже нельзя двигать. Чтобы изобразить движение нам нужно перерисовать фигуру и всё, что было нарисовано до неё. Перерисовка сложных кадров занимает много времени, и производительность сильно зависит от скорости компьютера, на котором она выполняется.

- -

Основные шаги анимации

- -

Ниже перечислены необходимые шаги для того, чтобы нарисовать кадр:

- -
    -
  1. Очистить canvas
    - Если фигура, которую вы собираетесь нарисовать, не занимает всю площадь canvas (как фон, например), то всё что было нарисовано ранее необходимо стереть. Проще всего это сделать при помощи метода {{domxref("CanvasRenderingContext2D.clearRect", "clearRect()")}}.
  2. -
  3. Сохранить изначальное состояние canvas
    - Если вы изменяете любые настройки (такие как стили, трансформации и т.п.), которые затрагивают состояние canvas и вы хотите убедиться, что оригинальное состояние используется каждый раз, когда был отрисован кадр, то вам следует сохранить это оригинальное состояние.
  4. -
  5. Нарисовать анимированные фигуры
    - Шаг на котором вы собственно отрисовываете кадр.
  6. -
  7. Восстановить состояние canvas
    - Если вы сохраняли состояние, восстановите его, прежде чем отрисовывать новый кадр.
  8. -
- -

Управление анимацией

- -

Фигуры отрисовываются на canvas либо напрямую — при помощи методов canvas, либо с помощью сторонних функций. В нормальной ситуации результат станет виден на canvas после окончания выполнения скрипта. К примеру, цикл for использовать для анимации нельзя. 

- -

Это значит, нужен способ выполнения функций отрисовки через интервалы времени. Есть два способа для управления такой анимацией.

- -

Запланированные обновления

- -

Первый — это функции {{domxref("window.setInterval()")}}, {{domxref("window.setTimeout()")}}, и {{domxref("window.requestAnimationFrame()")}}, которые могут быть использованы для вызова некоторой функции, через заданный промежуток времени.

- -
-
{{domxref("WindowTimers.setInterval", "setInterval(function, delay)")}}
-
Начинает периодически исполнять функцию function каждые delay миллисекунд.
-
{{domxref("WindowTimers.setTimeout", "setTimeout(function, delay)")}}
-
Запускает выполнение указанной функции function через delay миллисекунд.
-
{{domxref("Window.requestAnimationFrame()", "requestAnimationFrame(callback)")}}
-
Сообщает браузеру, что вы хотите выполнить анимацию, и запрашивает, чтобы браузер вызвал указанную функцию callback для обновления анимации перед следующей перерисовкой.
-
- -

Если вы не планируете никакого взаимодействия с пользователем, вы можете использовать функцию setInterval() , которая многократно выполняет, предоставленный ей код. Если же вы планиуете создать игру, в которой контроль анимации осуществляется мышью или клавиатурой, то необходимо использовать  setTimeout(). Установив {{domxref("EventListener")}}, вы можете перехватываете любые действия пользователя и запустить соответствующие функции анимации.

- -
-

В примерах ниже мы будем использовать функцию {{domxref("window.requestAnimationFrame()")}} для контроля анимации. Функция requestAnimationFrame является более эффективной для создания анимации, так как новая итерация вызывается, когда система готова к отрисовке нового кадра. Количество вызовов в секунду примерно равно 60 и уменьшается, когда вкладка неактивна. Для более подробного изучения цикла анимации, особенно для игр, прочитайте статью Анатомия видеоигр В Зоне разработке игр.

-
- -

Анимированная солнечная система

- -

В этом примере анимируется небольшая модель солнечной системы.

- -
var sun = new Image();
-var moon = new Image();
-var earth = new Image();
-function init(){
-  sun.src = 'https://mdn.mozillademos.org/files/1456/Canvas_sun.png';
-  moon.src = 'https://mdn.mozillademos.org/files/1443/Canvas_moon.png';
-  earth.src = 'https://mdn.mozillademos.org/files/1429/Canvas_earth.png';
-  window.requestAnimationFrame(draw);
-}
-
-function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  ctx.globalCompositeOperation = 'destination-over';
-  ctx.clearRect(0,0,300,300); // clear canvas
-
-  ctx.fillStyle = 'rgba(0,0,0,0.4)';
-  ctx.strokeStyle = 'rgba(0,153,255,0.4)';
-  ctx.save();
-  ctx.translate(150,150);
-
-  // Earth
-  var time = new Date();
-  ctx.rotate( ((2*Math.PI)/60)*time.getSeconds() + ((2*Math.PI)/60000)*time.getMilliseconds() );
-  ctx.translate(105,0);
-  ctx.fillRect(0,-12,50,24); // Shadow
-  ctx.drawImage(earth,-12,-12);
-
-  // Moon
-  ctx.save();
-  ctx.rotate( ((2*Math.PI)/6)*time.getSeconds() + ((2*Math.PI)/6000)*time.getMilliseconds() );
-  ctx.translate(0,28.5);
-  ctx.drawImage(moon,-3.5,-3.5);
-  ctx.restore();
-
-  ctx.restore();
-
-  ctx.beginPath();
-  ctx.arc(150,150,105,0,Math.PI*2,false); // Earth orbit
-  ctx.stroke();
-
-  ctx.drawImage(sun,0,0,300,300);
-
-  window.requestAnimationFrame(draw);
-}
-
-init();
-
- - - -

{{EmbedLiveSample("An_animated_solar_system", "310", "310", "https://mdn.mozillademos.org/files/202/Canvas_animation1.png")}}

- -

Анимированные часы

- -

В этом примере создаются анимированные часы, показывающие правильное время.

- -
function clock(){
-  var now = new Date();
-  var ctx = document.getElementById('canvas').getContext('2d');
-  ctx.save();
-  ctx.clearRect(0,0,150,150);
-  ctx.translate(75,75);
-  ctx.scale(0.4,0.4);
-  ctx.rotate(-Math.PI/2);
-  ctx.strokeStyle = "black";
-  ctx.fillStyle = "white";
-  ctx.lineWidth = 8;
-  ctx.lineCap = "round";
-
-  // Hour marks
-  ctx.save();
-  for (var i=0;i<12;i++){
-    ctx.beginPath();
-    ctx.rotate(Math.PI/6);
-    ctx.moveTo(100,0);
-    ctx.lineTo(120,0);
-    ctx.stroke();
-  }
-  ctx.restore();
-
-  // Minute marks
-  ctx.save();
-  ctx.lineWidth = 5;
-  for (i=0;i<60;i++){
-    if (i%5!=0) {
-      ctx.beginPath();
-      ctx.moveTo(117,0);
-      ctx.lineTo(120,0);
-      ctx.stroke();
-    }
-    ctx.rotate(Math.PI/30);
-  }
-  ctx.restore();
-
-  var sec = now.getSeconds();
-  var min = now.getMinutes();
-  var hr  = now.getHours();
-  hr = hr>=12 ? hr-12 : hr;
-
-  ctx.fillStyle = "black";
-
-  // write Hours
-  ctx.save();
-  ctx.rotate( hr*(Math.PI/6) + (Math.PI/360)*min + (Math.PI/21600)*sec )
-  ctx.lineWidth = 14;
-  ctx.beginPath();
-  ctx.moveTo(-20,0);
-  ctx.lineTo(80,0);
-  ctx.stroke();
-  ctx.restore();
-
-  // write Minutes
-  ctx.save();
-  ctx.rotate( (Math.PI/30)*min + (Math.PI/1800)*sec )
-  ctx.lineWidth = 10;
-  ctx.beginPath();
-  ctx.moveTo(-28,0);
-  ctx.lineTo(112,0);
-  ctx.stroke();
-  ctx.restore();
-
-  // Write seconds
-  ctx.save();
-  ctx.rotate(sec * Math.PI/30);
-  ctx.strokeStyle = "#D40000";
-  ctx.fillStyle = "#D40000";
-  ctx.lineWidth = 6;
-  ctx.beginPath();
-  ctx.moveTo(-30,0);
-  ctx.lineTo(83,0);
-  ctx.stroke();
-  ctx.beginPath();
-  ctx.arc(0,0,10,0,Math.PI*2,true);
-  ctx.fill();
-  ctx.beginPath();
-  ctx.arc(95,0,10,0,Math.PI*2,true);
-  ctx.stroke();
-  ctx.fillStyle = "rgba(0,0,0,0)";
-  ctx.arc(0,0,3,0,Math.PI*2,true);
-  ctx.fill();
-  ctx.restore();
-
-  ctx.beginPath();
-  ctx.lineWidth = 14;
-  ctx.strokeStyle = '#325FA2';
-  ctx.arc(0,0,142,0,Math.PI*2,true);
-  ctx.stroke();
-
-  ctx.restore();
-
-  window.requestAnimationFrame(clock);
-}
-
-window.requestAnimationFrame(clock);
- - - -

{{EmbedLiveSample("An_animated_clock", "180", "180", "https://mdn.mozillademos.org/files/203/Canvas_animation2.png")}}

- -

Зацикленная панорама

- -

В этом примере панорама прокручивается слева направо. Мы используем фото национального парка Йосемити взятое из Википедии, но вы можете использовать любое изображение, большее элемента canvas.

- -
var img = new Image();
-
-// User Variables - customize these to change the image being scrolled, its
-// direction, and the speed.
-
-img.src = 'https://mdn.mozillademos.org/files/4553/Capitan_Meadows,_Yosemite_National_Park.jpg';
-var CanvasXSize = 800;
-var CanvasYSize = 200;
-var speed = 30; //lower is faster
-var scale = 1.05;
-var y = -4.5; //vertical offset
-
-// Main program
-
-var dx = 0.75;
-var imgW;
-var imgH;
-var x = 0;
-var clearX;
-var clearY;
-var ctx;
-
-img.onload = function() {
-    imgW = img.width*scale;
-    imgH = img.height*scale;
-    if (imgW > CanvasXSize) { x = CanvasXSize-imgW; } // image larger than canvas
-    if (imgW > CanvasXSize) { clearX = imgW; } // image larger than canvas
-    else { clearX = CanvasXSize; }
-    if (imgH > CanvasYSize) { clearY = imgH; } // image larger than canvas
-    else { clearY = CanvasYSize; }
-    //Get Canvas Element
-    ctx = document.getElementById('canvas').getContext('2d');
-    //Set Refresh Rate
-    return setInterval(draw, speed);
-}
-
-function draw() {
-    //Clear Canvas
-    ctx.clearRect(0,0,clearX,clearY);
-    //If image is <= Canvas Size
-    if (imgW <= CanvasXSize) {
-        //reset, start from beginning
-        if (x > (CanvasXSize)) { x = 0; }
-        //draw aditional image
-        if (x > (CanvasXSize-imgW)) { ctx.drawImage(img,x-CanvasXSize+1,y,imgW,imgH); }
-    }
-    //If image is > Canvas Size
-    else {
-        //reset, start from beginning
-        if (x > (CanvasXSize)) { x = CanvasXSize-imgW; }
-        //draw aditional image
-        if (x > (CanvasXSize-imgW)) { ctx.drawImage(img,x-imgW+1,y,imgW,imgH); }
-    }
-    //draw image
-    ctx.drawImage(img,x,y,imgW,imgH);
-    //amount to move
-    x += dx;
-}
-
- -

Заметьте, что ширина и высота должны совпадать  со значениями CanvasXZSize и CanvasYSize.

- -
<canvas id="canvas" width="800" height="200"></canvas>
- -

{{EmbedLiveSample("A_looping_panorama", "830", "230")}}

- -

Другие примеры

- -
-
A basic ray-caster
-
Хороший пример того, как сделать управляемую анимацию с клавиатуры.
-
Advanced animations
-
Мы рассмотрим некоторые продвинутые методы анимации и физику в следующей главе.
-
- -

{{PreviousNext("Web/API/Canvas_API/Tutorial/Compositing", "Web/API/Canvas_API/Tutorial/Advanced_animations")}}

diff --git "a/files/ru/web/api/canvas_api/tutorial/\320\277\321\200\320\270\320\274\320\265\320\275\320\265\320\275\320\270\320\265_\321\201\321\202\320\270\320\273\320\265\320\271_\320\270_\321\206\320\262\320\265\321\202\320\276\320\262/index.html" "b/files/ru/web/api/canvas_api/tutorial/\320\277\321\200\320\270\320\274\320\265\320\275\320\265\320\275\320\270\320\265_\321\201\321\202\320\270\320\273\320\265\320\271_\320\270_\321\206\320\262\320\265\321\202\320\276\320\262/index.html" deleted file mode 100644 index 2c9eeaae78..0000000000 --- "a/files/ru/web/api/canvas_api/tutorial/\320\277\321\200\320\270\320\274\320\265\320\275\320\265\320\275\320\270\320\265_\321\201\321\202\320\270\320\273\320\265\320\271_\320\270_\321\206\320\262\320\265\321\202\320\276\320\262/index.html" +++ /dev/null @@ -1,726 +0,0 @@ ---- -title: Применение стилей и цветов -slug: Web/API/Canvas_API/Tutorial/Применение_стилей_и_цветов -translation_of: Web/API/Canvas_API/Tutorial/Applying_styles_and_colors ---- -
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_shapes", "Web/API/Canvas_API/Tutorial/Drawing_text")}}
- -
-

В главе о рисовании фигур, мы использовали для линий и заполнения только стили по умолчанию. Здесь мы будем исследовать опции canvas, которые мы имеем в нашем распоряжении, чтобы сделать наши рисунки немного более привлекательными. Вы узнаете, как добавлять различные цвета, стили линий, градиенты, узоры и тени вашим рисункам.

-
- -

Цвета

- -

До сих пор мы видели только методы рисования контекста. Если мы хотим применить цвета к фигуре, то есть два важных свойства, которые мы можем использовать: fillStyle и strokeStyle.

- -
-
{{domxref("CanvasRenderingContext2D.fillStyle", "fillStyle = color")}}
-
Устанавливает стиль для фона фигур.
-
{{domxref("CanvasRenderingContext2D.strokeStyle", "strokeStyle = color")}}
-
Устанавливает стиль контура фигуры. 
-
- -

color может быть цветом, (строка, представленная в CSS {{cssxref("<color>")}}), градиентом или паттерном. Градиенты и паттерны мы рассмотрим позже. По умолчанию цвет фона и контура  — черный (значение CSS цвета  #000000).

- -
-

На заметку: Когда вы устанавливаете  значения strokeStyle и/или fillStyle, то новое значение становится стандартным для всех фигур, которые будут нарисованы с этого момента. Когда вам нужен другой цвет, вы должны перезаписать значение в fillStyle или в strokeStyle для каждой фигуры.

-
- -

Чтобы строка color считалась валидной, она должна соответствовать CSS {{cssxref("<color>")}}. Далее приведены примеры того, как можно по-разному задать один и тот же цвет. 

- -
// these all set the fillStyle to 'orange'
-
-ctx.fillStyle = "orange";
-ctx.fillStyle = "#FFA500";
-ctx.fillStyle = "rgb(255,165,0)";
-ctx.fillStyle = "rgba(255,165,0,1)";
-
- -

Пример fillStyle

- -

В этом примере мы опять воспользуемся двойным циклом, чтобы нарисовать сетку из прямоугольников, каждый из которых имеет свой цвет. Окончательное изображение должно иметь вид, как показано на скриншоте. Здесь не происходит ничего сверхъестественного. Мы используем две переменные i и j для генерации уникального RGB цвета для каждого квадрата и изменяем только красные и зеленые значения. Синий канал представляет собой фиксированное значение. Путем изменения каналов вы можете генерировать всю палитру. Увеличив количество шагов вы можете достигнуть такого вида палитры, какая используется в Photoshop.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  for (var i=0;i<6;i++){
-    for (var j=0;j<6;j++){
-      ctx.fillStyle = 'rgb(' + Math.floor(255-42.5*i) + ',' +
-                       Math.floor(255-42.5*j) + ',0)';
-      ctx.fillRect(j*25,i*25,25,25);
-    }
-  }
-}
- - - -

Результат выглядит так:

- -

{{EmbedLiveSample("Пример_fillStyle", 160, 160, "https://mdn.mozillademos.org/files/5417/Canvas_fillstyle.png")}}

- -

Пример strokeStyle

- -

Этот пример похож на предыдущий, но мы используем свойство strokeStyle чтобы изменить цвета очертаний фигур. Так же мы используем метод arc() для рисования окружностей вместо квадратов.

- -
  function draw() {
-    var ctx = document.getElementById('canvas').getContext('2d');
-    for (var i=0;i<6;i++){
-      for (var j=0;j<6;j++){
-        ctx.strokeStyle = 'rgb(0,' + Math.floor(255-42.5*i) + ',' +
-                         Math.floor(255-42.5*j) + ')';
-        ctx.beginPath();
-        ctx.arc(12.5+j*25,12.5+i*25,10,0,Math.PI*2,true);
-        ctx.stroke();
-      }
-    }
-  }
-
- - - -

Результат выглядит так:

- -

{{EmbedLiveSample("Пример_strokeStyle", "180", "180", "https://mdn.mozillademos.org/files/253/Canvas_strokestyle.png")}}

- -

Прозрачность

- -

В дополнении к рисованию непрозрачных фигур, мы также можем рисовать прозрачные (полупрозрачные) фигуры.  Это делается через установку свойства globalAlpha или задачи полупрозрачного цвета фона или контура.

- -
-
{{domxref("CanvasRenderingContext2D.globalAlpha", "globalAlpha = transparencyValue")}}
-
Для применения, указывается значения прозрачности для всех будущих фигур, что будут нарисованы на canvas. Значение полупрозрачности могут быть между 0.0 (полная прозрачность) и 1.0 (полная непрозрачность). Значение 1.0 (полная непрозрачность) установлено по умолчанию.
-
- -

Свойство globalAlpha может быть использовано, если вы хотите рисовать формы с одинаковой прозрачностью, но в иной ситуации, обычно устанавливают прозрачность индивидуально к каждой форме, когда указывают их цвет.

- -

Так как свойства strokeStyle и fillStyle принимают цветовые значения rgba через CSS, мы можем использовать следующее обозначение  для назначения прозрачных цветов.

- -
// Assigning transparent colors to stroke and fill style
-
-ctx.strokeStyle = "rgba(255,0,0,0.5)";
-ctx.fillStyle = "rgba(255,0,0,0.5)";
-
- -

Функция rgba() похожа на функцию rgb(), но имеет один дополнительный параметр. Последний параметр устанавливает значение прозрачности для конкретного цвета. Действующий диапозон значений находится между 0.0 (полная прозрачность) и 1.0 (полная непрозрачность).

- -

Пример globalAlpha

- -

В данном примере мы нарисуем фон и четыре квадрата с различными цветами.  Сверху изображения будет выведен набор полупрозрачных кругов. Установим свойство globalAlpha значением 0.2, которое будет использовано для всех последующих форм. Каждый шаг цикла рисует круг с большим радиусом. По окончанию получим радиальный градиент. Накладывая еще больше кругов друг на друга, мы фактически сможем уменьшить прозрачность ранее нарисованных кругов. Увеличив счетчик итераций, при этом рисуя еще круги, мы сможем добиться исчезновение центра изображения.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  // фон изображения
-  ctx.fillStyle = '#FD0';
-  ctx.fillRect(0,0,75,75);
-  ctx.fillStyle = '#6C0';
-  ctx.fillRect(75,0,75,75);
-  ctx.fillStyle = '#09F';
-  ctx.fillRect(0,75,75,75);
-  ctx.fillStyle = '#F30';
-  ctx.fillRect(75,75,75,75);
-  ctx.fillStyle = '#FFF';
-
-  // устанавливаем значение прозрачности
-  ctx.globalAlpha = 0.2;
-
-  // Рисуем полупрозрачные круги
-  for (i=0;i<7;i++){
-    ctx.beginPath();
-    ctx.arc(75,75,10+10*i,0,Math.PI*2,true);
-    ctx.fill();
-  }
-}
- - - -

{{EmbedLiveSample("Пример_globalAlpha", "180", "180", "https://mdn.mozillademos.org/files/232/Canvas_globalalpha.png")}}

- -

Пример использования rgba()

- -

В этом втором примере мы делаем что-то похожее на предыдущее, но вместо рисования кругов друг над другом, я рисовал маленькие прямоугольники с увеличением непрозрачности. Использование rgba() добавляет контроля и гибкости, поскольку мы можем индивидуально настраивать стиль заливки и штриха.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  // Нарисовать фон
-  ctx.fillStyle = 'rgb(255,221,0)';
-  ctx.fillRect(0,0,150,37.5);
-  ctx.fillStyle = 'rgb(102,204,0)';
-  ctx.fillRect(0,37.5,150,37.5);
-  ctx.fillStyle = 'rgb(0,153,255)';
-  ctx.fillRect(0,75,150,37.5);
-  ctx.fillStyle = 'rgb(255,51,0)';
-  ctx.fillRect(0,112.5,150,37.5);
-
-  // Нарисовать полупрозрачные прямоугольники
-  for (var i=0;i<10;i++){
-    ctx.fillStyle = 'rgba(255,255,255,'+(i+1)/10+')';
-    for (var j=0;j<4;j++){
-      ctx.fillRect(5+i*14,5+j*37.5,14,27.5);
-    }
-  }
-}
- - - -

{{EmbedLiveSample("Пример_использования_rgba()", "180", "180", "https://mdn.mozillademos.org/files/246/Canvas_rgba.png")}}

- -

Стили линий

- -

Есть несколько свойств, которые позволяют нам стилизовать линии.

- -
-
{{domxref("CanvasRenderingContext2D.lineWidth", "lineWidth = value")}}
-
Устанавливает ширину линий, рисуемых в будущем.
-
{{domxref("CanvasRenderingContext2D.lineCap", "lineCap = type")}}
-
Устанавливает внешний вид концов линий.
-
{{domxref("CanvasRenderingContext2D.lineJoin", "lineJoin = type")}}
-
Устанавливает внешний вид «углов», где встречаются линии.
-
{{domxref("CanvasRenderingContext2D.miterLimit", "miterLimit = value")}}
-
Устанавливает ограничение на митру, когда две линии соединяются под острым углом, чтобы вы могли контролировать её толщину.
-
{{domxref("CanvasRenderingContext2D.getLineDash", "getLineDash()")}}
-
Возвращает текущий массив тире штриховки, содержащий четное число неотрицательных чисел.
-
{{domxref("CanvasRenderingContext2D.setLineDash", "setLineDash(segments)")}}
-
Устанавливает текущий пунктир линии.
-
{{domxref("CanvasRenderingContext2D.lineDashOffset", "lineDashOffset = value")}}
-
Указывает, где следует начинать тире массива в строке.
-
- -

Вы лучше поймете, что они делают, глядя на приведенные ниже примеры.

- -

Пример lineWidth

- -

Это свойство задает толщину текущей строки. Значения должны быть положительными. По умолчанию для этого значения установлено 1.0 единицы.

- -

Ширина линии - это толщина хода, центрированного по данному пути. Другими словами, область, которая нарисована, простирается до половины ширины линии по обе стороны пути. Поскольку координаты холста не напрямую ссылаются на пиксели, особое внимание следует уделять получению четких горизонтальных и вертикальных линий.

- -

В приведенном ниже примере 10 прямых линий рисуются с увеличением ширины линий. Линия в крайнем левом углу - 1.0 единицы. Тем не менее, толщина левой и всех других линий нечетной ширины не выглядят четкими из-за позиционирования пути.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  for (var i = 0; i < 10; i++){
-    ctx.lineWidth = 1+i;
-    ctx.beginPath();
-    ctx.moveTo(5+i*14,5);
-    ctx.lineTo(5+i*14,140);
-    ctx.stroke();
-  }
-}
-
- - - -

{{EmbedLiveSample("Пример_lineWidth", "180", "180", "https://mdn.mozillademos.org/files/239/Canvas_linewidth.png")}}

- -

Получение четких строк требует понимания путей сглаживания. На рисунках ниже представлена сетка координат холста. Квадраты между сетками являются фактическими экранными пикселями. В первом изображении сетки ниже прямоугольник от (2, 1) до (5, 5) заполняется. Вся область между ними (светло-красный) падает на границы пикселей, поэтому полученный заполненный прямоугольник будет иметь четкие края.

- -

- -

Если вы рассмотрите путь от (3, 1) до (3, 5) с толщиной строки 1.0, вы получите ситуацию во втором изображении. Фактическая заполняемая область, (синяя), распространяется только наполовину в пикселях по обе стороны пути. Приблизительно это означает, что частично затенённые пиксели приводят к заполнению всей области (светло-голубой и синей) цветом, только наполовину темным, чем фактический цвет штриха. Это то, что происходит с линией шириной 1.0 в предыдущем примере кода.

- -

Чтобы исправить это, вы должны быть более точными при создании пути. Зная, что линия шириной 1.0 занимает половину единицы по обе стороны пути, создание пути от (3.5, 1) до (3.5, 5) приведёт к ситуации в третьем изображении - ширина линии 1.0 закончится верно, точно заполняя вертикальную линию с одним пикселем.

- -
-

Примечание: Имейте в виду, что в нашем примере с вертикальной линией позиция Y по-прежнему ссылается на целочисленную позицию сетки - иначе мы увидели бы пиксели с половинным охватом в конечных точках (также обратите внимание, что это поведение зависит от текущего стиля lineCap,  значение по умолчанию - butt; вы можете вычислить согласованные штрихи с полупиксельными координатами для линий с нечетной шириной, установив стиль lineCap в square, чтобы внешняя граница вокруг конечной точки линии автоматически расширялась, охватывая весь пиксель в точку).

- -

Также обратите внимание, что затронуты только начальные и конечные  точки пути: если путь закрыт с помощью closePath(), - нет начальной и конечной точки; вместо этого все конечные точки в пути подключены к их прикрепленному предыдущему и следующему сегментам и при текущей настройке стиля lineJoin в значении по умолчанию - miter, с эффектом автоматического расширения внешних границ подключенных сегментов до их точки пересечения - обработанный ход будет точно покрывать полные пиксели с центром в каждой конечной точке, если эти связанные сегменты горизонтальны и/или вертикальны). См. следующие два раздела, демонстрирующие эти дополнительные стили.

-
- -

Для линий с четной шириной каждая половина заканчивается как целое количество пикселей, поэтому вам нужен путь, который находится между пикселями (то есть (3,1) - (3,5)), вместо середины пикселей.

- -

Хотя это и необычно, когда изначально работаешь с масштабируемой 2D-графикой, обращая внимание на сетку пикселей и положение путей, но вы убедитесь, что ваши рисунки будут выглядеть правильно, независимо от масштабирования или любых других преобразований. Вертикальная линия ширины 1,0, построенная таким образом, станет четкой 2-пиксельной линией при увеличении на 2 и появится в правильном положении.

- -

Пример lineCap

- -

Свойство lineCap определяет, как выводятся конечные точки каждой строки. Для этого свойства есть три возможных значения: butt, round и square. По умолчанию для этого свойства установлено значение butt.

- -

- -
-
butt
-
Концы линий соответствуют крайним точкам.
-
round
-
Концы линий округлены.
-
square
-
Концы линий описаны квадратом с равной шириной и половиной высоты толщины линии.
-
- -

В этом примере мы проведем три строки, каждая из которых имеет другое значение для свойства lineCap. Я также добавил два руководства, чтобы увидеть точные различия между ними. Каждая из этих линий начинается и заканчивается именно на этих направляющих.

- -

Строка слева использует butt опцию по умолчанию. Вы заметите, что она полностью очищена от направляющих. Второй вариант -  round опция. Это добавляет полукруг к концу, который имеет радиус, равный половине ширины линии. Строка справа использует square опцию. Это добавляет поле с равной шириной и половиной высоты толщины линии.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  var lineCap = ['butt','round','square'];
-
-  // Draw guides
-  ctx.strokeStyle = '#09f';
-  ctx.beginPath();
-  ctx.moveTo(10,10);
-  ctx.lineTo(140,10);
-  ctx.moveTo(10,140);
-  ctx.lineTo(140,140);
-  ctx.stroke();
-
-  // Draw lines
-  ctx.strokeStyle = 'black';
-  for (var i=0;i<lineCap.length;i++){
-    ctx.lineWidth = 15;
-    ctx.lineCap = lineCap[i];
-    ctx.beginPath();
-    ctx.moveTo(25+i*50,10);
-    ctx.lineTo(25+i*50,140);
-    ctx.stroke();
-  }
-}
-
- - - -

{{EmbedLiveSample("Пример_lineCap", "180", "180", "https://mdn.mozillademos.org/files/236/Canvas_linecap.png")}}

- -

Пример lineJoin

- -

Свойство lineJoin определяет, как соединяются два сегмента (линий, дуг или кривых) с ненулевой длиной в форме (вырожденные сегменты с нулевой длиной, заданные конечные точки и контрольные точки находятся точно в том же положении - пропущены).

- -

Для этого свойства есть три возможных значения: round, bevel и miter. По умолчанию для этого свойства установлено значение miter. Обратите внимание, что настройка lineJoin не действует, если два связанных сегмента имеют одно и то же направление, потому что в этом случае не будет добавлена ​​область соединения.

- -

- -
-
round
-
Радиус заполняемой части для скругленных углов равен половине ширины линии. центр этого радиуса совпадает с концами подключенных сегментов.
-
bevel
-
Заполняет дополнительную треугольную область между общей конечной точкой подключенных сегментов и отдельными внешними прямоугольными углами каждого сегмента. 
-
miter
-
Подключенные сегменты соединяются путем расширения их внешних краев для соединения в одной точке с эффектом заполнения дополнительной области в форме пастилки. Эта настройка выполняется с помощью свойства miterLimit, которое объясняется ниже.
-
- -

В приведенном ниже примере показаны три разных пути, демонстрирующие каждый из этих трех свойств lineJoin; результат - выше. 

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  var lineJoin = ['round','bevel','miter'];
-  ctx.lineWidth = 10;
-  for (var i=0;i<lineJoin.length;i++){
-    ctx.lineJoin = lineJoin[i];
-    ctx.beginPath();
-    ctx.moveTo(-5,5+i*40);
-    ctx.lineTo(35,45+i*40);
-    ctx.lineTo(75,5+i*40);
-    ctx.lineTo(115,45+i*40);
-    ctx.lineTo(155,5+i*40);
-    ctx.stroke();
-  }
-}
-
- - - -

{{EmbedLiveSample("Пример_lineJoin", "180", "180", "https://mdn.mozillademos.org/files/237/Canvas_linejoin.png")}}

- -

Демонстрация свойства miterLimit

- -

Как вы видели в предыдущем примере, при объединении двух строк с опцией miter внешние края двух соединительных линий расширены до точки, где они встречаются. Для линий, которые находятся под большими углами друг с другом, эта точка находится недалеко от внутренней точки соединения. Однако, поскольку углы между каждой линией уменьшаются, расстояние (длина меча) между этими точками увеличивается экспоненциально.

- -

Свойство miterLimit определяет, как далеко можно установить внешнюю точку соединения из внутренней точки подключения. Если две линии превышают это значение, вместо этого получается привязка конуса. Обратите внимание, что максимальная длина митра является произведением ширины линии, измеренной в текущей системе координат, значением этого свойства miterLimit (значение по умолчанию 10,0 в HTML {{HTMLElement("canvas")}}), поэтому miterLimit может устанавливаться независимо от текущей шкалы дисплея или любых аффинных преобразований путей: она влияет только на эффективно визуализированную форму ребер линии.

- -

Точнее, предел митры является максимально допустимым отношением длины расширения (в холсте HTML он измеряется между внешним углом соединенных краев линии и общей конечной точкой соединительных сегментов, указанными на пути), до половины ширины линии. Его можно равнозначно определить как максимально допустимое отношение расстояния между внутренней и внешней точками перехода краев к общей ширине линии. Затем он равен косекансу с половиной минимального внутреннего угла соединительных сегментов, ниже которого не будет создано ни одного соединения митра, а только скос соединяется:

- -
    -
  • miterLimit = max miterLength / lineWidth = 1 / sin ( min θ / 2 )
  • -
  • Предел митры по умолчанию, равный 10,0, разделит все митры углов, острее примерно 11 градусов.
  • -
  • Предел митры, равный √2 ≈ 1.4142136 (rounded up) сгладит миты для всех острых углов, поддерживая митры только для тупых или прямых углов.
  • -
  • Предел митры, равный 1,0, действителен, но отключит все миты.
  • -
  • Значения ниже 1.0 являются недопустимыми для предела митры.
  • -
- -

Вот небольшая демонстрация, в которой вы можете динамически установить miterLimit и посмотреть, как это влияет на фигуры на холсте. Синие линии показывают, где начальная и конечная точки для каждой из линий в шаблоне зигзага.

- -

Если вы укажете в этой демонстрации значение miterLimit ниже 4.2, ни один из видимых углов не присоединится к расширению митры, но только с небольшим скосом рядом с синими линиями; с отметкой miterLimit выше 10, большинство углов в этой демонстрации должны соединяться с митрой, удаленной от синих линий, высота которой уменьшается между углами слева направо, потому что они соединяются с растущими углами; с промежуточными значениями углы с левой стороны будут соединяться только с скосом рядом с синими линиями, а углы с правой стороны с удлинителем митры (также с уменьшающейся высотой).

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  // Clear canvas
-  ctx.clearRect(0,0,150,150);
-
-  // Draw guides
-  ctx.strokeStyle = '#09f';
-  ctx.lineWidth   = 2;
-  ctx.strokeRect(-5,50,160,50);
-
-  // Set line styles
-  ctx.strokeStyle = '#000';
-  ctx.lineWidth = 10;
-
-  // check input
-  if (document.getElementById('miterLimit').value.match(/\d+(\.\d+)?/)) {
-    ctx.miterLimit = parseFloat(document.getElementById('miterLimit').value);
-  } else {
-    alert('Value must be a positive number');
-  }
-
-  // Draw lines
-  ctx.beginPath();
-  ctx.moveTo(0,100);
-  for (i=0;i<24;i++){
-    var dy = i%2==0 ? 25 : -25 ;
-    ctx.lineTo(Math.pow(i,1.5)*2,75+dy);
-  }
-  ctx.stroke();
-  return false;
-}
-
- - - -

{{EmbedLiveSample("Демонстрация_свойства_miterLimit", "400", "180", "https://mdn.mozillademos.org/files/240/Canvas_miterlimit.png")}}

- -

Использование штрихов

- -

Метод setLineDash и свойство lineDashOffset задают шаблон штрихов для линий. Метод setLineDash принимает список чисел, который определяет расстояния для попеременного рисования линии и разрыва, а свойство lineDashOffset устанавливает смещение, с которого начинается шаблон.

- -

В этом примере мы создаем эффект походных муравьев. Это техника анимации, часто встречающаяся в инструментах выбора программ компьютерной графики. Это помогает пользователю отличить границу выделения от фона изображения, анимируя границу. В следующей части этого руководства вы узнаете, как сделать эту и другие основные анимации.

- - - -
var ctx = document.getElementById('canvas').getContext('2d');
-var offset = 0;
-
-function draw() {
-  ctx.clearRect(0,0, canvas.width, canvas.height);
-  ctx.setLineDash([4, 2]);
-  ctx.lineDashOffset = -offset;
-  ctx.strokeRect(10,10, 100, 100);
-}
-
-function march() {
-  offset++;
-  if (offset > 16) {
-    offset = 0;
-  }
-  draw();
-  setTimeout(march, 20);
-}
-
-march();
- -

{{EmbedLiveSample("Используемый штрих", "120", "120", "https://mdn.mozillademos.org/files/9853/marching-ants.png")}}

- -

Градиенты

- -

Just like any normal drawing program, we can fill and stroke shapes using linear and radial gradients. We create a {{domxref("CanvasGradient")}} object by using one of the following methods. We can then assign this object to the fillStyle or strokeStyle properties.

- -
-
{{domxref("CanvasRenderingContext2D.createLinearGradient", "createLinearGradient(x1, y1, x2, y2)")}}
-
Creates a linear gradient object with a starting point of (x1, y1) and an end point of (x2, y2).
-
{{domxref("CanvasRenderingContext2D.createRadialGradient", "createRadialGradient(x1, y1, r1, x2, y2, r2)")}}
-
Creates a radial gradient. The parameters represent two circles, one with its center at (x1, y1) and a radius of r1, and the other with its center at (x2, y2) with a radius of r2.
-
- -

For example:

- -
var lineargradient = ctx.createLinearGradient(0, 0, 150, 150);
-var radialgradient = ctx.createRadialGradient(75, 75, 0, 75, 75, 100);
-
- -

Once we've created a CanvasGradient object we can assign colors to it by using the addColorStop() method.

- -
-
{{domxref("CanvasGradient.addColorStop", "gradient.addColorStop(position, color)")}}
-
Creates a new color stop on the gradient object. The position is a number between 0.0 and 1.0 and defines the relative position of the color in the gradient, and the color argument must be a string representing a CSS {{cssxref("<color>")}}, indicating the color the gradient should reach at that offset into the transition.
-
- -

You can add as many color stops to a gradient as you need. Below is a very simple linear gradient from white to black.

- -
var lineargradient = ctx.createLinearGradient(0,0,150,150);
-lineargradient.addColorStop(0, 'white');
-lineargradient.addColorStop(1, 'black');
-
- -

Пример createLinearGradient

- -

In this example, we'll create two different gradients. As you can see here, both the strokeStyle and fillStyle properties can accept a canvasGradient object as valid input.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  // Create gradients
-  var lingrad = ctx.createLinearGradient(0,0,0,150);
-  lingrad.addColorStop(0, '#00ABEB');
-  lingrad.addColorStop(0.5, '#fff');
-  lingrad.addColorStop(0.5, '#26C000');
-  lingrad.addColorStop(1, '#fff');
-
-  var lingrad2 = ctx.createLinearGradient(0,50,0,95);
-  lingrad2.addColorStop(0.5, '#000');
-  lingrad2.addColorStop(1, 'rgba(0,0,0,0)');
-
-  // assign gradients to fill and stroke styles
-  ctx.fillStyle = lingrad;
-  ctx.strokeStyle = lingrad2;
-
-  // draw shapes
-  ctx.fillRect(10,10,130,130);
-  ctx.strokeRect(50,50,50,50);
-
-}
-
- - - -

The first is a background gradient. As you can see, we assigned two colors at the same position. You do this to make very sharp color transitions—in this case from white to green. Normally, it doesn't matter in what order you define the color stops, but in this special case, it does significantly. If you keep the assignments in the order you want them to appear, this won't be a problem.

- -

In the second gradient, we didn't assign the starting color (at position 0.0) since it wasn't strictly necessary, because it will automatically assume the color of the next color stop. Therefore, assigning the black color at position 0.5 automatically makes the gradient, from the start to this stop, black.

- -

{{EmbedLiveSample("Пример_createLinearGradient", "180", "180", "https://mdn.mozillademos.org/files/235/Canvas_lineargradient.png")}}

- -

Пример createRadialGradient

- -

In this example, we'll define four different radial gradients. Because we have control over the start and closing points of the gradient, we can achieve more complex effects than we would normally have in the "classic" radial gradients we see in, for instance, Photoshop (that is, a gradient with a single center point where the gradient expands outward in a circular shape).

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  // Create gradients
-  var radgrad = ctx.createRadialGradient(45,45,10,52,50,30);
-  radgrad.addColorStop(0, '#A7D30C');
-  radgrad.addColorStop(0.9, '#019F62');
-  radgrad.addColorStop(1, 'rgba(1,159,98,0)');
-
-  var radgrad2 = ctx.createRadialGradient(105,105,20,112,120,50);
-  radgrad2.addColorStop(0, '#FF5F98');
-  radgrad2.addColorStop(0.75, '#FF0188');
-  radgrad2.addColorStop(1, 'rgba(255,1,136,0)');
-
-  var radgrad3 = ctx.createRadialGradient(95,15,15,102,20,40);
-  radgrad3.addColorStop(0, '#00C9FF');
-  radgrad3.addColorStop(0.8, '#00B5E2');
-  radgrad3.addColorStop(1, 'rgba(0,201,255,0)');
-
-  var radgrad4 = ctx.createRadialGradient(0,150,50,0,140,90);
-  radgrad4.addColorStop(0, '#F4F201');
-  radgrad4.addColorStop(0.8, '#E4C700');
-  radgrad4.addColorStop(1, 'rgba(228,199,0,0)');
-
-  // draw shapes
-  ctx.fillStyle = radgrad4;
-  ctx.fillRect(0,0,150,150);
-  ctx.fillStyle = radgrad3;
-  ctx.fillRect(0,0,150,150);
-  ctx.fillStyle = radgrad2;
-  ctx.fillRect(0,0,150,150);
-  ctx.fillStyle = radgrad;
-  ctx.fillRect(0,0,150,150);
-}
-
- - - -

In this case, we've offset the starting point slightly from the end point to achieve a spherical 3D effect. It's best to try to avoid letting the inside and outside circles overlap because this results in strange effects which are hard to predict.

- -

The last color stop in each of the four gradients uses a fully transparent color. If you want to have a nice transition from this to the previous color stop, both colors should be equal. This isn't very obvious from the code because it uses two different CSS color methods as a demonstration, but in the first gradient #019F62 = rgba(1,159,98,1).

- -

{{EmbedLiveSample("Пример_createRadialGradient", "180", "180", "https://mdn.mozillademos.org/files/244/Canvas_radialgradient.png")}}

- -

Шаблоны

- -

В одном из предыдущих примеров мы использовали несколько циклов, чтобы создать шаблон из повторяющихся изображений. Однако, есть более простой способ сделать подобное - метод createPattern().

- -
-
{{domxref("CanvasRenderingContext2D.createPattern", "createPattern(image, type)")}}
-
Создает и возвращает новый canvas объект - шаблон (pattern). image - {{domxref("CanvasImageSource")}} (то есть {{domxref ("HTMLImageElement")}}, другой холст, элемент {{HTMLElement ("video")}} или подобный  объект. type - строка, указывающая, как использовать image.
-
- -

Тип указывает, как использовать image для создания шаблона и должен быть одним из следующих значений:

- -
-
repeat
-
Повторяет изображение в вертикальном и горизонтальном направлениях.
-
repeat-x
-
Повторяет изображение по горизонтали, но не по вертикали.
-
repeat-y
-
Повторяет изображение по вертикали, но не по горизонтали.
-
no-repeat
-
Не повторяет изображение. Используется только один раз.
-
- -

Мы используем этот метод, чтобы создать {{domxref("CanvasPattern")}} объект, который очень похож на методы градиента, рассмотренные ранее. Как только мы создали шаблон, мы можем назначить ему свойства fillStyle или strokeStyle. Например:

- -
var img = new Image();
-img.src = 'someimage.png';
-var ptrn = ctx.createPattern(img,'repeat');
-
- -
-

Примечание: По аналогии с методом drawImage(), вы должны убедиться, что изображение, которое вы используете, загружено до вызова этого метода. Иначе шаблон может быть отрисован некорректно.

-
- -

Пример createPattern

- -

In this last example, we'll create a pattern to assign to the fillStyle property. The only thing worth noting is the use of the image's onload handler. This is to make sure the image is loaded before it is assigned to the pattern.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  // create new image object to use as pattern
-  var img = new Image();
-  img.src = 'https://mdn.mozillademos.org/files/222/Canvas_createpattern.png';
-  img.onload = function(){
-
-    // create pattern
-    var ptrn = ctx.createPattern(img,'repeat');
-    ctx.fillStyle = ptrn;
-    ctx.fillRect(0,0,150,150);
-
-  }
-}
-
- - - -

{{EmbedLiveSample("Пример_createPattern", "180", "180", "https://mdn.mozillademos.org/files/222/Canvas_createpattern.png")}}

- -

Тени

- -

Using shadows involves just four properties:

- -
-
{{domxref("CanvasRenderingContext2D.shadowOffsetX", "shadowOffsetX = float")}}
-
Indicates the horizontal distance the shadow should extend from the object. This value isn't affected by the transformation matrix. The default is 0.
-
{{domxref("CanvasRenderingContext2D.shadowOffsetY", "shadowOffsetY = float")}}
-
Indicates the vertical distance the shadow should extend from the object. This value isn't affected by the transformation matrix. The default is 0.
-
{{domxref("CanvasRenderingContext2D.shadowBlur", "shadowBlur = float")}}
-
Indicates the size of the blurring effect; this value doesn't correspond to a number of pixels and is not affected by the current transformation matrix. The default value is 0.
-
{{domxref("CanvasRenderingContext2D.shadowColor", "shadowColor = color")}}
-
A standard CSS color value indicating the color of the shadow effect; by default, it is fully-transparent black.
-
- -

The properties shadowOffsetX and shadowOffsetY indicate how far the shadow should extend from the object in the X and Y directions; these values aren't affected by the current transformation matrix. Use negative values to cause the shadow to extend up or to the left, and positive values to cause the shadow to extend down or to the right. These are both 0 by default.

- -

The shadowBlur property indicates the size of the blurring effect; this value doesn't correspond to a number of pixels and is not affected by the current transformation matrix. The default value is 0.

- -

The shadowColor property is a standard CSS color value indicating the color of the shadow effect; by default, it is fully-transparent black.

- -
-

Note: Shadows are only drawn for source-over compositing operations.

-
- -

Пример текста с тенью

- -

This example draws a text string with a shadowing effect.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  ctx.shadowOffsetX = 2;
-  ctx.shadowOffsetY = 2;
-  ctx.shadowBlur = 2;
-  ctx.shadowColor = "rgba(0, 0, 0, 0.5)";
-
-  ctx.font = "20px Times New Roman";
-  ctx.fillStyle = "Black";
-  ctx.fillText("Sample String", 5, 30);
-}
-
- - - -

{{EmbedLiveSample("Пример_текста_с_тенью", "180", "100", "https://mdn.mozillademos.org/files/2505/shadowed-string.png")}}

- -

We will look at the font property and fillText method in the next chapter about drawing text.

- -

Canvas fill rules

- -

When using fill (or {{domxref("CanvasRenderingContext2D.clip", "clip")}} and {{domxref("CanvasRenderingContext2D.isPointInPath", "isPointinPath")}}) you can optionally provide a fill rule algorithm by which to determine if a point is inside or outside a path and thus if it gets filled or not. This is useful when a path intersetcs itself or is nested.
-
- Two values are possible:

- - - -

In this example we are using the evenodd rule.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  ctx.beginPath();
-  ctx.arc(50, 50, 30, 0, Math.PI*2, true);
-  ctx.arc(50, 50, 15, 0, Math.PI*2, true);
-  ctx.fill("evenodd");
-}
- - - -

{{EmbedLiveSample("Canvas_fill_rules", "110", "110", "https://mdn.mozillademos.org/files/9855/fill-rule.png")}}

- -

{{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_shapes", "Web/API/Canvas_API/Tutorial/Drawing_text")}}

diff --git "a/files/ru/web/api/canvas_api/tutorial/\321\200\320\270\321\201\320\276\320\262\320\260\320\275\320\270\320\265_\321\202\320\265\320\272\321\201\321\202\320\260/index.html" "b/files/ru/web/api/canvas_api/tutorial/\321\200\320\270\321\201\320\276\320\262\320\260\320\275\320\270\320\265_\321\202\320\265\320\272\321\201\321\202\320\260/index.html" deleted file mode 100644 index 90915c5e09..0000000000 --- "a/files/ru/web/api/canvas_api/tutorial/\321\200\320\270\321\201\320\276\320\262\320\260\320\275\320\270\320\265_\321\202\320\265\320\272\321\201\321\202\320\260/index.html" +++ /dev/null @@ -1,166 +0,0 @@ ---- -title: Рисование текста -slug: Web/API/Canvas_API/Tutorial/Рисование_текста -tags: - - Canvas - - Графика - - Примеры - - Рукводовство - - мануал -translation_of: Web/API/Canvas_API/Tutorial/Drawing_text ---- -
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Applying_styles_and_colors", "Web/API/Canvas_API/Tutorial/Using_images")}}
- -
-

После того, как мы увидели в предыдущей главе, как применять стили и цвета, взглянем на написание текста в canvas.

-
- -

Рисование текста

- -

Контекст рендеринга canvas предоставляет два метода для рисования текста:

- -
-
{{domxref("CanvasRenderingContext2D.fillText", "fillText(text, x, y [, maxWidth])")}}
-
Вставляет заданный текст в положении (x,y). Опционально может быть указана максимальная ширина.
-
{{domxref("CanvasRenderingContext2D.strokeText", "strokeText(text, x, y [, maxWidth])")}}
-
Вставляет контур заданного текста в положении (x,y). Опционально может быть указана максимальная ширина.
-
- -

Пример fillText

- -

Текст вставлен с использованием текущего fillStyle.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  ctx.font = "48px serif";
-  ctx.fillText("Hello world", 10, 50);
-}
- - - -

{{EmbedLiveSample("A_fillText_example", 310, 110)}}

- -

Пример strokeText

- -

Текст вставлен с использованием текущего strokeStyle.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  ctx.font = "48px serif";
-  ctx.strokeText("Hello world", 10, 50);
-}
- - - -

{{EmbedLiveSample("A_strokeText_example", 310, 110)}}

- -

Стилизация текста

- -

В примерах выше мы уже использовали свойство font для изменения размера текста. Кроме него существуют еще несколько свойств, позволяющие настроить вывод текста на canvas:

- -
-
{{domxref("CanvasRenderingContext2D.font", "font = value")}}
-
Это основной стиль, который будет использоваться для вывода текста. Строка имеет такой же синтаксис, как CSS-свойство {{cssxref("font")}}. По умолчанию - sans-serif высотой 10px.
-
{{domxref("CanvasRenderingContext2D.textAlign", "textAlign = value")}}
-
Настройка выравнивания текста. Возможные значения: start, end, left, right или center. По умолчанию - start.
-
{{domxref("CanvasRenderingContext2D.textBaseline", "textBaseline = value")}}
-
Настройка выравнивания текста по вертикали. Возможные значения: top, hanging, middle, alphabetic, ideographic, bottom. По умолчанию - alphabetic.
-
{{domxref("CanvasRenderingContext2D.direction", "direction = value")}}
-
Направление текста. Возможные значения: ltr, rtl, inherit. По умолчанию - inherit.
-
- -

Эти свойства могут быть вам знакомы если вы работали с CSS.

- -

Изображение от WHATWG ниже показывает различные варианты свойства textBaseline.The top of the em square is
-roughly at the top of the glyphs in a font, the hanging baseline is
-where some glyphs like आ are anchored, the middle is half-way
-between the top of the em square and the bottom of the em square,
-the alphabetic baseline is where characters like Á, ÿ,
-f, and Ω are anchored, the ideographic baseline is
-where glyphs like 私 and 達 are anchored, and the bottom
-of the em square is roughly at the bottom of the glyphs in a
-font. The top and bottom of the bounding box can be far from these
-baselines, due to glyphs extending far outside the em square.

- -

Пример textBaseline

- -

Редактируя код ниже, вы можете видеть, как меняется отображение текста на canvas в реальном времени:

- -
ctx.font = "48px serif";
-ctx.textBaseline = "hanging";
-ctx.strokeText("Hello world!", 0, 100);
-
- - - -

{{ EmbedLiveSample('Playable_code', 700, 360) }}

- -

Измерение ширины текста

- -

Для измерения ширины текста (без рисования его на canvas) можно воспользоваться следующим методом:

- -
-
{{domxref("CanvasRenderingContext2D.measureText", "measureText()")}}
-
Возвращает объект {{domxref("TextMetrics")}}, содержащий ширину текста в пикселах, до отрисовки на canvas.
-
- -

Пример ниже показывает, как можно измерить ширину текста.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  var text = ctx.measureText("foo"); // TextMetrics object
-  text.width; // 16;
-}
-
- -

Примечания

- -

В ранних версиях Gecko (движок рендеринга в Firefox, Firefox OS и других приложениях Mozilla) были реализованы методы API с префиксами для рисования текста на canvas. На данный момент они устарели и уже, возможно, удалены, поэтому их правильная работа не гарантируется.

- -

{{PreviousNext("Web/API/Canvas_API/Tutorial/Applying_styles_and_colors", "Web/API/Canvas_API/Tutorial/Using_images")}}

diff --git "a/files/ru/web/api/canvas_api/tutorial/\321\200\320\270\321\201\320\276\320\262\320\260\320\275\320\270\320\265_\321\204\320\270\320\263\321\203\321\200/index.html" "b/files/ru/web/api/canvas_api/tutorial/\321\200\320\270\321\201\320\276\320\262\320\260\320\275\320\270\320\265_\321\204\320\270\320\263\321\203\321\200/index.html" deleted file mode 100644 index f6ca6c23ef..0000000000 --- "a/files/ru/web/api/canvas_api/tutorial/\321\200\320\270\321\201\320\276\320\262\320\260\320\275\320\270\320\265_\321\204\320\270\320\263\321\203\321\200/index.html" +++ /dev/null @@ -1,582 +0,0 @@ ---- -title: Рисование фигур с помощью canvas -slug: Web/API/Canvas_API/Tutorial/Рисование_фигур -translation_of: Web/API/Canvas_API/Tutorial/Drawing_shapes ---- -
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_usage", "Web/API/Canvas_API/Tutorial/Applying_styles_and_colors")}}
- -
-

Теперь, установив наше окружение canvas, мы можем погрузиться в детали того, как рисовать в canvas. К концу этой статьи, Вы научитесь рисовать прямоугольники, треугольники, линии, дуги и кривые, при условии что Вы хорошо знакомы с основными геометрическими фигурами. Работа с путями весьма важна, когда рисуете объекты на canvas и мы увидим как это может быть сделано.

-
- -

Сетка

- -

Перед тем, как мы начнем рисовать, нам нужно поговорить о сетке canvas или координатной плоскости. Наш HTML каркас из предыдущей страницы включал в себя элемент canvas 150 пикселей в ширину и 150 пикселей в высоту. Справа можно увидеть этот canvas с сеткой, накладываемой по умолчанию. Обычно 1 единица на сетке соответствует 1 пикселю на canvas. Начало координат этой сетки расположено в верхнем левом углу в координате (0,0 ). Все элементы размещены относительно этого начала. Таким образом, положение верхнего левого угла синего квадрата составляет х пикселей слева и у пикселей сверху, на координате , у). Позже в этом уроке мы увидим, как можно перевести начало координат в другое место, вращать сетку и даже масштабировать ее, но сейчас мы будем придерживаться настроек сетки по умолчанию.

- -

Рисование прямоугольников

- -

В отличие от {{Glossary("SVG")}}, {{HTMLElement("canvas")}} поддерживает только одну примитивную фигуру: прямоугольник. Все другие фигуры должны быть созданы комбинацией одного или большего количества контуров (paths), набором точек, соединенных в линии. К счастью в ассортименте рисования контуров у нас есть  функции, которые делают возможным составление очень сложных фигур.

- -

Сначала рассмотрим прямоугольник. Ниже представлены три функции рисования прямоугольников в canvas:

- -
-
{{domxref("CanvasRenderingContext2D.fillRect", "fillRect(x, y, width, height)")}}
-
Рисование заполненного прямоугольника.
-
{{domxref("CanvasRenderingContext2D.strokeRect", "strokeRect(x, y, width, height)")}}
-
Рисование прямоугольного контура.
-
{{domxref("CanvasRenderingContext2D.clearRect", "clearRect(x, y, width, height)")}}
-
Очистка  прямоугольной области, делая содержимое совершенно прозрачным.
-
- -

Каждая из приведенных функций принимает несколько параметров: 

- -
    -
  • xy устанавливают положение верхнего левого угла прямоугольника в canvas (относительно начала координат);
  • -
  • width(ширина) и height(высота) определяют размеры прямоугольника.
  • -
- -

Ниже приведена функция draw(), использующая эти три функции.

- -

Пример создания прямоугольных фигур

- - - -
function draw() {
-  var canvas = document.getElementById('canvas');
-  if (canvas.getContext) {
-    var ctx = canvas.getContext('2d');
-
-    ctx.fillRect(25,25,100,100);
-    ctx.clearRect(45,45,60,60);
-    ctx.strokeRect(50,50,50,50);
-  }
-}
- -

Этот пример изображен ниже.

- -

{{EmbedLiveSample("Пример_создания_прямоугольных_фигур", 160, 160, "https://mdn.mozillademos.org/files/245/Canvas_rect.png")}}

- -

Функция fillRect() рисует большой чёрный квадрат со стороной 100 px. Функция clearRect() вырезает квадрат 60х60 из центра, а функция strokeRect() создает прямоугольный контур 50х50 пикселей внутри очищенного квадрата.

- -

На следующей странице мы рассмотрим две альтернативы методу clearRect(), и также увидим, как можно изменять цвет и стиль контура отображаемых фигур.

- -

В отличие от функций создания контуров, которые будут рассмотрены в следующем разделе, все три функции создания прямоугольника сразу же отображаются на canvas.

- -

Рисование контуров (path)

- -

Остальные примитивные фигуры создаются контурами. Контур - это набор точек, которые, соединяясь в отрезки линий, могут образовывать различные фигуры, изогнутые или нет, разной ширины и разного цвета. Контур (или субконтур) может быть закрытым.

- -

Создание фигур используя контуры происходит в несколько важных шагов:

- -
    -
  1. Сначала вы создаете контур.
  2. -
  3. Затем, используя команды рисования, рисуете контур.
  4. -
  5. Потом закрываете контур.
  6. -
  7. Созданный контур вы можете обвести или залить для его отображения.
  8. -
- -

Здесь приведены функции, которые можно использовать в описанных шагах:

- -
-
{{domxref("CanvasRenderingContext2D.beginPath", "beginPath()")}}
-
Создает новый контур. После создания используется в дальнейшем командами рисования при построении контуров.
-
Path методы
-
Методы для установки различных контуров объекта.
-
{{domxref("CanvasRenderingContext2D.closePath", "closePath()")}}
-
Закрывает контур, так что будущие команды рисования вновь направлены контекст.
-
{{domxref("CanvasRenderingContext2D.stroke", "stroke()")}}
-
Рисует фигуру с внешней обводкой.
-
{{domxref("CanvasRenderingContext2D.fill", "fill()")}}
-
Рисует фигуру с заливкой внутренней области.
-
- -

Первый шаг создания контура заключается в вызове функции beginPath(). Внутри содержатся контуры в виде набора суб-контуров (линии, дуги и др.), которые вместе образуют форму фигуры. Каждый вызов этого метода очищает набор, и мы можем начинать рисовать новые фигуры.

- -
Note:  если текущий контур пуст (например, как после вызова beginPath() или на вновь созданном canvas), первой командой построения контура всегда является функция  moveTo(). Поэтому мы всегда можем установить начальную позицию рисования контура после перезагрузки.
- -

Вторым шагом является вызов методов, определяемых видом контура, который нужно нарисовать. Их мы рассмотрим позднее.

- -

Третий и необязательный шаг - это вызов closePath(). Этот метод пытается закрыть фигуру, рисуя прямую линию из текущей точки в начальную. Если фигура была уже закрыта или является просто точкой, то функция ничего не делает.

- -
Note: Когда вы вызываете fill(), то каждая открытая фигура закрывается автоматически, так что вы можете не использовать closePath(). Это обстоятельство не имеет место в случае вызова stroke().
- -

Рисование треугольника

- -

Например, код для рисования треугольника будет выглядеть как-то так:

- - - -
function draw() {
-  var canvas = document.getElementById('canvas');
-  if (canvas.getContext){
-    var ctx = canvas.getContext('2d');
-
-    ctx.beginPath();
-    ctx.moveTo(75,50);
-    ctx.lineTo(100,75);
-    ctx.lineTo(100,25);
-    ctx.fill();
-  }
-}
-
- -

Результат выглядит так:

- -

{{EmbedLiveSample("Рисование_треугольника", 110, 110, "https://mdn.mozillademos.org/files/9847/triangle.png")}}

- -

Передвижение пера

- -

Одна очень полезная функция, которая ничего не рисует, но связана по смыслу с вышеописанными функциями  - это moveTo(). Вы можете представить это как отрыв (подъем) пера от бумаги и его перемещение в другое место.

- -
-
{{domxref("CanvasRenderingContext2D.moveTo", "moveTo(x, y)")}}
-
Перемещает перо в точку с координатами x и y.
-
- -

При инициализации canvas или при вызове beginPath(), вы захотите использовать функцию moveTo() для перемещения в точку начала рисования. Можно использовать moveTo() и для рисования несвязанного(незакрытого) контура. Посмотрите на смайлик ниже.

- -

Вы можете проверить это сами, используя участок кода ниже. Просто вставьте в функцию draw(), рассмотренную ранее.

- - - -
function draw() {
-  var canvas = document.getElementById('canvas');
-  if (canvas.getContext){
-     var ctx = canvas.getContext('2d');
-
-    ctx.beginPath();
-    ctx.arc(75,75,50,0,Math.PI*2,true); // Внешняя окружность
-    ctx.moveTo(110,75);
-    ctx.arc(75,75,35,0,Math.PI,false);  // рот (по часовой стрелке)
-    ctx.moveTo(65,65);
-    ctx.arc(60,65,5,0,Math.PI*2,true);  // Левый глаз
-    ctx.moveTo(95,65);
-    ctx.arc(90,65,5,0,Math.PI*2,true);  // Правый глаз
-    ctx.stroke();
-  }
-}
-
- -

Результат этого ниже:

- -

{{EmbedLiveSample("Передвижение_пера", 160, 160, "https://mdn.mozillademos.org/files/252/Canvas_smiley.png")}}

- -

Если вы захотите увидеть соединные линии, то можете удалить вызов moveTo().

- -
-

Note: Подробнее о функции arc(),посмотрите {{anch("Дуги")}} .

-
- -

Линии

- -

Для рисования прямых линий используйте метод lineTo().

- -
-
{{domxref("CanvasRenderingContext2D.lineTo", "lineTo(x, y)")}}
-
Рисует линию с текущей позиции до позиции, определенной x и y.
-
- -

Этот метод принимает два аргумента x и y, которые являются координатами конечной точки линии. Начальная точка зависит от ранее нарисованных путей, причём конечная точка предыдущего пути является начальной точкой следующего и т. д. Начальная точка также может быть изменена с помощью метода moveTo().

- -

Пример ниже рисует два треугольника, один закрашенный и другой обведен контуром.

- - - -
function draw() {
-  var canvas = document.getElementById('canvas');
-  if (canvas.getContext){
-    var ctx = canvas.getContext('2d');
-
-    // Filled triangle
-    ctx.beginPath();
-    ctx.moveTo(25,25);
-    ctx.lineTo(105,25);
-    ctx.lineTo(25,105);
-    ctx.fill();
-
-    // Stroked triangle
-    ctx.beginPath();
-    ctx.moveTo(125,125);
-    ctx.lineTo(125,45);
-    ctx.lineTo(45,125);
-    ctx.closePath();
-    ctx.stroke();
-  }
-}
-
- -

Отрисовка начинается с вызова beginPath(), чтобы начать рисовать путь новой фигуры. Затем мы используем метод moveTo(), чтобы переместить начальную точку в нужное положение. Ниже рисуются две линии, которые образуют две стороны треугольника.

- -

{{EmbedLiveSample("Линии", 160, 160, "https://mdn.mozillademos.org/files/238/Canvas_lineTo.png")}}

- -

Вы заметите разницу между закрашенным и обведенным контуром треугольниками. Это, как упоминалось выше, из-за того, что фигуры автоматически закрываются, когда путь заполнен (т. е. закрашен), но не тогда, когда он очерчен (т. е. обведен контуром). Если бы мы не учли closePath() для очерченного треугольника, тогда только две линии были бы нарисованы, а не весь треугольник.

- -

Дуги

- -

Для рисования дуг и окружностей, используем методы arc() и arcTo().

- -
-
{{domxref("CanvasRenderingContext2D.arc", "arc(x, y, radius, startAngle, endAngle, anticlockwise)")}}
-
Рисуем дугу с центром в точке (x,y) радиусом radius, начиная с угла startAngle и заканчивая в endAngle в направлении против часовой стрелки anticlockwise (по умолчанию по ходу движения часовой стрелки).
-
{{domxref("CanvasRenderingContext2D.arcTo", "arcTo(x1, y1, x2, y2, radius)")}}
-
Рисуем дугу с заданными контрольными точками и радиусом, соединяя эти точки прямой линией.
-
- -

Рассмотрим детальнее метод arc(), который имеет пять параметров: x и y — это координаты центра окружности, в которой должна быть нарисована дуга. radius — не требует пояснений. Углы startAngle и endAngle определяют начальную и конечную точки дуги в радианах вдоль кривой окружности. Отсчет происходит от оси x. Параметр anticlockwise — логическое значение, которое, если true, то рисование дуги совершается против хода часовой стрелки; иначе рисование происходит по ходу часовой стрелки.

- -
-

Note: Углы в функции arc() измеряют в радианах, не в градусах. Для перевода градусов в радианы вы можете использовать JavaScript-выражение: radians = (Math.PI/180)*degrees.

-
- -

Следующий пример немного сложнее, чем мы рассматривали ранее. Здесь нарисованы 12 различных дуг с разными углами и заливками.

- -

Два for цикла размещают дуги по столбцам и строкам. Для каждой дуги, мы начинаем новый контур, вызывая beginPath(). В этом коде каждый параметр дуги для большей ясности задан в виде переменной, но вам не обязательно делать так в реальных проектах.

- -

Координаты x и y  должны быть достаточно ясны. radius and startAngle — фиксированы. endAngle начинается со 180 градусов (полуокружность) в первой колонке и, увеличиваясь с шагом 90 градусов, достигает кульминации полноценной окружностью в последнем столбце.

- -

Установка параметра clockwise определяет результат; в первой и третьей строках рисование дуг происходит по часовой стрелке, а во второй и четвертой - против часовой стрелки. Благодаря if-условию верхняя половина дуг образуется с контуром, (обводкой), а нижняя половина дуг - с заливкой.

- -
-

Note: Этот пример требует немного большего холста (canvas), чем другие на этой странице: 150 x 200 pixels.

-
- - - -
function draw() {
-  var canvas = document.getElementById('canvas');
-  if (canvas.getContext){
-    var ctx = canvas.getContext('2d');
-
-    for(var i=0;i<4;i++){
-      for(var j=0;j<3;j++){
-        ctx.beginPath();
-        var x = 25+j*50; // x coordinate
-        var y = 25+i*50; // y coordinate
-        var radius = 20; // Arc radius
-        var startAngle = 0; // Starting point on circle
-        var endAngle = Math.PI+(Math.PI*j)/2; // End point on circle
-        var anticlockwise = i%2==0 ? false : true; // clockwise or anticlockwise
-
-        ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);
-
-        if (i>1){
-          ctx.fill();
-        } else {
-          ctx.stroke();
-        }
-      }
-    }
-  }
-}
-
- -

{{EmbedLiveSample("Дуги", 160, 210, "https://mdn.mozillademos.org/files/204/Canvas_arc.png")}}

- -

Безье и квадратичные кривые

- -

Следующим типом доступных контуров являются  кривые Безье, и к тому же доступны в кубическом и квадратичном вариантах. Обычно они используются при рисовании сложных составных фигур.

- -
-
{{domxref("CanvasRenderingContext2D.quadraticCurveTo", "quadraticCurveTo(cp1x, cp1y, x, y)")}}
-
Рисуется квадратичная кривая Безье с текущей позиции пера в конечную точку с координатами x и y, используя контрольную точку с координатами cp1x и cp1y.
-
{{domxref("CanvasRenderingContext2D.bezierCurveTo", "bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)")}}
-
Рисуется кубическая кривая Безье с текущей позиции пера в конечную точку с координатами x и y, используя две контрольные точки с координатами (cp1x, cp1y) и (cp2x, cp2y).
-
- -

Различие между ними можно увидеть на рисунке, изображенном справа. Квадратичная кривая Безье имеет стартовую и конечную точки (синие точки) и всего одну контрольную точку (красная точка), в то время как кубическая кривая Безье использует две контрольные точки.

- -

Параметры x и y в этих двух методах являются координатами конечной точки. cp1x и cp1y — координаты первой контрольной точки, а cp2x и cp2y — координаты второй контрольной точки.

- -

Использование квадратичных или кубических кривых Безье может быть  спорным выходом, так как в отличие от приложений векторной графики типа Adobe Illustrator, мы не имеем полной видимой обратной связи с тем, что мы делаем. Этот факт делает довольно сложным процесс рисования сложных фигур. В следующем примере мы нарисуем совсем простую составную фигуру, но, если у вас есть время и ещё больше терпения, можно создать более сложные составные фигуры.

- -

В этом примере нет ничего слишком тяжелого. В обоих случаях мы видим последовательность кривых, рисуя которые, в результате получим составную фигуру.

- -

Квадратичные кривые Безье

- -

В этом примере многократно используются квадратичные кривые Безье для рисования речевой выноски.

- - - -
function draw() {
-  var canvas = document.getElementById('canvas');
-  if (canvas.getContext) {
-    var ctx = canvas.getContext('2d');
-
-    // Quadratric curves example
-    ctx.beginPath();
-    ctx.moveTo(75,25);
-    ctx.quadraticCurveTo(25,25,25,62.5);
-    ctx.quadraticCurveTo(25,100,50,100);
-    ctx.quadraticCurveTo(50,120,30,125);
-    ctx.quadraticCurveTo(60,120,65,100);
-    ctx.quadraticCurveTo(125,100,125,62.5);
-    ctx.quadraticCurveTo(125,25,75,25);
-    ctx.stroke();
-  }
-}
-
- -

{{EmbedLiveSample("Квадратичные_кривые_Безье", 160, 160, "https://mdn.mozillademos.org/files/243/Canvas_quadratic.png")}}

- -

Кубические кривые Безье

- -

В этом примере нарисовано сердце с использованием кубических кривых Безье.

- - - -
function draw() {
-  var canvas = document.getElementById('canvas');
-  if (canvas.getContext){
-    var ctx = canvas.getContext('2d');
-
-    // Cubic curves example
-    ctx.beginPath();
-    ctx.moveTo(75,40);
-    ctx.bezierCurveTo(75,37,70,25,50,25);
-    ctx.bezierCurveTo(20,25,20,62.5,20,62.5);
-    ctx.bezierCurveTo(20,80,40,102,75,120);
-    ctx.bezierCurveTo(110,102,130,80,130,62.5);
-    ctx.bezierCurveTo(130,62.5,130,25,100,25);
-    ctx.bezierCurveTo(85,25,75,37,75,40);
-    ctx.fill();
-  }
-}
-
- -

{{EmbedLiveSample("Cubic_Bezier_curves", 160, 160, "https://mdn.mozillademos.org/files/207/Canvas_bezier.png")}}

- -

Прямоугольники

- -

Все эти методы мы видели в  {{anch("Рисование прямоугольников")}}, которые рисуют прямоугольники сразу в canvas, так же есть метод rect(), который не отображает, а только добавляет контур рисования (path) заданного прямоугольника к последнему открытому контуру.

- -
-
{{domxref("CanvasRenderingContext2D.rect", "rect(x, y, width, height)")}}
-

- Добавляет в path прямоугольник, верхний левый угол которого указан с помощью (x, y) с вашими width и height
-
-
- -

Когда этот метод вызван, автоматически вызывается метод moveTo() с параметрами (x, y). Другими словами, позиция курсора устанавливается в начало добавленного прямоугольника.

- -

Создание комбинаций

- -

До сих пор, в каждом примере использовался только один тип функции контуров для каждой фигуры.
- Однако, нет никаких ограничений на количество или типы контуров, которые вы можете использовать для создания фигур. Давайте в этом примере объединим все вышеперечисленные  функции контуров, чтобы создать набор очень известных игровых персонажей.

- - - -
function draw() {
-  var canvas = document.getElementById('canvas');
-  if (canvas.getContext){
-    var ctx = canvas.getContext('2d');
-
-    roundedRect(ctx,12,12,150,150,15);
-    roundedRect(ctx,19,19,150,150,9);
-    roundedRect(ctx,53,53,49,33,10);
-    roundedRect(ctx,53,119,49,16,6);
-    roundedRect(ctx,135,53,49,33,10);
-    roundedRect(ctx,135,119,25,49,10);
-
-    ctx.beginPath();
-    ctx.arc(37,37,13,Math.PI/7,-Math.PI/7,false);
-    ctx.lineTo(31,37);
-    ctx.fill();
-
-    for(var i=0;i<8;i++){
-      ctx.fillRect(51+i*16,35,4,4);
-    }
-
-    for(i=0;i<6;i++){
-      ctx.fillRect(115,51+i*16,4,4);
-    }
-
-    for(i=0;i<8;i++){
-      ctx.fillRect(51+i*16,99,4,4);
-    }
-
-    ctx.beginPath();
-    ctx.moveTo(83,116);
-    ctx.lineTo(83,102);
-    ctx.bezierCurveTo(83,94,89,88,97,88);
-    ctx.bezierCurveTo(105,88,111,94,111,102);
-    ctx.lineTo(111,116);
-    ctx.lineTo(106.333,111.333);
-    ctx.lineTo(101.666,116);
-    ctx.lineTo(97,111.333);
-    ctx.lineTo(92.333,116);
-    ctx.lineTo(87.666,111.333);
-    ctx.lineTo(83,116);
-    ctx.fill();
-
-    ctx.fillStyle = "white";
-    ctx.beginPath();
-    ctx.moveTo(91,96);
-    ctx.bezierCurveTo(88,96,87,99,87,101);
-    ctx.bezierCurveTo(87,103,88,106,91,106);
-    ctx.bezierCurveTo(94,106,95,103,95,101);
-    ctx.bezierCurveTo(95,99,94,96,91,96);
-    ctx.moveTo(103,96);
-    ctx.bezierCurveTo(100,96,99,99,99,101);
-    ctx.bezierCurveTo(99,103,100,106,103,106);
-    ctx.bezierCurveTo(106,106,107,103,107,101);
-    ctx.bezierCurveTo(107,99,106,96,103,96);
-    ctx.fill();
-
-    ctx.fillStyle = "black";
-    ctx.beginPath();
-    ctx.arc(101,102,2,0,Math.PI*2,true);
-    ctx.fill();
-
-    ctx.beginPath();
-    ctx.arc(89,102,2,0,Math.PI*2,true);
-    ctx.fill();
-  }
-}
-
-// A utility function to draw a rectangle with rounded corners.
-
-function roundedRect(ctx,x,y,width,height,radius){
-  ctx.beginPath();
-  ctx.moveTo(x,y+radius);
-  ctx.lineTo(x,y+height-radius);
-  ctx.quadraticCurveTo(x,y+height,x+radius,y+height);
-  ctx.lineTo(x+width-radius,y+height);
-  ctx.quadraticCurveTo(x+width,y+height,x+width,y+height-radius);
-  ctx.lineTo(x+width,y+radius);
-  ctx.quadraticCurveTo(x+width,y,x+width-radius,y);
-  ctx.lineTo(x+radius,y);
-  ctx.quadraticCurveTo(x,y,x,y+radius);
-  ctx.stroke();
-}
-
- -

Конечное изображение выглядит так:

- -

{{EmbedLiveSample("Создание_комбинаций", 160, 160, "https://mdn.mozillademos.org/files/9849/combinations.png")}}

- -

Мы не будем подробно останавливаться на том, так как это на самом деле удивительно просто. Наиболее важные вещи, которые следует отметить, это использование свойства fillStyle в контексте рисования и использование функции утилиты (в данном случае roundedRect()). Использование функций утилиты для битов чертежа часто может быть очень полезным и сократить количество необходимого кода, а также его сложность.

- -

Позже, в этом уроке, мы еще раз рассмотрим fillStyle, но более подробно. Здесь же мы используем его для изменения цвета заливки путей вместо цвета по умолчанию от черного до белого, а затем обратно.

- -

Path2D объекты

- -

Как мы видели в последнем примере, есть серия путей и команд для рисования объектов на вашем холсте. Чтобы упростить код и повысить производительность, объект {{domxref("Path2D")}}, доступный в последних версиях браузеров, позволяет вам кэшировать или записывать эти команды рисования. Вы можете быстро запускать свои пути.
- Давайте посмотрим, как мы можем построить объект Path2D :

- -
-
{{domxref("Path2D.Path2D", "Path2D()")}}
-
Конструктор Path2D() возвращает вновь созданный объект Path2D  необязательно с другим путем в качестве аргумента (создает копию) или необязательно со строкой, состоящей из данных пути SVG path .
-
- -
new Path2D();     // пустой path объект
-new Path2D(path); // копирование из другого path
-new Path2D(d);    // path из SVG
- -

Все  методы path , такие как  moveTo,  rect,  arc, или quadraticCurveTo,  итп, которые мы уже знаем, доступны для объектов Path2D

- -

API Path2D также добавляет способ комбинирования путей с использованием метода addPath. Это может быть полезно, если вы хотите, например, создавать объекты из нескольких компонентов.

- -
-
{{domxref("Path2D.addPath", "Path2D.addPath(path [, transform])")}}
-
Добавляет путь к текущему пути с необязательной матрицей преобразования.
-
- -

Path2D пример

- -

В этом примере мы создаем прямоугольник и круг. Оба они сохраняются как объект Path2D, поэтому они доступны для последующего использования. С новым API Path2D несколько методов были обновлены, чтобы при необходимости принять объект Path2D для использования вместо текущего пути. Здесь stroke и fill используются с аргументом пути, например, для рисования обоих объектов на холст.

- - - -
function draw() {
-  var canvas = document.getElementById('canvas');
-  if (canvas.getContext){
-    var ctx = canvas.getContext('2d');
-
-    var rectangle = new Path2D();
-    rectangle.rect(10, 10, 50, 50);
-
-    var circle = new Path2D();
-    circle.moveTo(125, 35);
-    circle.arc(100, 35, 25, 0, 2 * Math.PI);
-
-    ctx.stroke(rectangle);
-    ctx.fill(circle);
-  }
-}
-
- -

{{EmbedLiveSample("Path2D_example", 130, 110, "https://mdn.mozillademos.org/files/9851/path2d.png")}}

- -

Использование SVG путей

- -

Еще одна мощная функция нового Canvas Path2D API использует данные пути SVG, SVG path data, для инициализации путей на вашем холсте. Это может позволить вам передавать данные пути и повторно использовать их как в SVG, так и в холсте.

- -

Путь перемещается в точку (M10 10), а затем горизонтально перемещается на 80 пунктов вправо (h 80), затем на 80 пунктов вниз (v 80), затем на 80 пунктов влево (h -80), а затем обратно на start (z). 
- Этот пример можно увидеть на странице  Path2D constructor.

- -
var p = new Path2D("M10 10 h 80 v 80 h -80 Z");
- -
{{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_usage", "Web/API/Canvas_API/Tutorial/Applying_styles_and_colors")}}
diff --git a/files/ru/web/api/crypto/getrandomvalues/index.html b/files/ru/web/api/crypto/getrandomvalues/index.html new file mode 100644 index 0000000000..c59f5dde54 --- /dev/null +++ b/files/ru/web/api/crypto/getrandomvalues/index.html @@ -0,0 +1,73 @@ +--- +title: RandomSource.getRandomValues() +slug: Web/API/RandomSource/getRandomValues +tags: + - АПИ + - Криптография + - Справка + - метод +translation_of: Web/API/Crypto/getRandomValues +--- +

{{APIRef("Web Crypto API")}}

+ +

Метод RandomSource.getRandomValues() позволяет вам получать криптографически стойкие числа. Массив, переданный как параметр, заполняется случайными числами (случайными в криптографическом смысле).

+ +

Для того, чтобы гарантировать достаточную производительность, реализации используют не настоящий генератор случайных чисел (RNG, en - Random Number Generator), а генератор псевдо-случайных чисел, которому предоставлено начальное зерно (wiki - https://en.wikipedia.org/wiki/Random_seed) с достаточной энтропией (http://cryptography.ru/ref/энтропия). Реализация генератора псевдо-случайных чисел (PRNG, en - PseudoRandom Number Generator) отличается от других реализаций RNG, но она больше подходит для использования в криптографии. Реализации также требуют использование начального зерна с достаточной энтропией, как источник системно-уровневой энтропии.

+ +

Синтаксис

+ +
cryptoObj.getRandomValues(typedArray);
+ +

Параметры

+ +
+
typedArray
+
Целочисленный массив {{jsxref("TypedArray")}}, например {{jsxref("Int8Array")}}, {{jsxref("Uint8Array")}}, {{jsxref("Uint16Array")}}, {{jsxref("Int32Array")}}, или {{jsxref("Uint32Array")}}. Все элементы массива замещаются случайными числами.
+
+ +

Исключения

+ +
    +
  • Исключение {{exception("QuotaExceededError")}} {{domxref("DOMException")}} выбрасывается если запрошенная длина больше чем 65536 байт.
  • +
+ +

Пример

+ +
/* Предполагается что функция window.crypto.getRandomValues доступна */
+
+var array = new Uint32Array(10);
+window.crypto.getRandomValues(array);
+
+console.log("Ваше счастливое число:");
+for (var i = 0; i < array.length; i++) {
+    console.log(array[i]);
+}
+
+ +

Спецификация

+ + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('Web Crypto API', '#RandomSource-method-getRandomValues')}}{{Spec2('Web Crypto API')}}Изначальное определение
+ +

Совместимость с браузерами

+ +

{{Compat("api.Crypto.getRandomValues")}}

+ +

Смотрите также

+ +
    +
  • {{ domxref("Window.crypto") }} чтобы получить объект {{domxref("Crypto")}}.
  • +
  • {{jsxref("Math.random")}}, не криптографический способ получения случайных чисел.
  • +
diff --git a/files/ru/web/api/css_object_model/managing_screen_orientation/index.html b/files/ru/web/api/css_object_model/managing_screen_orientation/index.html new file mode 100644 index 0000000000..a6b16cba4a --- /dev/null +++ b/files/ru/web/api/css_object_model/managing_screen_orientation/index.html @@ -0,0 +1,183 @@ +--- +title: Разбираемся с ориентацией экрана +slug: Web/API/CSS_Object_Model/ориентация_экрана +tags: + - Ориентация экрана + - Положение экрана + - Руководство +translation_of: Web/API/CSS_Object_Model/Managing_screen_orientation +--- +

{{DefaultAPISidebar("Screen Orientation API")}}{{SeeCompatTable}}

+ +

Ориентация экрана не идентична ориентации устройства. +Даже если устройство не способно определить свое положение в пространстве — экран может всегда. А когда устройство знает свою ориентацию, хорошо бы иметь возможность управлять ориентацией экрана для +сохранения или адаптации интерфейса веб-приложения.

+ +

Управление ориентацией экрана доступно в CSS и JavaScript. +Например, использование медиа-запросов позволяет контенту адаптироваться с помощью CSS в зависимости от того, в каком режиме просмотра находится браузер: альбомный (горизонтальный, когда ширина экрана больше высоты) или портретный (вертикальный, высота экрана больше ширины).

+ +

Для определения положения экрана и его блокировки можно воспользоваться JavaScript Screen orientation API.

+ +

Настройка раскладки содержимого по ориентации экрана

+ +

Допустим Вы хотите связать отображение содержимого с ориентацией экрана. Например, добавить панель, растягивающуюся по наибольшему направлению дисплея устройства. Это довольно просто реализовать с помощью медиа запросов.

+ +

Пример. Имеется HTML страница:

+ +
<ul id="toolbar">
+  <li>A</li>
+  <li>B</li>
+  <li>C</li>
+</ul>
+
+<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis lacinia nisi nec sem viverra vitae fringilla nulla ultricies. In ac est dolor, quis tincidunt leo. Cras commodo quam non tortor consectetur eget rutrum dolor ultricies. Ut interdum tristique dapibus. Nullam quis malesuada est.</p>
+
+ +

Соответствующий CSS:

+ +
/* Сначала зададим простые стили */
+
+html, body {
+  width : 100%;
+  height: 100%;
+}
+
+body {
+  border: 1px solid black;
+
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+
+p {
+  font   : 1em sans-serif;
+  margin : 0;
+  padding: .5em;
+}
+
+ul {
+  list-style: none;
+
+  font   : 1em monospace;
+  margin : 0;
+  padding: .5em;
+
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+
+  background: black;
+}
+
+li {
+  display: inline-block;
+  margin : 0;
+  padding: 0.5em;
+  background: white;
+}
+
+ +

Теперь разберемся с поведением страницы в различных случаях ориентации.

+ +
/* Для портретного режима отправим панель на верхнюю часть области отображения */
+
+@media screen and (orientation: portrait) {
+  #toolbar {
+    width: 100%;
+  }
+}
+
+/* Для альбомного режима пускай панель отображается слева */
+
+@media screen and (orientation: landscape) {
+  #toolbar {
+    position: fixed;
+    width: 2.65em;
+    height: 100%;
+  }
+
+  p {
+    margin-left: 2em;
+  }
+
+  li + li {
+    margin-top: .5em;
+  }
+}
+
+ +

Результат:

+ + + + + + + + + + + + + + +
Портреный режим просмотраАльбомный режим просмотра
+
{{ EmbedLiveSample('Adjusting_layout_based_on_the_orientation', 180, 350) }}
+
+
{{ EmbedLiveSample('Adjusting_layout_based_on_the_orientation', 350, 180) }}
+
+ +
+

Примечание: Медиа запрос по ориентации ссылается на окно браузера (соотношение его размеров), а не на ориентацию устройства.

+
+ +

Блокировка ориентации экрана

+ +
+

Предупреждение: Этот API вводится в экспериментальном режиме и доступен в Firefox OS и Firefox для Android с приставкой moz, а также для Internet Explorer на Windows 8.1 и выше с приставкой ms.

+
+ +

Некоторые устройства (в основном мобильные) могут изменять ориентацию экрана в соответствии с ориентацией самого устройства для удобства восприятия информации пользователем. +Это хорошо подходит для текста, но на некоторое содержимое такое поведение может оказать негативное воздействие. Например, это трагичная ситуация для игры, разработанной под определенную ориентацию.

+ +

Урегулировать вопрос, связанный с изменением положения экрана, поможет интерфейс Screen Orientation API.

+ +

Отслеживание изменения ориентации

+ +

Событие {{event("orientationchange")}} возникает каждый раз, когда устройство изменяет ориентацию экрана и самого себя, и может быть отслежено свойством {{domxref("Screen.orientation")}}.

+ +
screen.addEventListener("orientationchange", function () {
+  console.log("The orientation of the screen is: " + screen.orientation);
+});
+
+ +

Запрещаем поворот экрана

+ +

Любое веб-приложение может заблокировать положение экрана. Методом {{domxref("Screen.lockOrientation()")}} положение блокируется. Разблокирование осуществляется методом {{domxref("Screen.unlockOrientation()")}}.

+ +

Метод {{domxref("Screen.lockOrientation()")}} принимает одну или несколько строк для определения типа блокировки: portrait-primary, portrait-secondary, landscape-primary, landscape-secondary, portrait, landscape. Подробнее: {{domxref("Screen.lockOrientation")}}.

+ +
screen.lockOrientation('landscape');
+ +
+

Примечание: Положение экрана зависит от конкретной настройки приложения. Если в приложении A экран блокируется на альбомную ориентацию (landscape), а приложение B блокирует экран на портретный режим (portrait), +то переход из приложения A в приложение B (или наоборот) не вызовет событие изменения ориентации экрана {{event("orientationchange")}}, т. к. оба приложения сохраняют заданную ориентацию.

+ +

В то же время, событие {{event("orientationchange")}} может возникнуть в момент блокировки ориентации, если для удовлетворения заданному параметру блокировки изменяется положение экрана.

+
+ +

Firefox OS и Android: блокирование ориентации через манифест

+ +

Для Firefox OS и Firefox Android (скоро заработает и в десктопном Firefox) существует более специфичный способ: в файле манифеста Вашего приложения можно указать ориентацию:

+ +
"orientation": "portrait"
+ +

См. также

+ + diff --git "a/files/ru/web/api/css_object_model/\320\276\321\200\320\270\320\265\320\275\321\202\320\260\321\206\320\270\321\217_\321\215\320\272\321\200\320\260\320\275\320\260/index.html" "b/files/ru/web/api/css_object_model/\320\276\321\200\320\270\320\265\320\275\321\202\320\260\321\206\320\270\321\217_\321\215\320\272\321\200\320\260\320\275\320\260/index.html" deleted file mode 100644 index a6b16cba4a..0000000000 --- "a/files/ru/web/api/css_object_model/\320\276\321\200\320\270\320\265\320\275\321\202\320\260\321\206\320\270\321\217_\321\215\320\272\321\200\320\260\320\275\320\260/index.html" +++ /dev/null @@ -1,183 +0,0 @@ ---- -title: Разбираемся с ориентацией экрана -slug: Web/API/CSS_Object_Model/ориентация_экрана -tags: - - Ориентация экрана - - Положение экрана - - Руководство -translation_of: Web/API/CSS_Object_Model/Managing_screen_orientation ---- -

{{DefaultAPISidebar("Screen Orientation API")}}{{SeeCompatTable}}

- -

Ориентация экрана не идентична ориентации устройства. -Даже если устройство не способно определить свое положение в пространстве — экран может всегда. А когда устройство знает свою ориентацию, хорошо бы иметь возможность управлять ориентацией экрана для -сохранения или адаптации интерфейса веб-приложения.

- -

Управление ориентацией экрана доступно в CSS и JavaScript. -Например, использование медиа-запросов позволяет контенту адаптироваться с помощью CSS в зависимости от того, в каком режиме просмотра находится браузер: альбомный (горизонтальный, когда ширина экрана больше высоты) или портретный (вертикальный, высота экрана больше ширины).

- -

Для определения положения экрана и его блокировки можно воспользоваться JavaScript Screen orientation API.

- -

Настройка раскладки содержимого по ориентации экрана

- -

Допустим Вы хотите связать отображение содержимого с ориентацией экрана. Например, добавить панель, растягивающуюся по наибольшему направлению дисплея устройства. Это довольно просто реализовать с помощью медиа запросов.

- -

Пример. Имеется HTML страница:

- -
<ul id="toolbar">
-  <li>A</li>
-  <li>B</li>
-  <li>C</li>
-</ul>
-
-<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis lacinia nisi nec sem viverra vitae fringilla nulla ultricies. In ac est dolor, quis tincidunt leo. Cras commodo quam non tortor consectetur eget rutrum dolor ultricies. Ut interdum tristique dapibus. Nullam quis malesuada est.</p>
-
- -

Соответствующий CSS:

- -
/* Сначала зададим простые стили */
-
-html, body {
-  width : 100%;
-  height: 100%;
-}
-
-body {
-  border: 1px solid black;
-
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
-}
-
-p {
-  font   : 1em sans-serif;
-  margin : 0;
-  padding: .5em;
-}
-
-ul {
-  list-style: none;
-
-  font   : 1em monospace;
-  margin : 0;
-  padding: .5em;
-
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
-
-  background: black;
-}
-
-li {
-  display: inline-block;
-  margin : 0;
-  padding: 0.5em;
-  background: white;
-}
-
- -

Теперь разберемся с поведением страницы в различных случаях ориентации.

- -
/* Для портретного режима отправим панель на верхнюю часть области отображения */
-
-@media screen and (orientation: portrait) {
-  #toolbar {
-    width: 100%;
-  }
-}
-
-/* Для альбомного режима пускай панель отображается слева */
-
-@media screen and (orientation: landscape) {
-  #toolbar {
-    position: fixed;
-    width: 2.65em;
-    height: 100%;
-  }
-
-  p {
-    margin-left: 2em;
-  }
-
-  li + li {
-    margin-top: .5em;
-  }
-}
-
- -

Результат:

- - - - - - - - - - - - - - -
Портреный режим просмотраАльбомный режим просмотра
-
{{ EmbedLiveSample('Adjusting_layout_based_on_the_orientation', 180, 350) }}
-
-
{{ EmbedLiveSample('Adjusting_layout_based_on_the_orientation', 350, 180) }}
-
- -
-

Примечание: Медиа запрос по ориентации ссылается на окно браузера (соотношение его размеров), а не на ориентацию устройства.

-
- -

Блокировка ориентации экрана

- -
-

Предупреждение: Этот API вводится в экспериментальном режиме и доступен в Firefox OS и Firefox для Android с приставкой moz, а также для Internet Explorer на Windows 8.1 и выше с приставкой ms.

-
- -

Некоторые устройства (в основном мобильные) могут изменять ориентацию экрана в соответствии с ориентацией самого устройства для удобства восприятия информации пользователем. -Это хорошо подходит для текста, но на некоторое содержимое такое поведение может оказать негативное воздействие. Например, это трагичная ситуация для игры, разработанной под определенную ориентацию.

- -

Урегулировать вопрос, связанный с изменением положения экрана, поможет интерфейс Screen Orientation API.

- -

Отслеживание изменения ориентации

- -

Событие {{event("orientationchange")}} возникает каждый раз, когда устройство изменяет ориентацию экрана и самого себя, и может быть отслежено свойством {{domxref("Screen.orientation")}}.

- -
screen.addEventListener("orientationchange", function () {
-  console.log("The orientation of the screen is: " + screen.orientation);
-});
-
- -

Запрещаем поворот экрана

- -

Любое веб-приложение может заблокировать положение экрана. Методом {{domxref("Screen.lockOrientation()")}} положение блокируется. Разблокирование осуществляется методом {{domxref("Screen.unlockOrientation()")}}.

- -

Метод {{domxref("Screen.lockOrientation()")}} принимает одну или несколько строк для определения типа блокировки: portrait-primary, portrait-secondary, landscape-primary, landscape-secondary, portrait, landscape. Подробнее: {{domxref("Screen.lockOrientation")}}.

- -
screen.lockOrientation('landscape');
- -
-

Примечание: Положение экрана зависит от конкретной настройки приложения. Если в приложении A экран блокируется на альбомную ориентацию (landscape), а приложение B блокирует экран на портретный режим (portrait), -то переход из приложения A в приложение B (или наоборот) не вызовет событие изменения ориентации экрана {{event("orientationchange")}}, т. к. оба приложения сохраняют заданную ориентацию.

- -

В то же время, событие {{event("orientationchange")}} может возникнуть в момент блокировки ориентации, если для удовлетворения заданному параметру блокировки изменяется положение экрана.

-
- -

Firefox OS и Android: блокирование ориентации через манифест

- -

Для Firefox OS и Firefox Android (скоро заработает и в десктопном Firefox) существует более специфичный способ: в файле манифеста Вашего приложения можно указать ориентацию:

- -
"orientation": "portrait"
- -

См. также

- - diff --git a/files/ru/web/api/document/activeelement/index.html b/files/ru/web/api/document/activeelement/index.html deleted file mode 100644 index 71db5bc678..0000000000 --- a/files/ru/web/api/document/activeelement/index.html +++ /dev/null @@ -1,165 +0,0 @@ ---- -title: Document.activeElement -slug: Web/API/Document/activeElement -tags: - - API - - Document - - HTML DOM - - Property - - Reference -translation_of: Web/API/DocumentOrShadowRoot/activeElement -translation_of_original: Web/API/Document/activeElement ---- -

{{ ApiRef() }}

- -

Анотация

- -

Возвращает текущий сфокусированный элемент, то есть элемент, на котором будут вызываться события клавиатуры, если пользователь начнёт с неё ввод. Этот атрибут доступен только для чтения.

- -

Часто возвращается {{ HTMLElement("input") }} или {{ HTMLElement("textarea") }} объект, если он содержит в себе выделенный в данный момент текст. При этом вы можете получить более подробные сведения, используя свойства элемента  selectionStart и selectionEnd.  В других случаях сфокусированным элементом может быть {{ HTMLElement("select") }} элемент (меню) или {{ HTMLElement("input") }} элемент типа button, checkbox или radio.

- -

{{ Note("На Mac, элементы, не являющиеся текстовыми полями, как правило, не получают фокус.") }}

- -

Как правило, пользователь может нажать клавишу табуляции для перемещения по фокусируемым элементам страницы, и использовать пробел для их активации (нажать кнопку button, выбрать переключатель radio).

- -

Не следует путать фокус с выделением документа, состоящего в основном из статических текстовых узлов. См. {{ domxref("window.getSelection()") }}. 

- -

Когда выделение отсутствует, активным элементом является {{ HTMLElement("body") }} страницы или null. 

- -

{{ Note("Этот атрибут является частью разрабатываемой спецификации HTML 5.") }}

- -

Синтаксис

- -
var curElement = document.activeElement;
-
- -

Пример

- -
<!DOCTYPE HTML>
-<html>
-<head>
-    <script type="text/javascript" charset="utf-8">
-    function init() {
-
-        function onMouseUp(e) {
-            console.log(e);
-            var outputElement = document.getElementById('output-element');
-            var outputText = document.getElementById('output-text');
-            var selectedTextArea = document.activeElement;
-            var selection = selectedTextArea.value.substring(
-            selectedTextArea.selectionStart, selectedTextArea.selectionEnd);
-            outputElement.innerHTML = selectedTextArea.id;
-            outputText.innerHTML = selection;
-        }
-
-        document.getElementById("ta-example-one").addEventListener("mouseup", onMouseUp, false);
-        document.getElementById("ta-example-two").addEventListener("mouseup", onMouseUp, false);
-    }
-    </script>
-</head>
-<body onload="init()">
-<div>
-    Выделите текст в одном из текстовых полей ниже:
-</div>
-<form id="frm-example" action="#" accept-charset="utf-8">
-<textarea name="ta-example-one" id="ta-example-one" rows="8" cols="40">
-Это текстовое поле 1:
-Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec tincidunt, lorem a porttitor molestie, odio nibh iaculis libero, et accumsan nunc orci eu dui.
-</textarea>
-<textarea name="ta-example-two" id="ta-example-two" rows="8" cols="40">
-Это текстовое поле 2:
-Fusce ullamcorper, nisl ac porttitor adipiscing, urna orci egestas libero, ut accumsan orci lacus laoreet diam. Morbi sed euismod diam.
-</textarea>
-</form>
-ID активного элемента: <span id="output-element"></span><br/>
-Выделенный текст: <span id="output-text"></span>
-
-</body>
-</html>
-
- -

Посмотреть на JSFiddle

- -

Примечания

- -

Первоначально введенное как собственное расширение DOM в Internet Explorer 4, это свойство также поддерживается в Opera и Safari (в версии 4).

- -

Спецификации

- - - - - - - - - - - - - - - - -
СпецификацияСтатусКомментарий
{{SpecName('HTML WHATWG', 'interaction.html#dom-document-activeelement', 'activeElement')}}{{Spec2('HTML WHATWG')}} 
- -

Совместимость с браузерами

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support23.04 [1]9.64.0
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
-
- -

[1]: В IE9 наблюдается баг: при попытке получения доступа к activeElement в {{domxref("window.parent")}} {{domxref("Document")}} из {{HTMLElement("iframe")}} (т.е. parent.document.activeElement) выбрасывается ошибка.

- -

Связанные события

- -
    -
  • {{event("focus")}}
  • -
  • {{event("blur")}}
  • -
  • {{event("focusin")}}
  • -
  • {{event("focusout")}}
  • -
diff --git a/files/ru/web/api/document/async/index.html b/files/ru/web/api/document/async/index.html deleted file mode 100644 index 2ff21f28af..0000000000 --- a/files/ru/web/api/document/async/index.html +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: Document.async -slug: Web/API/Document/async -translation_of: Web/API/XMLDocument/async ---- -

{{APIRef("DOM")}}{{Deprecated_header}} {{Non-standard_header}}

- -

document.async может быть установлен, для того, чтобы определить, что вызов {{domxref("document.load")}} должен быть выполнен синхронно или не синхронно. true - стандартное значение, определяющее, асинхронно ли должны быть загружены документы.

- -

(Загружать документы синхронно стало возможно с версии 1.4 alpha.)

- -

Пример

- -
function loadXMLData(e) {
-  alert(new XMLSerializer().serializeToString(e.target)); // Gives querydata.xml contents as string
-}
-
-var xmlDoc = document.implementation.createDocument("", "test", null);
-
-xmlDoc.async = false;
-xmlDoc.onload = loadXMLData;
-xmlDoc.load('querydata.xml');
- -

Спецификация

- - - -

Смотрите также

- - diff --git a/files/ru/web/api/document/createelement/index.html b/files/ru/web/api/document/createelement/index.html new file mode 100644 index 0000000000..15542d751d --- /dev/null +++ b/files/ru/web/api/document/createelement/index.html @@ -0,0 +1,82 @@ +--- +title: document.createElement +slug: DOM/document.createElement +tags: + - DOM + - Gecko +translation_of: Web/API/Document/createElement +--- +

{{ ApiRef() }}

+ +

Общая информация

+ +

В HTML-документах создает элемент c тем тегом, что указан в аргументе или HTMLUnknownElement, если имя тега не распознаётся.

+ +

В XUL-документах создает указанный в аргументе элемент XUL.

+ +

В остальных случаях создаёт элемент с нулевым NamespaceURI.

+ +

Параметры

+ +
var element = document.createElement(tagName, [options]);
+
+ +
    +
  • element — созданый объект элемента.
  • +
  • tagName — строка, указывающая элемент какого типа должен быть создан. nodeName создается и инициализируется со значением tagName.
  • +
  • +

    options — необязательный параметр, объект ElementCreationOptions, который может содержать только поле is, указывающее имя пользовательского элемента, созданного с помощью customElements.define() (см. Веб-компоненты).

    +
  • +
+ +

Пример

+ +

Данный пример создает новый элемент <div> и вставляет его перед элементом с идентификатором org_div1:

+ +
<!DOCTYPE html>
+<html>
+<head>
+<title>||Работа с элементами||</title>
+</head>
+
+<body>
+<div><h1>Привет!</h1></div>
+<div id='org_div1'>Текст выше сгенерирован автоматически.</div>
+</body>
+
+<script>
+  document.body.onload = addElement;
+  var my_div = newDiv = null;
+
+  function addElement() {
+
+    // Создаем новый элемент div
+    // и добавляем в него немного контента
+
+    var newDiv = document.createElement("div");
+        newDiv.innerHTML = "<h1>Привет!</h1>";
+
+    // Добавляем только что созданый элемент в дерево DOM
+
+    my_div = document.getElementById("org_div1");
+    document.body.insertBefore(newDiv, my_div);
+  }
+</script>
+</html>
+
+ +

Заметки

+ +

Если существуют атрибуты со значениями по умолчанию, атрибуты узлов предоставляющие их создаются автоматически и применяются к элементу.

+ +

Для создания элементов с заданым пространством имен используйте метод createElementNS.

+ +

Реализация createElement в Gecko не соответствует DOM спецификации для XUL и XHTML документов: localName и namespaceURI не устанавливаются в  null в созданном документе. Смотрите {{ Bug(280692) }} для подробностей.

+ +

Для обратной совместимости с предыдущими версиями спецификации пользовательских элементов некоторые браузеры позволяют передавать здесь строку вместо объекта, где значением строки является имя тега пользовательского элемента.

+ +

Спецификации

+ +

DOM 2 Модуль: createElement

+ +

{{ languages( { "fr": "fr/DOM/document.createElement", "it": "it/DOM/document.createElement", "pl": "pl/DOM/document.createElement" } ) }}

diff --git a/files/ru/web/api/document/getselection/index.html b/files/ru/web/api/document/getselection/index.html deleted file mode 100644 index c57695e055..0000000000 --- a/files/ru/web/api/document/getselection/index.html +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: Document.getSelection() -slug: Web/API/Document/getSelection -translation_of: Web/API/DocumentOrShadowRoot/getSelection -translation_of_original: Web/API/Document/getSelection ---- -

{{APIRef("DOM")}}

- -

Этот метод работает в точности так же, как {{domxref("Window.getSelection()")}}; он возвращает объект {{domxref("Selection")}}, в котором содержатся данные о тексте, выделенном в документе на данный момент.

diff --git a/files/ru/web/api/document/images/index.html b/files/ru/web/api/document/images/index.html new file mode 100644 index 0000000000..c9ba4ac1e2 --- /dev/null +++ b/files/ru/web/api/document/images/index.html @@ -0,0 +1,29 @@ +--- +title: document.images +slug: DOM/document.images +tags: + - DOM + - JavaScript +translation_of: Web/API/Document/images +--- +

{{ ApiRef() }}

+

Кратко об обьекте

+

document.images возвращает коллекцию изображений в текущем HTML документе.

+

Синтаксис

+
var htmlCollection = document.images;
+
+

Пример

+
var images = document.images;
+
+for(var i = 0; i < images.length; i++) {
+    if(images[i].src == "banner.gif") {
+      alert('Баннер найден!');
+    };
+};
+
+

Примечания

+

document.images.length — возвращает количество изображений на странице.

+

document.images является частью DOM HTML, и работает только в HTML документах.

+

Спецификация

+

DOM Level 2 HTML: HTMLDocument.images

+

{{ languages( { "en": "en/DOM/document.images", "fr": "fr/DOM/document.images", "pl": "pl/DOM/document.images","ru":"ru/DOM/document.images" } ) }}

diff --git a/files/ru/web/api/document/readystatechange_event/index.html b/files/ru/web/api/document/readystatechange_event/index.html new file mode 100644 index 0000000000..5a268b033f --- /dev/null +++ b/files/ru/web/api/document/readystatechange_event/index.html @@ -0,0 +1,90 @@ +--- +title: readystatechange +slug: Web/Events/readystatechange +tags: + - события +translation_of: Web/API/Document/readystatechange_event +--- +

{{ApiRef}}

+ +

Событие readystatechange срабатывает, когда изменяется атрибут документа readyState.

+ +

Основная информация

+ +
+
Спецификация
+
HTML5
+
 
+
Интерфейс
+
Event
+
Всплывает
+
Нет
+
Отменяемое
+
Нет
+
Цель
+
Document
+
Действие по умолчаанию
+
Нет
+
+ +

Свойства

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
СвойствоТипОписание
target {{readonlyInline}}{{domxref("EventTarget")}}Цель события (Самая верхняя цель в дереве DOM).
type {{readonlyInline}}{{domxref("DOMString")}}Тип события.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Всплывает ли событие.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Возможно ли отменить событие.
+ +

Примеры

+ +
document.readyState === "complete";
+// true
+
+
+// Альтернатива DOMContentLoaded
+document.onreadystatechange = function () {
+    if (document.readyState === "interactive") {
+        initApplication();
+    }
+}
+
+ +

Поддержка браузерами

+ +

Данное событие давно поддерживается Internet Explorer и может быть использовано в качестве альтернативы событию DOMContentLoaded (см. примечание [2] в разделе  Поддержка браузерами).

+ +

Связанные события

+ +
    +
  • {{event("DOMContentLoaded")}}
  • +
  • {{event("readystatechange")}}
  • +
  • {{event("load")}}
  • +
  • {{event("beforeunload")}}
  • +
  • {{event("unload")}}
  • +
diff --git a/files/ru/web/api/document_object_model/events/index.html b/files/ru/web/api/document_object_model/events/index.html new file mode 100644 index 0000000000..eeadb57328 --- /dev/null +++ b/files/ru/web/api/document_object_model/events/index.html @@ -0,0 +1,80 @@ +--- +title: Events and the DOM +slug: DOM/DOM_Reference/Events +translation_of: Web/API/Document_Object_Model/Events +--- +

Вступление

+ +

Вступление

+ +

В этой главе описывается модель событий DOM. Топ скрыть Интерфейс сам по себе описано, а также интерфейсы для регистрации событий на узлах в DOM, Также а слушатели события Главного , Также а Несколько больше Примеры, которые показывают, как Различные интерфейсы связаны друг события Главного с другом.

+ +

Существует отличная диаграмма, которая четко объясняет события трех этапов через DOM в проекте DOM Level 3 Events .

+ +

Также см. Пример 5: Распространение событий в главе «Примеры» для более подробного примера.

+ +

Регистрация слушателей событий

+ +

Есть 3 способа регистрации обработанных событий для элемента DOM.

+ +

EventTarget.addEventListener

+ +
// Предполагая, что myButton является элементом кнопки
+myButton.addEventListener ('click', greet, false);
+function greet (event) {
+    // распечатать и посмотреть на объект события
+    // всегда печатать аргументы в случае пропуска любых других аргументов
+    console.log ('greet:', arguments);
+    оповещение («Привет, мир»);
+}
+
+ +

Это метод, который вы должны использовать на современных веб-страницах.

+ +

Примечание. Internet Explorer 6-8 не поддерживает этот метод, предлагая аналогичный {{domxref ("EventTarget.attachEvent")}} API. Для кросс-браузерной совместимости используйте одну из множества доступных библиотек JavaScript.

+ +

Дополнительную информацию можно найти на справочной странице {{domxref ("EventTarget.addEventListener")}}.

+ +

Атрибут HTML

+ +
<button onclick = "alert ('Hello world!')">
+
+ +

Код JavaScript в атрибуте передается объекту Event через eventпараметр. Возвращаемое значение обрабатывается особым образом, описанным в спецификации HTML .

+ +

Этого пути следует избегать. Это делает разметку больше и менее читаемой. Проблемы содержания / структуры и поведения плохо разделены, что затрудняет поиск ошибки.

+ +

Свойства элемента DOM

+ +
// Предполагая, что myButton является элементом кнопки
+myButton.onclick = function(event){alert('Hello world');};
+
+ +

Функция может быть определена для получения eventпараметра. Возвращаемое значение обрабатывается особым образом, описанным в спецификации HTML .

+ +

Проблема этого метода в том, что для каждого элемента и для каждого события может быть установлен только один обработчик.

+ +

Доступ к интерфейсам событий

+ +

Обработчики событий могут быть присоединены к различным объектам, включая элементы DOM, документ, объект окна и т. Д. Когда происходит событие, объект события создается и последовательно передается слушателям события.

+ +

Интерфейс {{domxref ("Event")}} доступен из функции-обработчика через объект события, переданный в качестве первого аргумента. В следующем простом примере показано, как объект события передается в функцию-обработчик события и может использоваться из одной такой функции.

+ +
function print(evt) {
+  // параметру evt автоматически назначается объект события
+  // позаботимся о различиях в console.log и alert
+  console.log('print:', evt);
+  alert(evt);
+}
+// любая функция должна иметь подходящее имя, это то, что называется семантическим
+table_el.onclick = print; 
+
+ + + + diff --git a/files/ru/web/api/document_object_model/examples/index.html b/files/ru/web/api/document_object_model/examples/index.html new file mode 100644 index 0000000000..a3332f7585 --- /dev/null +++ b/files/ru/web/api/document_object_model/examples/index.html @@ -0,0 +1,382 @@ +--- +title: Examples of web and XML development using the DOM +slug: DOM/DOM_Reference/Examples +translation_of: Web/API/Document_Object_Model/Examples +--- +

В этой главе представлены более длинные примеры разработки веб-сайтов и XML с использованием DOM. По возможности, примеры используют общие API, трюки и шаблоны в JavaScript для управления объектом документа.

+ +

Пример 1: высота и ширина

+ +

В следующем примере показано использование свойств высоты и ширины для изображений разных размеров:
+  

+ +
<!DOCTYPE html>
+<html lang="en">
+<head>
+<title>width/height example</title>
+<script>
+function init() {
+  var arrImages = new Array(3);
+
+  arrImages[0] = document.getElementById("image1");
+  arrImages[1] = document.getElementById("image2");
+  arrImages[2] = document.getElementById("image3");
+
+  var objOutput = document.getElementById("output");
+  var strHtml = "<ul>";
+
+  for (var i = 0; i < arrImages.length; i++) {
+    strHtml += "<li>image" + (i+1) +
+            ": height=" + arrImages[i].height +
+            ", width=" + arrImages[i].width +
+            ", style.height=" + arrImages[i].style.height +
+            ", style.width=" + arrImages[i].style.width +
+            "<\/li>";
+  }
+
+  strHtml += "<\/ul>";
+
+  objOutput.innerHTML = strHtml;
+}
+</script>
+</head>
+<body onload="init();">
+
+<p>Image 1: no height, width, or style
+  <img id="image1" src="http://www.mozilla.org/images/mozilla-banner.gif">
+</p>
+
+<p>Image 2: height="50", width="500", but no style
+  <img id="image2"
+       src="http://www.mozilla.org/images/mozilla-banner.gif"
+       height="50" width="500">
+</p>
+
+<p>Image 3: no height, width, but style="height: 50px; width: 500px;"
+  <img id="image3"
+       src="http://www.mozilla.org/images/mozilla-banner.gif"
+       style="height: 50px; width: 500px;">
+</p>
+
+<div id="output"> </div>
+</body>
+</html>
+
+ +

Пример 2: Аттрибуты Изображения

+ +
<!DOCTYPE html>
+<html lang="en">
+<head>
+<title>Modifying an image border</title>
+
+<script>
+function setBorderWidth(width) {
+  document.getElementById("img1").style.borderWidth = width + "px";
+}
+</script>
+</head>
+
+<body>
+<p>
+  <img id="img1"
+       src="image1.gif"
+       style="border: 5px solid green;"
+       width="100" height="100" alt="border test">
+</p>
+
+<form name="FormName">
+  <input type="button" value="Make border 20px-wide" onclick="setBorderWidth(20);" />
+  <input type="button" value="Make border 5px-wide"  onclick="setBorderWidth(5);" />
+</form>
+
+</body>
+</html>
+
+ +

Пример 3: Управление Стилями

+ +

В этом простом примере, некоторые базовые свойства стиля элемента абзаца HTML доступны с помощью объекта стиля элемента и свойств стиля CSS этого объекта, который можно получить и установить из DOM. В этом случае вы напрямую управляете отдельными стилями. В следующем примере (см. Пример 4), вы можете использовать таблицы стилей и их правила для изменения стилей для целых документов.

+ +
<!DOCTYPE html>
+<html lang="en">
+<head>
+<title>Changing color and font-size example</title>
+
+<script>
+function changeText() {
+  var p = document.getElementById("pid");
+
+  p.style.color = "blue"
+  p.style.fontSize = "18pt"
+}
+</script>
+</head>
+<body>
+
+<p id="pid" onclick="window.location.href = 'http://www.cnn.com/';">linker</p>
+
+<form>
+  <p><input value="rec" type="button" onclick="changeText();" /></p>
+</form>
+
+</body>
+</html>
+
+ +

Пример 4: Использование Стилей

+ +

Свойство styleSheets объекта документа возвращает список таблиц стилей, которые были загружены в этот документ. Вы можете получить доступ к этим таблицам стилей и их правилам индивидуально, используя объекты таблицы стилей, стилей и CSS правил объекта, как показано в этом примере, который выводит все селектора правил стиля в консоль.

+ +
var ss = document.styleSheets;
+
+for(var i = 0; i < ss.length; i++) {
+  for(var j = 0; j < ss[i].cssRules.length; j++) {
+    dump( ss[i].cssRules[j].selectorText + "\n" );
+  }
+}
+ +

Для документа с единой таблицей стилей, в которой определены следующие три правила:

+ +
body { background-color: darkblue; }
+p { font-face: Arial; font-size: 10pt; margin-left: .125in; }
+#lumpy { display: none; }
+
+ +

Этот скрипт выводит следующее:

+ +
BODY
+P
+#LUMPY
+
+ +

Пример 5: Распространение Событий

+ +

Этот пример демонстрирует, как события срабатывают и обрабатываются в DOM очень простым путём. Когда загружается BODY в составе HTML-документа, обработчик событий регистрируется в верхней строке таблицы TABLE. Обработчик событий реагирует на событие запуском функции stopEvent, изменяющей значение в нижней ячейке.

+ +

Однако, stopEvent также вызывает метод объекта событий, {{domxref("event.stopPropagation")}}, что препятствует дальнейшему всплытию события в DOM. Обратите внимание, что сама таблица имеет {{domxref("element.onclick","onclick")}} обработчик событий, который должен отображать сообщение при нажатии на таблицу. Но метод stopEvent метод прекратил распространение, и поэтому после обновления данных в таблице фаза события эффективно завершается, и отображается окно предупреждения для подтверждения.

+ +
<!DOCTYPE html>
+<html lang="en">
+<head>
+<title>Event Propagation</title>
+
+<style>
+#t-daddy { border: 1px solid red }
+#c1 { background-color: pink; }
+</style>
+
+<script>
+function stopEvent(ev) {
+  c2 = document.getElementById("c2");
+  c2.innerHTML = "hello";
+
+  // this ought to keep t-daddy from getting the click.
+  ev.stopPropagation();
+  alert("event propagation halted.");
+}
+
+function load() {
+  elem = document.getElementById("tbl1");
+  elem.addEventListener("click", stopEvent, false);
+}
+</script>
+</head>
+
+<body onload="load();">
+
+<table id="t-daddy" onclick="alert('hi');">
+  <tr id="tbl1">
+    <td id="c1">one</td>
+  </tr>
+  <tr>
+    <td id="c2">two</td>
+  </tr>
+</table>
+
+</body>
+</html>
+
+ +

Пример 6: getComputedStyle

+ +

Этот пример показывает как {{domxref("window.getComputedStyle")}} метод может использоваться для получения стилей элемента, которые не заданы с помощью атрибута style или с помощью JavaScript (e.g., elt.style.backgroundColor="rgb(173, 216, 230)"). Эти последние типы стилей можно получить с помощью более прямых {{domxref("element.style", "elt.style")}} свойств, которые указаны в DOM CSS Properties List.

+ +

getComputedStyle () возвращает объект ComputedCSSStyleDeclaration, свойства индивидуального стиля которого могут ссылаться на метод getPropertyValue () этого объекта, как показано в следующем примере документа.

+ +
<!DOCTYPE html>
+<html lang="en">
+<head>
+
+<title>getComputedStyle example</title>
+
+<script>
+function cStyles() {
+  var RefDiv = document.getElementById("d1");
+  var txtHeight = document.getElementById("t1");
+  var h_style = document.defaultView.getComputedStyle(RefDiv, null).getPropertyValue("height");
+
+  txtHeight.value = h_style;
+
+  var txtWidth = document.getElementById("t2");
+  var w_style = document.defaultView.getComputedStyle(RefDiv, null).getPropertyValue("width");
+
+  txtWidth.value = w_style;
+
+  var txtBackgroundColor = document.getElementById("t3");
+  var b_style = document.defaultView.getComputedStyle(RefDiv, null).getPropertyValue("background-color");
+
+  txtBackgroundColor.value = b_style;
+}
+</script>
+
+<style>
+#d1 {
+  margin-left: 10px;
+  background-color: rgb(173, 216, 230);
+  height: 20px;
+  max-width: 20px;
+}
+</style>
+
+</head>
+
+<body>
+
+<div id="d1">&nbsp;</div>
+
+<form action="">
+  <p>
+    <button type="button" onclick="cStyles();">getComputedStyle</button>
+    height<input id="t1" type="text" value="1" />
+    max-width<input id="t2" type="text" value="2" />
+    bg-color<input id="t3" type="text" value="3" />
+  </p>
+</form>
+
+</body>
+</html>
+
+ +

Пример 7: Отображение Свойств Событий Объекта

+ + + +

В этом примере используются методы DOM для отображения всех свойств объекта {{domxref ("window.onload")}} {{domxref ("event")}} и их значений в таблице. Он также показывает полезный метод использования цикла for..in для итерации по свойствам объекта для получения их значений.

+ +

Свойства объектов событий сильно различаются между браузерами, WHATWG DOM Standard перечисляет стандартные свойства, однако многие браузеры значительно расширили их.

+ +

Поместите следующий код в пустой текстовый файл и загрузите его в различные браузеры, вы будете удивлены различным количеством и именами свойств. Вы также можете добавить некоторые элементы на страницу и вызвать эту функцию из разных обработчиков событий.

+ + + +
<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8"/>
+<title>Show Event properties</title>
+
+<style>
+table { border-collapse: collapse; }
+thead { font-weight: bold; }
+td { padding: 2px 10px 2px 10px; }
+
+.odd { background-color: #efdfef; }
+.even { background-color: #ffffff; }
+</style>
+
+<script>
+
+function showEventProperties(e) {
+  function addCell(row, text) {
+    var cell = row.insertCell(-1);
+    cell.appendChild(document.createTextNode(text));
+  }
+
+  var e = e || window.event;
+  document.getElementById('eventType').innerHTML = e.type;
+
+  var table = document.createElement('table');
+  var thead = table.createTHead();
+  var row = thead.insertRow(-1);
+  var lableList = ['#', 'Property', 'Value'];
+  var len = lableList.length;
+
+  for (var i=0; i<len; i++) {
+    addCell(row, lableList[i]);
+  }
+
+  var tbody = document.createElement('tbody');
+  table.appendChild(tbody);
+
+  for (var p in e) {
+    row = tbody.insertRow(-1);
+    row.className = (row.rowIndex % 2)? 'odd':'even';
+    addCell(row, row.rowIndex);
+    addCell(row, p);
+    addCell(row, e[p]);
+  }
+
+  document.body.appendChild(table);
+}
+
+window.onload = function(event){
+  showEventProperties(event);
+}
+</script>
+</head>
+
+<body>
+<h1>Properties of the DOM <span id="eventType"></span> Event Object</h1>
+</body>
+
+</html>
+
+ +

Пример 8: Использование интерфейса таблицы DOM

+ + + +

Интерфейс DOM HTMLTableElement предоставляет некоторые удобные методы для создания и управления таблицами. Два часто используемых метода: {{domxref ("HTMLTableElement.insertRow")}} и {{domxref ("tableRow.insertCell")}}.

+ +

Чтобы добавить строку и некоторые ячейки в существующую таблицу:

+ + + +
<table id="table0">
+ <tr>
+  <td>Row 0 Cell 0</td>
+  <td>Row 0 Cell 1</td>
+ </tr>
+</table>
+
+<script>
+var table = document.getElementById('table0');
+var row = table.insertRow(-1);
+var cell,
+    text;
+
+for (var i = 0; i < 2; i++) {
+  cell = row.insertCell(-1);
+  text = 'Row ' + row.rowIndex + ' Cell ' + i;
+  cell.appendChild(document.createTextNode(text));
+}
+</script>
+
+ +

Заметки

+ +
    +
  • Свойство таблицы {{domxref ("element.innerHTML", "innerHTML")}} никогда не должно использоваться для изменения таблицы, хотя вы можете использовать ее для записи всей таблицы или содержимого ячейки.
  • +
  • Если для создания строк и ячеек используются методы DOM Core {{domxref ("document.createElement")}} и {{domxref ("Node.appendChild")}}, IE требует, чтобы они были добавлены к элементу tbody, тогда как другие браузеры позволят добавлять к элементу таблицы (строки будут добавлены к последнему элементу tbody).
  • +
  • Существует ряд других методов, относящихся к интерфейсу таблицы, которые могут использоваться для создания и изменения таблиц.
  • +
+ + + + diff --git a/files/ru/web/api/document_object_model/index.html b/files/ru/web/api/document_object_model/index.html new file mode 100644 index 0000000000..db06b01dd8 --- /dev/null +++ b/files/ru/web/api/document_object_model/index.html @@ -0,0 +1,387 @@ +--- +title: Руководство по DOM +slug: DOM/DOM_Reference +tags: + - DOM + - DOM Reference + - DOM интерфейс + - Intermediate + - Руководство +translation_of: Web/API/Document_Object_Model +--- +

Объектная Модель Документа (DOM) является программным интерфейсом для HTML, XML и SVG документов. Это обеспечивает структурированное представление документа (дерева), и определяет способ, по которому структура может быть доступна для программы, для изменения структуры документа, его стиля и содержания. DOM обеспечивает представление документа в виде структурированной группы узлов и объектов, которые имеют свойства и методы. По сути, она связывает веб -страницы со скриптами или языками программирования.

+ +

DOM чаще всего используется в JavaScript, но не является его частью, поэтому иногда с DOM работают в других языках.

+ +

Введение в DOM доступно.

+ +

DOM интерфейсы

+ +
+
    +
  • {{domxref("Attr")}}
  • +
  • {{domxref("CharacterData")}}
  • +
  • {{domxref("ChildNode")}} {{experimental_inline}}
  • +
  • {{domxref("Comment")}}
  • +
  • {{domxref("CustomEvent")}}
  • +
  • {{domxref("Document")}}
  • +
  • {{domxref("DocumentFragment")}}
  • +
  • {{domxref("DocumentType")}}
  • +
  • {{domxref("DOMError")}}
  • +
  • {{domxref("DOMException")}}
  • +
  • {{domxref("DOMImplementation")}}
  • +
  • {{domxref("DOMString")}}
  • +
  • {{domxref("DOMTimeStamp")}}
  • +
  • {{domxref("DOMSettableTokenList")}}
  • +
  • {{domxref("DOMStringList")}}
  • +
  • {{domxref("DOMTokenList")}}
  • +
  • {{domxref("Element")}}
  • +
  • {{domxref("Event")}}
  • +
  • {{domxref("EventTarget")}}
  • +
  • {{domxref("HTMLCollection")}}
  • +
  • {{domxref("MutationObserver")}}
  • +
  • {{domxref("MutationRecord")}}
  • +
  • {{domxref("Node")}}
  • +
  • {{domxref("NodeFilter")}}
  • +
  • {{domxref("NodeIterator")}}
  • +
  • {{domxref("NodeList")}}
  • +
  • {{domxref("ParentNode")}} {{experimental_inline}}
  • +
  • {{domxref("ProcessingInstruction")}}
  • +
  • {{domxref("Promise")}} {{experimental_inline}}
  • +
  • {{domxref("PromiseResolver")}} {{experimental_inline}}
  • +
  • {{domxref("Range")}}
  • +
  • {{domxref("Text")}}
  • +
  • {{domxref("TreeWalker")}}
  • +
  • {{domxref("URL")}}
  • +
  • {{domxref("Window")}}
  • +
  • {{domxref("Worker")}}
  • +
  • {{domxref("XMLDocument")}} {{experimental_inline}}
  • +
+
+ +

Устаревшие интерфейсы

+ +

Объектная модель документа находится в процессе значительного упрощения. Для того, чтобы достигнуть этого следующие интерфейсы, присутствующие на различных DOM level 3 или более ранних спецификациях были удалены. До сих пор неясно, будут ли некоторые из них возвращены, но на данный момент они должны быть рассмотрены как устаревшие, и их использования следует избегать:

+ +
+
    +
  • {{domxref("CDATASection")}}
  • +
  • {{domxref("DOMConfiguration")}}
  • +
  • {{domxref("DOMErrorHandler")}}
  • +
  • {{domxref("DOMImplementationList")}}
  • +
  • {{domxref("DOMImplementationRegistry")}}
  • +
  • {{domxref("DOMImplementationSource")}}
  • +
  • {{domxref("DOMLocator")}}
  • +
  • {{domxref("DOMObject")}}
  • +
  • {{domxref("DOMUserData")}}
  • +
  • {{domxref("Entity")}}
  • +
  • {{domxref("EntityReference")}}
  • +
  • {{domxref("NamedNodeMap")}}
  • +
  • {{domxref("NameList")}}
  • +
  • {{domxref("Notation")}}
  • +
  • {{domxref("TypeInfo")}}
  • +
  • {{domxref("UserDataHandler")}}
  • +
+
+ +

HTML интерфейсы

+ +

Документ, содержащий HTML описывается с помощью {{domxref("HTMLDocument")}} интерфейса. Обратите внимание, что HTML спецификация также расширяет {{domxref("Document")}} интерфейс.

+ +

Объект HTMLDocument также даёт доступ к следующим возможностям браузера: вкладки, окна, в которых отрисовывается страница, используя интерфейс {{domxref("Window")}}, асcоциированный с ним {{domxref("window.style", "Style")}} (обычно CSS), история браузера, относящаяся к контексту, {{domxref("window.history", "History")}}, в конце концов, {{domxref("Selection")}} в документе.

+ +

Интерфейсы HTML элементов

+ +
+
    +
  • {{domxref("HTMLAnchorElement")}}
  • +
  • {{domxref("HTMLAppletElement")}}
  • +
  • {{domxref("HTMLAreaElement")}}
  • +
  • {{domxref("HTMLAudioElement")}}
  • +
  • {{domxref("HTMLBaseElement")}}
  • +
  • {{domxref("HTMLBodyElement")}}
  • +
  • {{domxref("HTMLBRElement")}}
  • +
  • {{domxref("HTMLButtonElement")}}
  • +
  • {{domxref("HTMLCanvasElement")}}
  • +
  • {{domxref("HTMLDataElement")}}
  • +
  • {{domxref("HTMLDataListElement")}}
  • +
  • {{domxref("HTMLDirectoryElement")}}
  • +
  • {{domxref("HTMLDivElement")}}
  • +
  • {{domxref("HTMLDListElement")}}
  • +
  • {{domxref("HTMLElement")}}
  • +
  • {{domxref("HTMLEmbedElement")}}
  • +
  • {{domxref("HTMLFieldSetElement")}}
  • +
  • {{domxref("HTMLFontElement")}}
  • +
  • {{domxref("HTMLFormElement")}}
  • +
  • {{domxref("HTMLFrameElement")}}
  • +
  • {{domxref("HTMLFrameSetElement")}}
  • +
  • {{domxref("HTMLHeadElement")}}
  • +
  • {{domxref("HTMLHeadingElement")}}
  • +
  • {{domxref("HTMLHtmlElement")}}
  • +
  • {{domxref("HTMLHRElement")}}
  • +
  • {{domxref("HTMLIFrameElement")}}
  • +
  • {{domxref("HTMLImageElement")}}
  • +
  • {{domxref("HTMLInputElement")}}
  • +
  • {{domxref("HTMLKeygenElement")}}
  • +
  • {{domxref("HTMLLabelElement")}}
  • +
  • {{domxref("HTMLLegendElement")}}
  • +
  • {{domxref("HTMLLIElement")}}
  • +
  • {{domxref("HTMLLinkElement")}}
  • +
  • {{domxref("HTMLMapElement")}}
  • +
  • {{domxref("HTMLMediaElement")}}
  • +
  • {{domxref("HTMLMenuElement")}}
  • +
  • {{domxref("HTMLMetaElement")}}
  • +
  • {{domxref("HTMLMeterElement")}}
  • +
  • {{domxref("HTMLModElement")}}
  • +
  • {{domxref("HTMLObjectElement")}}
  • +
  • {{domxref("HTMLOListElement")}}
  • +
  • {{domxref("HTMLOptGroupElement")}}
  • +
  • {{domxref("HTMLOptionElement")}}
  • +
  • {{domxref("HTMLOutputElement")}}
  • +
  • {{domxref("HTMLParagraphElement")}}
  • +
  • {{domxref("HTMLParamElement")}}
  • +
  • {{domxref("HTMLPreElement")}}
  • +
  • {{domxref("HTMLProgressElement")}}
  • +
  • {{domxref("HTMLQuoteElement")}}
  • +
  • {{domxref("HTMLScriptElement")}}
  • +
  • {{domxref("HTMLSelectElement")}}
  • +
  • {{domxref("HTMLSourceElement")}}
  • +
  • {{domxref("HTMLSpanElement")}}
  • +
  • {{domxref("HTMLStyleElement")}}
  • +
  • {{domxref("HTMLTableElement")}}
  • +
  • {{domxref("HTMLTableCaptionElement")}}
  • +
  • {{domxref("HTMLTableCellElement")}}
  • +
  • {{domxref("HTMLTableDataCellElement")}}
  • +
  • {{domxref("HTMLTableHeaderCellElement")}}
  • +
  • {{domxref("HTMLTableColElement")}}
  • +
  • {{domxref("HTMLTableRowElement")}}
  • +
  • {{domxref("HTMLTableSectionElement")}}
  • +
  • {{domxref("HTMLTextAreaElement")}}
  • +
  • {{domxref("HTMLTimeElement")}}
  • +
  • {{domxref("HTMLTitleElement")}}
  • +
  • {{domxref("HTMLTrackElement")}}
  • +
  • {{domxref("HTMLUListElement")}}
  • +
  • {{domxref("HTMLUnknownElement")}}
  • +
  • {{domxref("HTMLVideoElement")}}
  • +
+
+ +

Другие интерфейсы

+ +
+
    +
  • {{domxref("CanvasRenderingContext2D")}}
  • +
  • {{domxref("CanvasGradient")}}
  • +
  • {{domxref("CanvasPattern")}}
  • +
  • {{domxref("TextMetrics")}}
  • +
  • {{domxref("ImageData")}}
  • +
  • {{domxref("CanvasPixelArray")}}
  • +
  • {{domxref("NotifyAudioAvailableEvent")}}
  • +
  • {{domxref("HTMLAllCollection")}}
  • +
  • {{domxref("HTMLFormControlsCollection")}}
  • +
  • {{domxref("HTMLOptionsCollection")}}
  • +
  • {{domxref("HTMLPropertiesCollection")}}
  • +
  • {{domxref("DOMStringMap")}}
  • +
  • {{domxref("RadioNodeList")}}
  • +
  • {{domxref("MediaError")}}
  • +
+
+ +

Устаревшие HTML интерфейсы

+ +
+
    +
  • {{domxref("HTMLBaseFontElement")}}
  • +
  • {{domxref("HTMLIsIndexElement")}}
  • +
+
+ +

SVG интерфейсы

+ +

Интерфейсы SVG элементов

+ +
+
    +
  • {{domxref("SVGAElement")}}
  • +
  • {{domxref("SVGAltGlyphElement")}}
  • +
  • {{domxref("SVGAltGlyphDefElement")}}
  • +
  • {{domxref("SVGAltGlyphItemElement")}}
  • +
  • {{domxref("SVGAnimationElement")}}
  • +
  • {{domxref("SVGAnimateElement")}}
  • +
  • {{domxref("SVGAnimateColorElement")}}
  • +
  • {{domxref("SVGAnimateMotionElement")}}
  • +
  • {{domxref("SVGAnimateTransformElement")}}
  • +
  • {{domxref("SVGCircleElement")}}
  • +
  • {{domxref("SVGClipPathElement")}}
  • +
  • {{domxref("SVGColorProfileElement")}}
  • +
  • {{domxref("SVGComponentTransferFunctionElement")}}
  • +
  • {{domxref("SVGCursorElement")}}
  • +
  • {{domxref("SVGDefsElement")}}
  • +
  • {{domxref("SVGDescElement")}}
  • +
  • {{domxref("SVGElement")}}
  • +
  • {{domxref("SVGEllipseElement")}}
  • +
  • {{domxref("SVGFEBlendElement")}}
  • +
  • {{domxref("SVGFEColorMatrixElement")}}
  • +
  • {{domxref("SVGFEComponentTransferElement")}}
  • +
  • {{domxref("SVGFECompositeElement")}}
  • +
  • {{domxref("SVGFEConvolveMatrixElement")}}
  • +
  • {{domxref("SVGFEDiffuseLightingElement")}}
  • +
  • {{domxref("SVGFEDisplacementMapElement")}}
  • +
  • {{domxref("SVGFEDistantLightElement")}}
  • +
  • {{domxref("SVGFEFloodElement")}}
  • +
  • {{domxref("SVGFEGaussianBlurElement")}}
  • +
  • {{domxref("SVGFEImageElement")}}
  • +
  • {{domxref("SVGFEMergeElement")}}
  • +
  • {{domxref("SVGFEMergeNodeElement")}}
  • +
  • {{domxref("SVGFEMorphologyElement")}}
  • +
  • {{domxref("SVGFEOffsetElement")}}
  • +
  • {{domxref("SVGFEPointLightElement")}}
  • +
  • {{domxref("SVGFESpecularLightingElement")}}
  • +
  • {{domxref("SVGFESpotLightElement")}}
  • +
  • {{domxref("SVGFETileElement")}}
  • +
  • {{domxref("SVGFETurbulenceElement")}}
  • +
  • {{domxref("SVGFEFuncRElement")}}
  • +
  • {{domxref("SVGFEFuncGElement")}}
  • +
  • {{domxref("SVGFEFuncBElement")}}
  • +
  • {{domxref("SVGFEFuncAElement")}}
  • +
  • {{domxref("SVGFilterElement")}}
  • +
  • {{domxref("SVGFilterPrimitiveStandardAttributes")}}
  • +
  • {{domxref("SVGFontElement")}}
  • +
  • {{domxref("SVGFontFaceElement")}}
  • +
  • {{domxref("SVGFontFaceFormatElement")}}
  • +
  • {{domxref("SVGFontFaceNameElement")}}
  • +
  • {{domxref("SVGFontFaceSrcElement")}}
  • +
  • {{domxref("SVGFontFaceUriElement")}}
  • +
  • {{domxref("SVGForeignObjectElement")}}
  • +
  • {{domxref("SVGGElement")}}
  • +
  • {{domxref("SVGGlyphElement")}}
  • +
  • {{domxref("SVGGlyphRefElement")}}
  • +
  • {{domxref("SVGGradientElement")}}
  • +
  • {{domxref("SVGHKernElement")}}
  • +
  • {{domxref("SVGImageElement")}}
  • +
  • {{domxref("SVGLinearGradientElement")}}
  • +
  • {{domxref("SVGLineElement")}}
  • +
  • {{domxref("SVGMarkerElement")}}
  • +
  • {{domxref("SVGMaskElement")}}
  • +
  • {{domxref("SVGMetadataElement")}}
  • +
  • {{domxref("SVGMissingGlyphElement")}}
  • +
  • {{domxref("SVGMPathElement")}}
  • +
  • {{domxref("SVGPathElement")}}
  • +
  • {{domxref("SVGPatternElement")}}
  • +
  • {{domxref("SVGPolylineElement")}}
  • +
  • {{domxref("SVGPolygonElement")}}
  • +
  • {{domxref("SVGRadialGradientElement")}}
  • +
  • {{domxref("SVGRectElement")}}
  • +
  • {{domxref("SVGScriptElement")}}
  • +
  • {{domxref("SVGSetElement")}}
  • +
  • {{domxref("SVGStopElement")}}
  • +
  • {{domxref("SVGStyleElement")}}
  • +
  • {{domxref("SVGSVGElement")}}
  • +
  • {{domxref("SVGSwitchElement")}}
  • +
  • {{domxref("SVGSymbolElement")}}
  • +
  • {{domxref("SVGTextElement")}}
  • +
  • {{domxref("SVGTextPathElement")}}
  • +
  • {{domxref("SVGTitleElement")}}
  • +
  • {{domxref("SVGTRefElement")}}
  • +
  • {{domxref("SVGTSpanElement")}}
  • +
  • {{domxref("SVGUseElement")}}
  • +
  • {{domxref("SVGViewElement")}}
  • +
  • {{domxref("SVGVKernElement")}}
  • +
+
+ +

Интерфейсы SVG данных

+ +

DOM API для типов данных, используемых в определениях SVG свойств и атрибутов.

+ +
+

Замечание: Начиная с {{Gecko("5.0")}}, следующие относящиеся к SVG DOM интерфейсы, представляя списки объектов, индексируются и к ним можно иметь доступ как к массивам; к тому же, у них есть свойство длины, обозначающее количество элементов в списках: {{domxref("SVGLengthList")}}, {{domxref("SVGNumberList")}}, {{domxref("SVGPathSegList")}} и {{domxref("SVGPointList")}}.

+
+ +

Статический тип

+ +
+
    +
  • {{domxref("SVGAngle")}}
  • +
  • {{domxref("SVGColor")}}
  • +
  • {{domxref("SVGICCColor")}}
  • +
  • {{domxref("SVGElementInstance")}}
  • +
  • {{domxref("SVGElementInstanceList")}}
  • +
  • {{domxref("SVGLength")}}
  • +
  • {{domxref("SVGLengthList")}}
  • +
  • {{domxref("SVGMatrix")}}
  • +
  • {{domxref("SVGNumber")}}
  • +
  • {{domxref("SVGNumberList")}}
  • +
  • {{domxref("SVGPaint")}}
  • +
  • {{domxref("SVGPoint")}}
  • +
  • {{domxref("SVGPointList")}}
  • +
  • {{domxref("SVGPreserveAspectRatio")}}
  • +
  • {{domxref("SVGRect")}}
  • +
  • {{domxref("SVGStringList")}}
  • +
  • {{domxref("SVGTransform")}}
  • +
  • {{domxref("SVGTransformList")}}
  • +
+
+ +

Анимированный тип

+ +
+
    +
  • {{domxref("SVGAnimatedAngle")}}
  • +
  • {{domxref("SVGAnimatedBoolean")}}
  • +
  • {{domxref("SVGAnimatedEnumeration")}}
  • +
  • {{domxref("SVGAnimatedInteger")}}
  • +
  • {{domxref("SVGAnimatedLength")}}
  • +
  • {{domxref("SVGAnimatedLengthList")}}
  • +
  • {{domxref("SVGAnimatedNumber")}}
  • +
  • {{domxref("SVGAnimatedNumberList")}}
  • +
  • {{domxref("SVGAnimatedPreserveAspectRatio")}}
  • +
  • {{domxref("SVGAnimatedRect")}}
  • +
  • {{domxref("SVGAnimatedString")}}
  • +
  • {{domxref("SVGAnimatedTransformList")}}
  • +
+
+ +

Относящиеся к SMIL

+ +
+
    +
  • {{domxref("ElementTimeControl")}}
  • +
  • {{domxref("TimeEvent")}}
  • +
+
+ +

Другие SVG интерфейсы

+ +
+
    +
  • {{domxref("SVGAnimatedPathData")}}
  • +
  • {{domxref("SVGAnimatedPoints")}}
  • +
  • {{domxref("SVGColorProfileRule")}}
  • +
  • {{domxref("SVGCSSRule")}}
  • +
  • {{domxref("SVGExternalResourcesRequired")}}
  • +
  • {{domxref("SVGFitToViewBox")}}
  • +
  • {{domxref("SVGLangSpace")}}
  • +
  • {{domxref("SVGLocatable")}}
  • +
  • {{domxref("SVGRenderingIntent")}}
  • +
  • {{domxref("SVGStylable")}}
  • +
  • {{domxref("SVGTests")}}
  • +
  • {{domxref("SVGTextContentElement")}}
  • +
  • {{domxref("SVGTextPositioningElement")}}
  • +
  • {{domxref("SVGTransformable")}}
  • +
  • {{domxref("SVGUnitTypes")}}
  • +
  • {{domxref("SVGURIReference")}}
  • +
  • {{domxref("SVGViewSpec")}}
  • +
  • {{domxref("SVGZoomAndPan")}}
  • +
+
+ +

Смотрите также

+ + + +
+
+
diff --git a/files/ru/web/api/document_object_model/introduction/index.html b/files/ru/web/api/document_object_model/introduction/index.html new file mode 100644 index 0000000000..3c02e5799f --- /dev/null +++ b/files/ru/web/api/document_object_model/introduction/index.html @@ -0,0 +1,230 @@ +--- +title: Введение +slug: DOM/DOM_Reference/Введение +tags: + - DOM +translation_of: Web/API/Document_Object_Model/Introduction +--- +
+

Этот раздел представляет краткое знакомство с Объектной Моделью Документа (DOM) - что такое DOM, каким образом предоставляются структуры HTML и XML документов, и как взаимодействовать с ними. Данный раздел содержит справочную информацию и примеры.

+ +

Что такое Объектная Модель Документа (DOM)?

+ +

Объектная Модель Документа (DOM) – это программный интерфейс (API) для HTML и XML документов. DOM предоставляет структурированное представление документа и определяет то, как эта структура может быть доступна из программ, которые могут изменять содержимое, стиль и структуру документа. Представление DOM состоит из структурированной группы узлов и объектов, которые имеют свойства и методы. По существу, DOM соединяет веб-страницу с языками описания сценариев либо языками программирования.
+
+ Веб-страница – это документ. Документ может быть представлен как в окне браузера, так и в самом HTML-коде. В любом случае, это один и тот же документ. DOM предоставляет другой способ представления, хранения и управления этого документа. DOM полностью поддерживает объектно-ориентированнное представление веб-страницы, делая возможным её изменение при помощи языка описания сценариев наподобие JavaScript.
+
+ Стандарты W3C DOM и WHATWG DOM формируют основы DOM, реализованные в большинстве современных браузеров. Многие браузеры предлагают расширения за пределами данного стандарта, поэтому необходимо проверять работоспособность тех или иных возможностей DOM для каждого конкретного браузера.

+ +

Например: стандарт DOM описывает, что метод getElementsByTagName в коде, указанном ниже, должен возращать список всех элементов <p> в документе.

+ +
paragraphs = document.getElementsByTagName("P");
+// paragraphs[0] это первый <p> элемент
+// paragraphs[1] это второй <p> элемент и т.д.
+alert(paragraphs[0].nodeName);
+ +

Все свойства, методы и события, доступные для управления и создания новых страниц, организованы в виде объектов. Например, объект document, который представляет сам документ, объект table, который реализует специальный интерфейс DOM HTMLTableElement, необходимый для доступа к HTML-таблицам, и так далее. Данная документация даёт справку об объектах DOM, реализованных Gecko-подобных браузерах.

+ +

DOM и JavaScript

+ +

Небольшой пример выше, как почти все примеры в этой справке – это JavaScript. То есть пример написан на JavaScript, но при этом используется DOM для доступа к документу и его элементам. DOM не является языком программирования, но без него JavaScript не имел бы никакой модели или представления о веб-странице, HTML-документе, XML-документе и их элементах. Каждый элемент в документе - весь документ в целом, заголовок, таблицы внутри документа, заголовки таблицы, текст внутри ячеек таблицы - это части объектной документной модели для этого документа, поэтому все они могут быть доступны и могут изменяться с помощью DOM и скриптового языка наподобие JavaScript.

+ +

Вначале JavaScript и DOM были тесно связаны, но впоследствии они развились в различные сущности. Содержимое страницы хранится в DOM и может быть доступно и изменяться с использованием JavaScript, поэтому мы можем записать это в виде приблизительного равенства:

+ +

API (веб либо XML страница) = DOM + JS (язык описания скриптов)

+ +

DOM спроектирован таким образом, чтобы быть независимым от любого конкретного языка программирования, обеспечивая структурное представление документа согласно единому и последовательному API. Хотя мы всецело сфокусированы на JavaScript в этой справочной документации, реализация DOM может быть построена для любого языка, как в следующем примере на Python:

+
+ +
# Пример DOM на языке Python
+import xml.dom.minidom as m
+doc = m.parse("C:\\Projects\\Py\\chap1.xml");
+doc.nodeName # Свойство объекта документа DOM;
+p_list = doc.getElementsByTagName("para");
+ +

Для подробной информации о том, какие технологии участвуют в написании JavaScript для веб, смотрите обзорную статью JavaScript technologies overview.

+ +

Каким образом доступен DOM? 

+ +

Вы не должны делать ничего особенного для работы с DOM. Различные браузеры имеют различную реализацию DOM, эти реализации показывают различную степень соответсвия с действительным стандартом DOM (это тема, которую мы пытались не затрагивать в данной документации), но каждый браузер использует свой DOM, чтобы сделать веб страницы доступными для взаимодествия с языками сценариев.

+ +

При создании сценария с использованием элемента <script>, либо включая в веб страницу инструкцию для загрузки скрипта, вы можете немедленно приступить к использованию программного интерфейса (API), используя элементы document или window для взаимодействия с самим документом, либо для получения потомков этого документа, т.е. различных элементов на странице. Ваше программирование DOM может быть чем-то простым, например, вывод сообщения с использованием функции alert() объекта window, или использовать более сложные методы DOM, которые создают новое содержимое, как показанно в следующем примере:

+ +
<body onload="window.alert('добро пожаловать на мою домашнюю страницу!');">
+
+ +

В следующем примере внутри элемента <script> определен код JavaScript, данный код устанавливает функцию при загрузке документа (когда весь DOM доступен для использования). Эта функция создает новый элемент H1, добавляет текст в данный элемент, а затем добавляет H1 в дерево документа:

+ +
<html>
+  <head>
+    <script>
+    // запуск данной функции при загрузке документа
+       window.onload = function() {
+    // создание нескольких элементов
+    // в пустой HTML странице
+       heading = document.createElement("h1");
+       heading_text = document.createTextNode("Big Head!");
+       heading.appendChild(heading_text);
+       document.body.appendChild(heading);
+      }
+    </script>
+  </head>
+  <body>
+  </body>
+</html>
+ +

Важные типы данных

+ +

Данный раздел предназначен для краткого описания различных типов и объектов в простой и доступной манере. Существует некоторое количество различных типов данных, которые используются в API, на которые вы должны обратить внимание. Для простоты, синтаксис примеров в данном разделе обычно ссылается на узлы как на elements, на массивы узлов как на nodeLists ( либо просто elements ) и на атрибуты узла, просто как на attributes.

+ +

Ниже таблица с кратким описанием этих типов данных.

+ + + + + + + + + + + + + + + + + + + + + + + + +
documentКогда член возвращает объект типа document (например, свойство элемента ownerDocument возвращает документ к которому он относится), этот обьект document является собственным корневым обьектом. В DOM document Reference разделе описан объект document.
+ element   
elementобозначает элемент или узел типа element, возвращаемый членом DOM API. Вместо того, чтобы говорить, что метод document.createElement() возвращает ссылку на node, мы просто скажем, что этот элемент возвращает element, который просто был создан в DOM. Объекты element реализуют DOM element интерфейс и также более общий Node интерфейс. Оба интерфейса включены в эту справку.
+ nodeList
NodeList +

массив элементов, как тот, что возвращается методом Document.getElementsByTagName(). Конкретные элементы в массиве доступны по индексу двумя способами:

+ +
    +
  •     list.item(1)
  • +
  •     list[1]
  • +
+ +

Эти способы эквивалентны. В первом способе item() - единственный метод объекта NodeList. Последний использует обычный синтаксис массивов, чтобы получить второе значение в списке.

+
attributeКогда attribute возвращается членом API (например, метод createAttribute()) - это будет ссылка на объект, который предоставляет специальный (хоть и небольшой) интерфейс для атрибутов. Атрибуты - это узлы в DOM, как и элементы, хотя вы можете редко использовать их в таком виде.
namedNodeMapnamedNodeMap подобна массиву, но элементы доступны по имени или индексу. Доступ по индексу - это лишь для удобства перечисления, т.к. элементы не имеют определенног порядка в списке. Этот тип данных имеет метод item() для этих целей и вы можете также добавлять и удалять элементы из namedNodeMap
+ + + +

DOM-интерфейсы (DOM interfaces)

+ + + +

Это руководство об объектах и реальных вещах, которые вы можете использовать для управления DOM-иерархией. Есть много моментов, где понимание того, как это работает, может удивлять. Например, объект, представляющий HTML form элемент, берет своё свойство name из интерфейса HTMLFormElement, а свойство className - из интерфейса HTMLElement. В обоих случаях свойство, которое вы хотите, находится в этом объекте формы.

+ +

Кроме того, отношение между объектами и интерфейсами, которые они реализуют в DOM может быть удивительным и этот раздел пытается рассказать немного о существующих интерфейсах в DOM и о том, как они могут быть доступны.

+ +

Интерфейсы и объекты (Interfaces and objects)

+ +

Многие объекты реализуют действия из нескольких интерфейсов. Объект таблицы, например, реализует специальный HTML Table Element Interface, который включает такие методы как createCaption и insertRow. Но так как это таблица - это ещё и HTML-элемент, table реализует интерфейс Element, описанный в разделе DOM element Reference. Наконец, так как HTML-элемент (в смысле DOM) - это узел (node) в дереве, которое составляет объектную модель для HTML- или XML-страницы, табличный элемент также реализует более общий интерфейс Node, из которого происходит Element.

+ +

Когда вы получаете ссылку на объект table, как в следующем примере, вы обычно используете все три интерфейса этого объекта, вероятно, даже не зная этого.

+ +
var table = document.getElementById("table");
+var tableAttrs = table.attributes; // Node/Element interface
+for (var i = 0; i < tableAttrs.length; i++) {
+  // HTMLTableElement interface: border attribute
+  if(tableAttrs[i].nodeName.toLowerCase() == "border")
+    table.border = "1";
+}
+// HTMLTableElement interface: summary attribute
+table.summary = "note: increased border";
+ +

Основные интерфейсы в DOM (Core interfaces in the DOM)

+ +

Этот раздел перечисляет несколько самых распространенных интерфейсов в DOM. Идея не в том чтобы описать, что делают эти методы API, но в том чтобы дать вам несколько мыслей насчет видов методов и свойств, которые вы будете часто видеть, используя DOM. Эти распространенные части API использованы в большинстве примеров раздела DOM Examples в конце этой справки.

+ +

Document, window - это объекты, чьи интерфейсы вы, как правило, очень часто используете в программировании DOM. Говоря простыми словами, объект window представляет что-то вроде браузера, а объект document - корень самого документа. Element наследуется от общего интерфейса Node, и эти интерфейсы вместе предоставляют много методов и свойств, которые можно применять у отдельных элементов. Эти элементы также могут иметь отдельные интерфейсы для работы с типами данных, которые эти элементы содержат, как в примере с объектом table в предыдущем случае.

+ +

Ниже представлен краткий список распространненых членов API, используемых в программировании веб- и XML-страниц с использованием DOM:

+ + + +

Тестирование DOM API

+ +

Этот документ содержит примеры для каждого интерфейса, который вы можете использовать в своей разработке. В некоторых случаях примеры - полноценные веб-страницы с доступом к DOM в элементе <script>, также перечислены элементы, необходимые чтобы запустить скрипт в форме, и HTML-элементы, над которыми будут производиться операции DOM. Когда встречается такой случай, можно просто копировать и вставить пример в новый HTML-документ, сохранить и запустить его в браузере.

+ +

Есть случаи, однако, где примеры более лаконичные. Чтобы запустить примеры, которые лишь демонстрируют основы взаимодействия интерфейсов с HTML-элементами, вы можете подготовить тестовую страницу, в которую будете помещать функции внутрь скриптов. Следующая очень простая веб-страница содержит элемент <script> в заголовке, в который вы можете поместить функции, чтобы протестировать интерфейс. Страница содержит несколько элементов с атрибутами, которые можно возвращать, устанавливать или, другими словами, манипулировать и содержит пользовательский интерфейс, необходимый, чтобы вызывать нужные функции из браузера.

+ +

Вы можете использовать эту тестовую страницу или похожую для проверки интерфейсов DOM, которые вас интересуют и просмотра того, как они работают в браузерах. Вы можете обновить содержмое функции test() при необходимости, создать больше кнопок или добавить элементы при необходимости.

+ +
<html>
+  <head>
+    <title>DOM Tests</title>
+    <script type="application/javascript">
+    function setBodyAttr(attr, value){
+      if (document.body) eval('document.body.'+attr+'="'+value+'"');
+      else notSupported();
+    }
+    </script>
+  </head>
+  <body>
+    <div style="margin: .5in; height: 400;">
+      <p><b><tt>text</tt></b></p>
+      <form>
+        <select onChange="setBodyAttr('text',
+        this.options[this.selectedIndex].value);">
+          <option value="black">black
+          <option value="darkblue">darkblue
+        </select>
+        <p><b><tt>bgColor</tt></b></p>
+        <select onChange="setBodyAttr('bgColor',
+        this.options[this.selectedIndex].value);">
+          <option value="white">white
+          <option value="lightgrey">gray
+        </select>
+        <p><b><tt>link</tt></b></p>
+        <select onChange="setBodyAttr('link',
+        this.options[this.selectedIndex].value);">
+          <option value="blue">blue
+          <option value="green">green
+        </select>  <small>
+        <a href="http://www.brownhen.com/dom_api_top.html" id="sample">
+        (sample link)</a></small><br>
+      </form>
+      <form>
+        <input type="button" value="version" onclick="ver()" />
+      </form>
+    </div>
+  </body>
+</html>
+ +

Чтобы протестировать много интерфейсов на одной странице, набор свойств, которые изменяют цвета веб-страницы, можно создать похожую веб-страницу с целой "консолью" кнопок, текстовых полей и других элементов. Следующий скриншот даёт идею, как интерфейсы могут быть сгруппированы вместе для тестирования

+ +

+ +

В этом примере выпадающее меню динамически обновляет доступные из DOM части веб-страницы (например, фоновый цвет, цвет ссылок и цвет текста). Однако при разработке тестовых страниц, тестирование интерфейсов, как вы об этом прочитали, важная часть изучения эффективной работы с DOM.

+ +

Другие статьи

+ + diff --git a/files/ru/web/api/document_object_model/locating_dom_elements_using_selectors/index.html b/files/ru/web/api/document_object_model/locating_dom_elements_using_selectors/index.html new file mode 100644 index 0000000000..73538e8616 --- /dev/null +++ b/files/ru/web/api/document_object_model/locating_dom_elements_using_selectors/index.html @@ -0,0 +1,50 @@ +--- +title: Locating DOM elements using selectors +slug: DOM/DOM_Reference/Locating_DOM_elements_using_selectors +translation_of: Web/API/Document_object_model/Locating_DOM_elements_using_selectors +--- +
{{ gecko_minversion_header("1.9.1") }}
+ +
Selectors API предоставляет методы, с помощью которых можно быстро и просто получить доступ к узлам Element из DOM путем сопоставления с набором селекторов. Это намного быстрее, чем прошлые техники, где надо было, например, использовать цикл в JS-коде, чтобы найти конкретные элементы.
+ +
 
+ +

Интерфейс NodeSelector (The NodeSelector interface)

+ +

Эта спецификация добавляет два новых метода к любым объектам, реализующим интерфейс Document, DocumentFragment, или Element:

+ +
+
querySelector
+
Возвращает первый совпадающий узел Element внутри поддерева. Если совпадающих узлов нет, будет возвращен null.
+
querySelectorAll
+
Возвращает NodeList, содержащий все подходящие узлы Element внутри поддерева узлов. Или возвращает пустой NodeList, если совпадений не найдено.
+
+ +
Замечание: NodeList, возвращаемый методом querySelectorAll(), не настоящий. Этот список отличается от других методов поиска DOM, которые возвращают настоящие (живые) узлы.
+ +

Вы можете найти примеры и детали, прочитав документацию для методов querySelector() и querySelectorAll(), а также в статье Code snippets for querySelector.

+ +

Selectors

+ +

Селекторные методы принимают один или больше селекторов, разделенных запятыми, чтобы определить, какие элементы должны быть возвращены. Например, чтобы все параграфы в документе, которые имеют классы warning или note, можно сделать следующее:

+ +
var special = document.querySelectorAll( "p.warning, p.note" );
+ +

Также можно искать по ID. Например:

+ +
var el = document.querySelector( "#main, #basic, #exclamation" );
+ +

После выполнения кода выше, el будет содержать первый элемент в документе, чей ID main, basic или exclamation

+ +

Вы можете использовать любые CSS-селекторы в методах querySelector(), querySelectorAll()

+ +

See also

+ + diff --git a/files/ru/web/api/documentorshadowroot/activeelement/index.html b/files/ru/web/api/documentorshadowroot/activeelement/index.html new file mode 100644 index 0000000000..71db5bc678 --- /dev/null +++ b/files/ru/web/api/documentorshadowroot/activeelement/index.html @@ -0,0 +1,165 @@ +--- +title: Document.activeElement +slug: Web/API/Document/activeElement +tags: + - API + - Document + - HTML DOM + - Property + - Reference +translation_of: Web/API/DocumentOrShadowRoot/activeElement +translation_of_original: Web/API/Document/activeElement +--- +

{{ ApiRef() }}

+ +

Анотация

+ +

Возвращает текущий сфокусированный элемент, то есть элемент, на котором будут вызываться события клавиатуры, если пользователь начнёт с неё ввод. Этот атрибут доступен только для чтения.

+ +

Часто возвращается {{ HTMLElement("input") }} или {{ HTMLElement("textarea") }} объект, если он содержит в себе выделенный в данный момент текст. При этом вы можете получить более подробные сведения, используя свойства элемента  selectionStart и selectionEnd.  В других случаях сфокусированным элементом может быть {{ HTMLElement("select") }} элемент (меню) или {{ HTMLElement("input") }} элемент типа button, checkbox или radio.

+ +

{{ Note("На Mac, элементы, не являющиеся текстовыми полями, как правило, не получают фокус.") }}

+ +

Как правило, пользователь может нажать клавишу табуляции для перемещения по фокусируемым элементам страницы, и использовать пробел для их активации (нажать кнопку button, выбрать переключатель radio).

+ +

Не следует путать фокус с выделением документа, состоящего в основном из статических текстовых узлов. См. {{ domxref("window.getSelection()") }}. 

+ +

Когда выделение отсутствует, активным элементом является {{ HTMLElement("body") }} страницы или null. 

+ +

{{ Note("Этот атрибут является частью разрабатываемой спецификации HTML 5.") }}

+ +

Синтаксис

+ +
var curElement = document.activeElement;
+
+ +

Пример

+ +
<!DOCTYPE HTML>
+<html>
+<head>
+    <script type="text/javascript" charset="utf-8">
+    function init() {
+
+        function onMouseUp(e) {
+            console.log(e);
+            var outputElement = document.getElementById('output-element');
+            var outputText = document.getElementById('output-text');
+            var selectedTextArea = document.activeElement;
+            var selection = selectedTextArea.value.substring(
+            selectedTextArea.selectionStart, selectedTextArea.selectionEnd);
+            outputElement.innerHTML = selectedTextArea.id;
+            outputText.innerHTML = selection;
+        }
+
+        document.getElementById("ta-example-one").addEventListener("mouseup", onMouseUp, false);
+        document.getElementById("ta-example-two").addEventListener("mouseup", onMouseUp, false);
+    }
+    </script>
+</head>
+<body onload="init()">
+<div>
+    Выделите текст в одном из текстовых полей ниже:
+</div>
+<form id="frm-example" action="#" accept-charset="utf-8">
+<textarea name="ta-example-one" id="ta-example-one" rows="8" cols="40">
+Это текстовое поле 1:
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec tincidunt, lorem a porttitor molestie, odio nibh iaculis libero, et accumsan nunc orci eu dui.
+</textarea>
+<textarea name="ta-example-two" id="ta-example-two" rows="8" cols="40">
+Это текстовое поле 2:
+Fusce ullamcorper, nisl ac porttitor adipiscing, urna orci egestas libero, ut accumsan orci lacus laoreet diam. Morbi sed euismod diam.
+</textarea>
+</form>
+ID активного элемента: <span id="output-element"></span><br/>
+Выделенный текст: <span id="output-text"></span>
+
+</body>
+</html>
+
+ +

Посмотреть на JSFiddle

+ +

Примечания

+ +

Первоначально введенное как собственное расширение DOM в Internet Explorer 4, это свойство также поддерживается в Opera и Safari (в версии 4).

+ +

Спецификации

+ + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('HTML WHATWG', 'interaction.html#dom-document-activeelement', 'activeElement')}}{{Spec2('HTML WHATWG')}} 
+ +

Совместимость с браузерами

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support23.04 [1]9.64.0
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
+
+ +

[1]: В IE9 наблюдается баг: при попытке получения доступа к activeElement в {{domxref("window.parent")}} {{domxref("Document")}} из {{HTMLElement("iframe")}} (т.е. parent.document.activeElement) выбрасывается ошибка.

+ +

Связанные события

+ +
    +
  • {{event("focus")}}
  • +
  • {{event("blur")}}
  • +
  • {{event("focusin")}}
  • +
  • {{event("focusout")}}
  • +
diff --git a/files/ru/web/api/documentorshadowroot/getselection/index.html b/files/ru/web/api/documentorshadowroot/getselection/index.html new file mode 100644 index 0000000000..c57695e055 --- /dev/null +++ b/files/ru/web/api/documentorshadowroot/getselection/index.html @@ -0,0 +1,9 @@ +--- +title: Document.getSelection() +slug: Web/API/Document/getSelection +translation_of: Web/API/DocumentOrShadowRoot/getSelection +translation_of_original: Web/API/Document/getSelection +--- +

{{APIRef("DOM")}}

+ +

Этот метод работает в точности так же, как {{domxref("Window.getSelection()")}}; он возвращает объект {{domxref("Selection")}}, в котором содержатся данные о тексте, выделенном в документе на данный момент.

diff --git a/files/ru/web/api/element/accesskey/index.html b/files/ru/web/api/element/accesskey/index.html deleted file mode 100644 index 0230ecc9e0..0000000000 --- a/files/ru/web/api/element/accesskey/index.html +++ /dev/null @@ -1,74 +0,0 @@ ---- -title: Element.accessKey -slug: Web/API/Element/accessKey -translation_of: Web/API/HTMLElement/accessKey -translation_of_original: Web/API/Element/accessKey ---- -
{{APIRef("DOM")}}
- -
 
- -

Описание

- -

Свойство accessKey позволяет перейти к элементу с помощью сочетания клавиш - заданной им и тех, что назначит браузер.

- -
-

По сути, accessKey задает значение для одноименного атрибута...

-
- -
-

Данное свойство использовать не рекоммендуется, поскольку в браузерах уже заданы подобные привязки и неосторожное обращение может привести к жестокому конфликту.

-
- -

 

- -

Синтаксис

- -
var key = elem.accessKey;
-elem.accessKey = key;
-
- -

 

- -

Пример

- -
var elem = document.getElementById("id");
-elem.accessKey = "w";
-
- -

Немного информации

- -

Фокусировка на элемент произойдет при нажатии следующих клавиш (,где acesskey - значение свойства acessKey).

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

      Браузер

-
-

      Сочетание

-
Firefox[Alt] [Shift] + accesskey
Internet Explorer[Alt] + accesskey
Chrome[Alt] + accesskey
Safari[Alt] + accesskey
Opera[Shift] [Esc] + accesskey
diff --git a/files/ru/web/api/element/blur_event/index.html b/files/ru/web/api/element/blur_event/index.html new file mode 100644 index 0000000000..a29fa0debc --- /dev/null +++ b/files/ru/web/api/element/blur_event/index.html @@ -0,0 +1,153 @@ +--- +title: blur (event) +slug: Web/Events/blur +tags: + - DOM + - DOM Events +translation_of: Web/API/Element/blur_event +--- +

Событие blur вызывается когда элемент теряет фокус. Главное отличие между этим событием и  focusout только в том что у последнего есть фаза всплытия.

+ +

Основная информация

+ +
+
Спецификация
+
DOM L3
+
Интерфейс
+
{{domxref("FocusEvent")}}
+
Всплытие
+
Нет
+
Отменяемый
+
Нет
+
Цель
+
Элемент
+
Действие по умолчанию
+
Нет
+
+ +

{{NoteStart}}Значение {{domxref("Document.activeElement")}} меняется в зависимости от браузера во время выполнения этого события ({{bug(452307)}}): IE10 устанавливает его к элементу на который будет перемещен фокус, в то время как Firefox и Chrome обычно устанавливают его к body документа{{NoteEnd}}

+ +

Свойства

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeDescription
target {{readonlyInline}}{{domxref("EventTarget")}}Event target (DOM element)
type {{readonlyInline}}{{domxref("DOMString")}}The type of event.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Whether the event normally bubbles or not.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Whether the event is cancellable or not.
relatedTarget {{readonlyInline}}{{domxref("EventTarget")}} (DOM element)null
+ +

Делегирование события

+ +

Есть два способа реализовать делегирование этого события: использовать событие focusout в браузерах которые поддерживают его (все браузеры, Firefox с 52+), или установить параметр "useCapture" метода addEventListener на true:

+ +

HTML Content

+ +
<form id="form">
+  <input type="text" placeholder="text input">
+  <input type="password" placeholder="password">
+</form>
+ +

JavaScript Content

+ +
var form = document.getElementById("form");
+form.addEventListener("focus", function( event ) {
+  event.target.style.background = "pink";
+}, true);
+form.addEventListener("blur", function( event ) {
+  event.target.style.background = "";
+}, true);
+ +

{{EmbedLiveSample('Event_delegation')}}

+ +

Совместимость с браузерами

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support5{{CompatVersionUnknown}}[1]612.15.1
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support4.053{{CompatUnknown}}10.012.15.1
+
+ +

[1] В Gecko до 24 {{geckoRelease(24)}} интефейс для этого события был {{domxref("Event")}}, не {{domxref("FocusEvent")}}. Смотреть ({{bug(855741)}}).

+ +

Похожие события

+ +
    +
  • {{event("focus")}}
  • +
  • {{event("blur")}}
  • +
  • {{event("focusin")}}
  • +
  • {{event("focusout")}}
  • +
diff --git a/files/ru/web/api/element/error_event/index.html b/files/ru/web/api/element/error_event/index.html new file mode 100644 index 0000000000..787fb9a4fa --- /dev/null +++ b/files/ru/web/api/element/error_event/index.html @@ -0,0 +1,95 @@ +--- +title: error +slug: Web/Events/error +tags: + - DOM + - UI события + - Видео + - Запись + - Медия + - Обработка ошибок + - Ошибки + - Событие + - аудио + - события +translation_of: Web/API/Element/error_event +--- +

Событие error возникает, когда произошла какая-либо ошибка. Точные обстоятельства могут быть различными, потому что события с этим именем используются множеством различных API.

+ +

Общая информация

+ +
+
Спецификация
+
DOM L3
+
Интерфейс
+
{{domxref("UIEvent")}} если создается элементом пользовательского интерфейса, {{domxref("MediaRecorderErrorEvent")}} если генерируется API записи MediaStream, и {{domxref("Event")}} иначе.
+
Вплывающее
+
Нет
+
Отменяемое
+
Нет
+
Цель
+
Элемент
+
Действие по умолчанию
+
Нет
+
+ +

Свойства

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeDescription
target {{readonlyInline}}EventTargetЦель события (наиболее верхлежащий элемент в DOM дереве).
type {{readonlyInline}}DOMStringТип события.
bubbles {{readonlyInline}}BooleanЯвляется ли событие вплывающим в стандартных условиях или нет.
cancelable {{readonlyInline}}BooleanЯвляется ли событие отменяемым или нет.
view {{readonlyInline}}WindowProxydocument.defaultView (свойство window объекта document)
detail {{readonlyInline}}long (float)0.
+ +

Для MediaStream Recording событий

+ +

Эти события типа {{domxref("MediaRecorderErrorEvent")}}.

+ +

{{page("/en-US/docs/Web/API/MediaRecorderErrorEvent", "Properties")}}

+ +

Смотрите также

+ +
+
{{domxref("GlobalEventHandlers.onerror")}}
+
События отсылаются в {{domxref("Window.onerror")}} и {{domxref("Element.onerror")}}
+
{{domxref("HTMLMediaElement.onerror")}}
+
События отсылаются в {{domxref("HTMLMediaElement")}}, включая {{HTMLElement("audio")}} и {{HTMLElement("video")}}
+
{{domxref("MediaRecorder.onerror")}}
+
События отсылаются в {{domxref("MediaRecorder.onerror")}}, типа {{domxref("MediaRecorderErrorEvent")}}
+
diff --git a/files/ru/web/api/element/focusin_event/index.html b/files/ru/web/api/element/focusin_event/index.html new file mode 100644 index 0000000000..02f27b66fb --- /dev/null +++ b/files/ru/web/api/element/focusin_event/index.html @@ -0,0 +1,123 @@ +--- +title: focusin +slug: Web/Events/focusin +translation_of: Web/API/Element/focusin_event +--- +

Событие focusin срабатывает, когда элемент получает фокус. Главное отличие от focus в том, что последний не всплывает.

+ +

Общая информация

+ +
+
Specification
+
DOM L3
+
Interface
+
{{domxref("FocusEvent")}}
+
Bubbles
+
Yes
+
Cancelable
+
No
+
Target
+
Element
+
Default Action
+
None.
+
+ +

Свойства

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeDescription
target {{readonlyInline}}{{domxref("EventTarget")}}Event target losing focus.
type {{readonlyInline}}{{domxref("DOMString")}}The type of event.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Whether the event normally bubbles or not.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Whether the event is cancellable or not.
relatedTarget {{readonlyInline}}{{domxref("EventTarget")}} (DOM element)Event target receiving focus.
+ +

Browser compatibility

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatNo}}[1]{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatNo}}[1]{{CompatVersionUnknown}}{{CompatUnknown}}{{CompatVersionUnknown}}
+
+ +

[1] Событие пока что не поддерживается в Firefox, см. {{Bug("687787")}}. Вместо него можно использовать событие focus, которое совместимо с делегированием событий.

+ + + +
    +
  • {{event("focus")}}
  • +
  • {{event("blur")}}
  • +
  • {{event("focusin")}}
  • +
  • {{event("focusout")}}
  • +
diff --git a/files/ru/web/api/element/focusout_event/index.html b/files/ru/web/api/element/focusout_event/index.html new file mode 100644 index 0000000000..742f52af03 --- /dev/null +++ b/files/ru/web/api/element/focusout_event/index.html @@ -0,0 +1,126 @@ +--- +title: focusout +slug: Web/Events/focusout +translation_of: Web/API/Element/focusout_event +--- +

Событие focusout вызывается перед потерей элементом фокуса. Главное отличие между этим событием и blur в том, что у последнего нет фазы всплытия.

+ +

 

+ +

Основная информация

+ +
+
Спецификация
+
DOM L3
+
Интерфейс
+
{{domxref("FocusEvent")}}
+
Всплытие
+
Да
+
Отменяемый
+
Нет
+
Цель
+
Элемент
+
Действие по умолчанию
+
Нет.
+
+ +

Свойства

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
СвойствоТипОписание
target {{readonlyInline}}{{domxref("EventTarget")}}Цель события, теряющая фокус.
type {{readonlyInline}}{{domxref("DOMString")}}Тип события.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Всплывает ли событие при нормальных условиях.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Возможно ли отменить событие.
relatedTarget {{readonlyInline}}{{domxref("EventTarget")}} (DOM-элемент)Цель события, получающая фокус.
+ +

Browser compatibility

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoDesktop(52)}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoMobile(52)}}{{CompatVersionUnknown}}{{CompatUnknown}}{{CompatVersionUnknown}}
+
+ + + +
    +
  • {{event("focus")}}
  • +
  • {{event("blur")}}
  • +
  • {{event("focusin")}}
  • +
diff --git a/files/ru/web/api/elementcssinlinestyle/style/index.html b/files/ru/web/api/elementcssinlinestyle/style/index.html new file mode 100644 index 0000000000..683bfa1101 --- /dev/null +++ b/files/ru/web/api/elementcssinlinestyle/style/index.html @@ -0,0 +1,78 @@ +--- +title: HTMLElement.style +slug: Web/API/HTMLElement/style +tags: + - API + - HTML DOM + - HTMLElement + - NeedsBrowserAgnosticism + - NeedsBrowserCompatibility + - NeedsMarkupWork + - NeedsSpecTable + - Свойство + - Ссылки +translation_of: Web/API/ElementCSSInlineStyle/style +--- +

Кратко

+ +
+
{{ APIRef("HTML DOM") }}
+
+ +

Свойство HTMLElement.style используется для получения и установки инлайновых стилей. При получении возвращается объект CSSStyleDeclaration , который содержит список из всех свойств стилей для этого элемента с значениями заданными  для атрибутов , что определенны  в инлайновом стиле (см. атрибут стиля) элемента. См. CSS Properties Reference для получения списка CSS свойств применимых вместе со style.  

+ +

Настройка стилей

+ +

Свойство style имеет тот же приоритет (и выше) в каскаде CSS как и прямая декларация стиля через атрибут style, полезен для настройки стиля отдельного специфичного элемента.

+ +

Стили не следует устанавливать непосредственно через свойство style (например elt.style = "color: blue;"), поскольку оно считается доступным только для чтения и атрибут style возвращает объект CSSStyleDeclaration который доступен только для чтения. Вместо этого стили могут быть установлены путем присвоения значений свойствам style. Для добавления определенных стилей для элемента без изменения других свойств стилей предпочтительно использовать отдельные свойства style (например elt.style.color = '...'). +При использовании
elt.style.cssText = '...' или elt.setAttribute('style','...') устанавливаются стили перезаписывая уже существующие. Обратите внимание, что имена свойств стилей задаются в camel-case а не в kebab-case elt.style.<property> (т.е., elt.style.fontSize, а не elt.style.font-size).

+ +

Объявленные стили сбрасываются присваиванием значения null,
elt.style.color = null

+ +

Примеры

+ +
// Устанавливает несколько стилей в одном выражении
+elt.style.cssText = "color: blue; border: 1px solid black";
+// Или
+elt.setAttribute("style", "color:red; border: 1px solid blue;");
+
+// Устанавливает определенный стиль оставляя другие значения стиля нетронутыми
+elt.style.color = "blue";
+ +

Получение стиль-информации

+ +

Свойство style в основном не имеет пользы в части информации о стиле элемента, оно только олицетворяет собой набор CSS деклараций атрибутов style элемента, а не тех которые проистекают из стиль-правил откуда-либо ещё, таких как стилевые правила раздела {{HTMLElement("head")}}, или внешней таблицы стилей. Для получения значений всех CSS свойств элемента вы должны использовать вместо этого {{domxref("window.getComputedStyle()")}}.

+ +
+
var div = document.getElementById("div1");
+div.style.marginTop = ".25in";
+
+ +

Следующий код показывает имена всех свойств стиля, значений, заданных явно для элемента elt и унаследованных "расчитанных" значений:

+ +
var elt = document.getElementById("elementIdHere");
+var out = "";
+var st = elt.style;
+var cs = window.getComputedStyle(elt, null);
+for (x in st) {
+  out += "  " + x + " = '" + st[x] + "' > '" + cs[x] + "'\n";
+}
+ +

Спецификация

+ +

DOM Level 2 Style: ElementCSSInlineStyle.style

+ +

CSSOM: ElementCSSInlineStyle

+ +

Совместимость

+ + + +

{{Compat("api.HTMLElement.style")}}

+ +

См. также

+ + diff --git a/files/ru/web/api/eventtarget/attachevent/index.html b/files/ru/web/api/eventtarget/attachevent/index.html deleted file mode 100644 index a428f9724c..0000000000 --- a/files/ru/web/api/eventtarget/attachevent/index.html +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: EventTarget.attachEvent() -slug: Web/API/EventTarget/attachEvent -tags: - - Junk -translation_of: Web/API/EventTarget/addEventListener -translation_of_original: Web/API/EventTarget/attachEvent ---- -

{{DOMxRef("EventTarget.addEventListener","EventTarget.addEventListener()")}}

diff --git a/files/ru/web/api/eventtarget/detachevent/index.html b/files/ru/web/api/eventtarget/detachevent/index.html deleted file mode 100644 index 9a62ecb63c..0000000000 --- a/files/ru/web/api/eventtarget/detachevent/index.html +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: EventTarget.detachEvent() -slug: Web/API/EventTarget/detachEvent -translation_of: Web/API/EventTarget/removeEventListener -translation_of_original: Web/API/EventTarget/detachEvent ---- -

{{APIRef("DOM Events")}}

- -

{{ Non-standard_header() }}

- -

Кратко

- -

Это проприетарная альтернатива методу {{domxref("EventTarget.removeEventListener()")}}  в Microsoft Internet Explorer.

- -

Синтаксис

- -
target.detachEvent(eventNameWithOn, callback)
-
- -
-
target
-
DOM елемент, для которого надо убрать обработчик.
-
eventNameWithOn
-
Название ивента, начинающийся на "on" (так если бы это был колбэк атрибут), чей обработчик должен быть убран. Например, вам следует использовать "onclick" для удаления обработчика для данного "click" ивента.
-
callback
-
Функция, которую стоит убрать.
-
- -

Спецификация

- -

Не является частью спецификации.

- -

Microsoft содержит описание на MSDN.

- -

Поддержка браузерами

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Базовая поддержка{{ CompatNo() }}{{ CompatNo() }}6 thru 10 [1]{{ CompatUnknown() }}{{ CompatNo() }}
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Базовая поддержка{{ CompatNo() }}{{ CompatNo() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatNo() }}
-
- -

[1]: detachEvent() больше не поддерживается в IE11+. {{domxref("EventTarget.removeEventListener()")}} поддерживается в IE9+.

- -

Смотрите так-же

- -
    -
  • {{ domxref("EventTarget.attachEvent()") }}
  • -
  • {{ domxref("EventTarget.fireEvent()") }}
  • -
diff --git a/files/ru/web/api/file_and_directory_entries_api/introduction/index.html b/files/ru/web/api/file_and_directory_entries_api/introduction/index.html new file mode 100644 index 0000000000..e5c76758c1 --- /dev/null +++ b/files/ru/web/api/file_and_directory_entries_api/introduction/index.html @@ -0,0 +1,291 @@ +--- +title: Введение в API файлов и каталогов +slug: Web/API/File_and_Directory_Entries_API/Введение +translation_of: Web/API/File_and_Directory_Entries_API/Introduction +--- +
{{DefaultAPISidebar("File System API")}}{{Non-standard_header}}
+ +

API файлов и каталогов эмулирует для веб-приложений локальную файловую систему. У вас есть возможность создания приложений, которые могут читать, записывать и создавать файлы и директории в изолированной виртуальной файловой системе.

+ +

API файлов и каталогов взаимодействует с другими API. Оно было создано на основе File Writer API, который в свою очередь использует File API. Каждое API реализует разную функциональность. Данные программные интерфейсы являются огромным эволюционным скачком для веб-приложений, которые теперь могут кешировать и обрабатывать большие объемы данных. 

+ +

Об этом документе

+ +

В данном документе приведены основные концепции и терминология API файлов и каталогов, которые должны показать общую картину и ключевые идеи. Также описаны ограничения, несоблюдение которых может привести к появлению ошибок безопасности. Используемая терминология описана в разделе Определений.

+ +

Ссылки на страницы данного API приведены в Ссылочном справочнике.

+ +

Спецификация находится на стадии разработки и будет изменяться в будущем.

+ +

Обзор

+ +

Программный интерфейс файлов и каталогов включает асинхронные и синхронные методы. Асинхронное API может быть использовано в тех случаях, когда нежелательно, чтобы длительные вычисления блокировали весь пользовательский интерфейс. В свою очередь синхронное API предлагает более простую модель программирования, однако оно должно использоваться только с объектами WebWorkers.

+ +

Применимость API

+ +

API файлов и каталогов является важным программным интерфейсом по следующим причинам:

+ +
    +
  • Благодаря ему у приложений могут быть автономные (offline) функции, а также функции хранения, позволяющие обрабатывать большие наборы двоичных данных.
  • +
  • У приложений появляется возможность предварительной загрузки и кеширования ресурсов, что повышает из производительность.
  • +
  • У пользователя приложения появляется возможность напрямую редактировать файлы, расположенные у него на компьютере.
  • +
  • Пользователям предоставляется интерфейс работы с файловым хранилищем, который схож с файловой системой.
  • +
+ +

Примеры таких приложений приведены в разделе Примеры использования.

+ +

API файлов и каталогов и другие программные интерфейсы хранения данных

+ +

API файлов и каталогов является альтернативой для других интерфейсов хранения данных, таких как IndexedDB, WebSQL (признано устаревшим с 18 ноября 2010 г.) и AppCache. Тем не менее данное API является более хорошим выбором для приложений, обрабатывающим большие объемы данных, по следующим причинам:

+ +
    +
  • Данное API предлагает возможность хранения данных на стороне клиента в вариантах использования, которые не могут быть решены с помощью баз данных. Например, данное API является намного более производительным в случае хранения и обработки больших файлов.
  • +
  • Firefox поддерживает хранение бинарных данных в IndexedDB, в то время как в Chrome эта функция по-прежнему находится на стадии разработки. Если Chrome является одним из целевых браузеров для вашего приложения и у вас есть необходимость хранения бинарных данных, то вы можете использовать только либо данное API, либо AppCache. В свою очередь хранилище AppCache не предоставляет возможности локальных изменений, а также тонкой настройки на стороне клиента.
  • +
  • В Chrome у вас есть возможность использования данного API вместе с программным интерфейсом управления квотами, позволяющее управлять квотами хранилища.
  • +
+ +

Примеры использования

+ +

Далее приведены лишь некоторые случаи, в которых можно использовать API файлов и каталогов:

+ +
    +
  • Приложения с постоянной загрузкой. +
      +
    • Когда файл или каталог выбран для загрузки на сервер, есть возможность скопировать файлы в локальную песочницу и начать их поочередную загрузку. 
    • +
    • Приложение может продолжить загрузку после закрытия или аварийного сбоя браузера, прерывание связи или завершения работы компьютера.
    • +
    +
  • +
  • Видеоигры или другие приложения с большим количеством медиа ресурсов. +
      +
    • Приложение скачивает один или несколько больших архивов с ресурсами и локально его распаковывает.
    • +
    • Приложение осуществляет предварительную фоновую загрузку ресурсов, благодаря чему у пользователя нет необходимости ожидать их загрузки для начала следующего уровня.
    • +
    +
  • +
  • Аудио- или фоторедактор с возможностью автономной работы или локальным кэшем. +
      +
    • Приложение может редактировать файлы без полной их перезаписи (например, ID3/EXIF теги).
    • +
    +
  • +
  • Offline видеопроигрыватель. +
      +
    • Приложение может загружать большие (> 1 ГБ) файлы.
    • +
    • Приложение может начать воспроизведение частично загруженного файла.
    • +
    +
  • +
  • Offline клиент электронной почты. +
      +
    • Возможность загрузки и локального хранения прикреплений.
    • +
    • Возможность кеширования прикреплений для более поздней отправки.
    • +
    +
  • +
+ +

Big concepts

+ +

Before you start using the File and Directory Entries API, you need to understand a few concepts:

+ + + +

The File and Directory Entries API is a virtual representation of a file system

+ +

The API doesn't give you access to the local file system, nor is the sandbox really a section of the file system. Instead, it is a virtualized file system that looks like a full-fledged file system to the web app. It does not necessarily have a relationship to the local file system outside the browser. 

+ +

What this means is that a web app and a desktop app cannot share the same file at the same time. The API does not let your web app reach outside the browser to files that desktop apps can also work on. You can, however, export a file from a web app to a desktop app. For example, you can use the File API, create a blob, redirect an iframe to the blob, and invoke the download manager.

+ +

The File and Directory Entries API can use different storage types

+ +

An application can request temporary or persistent storage. Temporary storage is easier to get, because the browser just gives it to you, but it is limited and can be deleted by the browser when it runs out of space. Persistent storage, on the other hand, might offer you larger space that can only be deleted by the user, but it requires the user to grant you permission.

+ +

Use temporary storage for caching and persistent storage for data that you want your app to keep—such as user-generated or unique data.

+ +

Browsers impose storage quotas

+ +

To prevent a web app from using up the entire disk, browsers might impose a quota for each app and allocate storage among web apps.

+ +

How storage space is granted or allocated and how you can manage storage are idiosyncratic to the browser, so you need to check the respective documentation of the browser. Google Chrome, for example, allows temporary storage beyond the 5 MB required in the specifications and supports the Quota Management API. To learn more about the Chrome-specific implementation, see Managing HTML5 Offline Storage.

+ +

The File and Directory Entries API has asynchronous and synchronous versions

+ +

The File and Directory Entries API comes with asynchronous and synchronous versions. Both versions of the API offer the same capabilities and features. In fact, they are almost alike, except for a few differences.

+ +
    +
  • WebWorkers. The asynchronous API can be used in either the document or WebWorkers context, while the synchronous API is for use with WebWorkers only. 
  • +
  • Callbacks. The asynchronous API doesn't give you data by returning values; instead, you have to pass a callback function. You send requests for operations to happen, and get notified by callbacks. In contrast, the synchronous API does not use callbacks because the API methods return values.
  • +
  • Global methods of the asynchronous and synchronous APIs. The asynchronous API has the following global methods: requestFileSystem() and resolveLocalFileSystemURL(). These methods are members of both the window object and the worker global scope. The synchronous API, on the other hand, uses the following methods:  requestFileSystemSync() and  resolveLocalFileSystemSyncURL(). These synchronous methods are members of the worker's global scope only, not the window object.
  • +
+ +

The synchronous API can be simpler for some tasks. Its direct, in-order programming model can make code easier to read. The drawback of synchronous API has to do with its interactions with Web Workers, which has some limitations.

+ +

When using the asynchronous API, always use the error callbacks

+ +

When using the asynchronous API, always use the error callbacks. Although the error callbacks for the methods are optional parameters, they are not optional for your sanity. You want to know why your calls failed. At minimum, handle the errors to provide error messages, so you'll have an idea of what's going on.

+ +

The File and Directory Entries API interacts with other APIs

+ +

The File and Directory Entries API is designed to be used with other APIs and elements on the web platform. For example, you are likely to use one of the following:

+ +
    +
  • XMLHttpRequest (such as the send() method for file and blob objects)
  • +
  • Drag and Drop API
  • +
  • Web Workers (for the synchronous version of the File and Directory Entries API)
  • +
  • The input element (to programmatically obtain a list of files from the element)
  • +
+ +

The File and Directory Entries API is case sensitive

+ +
The filesystem API is case-sensitive, and case-preserving. 
+ +

 

+ +

Ограничения

+ +

For security reasons, browsers impose restrictions on file access. If you ignore them, you will get security errors.

+ + + +

The File and Directory Entries API adheres to the same-origin policy

+ +

An origin is the domain, application layer protocol, and port of a URL of the document where the script is being executed. Each origin has its own associated set of file systems.

+ +

The security boundary imposed on file system prevents applications from accessing data with a different origin. This protects private data by preventing access and deletion. For example, while an app or a page in http://www.example.com/app/ can access files from http://www.example.com/dir/, because they have the same origin, it cannot retrieve files from http://www.example.com:8080/dir/ (different port) or https://www.example.com/dir/ (different protocol).

+ +

The File and Directory Entries API does not let you create and rename executable files

+ +

To prevent malicious apps from running hostile executables, you cannot create executable files within the sandbox of the File and Directory Entries API. 

+ +

The file system is sandboxed

+ +

Because the file system is sandboxed, a web app cannot access another app's files. You also cannot read or write files to an arbitrary folder (for example, My Pictures and My Documents) on the user's hard drive.

+ +

You cannot run your app from file://

+ +

You cannot run your app locally from file://. If you do so, the browser throws errors or your app fails silently. This restriction also applies to many of the file APIs, including BlobBuilder and FileReader.

+ +

For testing purposes, you can bypass the restriction on Chrome by starting the browser with the --allow-file-access-from-files flag. Use this flag only for this purpose.

+ +

Определения

+ +

This section defines and explains terms used in the File and Directory Entries API.

+ +
+
blob
+
Stands for binary large object. A blob is a set of binary data that is stored a single object. It is a general-purpose way to reference binary data in web applications. A blob can be an image or an audio file.
+
Blob
+
Blob—with a capital B—is a data structure that is immutable, which means that binary data referenced by a Blob cannot be modified directly. This makes Blobs act predictably when they are passed to asynchronous APIs.
+
persistent storage
+
Persistent storage is storage that stays in the browser unless the user expunges it or the app deletes it. 
+
temporary storage
+
Transient storage is available to any web app. It is automatic and does not need to be requested, but the browser can delete the storage without warning.
+
+ +

Specifications

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('File System API')}}{{Spec2('File System API')}}Draft of proposed API
+ +

This API has no official W3C or WHATWG specification.

+ +

Browser compatibility

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Asynchronous API13 {{ property_prefix("webkit") }}{{ CompatGeckoDesktop(50) }}[1]{{ CompatNo }}{{ CompatNo }}{{ CompatNo }}
Synchronous API13 {{ property_prefix("webkit") }}{{ CompatNo }}{{ CompatNo }}{{ CompatNo }}{{ CompatNo }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Asynchronous API{{ CompatNo }}{{ CompatVersionUnknown }} {{ property_prefix("webkit") }}{{ CompatGeckoMobile(50) }}[1]{{ CompatNo }}{{ CompatNo }}{{ CompatNo }}
Synchronous API{{ CompatNo }}{{ CompatVersionUnknown }} {{ property_prefix("webkit") }}{{ CompatNo }}{{ CompatNo }}{{ CompatNo }}{{ CompatNo }}
+
+ +

[1] Firefox 50 introduces partial support for the File and Directory Entries API. Be sure to check the compatibility tables for individual interfaces and methods before using them, to ensure that they're supported, before you use them.

+ +

See also

+ + diff --git "a/files/ru/web/api/file_and_directory_entries_api/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265/index.html" "b/files/ru/web/api/file_and_directory_entries_api/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265/index.html" deleted file mode 100644 index e5c76758c1..0000000000 --- "a/files/ru/web/api/file_and_directory_entries_api/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265/index.html" +++ /dev/null @@ -1,291 +0,0 @@ ---- -title: Введение в API файлов и каталогов -slug: Web/API/File_and_Directory_Entries_API/Введение -translation_of: Web/API/File_and_Directory_Entries_API/Introduction ---- -
{{DefaultAPISidebar("File System API")}}{{Non-standard_header}}
- -

API файлов и каталогов эмулирует для веб-приложений локальную файловую систему. У вас есть возможность создания приложений, которые могут читать, записывать и создавать файлы и директории в изолированной виртуальной файловой системе.

- -

API файлов и каталогов взаимодействует с другими API. Оно было создано на основе File Writer API, который в свою очередь использует File API. Каждое API реализует разную функциональность. Данные программные интерфейсы являются огромным эволюционным скачком для веб-приложений, которые теперь могут кешировать и обрабатывать большие объемы данных. 

- -

Об этом документе

- -

В данном документе приведены основные концепции и терминология API файлов и каталогов, которые должны показать общую картину и ключевые идеи. Также описаны ограничения, несоблюдение которых может привести к появлению ошибок безопасности. Используемая терминология описана в разделе Определений.

- -

Ссылки на страницы данного API приведены в Ссылочном справочнике.

- -

Спецификация находится на стадии разработки и будет изменяться в будущем.

- -

Обзор

- -

Программный интерфейс файлов и каталогов включает асинхронные и синхронные методы. Асинхронное API может быть использовано в тех случаях, когда нежелательно, чтобы длительные вычисления блокировали весь пользовательский интерфейс. В свою очередь синхронное API предлагает более простую модель программирования, однако оно должно использоваться только с объектами WebWorkers.

- -

Применимость API

- -

API файлов и каталогов является важным программным интерфейсом по следующим причинам:

- -
    -
  • Благодаря ему у приложений могут быть автономные (offline) функции, а также функции хранения, позволяющие обрабатывать большие наборы двоичных данных.
  • -
  • У приложений появляется возможность предварительной загрузки и кеширования ресурсов, что повышает из производительность.
  • -
  • У пользователя приложения появляется возможность напрямую редактировать файлы, расположенные у него на компьютере.
  • -
  • Пользователям предоставляется интерфейс работы с файловым хранилищем, который схож с файловой системой.
  • -
- -

Примеры таких приложений приведены в разделе Примеры использования.

- -

API файлов и каталогов и другие программные интерфейсы хранения данных

- -

API файлов и каталогов является альтернативой для других интерфейсов хранения данных, таких как IndexedDB, WebSQL (признано устаревшим с 18 ноября 2010 г.) и AppCache. Тем не менее данное API является более хорошим выбором для приложений, обрабатывающим большие объемы данных, по следующим причинам:

- -
    -
  • Данное API предлагает возможность хранения данных на стороне клиента в вариантах использования, которые не могут быть решены с помощью баз данных. Например, данное API является намного более производительным в случае хранения и обработки больших файлов.
  • -
  • Firefox поддерживает хранение бинарных данных в IndexedDB, в то время как в Chrome эта функция по-прежнему находится на стадии разработки. Если Chrome является одним из целевых браузеров для вашего приложения и у вас есть необходимость хранения бинарных данных, то вы можете использовать только либо данное API, либо AppCache. В свою очередь хранилище AppCache не предоставляет возможности локальных изменений, а также тонкой настройки на стороне клиента.
  • -
  • В Chrome у вас есть возможность использования данного API вместе с программным интерфейсом управления квотами, позволяющее управлять квотами хранилища.
  • -
- -

Примеры использования

- -

Далее приведены лишь некоторые случаи, в которых можно использовать API файлов и каталогов:

- -
    -
  • Приложения с постоянной загрузкой. -
      -
    • Когда файл или каталог выбран для загрузки на сервер, есть возможность скопировать файлы в локальную песочницу и начать их поочередную загрузку. 
    • -
    • Приложение может продолжить загрузку после закрытия или аварийного сбоя браузера, прерывание связи или завершения работы компьютера.
    • -
    -
  • -
  • Видеоигры или другие приложения с большим количеством медиа ресурсов. -
      -
    • Приложение скачивает один или несколько больших архивов с ресурсами и локально его распаковывает.
    • -
    • Приложение осуществляет предварительную фоновую загрузку ресурсов, благодаря чему у пользователя нет необходимости ожидать их загрузки для начала следующего уровня.
    • -
    -
  • -
  • Аудио- или фоторедактор с возможностью автономной работы или локальным кэшем. -
      -
    • Приложение может редактировать файлы без полной их перезаписи (например, ID3/EXIF теги).
    • -
    -
  • -
  • Offline видеопроигрыватель. -
      -
    • Приложение может загружать большие (> 1 ГБ) файлы.
    • -
    • Приложение может начать воспроизведение частично загруженного файла.
    • -
    -
  • -
  • Offline клиент электронной почты. -
      -
    • Возможность загрузки и локального хранения прикреплений.
    • -
    • Возможность кеширования прикреплений для более поздней отправки.
    • -
    -
  • -
- -

Big concepts

- -

Before you start using the File and Directory Entries API, you need to understand a few concepts:

- - - -

The File and Directory Entries API is a virtual representation of a file system

- -

The API doesn't give you access to the local file system, nor is the sandbox really a section of the file system. Instead, it is a virtualized file system that looks like a full-fledged file system to the web app. It does not necessarily have a relationship to the local file system outside the browser. 

- -

What this means is that a web app and a desktop app cannot share the same file at the same time. The API does not let your web app reach outside the browser to files that desktop apps can also work on. You can, however, export a file from a web app to a desktop app. For example, you can use the File API, create a blob, redirect an iframe to the blob, and invoke the download manager.

- -

The File and Directory Entries API can use different storage types

- -

An application can request temporary or persistent storage. Temporary storage is easier to get, because the browser just gives it to you, but it is limited and can be deleted by the browser when it runs out of space. Persistent storage, on the other hand, might offer you larger space that can only be deleted by the user, but it requires the user to grant you permission.

- -

Use temporary storage for caching and persistent storage for data that you want your app to keep—such as user-generated or unique data.

- -

Browsers impose storage quotas

- -

To prevent a web app from using up the entire disk, browsers might impose a quota for each app and allocate storage among web apps.

- -

How storage space is granted or allocated and how you can manage storage are idiosyncratic to the browser, so you need to check the respective documentation of the browser. Google Chrome, for example, allows temporary storage beyond the 5 MB required in the specifications and supports the Quota Management API. To learn more about the Chrome-specific implementation, see Managing HTML5 Offline Storage.

- -

The File and Directory Entries API has asynchronous and synchronous versions

- -

The File and Directory Entries API comes with asynchronous and synchronous versions. Both versions of the API offer the same capabilities and features. In fact, they are almost alike, except for a few differences.

- -
    -
  • WebWorkers. The asynchronous API can be used in either the document or WebWorkers context, while the synchronous API is for use with WebWorkers only. 
  • -
  • Callbacks. The asynchronous API doesn't give you data by returning values; instead, you have to pass a callback function. You send requests for operations to happen, and get notified by callbacks. In contrast, the synchronous API does not use callbacks because the API methods return values.
  • -
  • Global methods of the asynchronous and synchronous APIs. The asynchronous API has the following global methods: requestFileSystem() and resolveLocalFileSystemURL(). These methods are members of both the window object and the worker global scope. The synchronous API, on the other hand, uses the following methods:  requestFileSystemSync() and  resolveLocalFileSystemSyncURL(). These synchronous methods are members of the worker's global scope only, not the window object.
  • -
- -

The synchronous API can be simpler for some tasks. Its direct, in-order programming model can make code easier to read. The drawback of synchronous API has to do with its interactions with Web Workers, which has some limitations.

- -

When using the asynchronous API, always use the error callbacks

- -

When using the asynchronous API, always use the error callbacks. Although the error callbacks for the methods are optional parameters, they are not optional for your sanity. You want to know why your calls failed. At minimum, handle the errors to provide error messages, so you'll have an idea of what's going on.

- -

The File and Directory Entries API interacts with other APIs

- -

The File and Directory Entries API is designed to be used with other APIs and elements on the web platform. For example, you are likely to use one of the following:

- -
    -
  • XMLHttpRequest (such as the send() method for file and blob objects)
  • -
  • Drag and Drop API
  • -
  • Web Workers (for the synchronous version of the File and Directory Entries API)
  • -
  • The input element (to programmatically obtain a list of files from the element)
  • -
- -

The File and Directory Entries API is case sensitive

- -
The filesystem API is case-sensitive, and case-preserving. 
- -

 

- -

Ограничения

- -

For security reasons, browsers impose restrictions on file access. If you ignore them, you will get security errors.

- - - -

The File and Directory Entries API adheres to the same-origin policy

- -

An origin is the domain, application layer protocol, and port of a URL of the document where the script is being executed. Each origin has its own associated set of file systems.

- -

The security boundary imposed on file system prevents applications from accessing data with a different origin. This protects private data by preventing access and deletion. For example, while an app or a page in http://www.example.com/app/ can access files from http://www.example.com/dir/, because they have the same origin, it cannot retrieve files from http://www.example.com:8080/dir/ (different port) or https://www.example.com/dir/ (different protocol).

- -

The File and Directory Entries API does not let you create and rename executable files

- -

To prevent malicious apps from running hostile executables, you cannot create executable files within the sandbox of the File and Directory Entries API. 

- -

The file system is sandboxed

- -

Because the file system is sandboxed, a web app cannot access another app's files. You also cannot read or write files to an arbitrary folder (for example, My Pictures and My Documents) on the user's hard drive.

- -

You cannot run your app from file://

- -

You cannot run your app locally from file://. If you do so, the browser throws errors or your app fails silently. This restriction also applies to many of the file APIs, including BlobBuilder and FileReader.

- -

For testing purposes, you can bypass the restriction on Chrome by starting the browser with the --allow-file-access-from-files flag. Use this flag only for this purpose.

- -

Определения

- -

This section defines and explains terms used in the File and Directory Entries API.

- -
-
blob
-
Stands for binary large object. A blob is a set of binary data that is stored a single object. It is a general-purpose way to reference binary data in web applications. A blob can be an image or an audio file.
-
Blob
-
Blob—with a capital B—is a data structure that is immutable, which means that binary data referenced by a Blob cannot be modified directly. This makes Blobs act predictably when they are passed to asynchronous APIs.
-
persistent storage
-
Persistent storage is storage that stays in the browser unless the user expunges it or the app deletes it. 
-
temporary storage
-
Transient storage is available to any web app. It is automatic and does not need to be requested, but the browser can delete the storage without warning.
-
- -

Specifications

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('File System API')}}{{Spec2('File System API')}}Draft of proposed API
- -

This API has no official W3C or WHATWG specification.

- -

Browser compatibility

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Asynchronous API13 {{ property_prefix("webkit") }}{{ CompatGeckoDesktop(50) }}[1]{{ CompatNo }}{{ CompatNo }}{{ CompatNo }}
Synchronous API13 {{ property_prefix("webkit") }}{{ CompatNo }}{{ CompatNo }}{{ CompatNo }}{{ CompatNo }}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Asynchronous API{{ CompatNo }}{{ CompatVersionUnknown }} {{ property_prefix("webkit") }}{{ CompatGeckoMobile(50) }}[1]{{ CompatNo }}{{ CompatNo }}{{ CompatNo }}
Synchronous API{{ CompatNo }}{{ CompatVersionUnknown }} {{ property_prefix("webkit") }}{{ CompatNo }}{{ CompatNo }}{{ CompatNo }}{{ CompatNo }}
-
- -

[1] Firefox 50 introduces partial support for the File and Directory Entries API. Be sure to check the compatibility tables for individual interfaces and methods before using them, to ensure that they're supported, before you use them.

- -

See also

- - diff --git a/files/ru/web/api/fullscreen_api/index.html b/files/ru/web/api/fullscreen_api/index.html new file mode 100644 index 0000000000..ad21d6d20e --- /dev/null +++ b/files/ru/web/api/fullscreen_api/index.html @@ -0,0 +1,198 @@ +--- +title: Fullscreen API +slug: DOM/Using_fullscreen_mode +translation_of: Web/API/Fullscreen_API +--- +
{{DefaultAPISidebar("Fullscreen API")}}
+ +

The Fullscreen API adds methods to present a specific {{DOMxRef("Element")}} (and its descendants) in full-screen mode, and to exit full-screen mode once it is no longer needed. This makes it possible to present desired content—such as an online game—using the user's entire screen, removing all browser user interface elements and other applications from the screen until full-screen mode is shut off.

+ +

See the article Guide to the Fullscreen API for details on how to use the API.

+ +
+

Note: Support for this API varies somewhat across browsers, with many requiring vendor prefixes and/or not implementing the latest specification. See the {{anch("Browser compatibility")}} section below for details on support for this API. You may wish to consider using a library such as Fscreen for vendor agnostic access to the Fullscreen API.

+
+ +

Interfaces

+ +

The Fullscreen API has no interfaces of its own. Instead, it augments several other interfaces to add the methods, properties, and event handlers needed to provide full-screen functionality. These are listed in the following sections.

+ +

Methods

+ +

The Fullscreen API adds methods to the {{DOMxRef("Document")}} and {{DOMxRef("Element")}} interfaces to allow turning off and on full-screen mode.

+ +

Methods on the Document interface

+ +
+
{{DOMxRef("Document.exitFullscreen()")}}
+
Requests that the {{Glossary("user agent")}} switch from full-screen mode back to windowed mode. Returns a {{jsxref("Promise")}} which is resolved once full-screen mode has been completely shut off.
+
+ +

Methods on the Element interface

+ +
+
{{DOMxRef("Element.requestFullscreen()")}}
+
Asks the user agent to place the specified element (and, by extension, its descendants) into full-screen mode, removing all of the browser's UI elements as well as all other applications from the screen. Returns a {{jsxref("Promise")}} which is resolved once full-screen mode has been activated.
+
+ +

Properties

+ +

The {{DOMxRef("Document")}} interface provides properties that can be used to determine if full-screen mode is supported and available, and if full-screen mode is currently active, which element is using the screen.

+ +
+
{{DOMxRef("DocumentOrShadowRoot.fullscreenElement")}}
+
The fullscreenElement property tells you the {{DOMxRef("Element")}} that's currently being displayed in full-screen mode on the DOM (or shadow DOM). If this is null, the document is not in full-screen mode.
+
{{DOMxRef("Document.fullscreenEnabled")}}
+
The fullscreenEnabled property tells you whether or not it is possible to engage full-screen mode. This is false if full-screen mode is not available for any reason (such as the "fullscreen" feature not being allowed, or full-screen mode not being supported).
+
+ +

Event handlers

+ +

The Fullscreen API defines two events which can be used to detect when full-screen mode is turned on and off, as well as when errors occur during the process of changing between full-screen and windowed modes. Event handlers for these events are available on the {{DOMxRef("Document")}} and {{DOMxRef("Element")}} interfaces.

+ +
+

Note: These event handler properties are not available as HTML content attributes. In other words, you cannot specify event handlers for {{Event("fullscreenchange")}} and {{Event("fullscreenerror")}} in the HTML content. They must be added by JavaScript code.

+
+ +

Event handlers on documents

+ +
+
{{DOMxRef("Document.onfullscreenchange")}}
+
An event handler for the {{Event("fullscreenchange")}} event that's sent to a {{DOMxRef("Document")}} when that document is placed into full-screen mode, or when that document exits full-screen mode. This handler is called only when the entire document is presented in full-screen mode.
+
{{DOMxRef("Document.onfullscreenerror")}}
+
An event handler for the {{Event("fullscreenerror")}} event that gets sent to a {{DOMxRef("Document")}} when an error occurs while trying to enable or disable full-screen mode for the entire document.
+
+ +

Event handlers on elements

+ +
+
{{DOMxRef("Element.onfullscreenchange")}}
+
An event handler which is called when the {{Event("fullscreenchange")}} event is sent to the element, indicating that the element has been placed into, or removed from, full-screen mode.
+
{{DOMxRef("Element.onfullscreenerror")}}
+
An event handler for the {{Event("fullscreenerror")}} event when sent to an element which has encountered an error while transitioning into or out of full-screen mode.
+
+ +

Obsolete properties

+ +
+
{{DOMxRef("Document.fullscreen")}} {{Deprecated_Inline}}
+
A Boolean value which is true if the document has an element currently being displayed in full-screen mode; otherwise, this returns false. +
Note: Use the {{DOMxRef("Document.fullscreenElement", "fullscreenElement")}} property on the {{DOMxRef("Document")}} or {{DOMxRef("ShadowRoot")}} instead; if it's not null, then it's an {{DOMxRef("Element")}} currently being displayed in full-screen mode.
+
+
+ +

Events

+ +

The Fullscreen API defines two events which can be used to detect when full-screen mode is turned on and off, as well as when errors occur during the process of changing between full-screen and windowed modes.

+ +
+
{{Event("fullscreenchange")}}
+
Sent to a {{DOMxRef("Document")}} or {{DOMxRef("Element")}} when it transitions into or out of full-screen mode.
+
{{Event("fullscreenerror")}}
+
Sent to a Document or Element if an error occurs while attempting to switch it into or out of full-screen mode.
+
+ +

Dictionaries

+ +
+
{{DOMxRef("FullscreenOptions")}}
+
Provides optional settings you can specify when calling {{DOMxRef("Element.requestFullscreen", "requestFullscreen()")}}.
+
+ +

Controlling access

+ +

The availability of full-screen mode can be controlled using Feature Policy. The full-screen mode feature is identified by the string "fullscreen", with a default allow-list value of "self", meaning that full-screen mode is permitted in top-level document contexts, as well as to nested browsing contexts loaded from the same origin as the top-most document.

+ +

See Using Feature Policy to learn more about using Feature Policy to control access to an API.

+ +

Usage notes

+ +

Users can choose to exit full-screen mode simply by pressing the ESC (or F11) key, rather than waiting for the site or app to programmatically do so. Make sure you provide, somewhere in your user interface, appropriate user interface elements that inform the user that this option is available to them.

+ +
+

Note: Navigating to another page, changing tabs, or switching to another application using any application switcher (or Alt-Tab) will likewise exit full-screen mode.

+
+ +

Example

+ +

In this example, a video is presented in a web page. Pressing the Return or Enter key lets the user toggle between windowed and full-screen presentation of the video.

+ +

View Live Examples

+ +

Watching for the Enter key

+ +

When the page is loaded, this code is run to set up an event listener to watch for the Enter key.

+ +
document.addEventListener("keypress", function(e) {
+  if (e.keyCode === 13) {
+    toggleFullScreen();
+  }
+}, false);
+
+ +

Toggling full-screen mode

+ +

This code is called by the event handler above when the user hits the Enter key.

+ +
function toggleFullScreen() {
+  if (!document.fullscreenElement) {
+      document.documentElement.requestFullscreen();
+  } else {
+    if (document.exitFullscreen) {
+      document.exitFullscreen();
+    }
+  }
+}
+ +

This starts by looking at the value of the {{DOMxRef("Document", "document")}}'s fullscreenElement attribute. In a real-world deployment, at this time, you'll want to check for prefixed versions of this (mozFullScreenElement, msFullscreenElement, or webkitFullscreenElement, for example). If the value is null, the document is currently in windowed mode, so we need to switch to full-screen mode; otherwise, it's the element that's currently in full-screen mode. Switching to full-screen mode is done by calling {{DOMxRef("Element.requestFullscreen()")}} on the {{HTMLElement("video")}} element.

+ +

If full-screen mode is already active (fullscreenElement is not null), we call {{DOMxRef("Document.exitFullscreen", "exitFullscreen()")}} on the document to shut off full-screen mode.

+ +

Specifications

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName("Fullscreen")}}{{Spec2("Fullscreen")}}Initial version.
+ +

Browser compatibility

+ +

Document.fullscreen

+ +
+ + +

{{Compat("api.Document.fullscreen")}}

+
+ +

Document.fullscreenEnabled

+ +
+ + +

{{Compat("api.Document.fullscreenEnabled")}}

+
+ +

See also

+ +
    +
  • Using full-screen mode
  • +
  • {{DOMxRef("Element.requestFullscreen()")}}
  • +
  • {{DOMxRef("Document.exitFullscreen()")}}
  • +
  • {{DOMxRef("Document.fullscreen")}}
  • +
  • {{DOMxRef("Document.fullscreenElement")}}
  • +
  • {{CSSxRef(":fullscreen")}}, {{CSSxRef("::backdrop")}}
  • +
  • {{HTMLAttrXRef("allowfullscreen", "iframe")}}
  • +
diff --git a/files/ru/web/api/geolocation/using_geolocation/index.html b/files/ru/web/api/geolocation/using_geolocation/index.html deleted file mode 100644 index 39847dedc5..0000000000 --- a/files/ru/web/api/geolocation/using_geolocation/index.html +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: Использование геолокации -slug: Web/API/Geolocation/Using_geolocation -tags: - - Geolocation API - - Guide - - Intermediate -translation_of: Web/API/Geolocation_API ---- -
{{securecontext_header}}{{DefaultAPISidebar("Geolocation API")}}
- -

Geolocation API позволяет пользователю предоставлять свое местоположение web-приложению, если пользователь согласится предоставить его. Из соображений конфиденциальности, у пользователя будет запрошено разрешение на предоставление информации о местоположении.

- -

Концепты и использование

- -

Вы часто хотите получать информацию о местоположении пользователя в своём веб приложении, например, для отображения участка на карте, либо для того, чтобы показывать информацию, основанную на местоположении посетителя.

- -

API геолокации может быть вызвано через {{domxref("Navigator.geolocation")}}; это заставит браузер пользователя вывести уведомление с запросом для доступа к текущему местоположению. Если его одобрят, то браузер сможет даст весь доступный функционал для работы с информацией о местонахождении (например, GPS).

- -

Тогда разработчику станут доступны несколько разных способов получения соответствующей информации:

- -
    -
  • {{domxref("Geolocation.getCurrentPosition()")}}: возвратит местоположение устройства
  • -
  • {{domxref("Geolocation.watchPosition()")}}: зарегистрирует функцию-обработчик, которая будет вызываться автоматически каждый раз, когда местоположение изменится, возвращая новые данные.
  • -
- -

В обоих случая, методы принимают три аргумента:

- -
    -
  • Обязательную callback-функцию при успехе: если удалось получить местоположение пользователя, то функция вызовется с объектом {{domxref("GeolocationPosition")}} как одним параметром, предоставляющим доступ к данным о месторасположении.
  • -
  • Необязательную callback-функцию при ошибке: если не удалось получить позицию, то callback-функция вызовется с объектом {{domxref("GeolocationPositionError")}} как одним параметром, содержащим информацию о том, что пошло не так.
  • -
  • Необязательный объект {{domxref("PositionOptions")}}, который содержит надстройки получения данных о местоположении.
  • -
- -

Интерфейсы

- -
-
{{domxref("Geolocation")}}
-
Главный класс этого API — содержит методы для получения текущего местоположения пользователя, наблюдает за его изменениями и удаляет функции-наблюдатели.
-
{{domxref("GeolocationPosition")}}
-
Предоставляет месторасположение пользователя. Экземпляр GeolocationPosition, полученный при успешном вызове одного из методов {{domxref("Geolocation")}}, внутри callback-функции при успехе, содержит метку времени плюс экземпляр объекта {{domxref("GeolocationCoordinates")}}.
-
{{domxref("GeolocationCoordinates")}}
-
Предоставлять координаты пользователя; Экземпляр GeolocationCoordinates содержит широту, долготу и прочую важную подобную информацию.
-
{{domxref("GeolocationPositionError")}}
-
GeolocationPositionError возвращается при неуспешном вызове методов, содержащихся в {{domxref("Geolocation")}}, внутри callback-функции при ошибке, содержит код ошибки и сообщение.
-
{{domxref("Navigator.geolocation")}}
-
Точка входа в API. Возвращает экземпляр объекта {{domxref("Geolocation")}}, из которого становятся доступны все функции и методы.
-
- -

Словари

- -
-
{{domxref("PositionOptions")}}
-
Предоставляет объект, содержащий опции, которые можно передать как параметр в  {{domxref("Geolocation.getCurrentPosition()")}} и {{domxref("Geolocation.watchPosition()")}}.
-
- -

Примеры

- -

{{page("/ru/docs/Web/API/Geolocation_API/Using","Examples")}}

- -

Спецификации

- - - - - - - - - - - - - -
СпецификацияСтатусКомментарий
{{SpecName("Geolocation")}}{{Spec2("Geolocation")}}
- -

Поддержка браузерами

- -

{{Compat("api.Geolocation")}}

- -

Доступность

- -

Так как местоположение, основанное на WiFi, часто предоставляется Google, API местоположения может быть не доступен в Китае. Вы можете использовать местных провайдеров, таких как Baidu, Autonavi или Tencent. Эти сервисы используют IP-адресс пользователя и/или приложение для предоставления наиболее точной позиции.

- -

Смотрите также

- - diff --git a/files/ru/web/api/geolocation/using_geolocation/using_the_geolocation_api/index.html b/files/ru/web/api/geolocation/using_geolocation/using_the_geolocation_api/index.html deleted file mode 100644 index 5fa1055292..0000000000 --- a/files/ru/web/api/geolocation/using_geolocation/using_the_geolocation_api/index.html +++ /dev/null @@ -1,170 +0,0 @@ ---- -title: Использование Geolocation API -slug: Web/API/Geolocation/Using_geolocation/Using_the_Geolocation_API -tags: - - Geolocation API - - Guide - - Tutorial -translation_of: Web/API/Geolocation_API/Using_the_Geolocation_API ---- -
{{securecontext_header}}{{DefaultAPISidebar("Geolocation API")}}
- -

Geolocation API позволяет пользователю предоставлять свое местоположение web-приложению, если пользователь согласится предоставить его. Из соображений конфиденциальности, у пользователя будет запрошено разрешение на предоставление информации о местоположении.

- -

Объект геолокации

- -

API геолокации доступен через объект {{domxref("navigator.geolocation")}}.

- -

Если объект существует, функции определения местоположения доступны. Вы можете проверить это слеюущим образом:

- -
if ("geolocation" in navigator) {
-  /* местоположение доступно */
-} else {
-  /* местоположение НЕ доступно */
-}
-
- -

Получение текущего местоположения

- -

Чтобы получить текущее местоположение пользователя, вы должны вызвать метод {{domxref("geolocation.getCurrentPosition()","getCurrentPosition()")}}. Это инициирует асихронный запрос для обнаружения местоположения пользователя, и запрашивает аппаратные средства позиционирования, чтобы получить последнюю актуальную информацию. Когда местоположение определено, выполняется callback. По желанию вы можете указать вторую callback функцию для обработки ошибки, которая запустится в случае ошибки. Третий, опциональный параметр - объект с опциями, где вы можете настроить максимальное значение возвращаемых данных, время ожидания ответа на запрос, и, при желании, точность возвращаемых данных.

- -
-

Note: По умолчанию {{domxref("Geolocation.getCurrentPosition()","getCurrentPosition()")}} пытается вернуть результат так быстро, как это возможно, за счёт чего даёт не очень точный результат. Это может быть полезно, если вам нужно быстро получить ответ, при этом не важна точность. Устройства с GPS, например, могут пытаться скорректировать данные GPS около минуты и даже больше, поэтому в самом начале могут вернуться менее точные данные (местоположение IP или wifi-сети), полученные {{domxref("Geolocation.getCurrentPosition()","getCurrentPosition()")}}.

-
- -
navigator.geolocation.getCurrentPosition(function(position) {
-  do_something(position.coords.latitude, position.coords.longitude);
-});
- -

Функция do_something(), в примере выше, будет вызвана лишь тогда, когда данные о местоположении будут получены.

- -

Наблюдение за текущим местоположением

- -

Если данные о местоположении меняются (либо устройство находится в движении, либо пришли более точные данные о геопозиции), вы можете указать callback функцию, которая будет вызывается при любом обновлении данных о местоположении. Это делается с использованием функции {{domxref("Geolocation.watchPosition()","watchPosition()")}}, которая имеет несколько входных параметров: {{domxref("Geolocation.getCurrentPosition()","getCurrentPosition()")}}. Эта функция вызывается много раз, позволяя браузеру обновлять данные о текущей локации либо во время движения, либо после получения более точной информации о местоположении (после применения более точных приемов). Функция, которая вызывается при ошибке, для {{domxref("Geolocation.getCurrentPosition()","getCurrentPosition()")}}, при желании, может быть вызвана неоднократно.

- -
-

Примечание: Вы можете использовать {{domxref("Geolocation.watchPosition()","watchPosition()")}} без вызова {{domxref("Geolocation.getCurrentPosition()","getCurrentPosition()")}}.

-
- -
var watchID = navigator.geolocation.watchPosition(function(position) {
-  do_something(position.coords.latitude, position.coords.longitude);
-});
- -

Метод {{domxref("Geolocation.watchPosition()","watchPosition()")}} возвращает числовой ID, который может быть использован для идентификации наблюдателя за местоположением; используйте его вместе с методом {{domxref("Geolocation.clearWatch()","clearWatch()")}}, чтобы перестать получать новые данные о местоположении.

- -
navigator.geolocation.clearWatch(watchID);
-
- -

Точная настройка отклика

- -

{{domxref("Geolocation.getCurrentPosition()","getCurrentPosition()")}} и {{domxref("Geolocation.watchPosition()","watchPosition()")}} принимают callback-функцию при успехе, необязательную callback-функцию при ошибке и необязательный объект PositionOptions.

- -

Этот объект позволяет вам включить возможность определения позиции с высокой точностью, указать максимальное время кэширования значения позиции (при повторных запросах, пока время не вышло, вам будет возвращается кэшированное значение; после браузер будет запрашивать актуальные данные), а также указать значение, устанавливающее интервал — как часто браузер должен пытаться получить данные о местоположении, прежде чем выйдет время.

- -

Вызов {{domxref("Geolocation.watchPosition()","watchPosition")}} может выглядит следующим образом:

- -
function geo_success(position) {
-  do_something(position.coords.latitude, position.coords.longitude);
-}
-
-function geo_error() {
-  alert("Извините, нет доступной позиции.");
-}
-
-var geo_options = {
-  enableHighAccuracy: true,
-  maximumAge        : 30000,
-  timeout           : 27000
-};
-
-var wpid = navigator.geolocation.watchPosition(geo_success, geo_error, geo_options);
- -

Описание позиции

- -

Местоположение пользователя содержится в экземпляре объекта {{domxref("GeolocationPosition")}}, содержащего внутри экземпляр другого объекта — {{domxref("GeolocationCoordinates")}}.

- -

Экземпляр GeolocationPosition содержит только две вещи, свойство coords, внутри которого GeolocationCoordinates и свойство timestamp, внутри которого экземпляр {{domxref("DOMTimeStamp")}}, предоставляющее метку времени, созданную при получении данные.

- -

Экземпляр GeolocationCoordinates содержит некоторое количество свойств, двое из которых вы будете чаще всего использовать: latitude и longitude, которые помогут вам отобразить полученную позицию на карте. Поэтому многие callback-функции с успешным получением позиции выглядят очень просто:

- -
function success(position) {
-  const latitude  = position.coords.latitude;
-  const longitude = position.coords.longitude;
-
-  // Дальше код, который что-то делает с широтой(latitude) и долготой(longitude)
-}
- -

Однако, вы также можете получить и другую информацию из объекта GeolocationCoordinates, такую как высота над уровнем моря, скорость, направление устройства и точные данные о высоте, долготе и широте.

- -

Обработка ошибок

- -

Callback-функция для ошибок, если она была передана в getCurrentPosition() или watchPosition(), ожидает экземпляр объекта GeolocationPositionError в качестве первого аргумента. Он будет содержать два свойства, code, который укажет на то, какая именно ошибка произошла и понятное для человека message, описывающее значение поля code.

- -

Функция может выглядеть примерно так:

- -
function errorCallback(error) {
-  alert('ERROR(' + error.code + '): ' + error.message);
-};
-
- -

Примеры

- -

Следующий пример использует Geolocation API для того, чтобы получить широту и долготу пользователя. При успешном выполнении, ссылка будет вести на openstreetmap.org, который отобразит пользовательскую позицию на карте.

- - - -

HTML

- -
<button id = "find-me">Show my location</button><br/>
-<p id = "status"></p>
-<a id = "map-link" target="_blank"></a>
-
- -

JavaScript

- -
function geoFindMe() {
-
-  const status = document.querySelector('#status');
-  const mapLink = document.querySelector('#map-link');
-
-  mapLink.href = '';
-  mapLink.textContent = '';
-
-  function success(position) {
-    const latitude  = position.coords.latitude;
-    const longitude = position.coords.longitude;
-
-    status.textContent = '';
-    mapLink.href = `https://www.openstreetmap.org/#map=18/${latitude}/${longitude}`;
-    mapLink.textContent = `Широта: ${latitude} °, Долгота: ${longitude} °`;
-  }
-
-  function error() {
-    status.textContent = 'Невозможно получить ваше местоположение';
-  }
-
-  if (!navigator.geolocation) {
-    status.textContent = 'Geolocation не поддерживается вашим браузером';
-  } else {
-    status.textContent = 'Определение местоположения…';
-    navigator.geolocation.getCurrentPosition(success, error);
-  }
-
-}
-
-document.querySelector('#find-me').addEventListener('click', geoFindMe);
-
- -

Демо

- -

{{EmbedLiveSample('Examples', 350, 150, "", "", "", "geolocation")}}

diff --git a/files/ru/web/api/geolocation_api/index.html b/files/ru/web/api/geolocation_api/index.html new file mode 100644 index 0000000000..39847dedc5 --- /dev/null +++ b/files/ru/web/api/geolocation_api/index.html @@ -0,0 +1,91 @@ +--- +title: Использование геолокации +slug: Web/API/Geolocation/Using_geolocation +tags: + - Geolocation API + - Guide + - Intermediate +translation_of: Web/API/Geolocation_API +--- +
{{securecontext_header}}{{DefaultAPISidebar("Geolocation API")}}
+ +

Geolocation API позволяет пользователю предоставлять свое местоположение web-приложению, если пользователь согласится предоставить его. Из соображений конфиденциальности, у пользователя будет запрошено разрешение на предоставление информации о местоположении.

+ +

Концепты и использование

+ +

Вы часто хотите получать информацию о местоположении пользователя в своём веб приложении, например, для отображения участка на карте, либо для того, чтобы показывать информацию, основанную на местоположении посетителя.

+ +

API геолокации может быть вызвано через {{domxref("Navigator.geolocation")}}; это заставит браузер пользователя вывести уведомление с запросом для доступа к текущему местоположению. Если его одобрят, то браузер сможет даст весь доступный функционал для работы с информацией о местонахождении (например, GPS).

+ +

Тогда разработчику станут доступны несколько разных способов получения соответствующей информации:

+ +
    +
  • {{domxref("Geolocation.getCurrentPosition()")}}: возвратит местоположение устройства
  • +
  • {{domxref("Geolocation.watchPosition()")}}: зарегистрирует функцию-обработчик, которая будет вызываться автоматически каждый раз, когда местоположение изменится, возвращая новые данные.
  • +
+ +

В обоих случая, методы принимают три аргумента:

+ +
    +
  • Обязательную callback-функцию при успехе: если удалось получить местоположение пользователя, то функция вызовется с объектом {{domxref("GeolocationPosition")}} как одним параметром, предоставляющим доступ к данным о месторасположении.
  • +
  • Необязательную callback-функцию при ошибке: если не удалось получить позицию, то callback-функция вызовется с объектом {{domxref("GeolocationPositionError")}} как одним параметром, содержащим информацию о том, что пошло не так.
  • +
  • Необязательный объект {{domxref("PositionOptions")}}, который содержит надстройки получения данных о местоположении.
  • +
+ +

Интерфейсы

+ +
+
{{domxref("Geolocation")}}
+
Главный класс этого API — содержит методы для получения текущего местоположения пользователя, наблюдает за его изменениями и удаляет функции-наблюдатели.
+
{{domxref("GeolocationPosition")}}
+
Предоставляет месторасположение пользователя. Экземпляр GeolocationPosition, полученный при успешном вызове одного из методов {{domxref("Geolocation")}}, внутри callback-функции при успехе, содержит метку времени плюс экземпляр объекта {{domxref("GeolocationCoordinates")}}.
+
{{domxref("GeolocationCoordinates")}}
+
Предоставлять координаты пользователя; Экземпляр GeolocationCoordinates содержит широту, долготу и прочую важную подобную информацию.
+
{{domxref("GeolocationPositionError")}}
+
GeolocationPositionError возвращается при неуспешном вызове методов, содержащихся в {{domxref("Geolocation")}}, внутри callback-функции при ошибке, содержит код ошибки и сообщение.
+
{{domxref("Navigator.geolocation")}}
+
Точка входа в API. Возвращает экземпляр объекта {{domxref("Geolocation")}}, из которого становятся доступны все функции и методы.
+
+ +

Словари

+ +
+
{{domxref("PositionOptions")}}
+
Предоставляет объект, содержащий опции, которые можно передать как параметр в  {{domxref("Geolocation.getCurrentPosition()")}} и {{domxref("Geolocation.watchPosition()")}}.
+
+ +

Примеры

+ +

{{page("/ru/docs/Web/API/Geolocation_API/Using","Examples")}}

+ +

Спецификации

+ + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName("Geolocation")}}{{Spec2("Geolocation")}}
+ +

Поддержка браузерами

+ +

{{Compat("api.Geolocation")}}

+ +

Доступность

+ +

Так как местоположение, основанное на WiFi, часто предоставляется Google, API местоположения может быть не доступен в Китае. Вы можете использовать местных провайдеров, таких как Baidu, Autonavi или Tencent. Эти сервисы используют IP-адресс пользователя и/или приложение для предоставления наиболее точной позиции.

+ +

Смотрите также

+ + diff --git a/files/ru/web/api/geolocation_api/using_the_geolocation_api/index.html b/files/ru/web/api/geolocation_api/using_the_geolocation_api/index.html new file mode 100644 index 0000000000..5fa1055292 --- /dev/null +++ b/files/ru/web/api/geolocation_api/using_the_geolocation_api/index.html @@ -0,0 +1,170 @@ +--- +title: Использование Geolocation API +slug: Web/API/Geolocation/Using_geolocation/Using_the_Geolocation_API +tags: + - Geolocation API + - Guide + - Tutorial +translation_of: Web/API/Geolocation_API/Using_the_Geolocation_API +--- +
{{securecontext_header}}{{DefaultAPISidebar("Geolocation API")}}
+ +

Geolocation API позволяет пользователю предоставлять свое местоположение web-приложению, если пользователь согласится предоставить его. Из соображений конфиденциальности, у пользователя будет запрошено разрешение на предоставление информации о местоположении.

+ +

Объект геолокации

+ +

API геолокации доступен через объект {{domxref("navigator.geolocation")}}.

+ +

Если объект существует, функции определения местоположения доступны. Вы можете проверить это слеюущим образом:

+ +
if ("geolocation" in navigator) {
+  /* местоположение доступно */
+} else {
+  /* местоположение НЕ доступно */
+}
+
+ +

Получение текущего местоположения

+ +

Чтобы получить текущее местоположение пользователя, вы должны вызвать метод {{domxref("geolocation.getCurrentPosition()","getCurrentPosition()")}}. Это инициирует асихронный запрос для обнаружения местоположения пользователя, и запрашивает аппаратные средства позиционирования, чтобы получить последнюю актуальную информацию. Когда местоположение определено, выполняется callback. По желанию вы можете указать вторую callback функцию для обработки ошибки, которая запустится в случае ошибки. Третий, опциональный параметр - объект с опциями, где вы можете настроить максимальное значение возвращаемых данных, время ожидания ответа на запрос, и, при желании, точность возвращаемых данных.

+ +
+

Note: По умолчанию {{domxref("Geolocation.getCurrentPosition()","getCurrentPosition()")}} пытается вернуть результат так быстро, как это возможно, за счёт чего даёт не очень точный результат. Это может быть полезно, если вам нужно быстро получить ответ, при этом не важна точность. Устройства с GPS, например, могут пытаться скорректировать данные GPS около минуты и даже больше, поэтому в самом начале могут вернуться менее точные данные (местоположение IP или wifi-сети), полученные {{domxref("Geolocation.getCurrentPosition()","getCurrentPosition()")}}.

+
+ +
navigator.geolocation.getCurrentPosition(function(position) {
+  do_something(position.coords.latitude, position.coords.longitude);
+});
+ +

Функция do_something(), в примере выше, будет вызвана лишь тогда, когда данные о местоположении будут получены.

+ +

Наблюдение за текущим местоположением

+ +

Если данные о местоположении меняются (либо устройство находится в движении, либо пришли более точные данные о геопозиции), вы можете указать callback функцию, которая будет вызывается при любом обновлении данных о местоположении. Это делается с использованием функции {{domxref("Geolocation.watchPosition()","watchPosition()")}}, которая имеет несколько входных параметров: {{domxref("Geolocation.getCurrentPosition()","getCurrentPosition()")}}. Эта функция вызывается много раз, позволяя браузеру обновлять данные о текущей локации либо во время движения, либо после получения более точной информации о местоположении (после применения более точных приемов). Функция, которая вызывается при ошибке, для {{domxref("Geolocation.getCurrentPosition()","getCurrentPosition()")}}, при желании, может быть вызвана неоднократно.

+ +
+

Примечание: Вы можете использовать {{domxref("Geolocation.watchPosition()","watchPosition()")}} без вызова {{domxref("Geolocation.getCurrentPosition()","getCurrentPosition()")}}.

+
+ +
var watchID = navigator.geolocation.watchPosition(function(position) {
+  do_something(position.coords.latitude, position.coords.longitude);
+});
+ +

Метод {{domxref("Geolocation.watchPosition()","watchPosition()")}} возвращает числовой ID, который может быть использован для идентификации наблюдателя за местоположением; используйте его вместе с методом {{domxref("Geolocation.clearWatch()","clearWatch()")}}, чтобы перестать получать новые данные о местоположении.

+ +
navigator.geolocation.clearWatch(watchID);
+
+ +

Точная настройка отклика

+ +

{{domxref("Geolocation.getCurrentPosition()","getCurrentPosition()")}} и {{domxref("Geolocation.watchPosition()","watchPosition()")}} принимают callback-функцию при успехе, необязательную callback-функцию при ошибке и необязательный объект PositionOptions.

+ +

Этот объект позволяет вам включить возможность определения позиции с высокой точностью, указать максимальное время кэширования значения позиции (при повторных запросах, пока время не вышло, вам будет возвращается кэшированное значение; после браузер будет запрашивать актуальные данные), а также указать значение, устанавливающее интервал — как часто браузер должен пытаться получить данные о местоположении, прежде чем выйдет время.

+ +

Вызов {{domxref("Geolocation.watchPosition()","watchPosition")}} может выглядит следующим образом:

+ +
function geo_success(position) {
+  do_something(position.coords.latitude, position.coords.longitude);
+}
+
+function geo_error() {
+  alert("Извините, нет доступной позиции.");
+}
+
+var geo_options = {
+  enableHighAccuracy: true,
+  maximumAge        : 30000,
+  timeout           : 27000
+};
+
+var wpid = navigator.geolocation.watchPosition(geo_success, geo_error, geo_options);
+ +

Описание позиции

+ +

Местоположение пользователя содержится в экземпляре объекта {{domxref("GeolocationPosition")}}, содержащего внутри экземпляр другого объекта — {{domxref("GeolocationCoordinates")}}.

+ +

Экземпляр GeolocationPosition содержит только две вещи, свойство coords, внутри которого GeolocationCoordinates и свойство timestamp, внутри которого экземпляр {{domxref("DOMTimeStamp")}}, предоставляющее метку времени, созданную при получении данные.

+ +

Экземпляр GeolocationCoordinates содержит некоторое количество свойств, двое из которых вы будете чаще всего использовать: latitude и longitude, которые помогут вам отобразить полученную позицию на карте. Поэтому многие callback-функции с успешным получением позиции выглядят очень просто:

+ +
function success(position) {
+  const latitude  = position.coords.latitude;
+  const longitude = position.coords.longitude;
+
+  // Дальше код, который что-то делает с широтой(latitude) и долготой(longitude)
+}
+ +

Однако, вы также можете получить и другую информацию из объекта GeolocationCoordinates, такую как высота над уровнем моря, скорость, направление устройства и точные данные о высоте, долготе и широте.

+ +

Обработка ошибок

+ +

Callback-функция для ошибок, если она была передана в getCurrentPosition() или watchPosition(), ожидает экземпляр объекта GeolocationPositionError в качестве первого аргумента. Он будет содержать два свойства, code, который укажет на то, какая именно ошибка произошла и понятное для человека message, описывающее значение поля code.

+ +

Функция может выглядеть примерно так:

+ +
function errorCallback(error) {
+  alert('ERROR(' + error.code + '): ' + error.message);
+};
+
+ +

Примеры

+ +

Следующий пример использует Geolocation API для того, чтобы получить широту и долготу пользователя. При успешном выполнении, ссылка будет вести на openstreetmap.org, который отобразит пользовательскую позицию на карте.

+ + + +

HTML

+ +
<button id = "find-me">Show my location</button><br/>
+<p id = "status"></p>
+<a id = "map-link" target="_blank"></a>
+
+ +

JavaScript

+ +
function geoFindMe() {
+
+  const status = document.querySelector('#status');
+  const mapLink = document.querySelector('#map-link');
+
+  mapLink.href = '';
+  mapLink.textContent = '';
+
+  function success(position) {
+    const latitude  = position.coords.latitude;
+    const longitude = position.coords.longitude;
+
+    status.textContent = '';
+    mapLink.href = `https://www.openstreetmap.org/#map=18/${latitude}/${longitude}`;
+    mapLink.textContent = `Широта: ${latitude} °, Долгота: ${longitude} °`;
+  }
+
+  function error() {
+    status.textContent = 'Невозможно получить ваше местоположение';
+  }
+
+  if (!navigator.geolocation) {
+    status.textContent = 'Geolocation не поддерживается вашим браузером';
+  } else {
+    status.textContent = 'Определение местоположения…';
+    navigator.geolocation.getCurrentPosition(success, error);
+  }
+
+}
+
+document.querySelector('#find-me').addEventListener('click', geoFindMe);
+
+ +

Демо

+ +

{{EmbedLiveSample('Examples', 350, 150, "", "", "", "geolocation")}}

diff --git a/files/ru/web/api/html_drag_and_drop_api/drag_operations/index.html b/files/ru/web/api/html_drag_and_drop_api/drag_operations/index.html new file mode 100644 index 0000000000..2dcdb6babb --- /dev/null +++ b/files/ru/web/api/html_drag_and_drop_api/drag_operations/index.html @@ -0,0 +1,314 @@ +--- +title: Drag Operations +slug: Web/Guide/HTML/Drag_and_drop/Drag_operations +translation_of: Web/API/HTML_Drag_and_Drop_API/Drag_operations +--- +

{{DefaultAPISidebar("HTML Drag and Drop API")}}

+ +

Ниже описаны шаги, которые происходят при drag and drop операции.

+ +

Drag операции описываются в документе, используя {{domxref("DataTransfer")}} интерфейс. Этот документ не использует не{{domxref("DataTransferItem")}} интерфейс, не{{domxref("DataTransferItemList")}} интерфейс.

+ +

draggable атрибуты

+ +

На веб-странице, в некоторых случаях используется поведение drag (перетаскивания) по умолчанию. Включая выделенный текст, изображения и ссылки. Когда изображение иои ссылка переносятся, URL изображения или ссылки устанавливается в качестве данных drag и перетаскивание начинается. Для других элементов, они должны быть частью выделения для выполнения перетаскивания по умолчанию. Чтобы увидеть это в действии, выделите область веб-страницы, а затем нажмите и удерживайте кнопку мыши и перетащите выделение. Появится специфичный для ОС рендеринг выделенного фрагмента и будет следовать за указателем мыши при перетаскивании. Однако это поведение является только drag поведением по умолчанию, если нет слушателей, определяющих данные для перетаскивания.

+ +

В HTML, кроме поведения по умолчанию изображений, ссылок и выделенных областей, ноикакие другие элементы по умолчанию не переносятся.

+ +

Для перетаскивания других HTML-элементов, должны быть выполнены три пункта :

+ +
    +
  1. Установить {{htmlattrxref("draggable")}}="true" на элемент, который вы хотите сделать перетаскиваемым.
  2. +
  3. Добавить слушатель события {{event("dragstart")}}.
  4. +
  5. Установить данные перетаскивания в слушатель выше.
  6. +
+ +

Вот пример, который позволяет перетаскивать часть содержимого.

+ +
<p draggable="true" ondragstart="event.dataTransfer.setData('text/plain', 'This text may be dragged')">
+  This text <strong>may</strong> be dragged.
+</p>
+
+ +

Атрибут {{htmlattrxref("draggable")}} установлен в  "true", т.о. этот элемент становится перетаскиваемым. Если этот атрибут был опущен или установлен в "false", то элемент не может быть перенесен, и вместо этого будет выбран текст.

+ +

Атрибут {{htmlattrxref("draggable")}} может быть использован для любого элемента, включаяизображения и ссылки. Однако, для последних двух, значение по умолчанию - true, т.о. вы можете только использвать атрибут  {{htmlattrxref("draggable")}} со значением false для отключение перетаскивания этих элементов.

+ +
+

Примечание: Когда элемент становится перетаскиваемыми, tтекст или другие элементы в нем больше не могут быть выбраны обычным способом, щелкая и перетаскивая мышью. Вместо этого пользователь должен удерживать клавишу Alt  чтобы выбрать текст с помощью мыши или клавиатуры.

+
+ +

Начало операции перетаскивания

+ +

В примере, слушатель добавлен для события {{event("dragstart")}} с использованием атрибута{{domxref("GlobalEventHandlers.ondragstart","ondragstart")}}.

+ +
<p draggable="true" ondragstart="event.dataTransfer.setData('text/plain', 'This text may be dragged')">
+  This text <strong>may</strong> be dragged.
+</p>
+
+ +

Когда пользователь начинает перетаскивание, запускается событиеdrag, the {{event("dragstart")}}.

+ +

В этом примере слушатель {{event("dragstart")}} добавлен к самому перемещаемом элементу. Однако, вы можете слушать более высокого предка, так как событие перетаскивание высплывает вверх как и большинство событий.

+ +

Внутри события {{event("dragstart")}}, вы можете указать drag данные, изображжение отклика, drag-эффекты, все это описано ниже. Однако, обязательны только drag данные. (Изображение и drag-эффекты по умолчанию, подходят в большинстве ситуаций)

+ +

Drag-данные

+ +

Все {{domxref("DragEvent","drag events")}} имеют свойство, называемое{{domxref("DragEvent.dataTransfer","dataTransfer")}}, которое содержит drag-данные (dataTransfer это {{domxref("DataTransfer")}} object).

+ +

Когда происходит перетаскивание, данные должны быть связаны с перетаскиванием, которое определяет, что перетаскивается. Например, при перетаскивании выделенного текста в текстовое поле данные, связанные с элементом данных перетаскивания, являются самим текстом. Аналогично, при перетаскивании ссылки на веб-странице элемент данных перетаскивания является URL-адресом ссылки.

+ +

{{domxref("DataTransfer","drag data")}} содержит два параметра, тип (или формат) данных, и значение данных. Формат это строковый тип (такой как text/plain текстовых данных), значение - строка текста. Когда начинается перетаскивание, вы добавляете данные, предоставляя тип и данные. Во время перетаскивания в слушателе события для событий {{event("dragenter")}} и {{event("dragover")}} , вы используете типы данных перетаскиваемых данных, чтобы проверить, разрешено ли удаление. Например, цель drop, которая принимает ссылки, будет проверять тип text/uri-list. В течение события drop, слушатель будет получать данные тащат и вставить его на место.

+ +

Свойство {{domxref("DataTransfer","drag data's")}} {{domxref("DataTransfer.types","types")}} возвращает список MIME-типов {{domxref("DOMString")}}, таких как text/plain или image/jpeg. Вы также можете создавать свои собственные типы. Большинство основные используемых типов описаны в  Recommended Drag Types.

+ +

Перетаскивание может включать элементы данных нескольких различных типов. Это позволяет предоставлять данные в более специфических типах, часто пользовательских, но по предоставляет резервные данные для drop, которые не поддерживают более специфические типы. Как правило, наименее специфичным типом будут обычные текстовые данные, использующие тип text/plain. Эти данные будут простым текстовым представлением.

+ +

Установка элементов drag-данных {{domxref("DragEvent.dataTransfer","dataTransfer")}}, используя метод {{domxref("DataTransfer.setData","setData()")}}. Требуется два аргумента: тип данных и значение данных. Например:

+ +
event.dataTransfer.setData("text/plain", "Text to drag");
+
+ +

Здесь, значение -  "Text to drag", формат -  text/plain.

+ +

Вы можете предусмотреть данные в нескольких форматах. Сделаем это, вызовем метод  {{domxref("DataTransfer.setData","setData()")}} несколько раз с различными форматами. Вы должны вызывать его с форматами от большей специфичности к меньшей.

+ +
const dt = event.dataTransfer;
+dt.setData("application/x.bookmark", bookmarkString);
+dt.setData("text/uri-list", "https://www.mozilla.org");
+dt.setData("text/plain", "https://www.mozilla.org");
+
+ +

Добавлены данные трех различных форматов. Первый тип - application/x.bookmark, пользовательский тип.Другие приложения не поддерживают данный тип, но вы можете использовать пользовательский тип для перетаскивания между областями в одном приложениее или на одной странице.

+ +

Предоставляя данные и в других типах, мы также можем поддерживать перетаскивание в другие приложения в менее специфичных формах. Тип application/x.bookmark может предоставлять данные с  более подробной информацией для использования в приложении, в то время как другие типы могут включать только один URL-адрес или текстовую версию.

+ +

Обратите внимание, что и text/uri-list и text/plain cодержат одни и те же данные в этом примере.  Это часто бывает так, но это не обязательно.

+ +

Если вы попытаетесь добавить данные дважды с тем же форматом, новые данные заменят старые данные, но в той же позиции в списке типов, что и старые данные.

+ +

Вы можете очистить данные, используя метод {{domxref("DataTransfer.clearData","clearData()")}}, который принимает один аргумент: тип данных для удаления.

+ +
event.dataTransfer.clearData("text/uri-list");
+
+ +

Аргумент type в методе {{domxref("DataTransfer.clearData","clearData()")}} опционален. Если type не указан, данные, связанные со всеми типами, удаляются. Если перетаскивание не содержит элементов данных перетаскивания или все элементы были впоследствии очищены, то перетаскивание не произойдет.

+ +

Настройка изображения отклика drag

+ +

Когда происходит перетаскивание, полупрозрачное изображение генерируется из цели перетаскивания (событие "{{event("dragstart")}}" элемента срабатывает), и следует за указателем пользователя во время перетаскивания. Это изображение создается автоматически, поэтому вам не нужно создавать его самостоятельно. Однако вы можете использовать {{domxref("DataTransfer.setDragImage","setDragImage()")}} для задания пользовательского изображения отклика перетаскивания.

+ +
event.dataTransfer.setDragImage(image, xOffset, yOffset);
+
+ +

Необходимы три аргумента. Первый - это ссылка на изображение. Эта ссылка обычно относится к элементу <img>, но также может относиться к элементу <canvas> или любому другому элементу. Изображение отклика будет генерироваться из того, как изображение выглядит на экране, для изображений они будут нарисованы в их первоначальном размере. Второй и третий аргументы метода {{domxref("DataTransfer.setDragImage","setDragImage()")}} - это смещения, в которых изображение должно появляться относительно указателя мыши.

+ +

Также можно использовать изображения и canvas, которых нет в документе. Этот метод полезен при рисовании пользовательских изображений перетаскивания с помощью элемента canvas, как показано в следующем примере:

+ +
function dragWithCustomImage(event) {
+  const canvas = document.createElement("canvas");
+  canvas.width = canvas.height = 50;
+
+  const ctx = canvas.getContext("2d");
+  ctx.lineWidth = 4;
+  ctx.moveTo(0, 0);
+  ctx.lineTo(50, 50);
+  ctx.moveTo(0, 50);
+  ctx.lineTo(50, 0);
+  ctx.stroke();
+
+  const dt = event.dataTransfer;
+  dt.setData('text/plain', 'Data to Drag');
+  dt.setDragImage(canvas, 25, 25);
+}
+
+ +

В этом примере мы делаем один canvas перетаскивания. Поскольку размер холста составляет 50×50 пикселей, мы используем смещение половины этого (25), чтобы изображение было центрировано на указателе мыши.

+ +

Drag эффекты

+ +

При перетаскивании можно выполнить несколько операций. Операция  copy используется для указания на то, что перетаскиваемые данные будут скопированы из текущего местоположения в место перетаскивания. Операция move используется для указания на то, что перетаскиваемые данные будут перемещены, а операция link используется для указания на то, что между исходным и удаляемым местоположениями будет создана некоторая форма связи или соединения.

+ +

Вы можете указать, какая из трех операций разрешена для источника перетаскивания, установив свойство {{domxref("DataTransfer.effectAllowed","effectAllowed")}} в слушателе событий{{event("dragstart")}}.

+ +
event.dataTransfer.effectAllowed = "copy";
+
+ +

В этом примере разрешена только копия.

+ +

Вы можете комбинировать значения различными способами:

+ +
+
none
+
никакая операция не разрешена
+
copy
+
только copy
+
move
+
только move
+
link
+
только link
+
copyMove
+
только copy или move
+
copyLink
+
только copy или link
+
linkMove
+
только link или move
+
all
+
только copy, move, или link
+
uninitialized
+
Значение по умолчанию all.
+
+ +

Обратите внимание, что эти значения должны использоваться так, как указано выше. Например, установка свойства {{domxref("DataTransfer.effectAllowed","effectAllowed")}} на copyMove позволяет выполнять операцию копирования или перемещения, но не позволяет пользователю выполнять операцию связывания. Если вы не измените свойство {{domxref("DataTransfer.effectAllowed","effectAllowed")}},  то любая операция разрешена, как и со значением 'all'. Поэтому вам не нужно настраивать это свойство, если вы не хотите исключить определенные типы.

+ +

Во время операции перетаскивания, слушатель для событий {{event("dragenter")}} или {{event("dragover")}} может проверить свойство {{domxref("DataTransfer.effectAllowed","effectAllowed")}} , какие операции разрешены. Связанное свойство,  {{domxref("DataTransfer.dropEffect","dropEffect")}}, должно быть установлено в пределах одного из этих событий, чтобы указать, какая единственная операция должна быть выполнена. Допустимые значения для {{domxref("DataTransfer.dropEffect","dropEffect")}} - none, copy, move, или link. Комбинированные значения для этого свойства не используются.

+ +

С событиями {{event("dragenter")}} и {{event("dragover")}}, свойство {{domxref("DataTransfer.dropEffect","dropEffect")}} инициализируется в соответствии с запросом пользователя. Пользователь может изменить желаемый эффект, нажав клавиши-модификаторы. Хотя точные используемые клавиши различаются в зависимости от платформы, обычно клавиши  Shift и Control используются для переключения между копированием, перемещением и связыванием. Указатель мыши изменится, чтобы указать, какая операция требуется. Например, для copy курсор может появиться со знаком плюс рядом с ним.

+ +

Вы можете изменять свойство {{domxref("DataTransfer.dropEffect","dropEffect")}} во время событий {{event("dragenter")}} или {{event("dragover")}}, например, определенная drop-цель поддерживает только определенные операции. Вы можете изменить свойство {{domxref("DataTransfer.dropEffect","dropEffect")}}, чтобы переопределить действие пользователя, и обеспечить выполнение специфичной  операции перетаскивания при ее наступлении. Обратите внимание, что этот эффект должен быть указан в списке свойств {{domxref("DataTransfer.effectAllowed","effectAllowed")}}. В противном случае ему будет присвоено другое допустимое значение.

+ +
event.dataTransfer.dropEffect = "copy";
+
+ +

В этом примере выполняется эффект копирования.

+ +

Вы можете использовать значение none, чтобы указать, что в этом месте не допускается удаление, хотя в этом случае лучше не отменять событие.

+ +

В событиях {{event("drop")}} и {{event("dragend")}}, yвы можете проверить свойства {{domxref("DataTransfer.dropEffect","dropEffect")}} для определения того, какой эффект был в конечном итоге выбран.  Если выбран эффект "move",то исходные данные должны быть удалены из источника перетаскивания в событии{{event("dragend")}}.

+ +

Указание drop-целей

+ +

Слушатель для событий {{event("dragenter")}} и {{event("dragover")}} используются для указания допустимых drop-целей, то есть мест, где могут быть сброшены перетаскиваемые элементы. Большинство областей веб-страницы или приложения не являются допустимыми местами для сброса данных. Таким образом, обработка этих событий по умолчанию не допускает сброса перетаскиваемых данных.

+ +

Если вы хотите разрешить сброс переносимых данных, вы должны предотвратить обработку по умолчанию, отменив оба события dragenter и dragover.  Это можно сделать, либо вернув false из определенных атрибутом слушателя событий, либо вызвав метод {{domxref("Event.preventDefault","preventDefault()")}} событие. Последнее может быть более осуществимо в функции, определенной в отдельном скрипте.

+ +
<div ondragover="return false">
+<div ondragover="event.preventDefault()">
+
+ +

Вызывая метод {{domxref("Event.preventDefault","preventDefault()")}} во время обоих событий {{event("dragenter")}} и {{event("dragover")}} укажите, что падение разрешено в этом месте. Однако обычно вы захотите вызвать метод  {{domxref("Event.preventDefault","preventDefault()")}} события только в определенных ситуациях (например, только при перетаскивании ссылки).

+ +

Для этого вызовите функцию, которая проверяет условие и отменяет событие только при его выполнении. Если условие не выполнено, не отменяйте событие, и сброс перетаскиваемых данных не произойдет, если пользователь отпустит кнопку мыши.

+ +

Наиболее распространенным является принятие или отклонение сброса в зависимости от типа данных перетаскивания при передаче данных — например, разрешение для изображений, ссылок или и того, и другого. Для этого вы можете проверить свойство {{domxref("DataTransfer.types","types")}} события {{domxref("DragEvent.dataTransfer","dataTransfer")}} (свойство). Свойство {{domxref("DataTransfer.types","types")}} возвращает массив из строк, добавленных при начале перетаскивания, в порядке от наиболее значимого к наименее значимому.

+ +
function doDragOver(event) {
+  const isLink = event.dataTransfer.types.includes("text/uri-list");
+  if (isLink) {
+    event.preventDefault();
+  }
+}
+ +

В этом примере мы используем метод includes  чтобы проверить, присутствует ли тип text/uri-list в списке типов. Если это так, мы отменим событие, так что сброс становится разрешен. Если перетаскиваемые данные не содержат ссылки, событие не будет отменено, и сброс не может произойти в этом месте.

+ +

Вы также можете установить либо свойство {{domxref("DataTransfer.effectAllowed","effectAllowed")}}, либо свойство{{domxref("DataTransfer.dropEffect","dropEffect")}}, либо оба одновременно, если вы хотите указать более конкретные сведения о типе операции, которая будет выполнена. Естественно, изменение любого свойства не будет иметь никакого эффекта, если вы не отмените событие.

+ +

Drop Feedback

+ +

There are several ways in which you can indicate to the user that a drop is allowed at a certain location. The mouse pointer will update as necessary depending on the value of the {{domxref("DataTransfer.dropEffect","dropEffect")}} property.

+ +

Although the exact appearance depends on the user's platform, typically a plus sign icon will appear for a 'copy' for example, and a 'cannot drop here' icon will appear when a drop is not allowed. This mouse pointer feedback is sufficient in many cases.

+ +

However, you can also update the user interface with an insertion point or highlight as needed. For simple highlighting, you can use the :-moz-drag-over CSS pseudoclass on a drop target.

+ +
.droparea:-moz-drag-over {
+  outline: 1px solid black;
+}
+
+ +

In this example, the element with the class droparea will receive a 1 pixel black outline while it is a valid drop target, that is, if the {{domxref("Event.preventDefault","preventDefault()")}} method was called during the {{event("dragenter")}} event.

+ +
+

Note: You must cancel the {{event("dragenter")}} event for this pseudoclass to apply, as this state is not checked for the {{event("dragover")}} event.

+
+ +

For more complex visual effects, you can also perform other operations during the {{event("dragenter")}} event. For example, by inserting an element at the location where the drop will occur. This might be an insertion marker, or an element that represents the dragged element in its new location. To do this, you could create an image or separator element and simply insert it into the document during the {{event("dragenter")}} event.

+ +

The {{event("dragover")}} event will fire at the element the mouse is pointing at. Naturally, you may need to move the insertion marker around a {{event("dragover")}} event as well. You can use the event's {{domxref("MouseEvent.clientX","clientX")}} and {{domxref("MouseEvent.clientY","clientY")}} properties as with other mouse events to determine the location of the mouse pointer.

+ +

Finally, the {{event("dragleave")}} event will fire at an element when the drag leaves the element. This is the time when you should remove any insertion markers or highlighting. You do not need to cancel this event. Any highlighting or other visual effects specified using the :-moz-drag-over pseudoclass will be removed automatically. The {{event("dragleave")}} event will always fire, even if the drag is cancelled, so you can always ensure that any insertion point cleanup can be done during this event.

+ +

Performing a Drop

+ +

When the user releases the mouse, the drag and drop operation ends.

+ +

If the mouse is released over an element that is a valid drop target, that is, one that cancelled the last {{event("dragenter")}} or {{event("dragover")}} event, then the drop will be successful, and a {{event("drop")}} event will fire at the target. Otherwise, the drag operation is cancelled, and no {{event("drop")}} event is fired.

+ +

During the {{event("drop")}} event, you should retrieve that data that was dropped from the event and insert it at the drop location. You can use the {{domxref("DataTransfer.dropEffect","dropEffect")}} property to determine which drag operation was desired.

+ +

As with all drag-related events, the event's {{domxref("DataTransfer","dataTransfer")}} property will hold the data that is being dragged. The {{domxref("DataTransfer.getData","getData()")}} method may be used to retrieve the data again.

+ +
function onDrop(event) {
+  const data = event.dataTransfer.getData("text/plain");
+  event.target.textContent = data;
+  event.preventDefault();
+}
+
+ +

The {{domxref("DataTransfer.getData","getData()")}} method takes one argument, the type of data to retrieve. It will return the string value that was set when {{domxref("DataTransfer.setData","setData()")}} was called at the beginning of the drag operation. An empty string will be returned if data of that type does not exist. (Naturally, though, you would likely know that the right type of data was available, as it was previously checked during a {{event("dragover")}} event.)

+ +

In the example here, once the data has been retrieved, we insert the string as the textual content of the target. This has the effect of inserting the dragged text where it was dropped, assuming that the drop target is an area of text such as a p or div element.

+ +

In a web page, you should call the {{domxref("Event.preventDefault","preventDefault()")}} method of the event if you have accepted the drop, so that the browser's default handling is not triggered by the dropped data as well. For example, when a link is dragged to a web page, Firefox will open the link. By cancelling the event, this behavior will be prevented.

+ +

You can retrieve other types of data as well. If the data is a link, it should have the type text/uri-list. You could then insert a link into the content.

+ +
function doDrop(event) {
+  const lines = event.dataTransfer.getData("text/uri-list").split("\n");
+  lines.filter(line => !line.startsWith("#"))
+    .forEach(line => {
+      const link = document.createElement("a");
+      link.href = line;
+      link.textContent = line;
+      event.target.appendChild(link);
+    })
+  event.preventDefault();
+}
+
+ +

This example inserts a link from the dragged data. As the name implies, the text/uri-list type actually may contain a list of URLs, each on a separate line. The above code uses split to break the string into lines, then iterates over the list of lines, and inserts each as a link into the document. (Note also that links starting with a number sign (#) are skipped, as these are comments.)

+ +

For simple cases, you can use the special type URL just to retrieve the first valid URL in the list. For example:

+ +
const link = event.dataTransfer.getData("URL");
+
+ +

This eliminates the need to check for comments or iterate through lines yourself. However, it is limited to only the first URL in the list.

+ +

The URL type is a special type. It is used only as a shorthand, and it does not appear within the list of types specified in the {{domxref("DataTransfer.types","types")}} property.

+ +

Sometimes you may support some different formats, and you want to retrieve the data that is most specific that is supported. In the following example, three formats are supported by a drop target.

+ +

The following example returns the data associated with the best-supported format:

+ +
function doDrop(event) {
+  const supportedTypes = ["application/x-moz-file", "text/uri-list", "text/plain"];
+  const types = event.dataTransfer.types.filter(type => supportedTypes.includes(type));
+  if (types.length) {
+    const data = event.dataTransfer.getData(types[0]);
+  }
+  event.preventDefault();
+}
+
+ +

Окончание перетаскивания

+ +

Как только перетаскивание завершено, событие {{event("dragend")}} запускается в источнике перетаскивания (тот же элемент, который получил событие {{event("dragstart")}}). Это событие сработает, если перетаскивание было успешным[1] или если оно было отменено. Однако вы можете использовать свойство {{domxref("DataTransfer.dropEffect","dropEffect")}} для определения, какая операция удаления произошла.

+ +

Если свойство {{domxref("DataTransfer.dropEffect","dropEffect")}} имеет значение none во время события {{event("dragend")}}, то перетаскивание было отменено. В противном случае эффект указывает, какая операция была выполнена. Источник может использовать эту информацию после операции перемещения для удаления перетаскиваемого элемента из старого расположения. Свойство {{domxref("DataTransfer.mozUserCancelled","mozUserCancelled")}} будет присвоено значение true, если пользователь отменил перетаскивание (нажав Escape), и false если перетаскивание было отменено по другим причинам, таким как недопустимая цель перетаскивания, или если оно было успешным.

+ +

Сброс может произойти внутри того же окна или над другим приложением. Событие{{event("dragend")}}будет срабатывать всегда, независимо от этого. Свойство события {{domxref("MouseEvent.screenX","screenX")}} и {{domxref("MouseEvent.screenY","screenY")}} будут установлены в координаты экрана, где произошел сброс.

+ +

Когда событие {{event("dragend")}} завершило распространение, операция перетаскивания завершена.

+ +

[1]: В Gecko, {{event("dragend")}} не отправляется, если исходный узел движется или удаляется во время перетаскивания (например, при сбрасывании или {{event("dragover")}}). Bug 460801

+ +

Смотрите также

+ + diff --git a/files/ru/web/api/html_drag_and_drop_api/index.html b/files/ru/web/api/html_drag_and_drop_api/index.html new file mode 100644 index 0000000000..86467501fd --- /dev/null +++ b/files/ru/web/api/html_drag_and_drop_api/index.html @@ -0,0 +1,72 @@ +--- +title: Drag and drop +slug: Web/Guide/HTML/Drag_and_drop +translation_of: Web/API/HTML_Drag_and_Drop_API +--- +

Firefox и прочие приложения компании Mozilla имеют ряд возможностей для управления drag и drop. Это позволяет пользователю нажать и удерживая зажатой кнопку мыши над элементом, переместить его на другую позицию, отпустив кнопку мыши пользователь может оставить элемент на новой позиции. На протяжении всей операции перемещения полупрозрачное представление элемента следует за курсором мыши. Новая позиция элемента может располагаться в совершенно другом приложении. Веб сайты, и XUL приложения могут использовать эту функциональность для того, чтобы определить какие элементы страницы могут быть перемещены, а также определить элементы куда первые могут быть перемещены.

+ +
Эта часть покрывает функциональность drag и drop в Firefox 3.5 (Gecko 1.9.1) а также последующие версии. Для старого API для Firefox 3.0 и ранее, в котором нет соответствующей поддержки данной функциональности, смотрите older API documentation.
+ +

Основы Drag и Drop

+ +

Использование функциональности drag и drop подразумевает выполнения следующих шагов:

+ +
    +
  • Определить переносимый элемент. Присвоить true атрибуту draggable элемента, который мы хотим перенести. Для детальной информации смотрите The Draggable Attribute.
  • +
  • Определить данные, которые могут быть перемещены, они могут быть разного формата. К примеру, текстовые данные, содержащие строку текста который может быть перемещен. Для детальной информации смотрите Drag Data.
  • +
  • (Необязательно) Определить изображение которое будет рядом с указателем мыши на протяжении всей операции перетаскивания.  Если пользовательское изображение не будет определено, будет сгенерирована картинка по умолчанию, в зависимости от элемента, на котором была зажата кнопка мыши (что будет означать, что элемент переносят). Ознакомиться детально с установкой изображения перетаскивания можно по ссылке Setting the Drag Feedback Image.
  • +
  • Определить возможные эффекты переноса. Возможны три таких эффекта: copy показывает, что перемещаемые данные копируются из прежнего места расположения в новое, move показывает, что перемещаемые данные полностью переносятся на новое место, и link показывает, что создается некая форма взаимодействия или связи между исходной точкой и точкой назначения. На протяжении операции перемещения, картинка которая следует за курсором мыши может меняться в зависимости от того, может ли элемент быть перемещен в область под курсором. Если перенос разрешен, перемещение может быть произведено. Смотрите Drag Effects для детальной информации.
  • +
  • Определить область назначения. По умолчанию браузер не позволяет перемещать что-либо на HTML элемент. Однако, чтобы сделать элемент активным для перемещения других элементов на него, просто отмените действие по умолчанию. То есть, подпишитесь на события "ondragenter" или "ondragover". Для детальной информации смотрите Specifying Drop Targets.
  • +
  • Обработать завершение переноса. Вы можете получить данные из переносимого элемента и произвести над ними необходимые операции. Для детальной информации, пожалуйста, смотрите Performing a Drop.
  • +
+ +

Mozilla и Firefox поддерживают ряд возможностей, которые выходят за рамку стандартной модели спецификации. Они позволяют пользователю перемещать несколько элементов и перемещать нестроковые данные. Для детальной информации смотрите Dragging and Dropping Multiple Items.

+ +

Для того, чтобы ознакомиться с общим списком данных поддерживаемых операцией drag and drop смотрите Recommended Drag Types.

+ +

Также доступны примеры с лучшей практикой использования операции drag and drop для перемещения данных разных типов:

+ + + +

Смотри DataTransfer для ссылки на объект DataTransfer.

+ +

События Drag

+ +

Ряд событий срабатывают на протяжении всей процедуры drag and drop. Запомните, что только drag-события срабатывают на протяжении операции перемещения; события мыши, такие как mousemove - нет. Также запомните, что события dragstart и dragend не срабатывают при попытке перенести файл из операционной системы в браузер.

+ +

Свойство dataTransfer всех событий перемещения содержит данные про все drag и drop операции.

+ +
+
dragstart
+
Срабатывает когда элeмент начал перемещаться. В момент срабатывания события dragstart пользователь начинает перетаскивание элемента. Обработчик данного события может быть использован для сохранения информации о перемещаемом объекте, а также для изменения изображения, которое будет ассоциировано с перемещением. Дaнное событие не срабатывает, когда некоторый файл будет переноситься из операционной системы в браузер. Для детальной информации Starting a Drag Operation.
+
dragenter
+
Срабатывает, когда перемещаемый элемент попадает на элемент-назначение. Обработчик этого события показывает, что элемент находится над объектом на который он может быть перенесен. Если же обработчика нет, либо он не совершает никаких действий перемещение по умолчанию запрещено. Это событие также используется для того, чтобы подсветить либо промаркировать объект над которым происходит перемещения в случае, если перемещение на данный элемент разрешено. Для детальной информации смотрите Specifying Drop Targets.
+
dragover
+
Данное событие срабатывает каждые несколько сотен милисекунд, когда перемещаемый элемент оказывается над зоной, принимающей перетаскиваемые элементы. Для детальной информации смотрите Specifying Drop Targets.
+
dragleave
+
Это событие запускается в момент перетаскивания, когда курсор мыши выходит за пределы элемента. Обработчикам следует убрать любую подсветку или иные индикаторы, указывавшие на присутствие курсора, чтобы тем самым обозначить реакцию на прекращение перетаскивания.
+
drag
+
Запускается при перемещении элемента или выделенного текста.
+
drop
+
Событие drop вызывается для элемента, над которым произошло "сбрасывание" перемещаемого элемента. Событие отвечает за извлечение "сброшенных" данных и их вставку. Событие будет срабатывать только при завершении операции перетаскивания, например, событие не сработает, если пользователь отменит перетаскивание нажатием Esc, или не донесет элемент, до цели. Для детальной информации смотрите Performing a Drop.
+
dragend
+
Источник перетаскивания получит событие dragend, когда перетаскивание завершится, было оно удачным или нет. Это событие не вызывается при перетаскивании файла в браузер из ОС.   Для детальной информации смотрите Finishing a Drag.
+
+ +

Смотрите также

+ + diff --git a/files/ru/web/api/htmlaudioelement/audio()/index.html b/files/ru/web/api/htmlaudioelement/audio()/index.html deleted file mode 100644 index 4d9e39dfab..0000000000 --- a/files/ru/web/api/htmlaudioelement/audio()/index.html +++ /dev/null @@ -1,85 +0,0 @@ ---- -title: Audio() -slug: Web/API/HTMLAudioElement/Audio() -tags: - - аудио -translation_of: Web/API/HTMLAudioElement/Audio ---- -

{{APIRef("HTML DOM")}}

- -

Конструктор Audio() создает и возвращает новый {{domxref("HTMLAudioElement")}} объект, который может быть прикреплен к документу, чтобы пользователь мог взаимодействовать и/или слушать его, либо может использоваться вне экрана для управления и воспроизведения звука.

- -

Синтаксис

- -
audioObj = new Audio(url);
- -

Параметры

- -
-
url {{optional_inline}}
-
Необязательный параметр {{domxref("DOMString")}}, содержащий URL-адрес аудиофайла, который будет связан с новым аудиоэлементом.
-
- -

Возвращаемое значение

- -

Новый {{domxref("HTMLAudioElement")}} объект, настроенный для воспроизведения файла, указанного в url. Свойство {{domxref("HTMLMediaElement.preload", "preload")}} нового объекта имеет значение по умолчанию auto, а его свойство src — указанный URL-адрес или null, если адрес не указан. Если указан URL-адрес, браузер начинает асинхронно загружать медиаресурс перед возвратом нового объекта.

- -
    -
- -

Примечания по использованию

- -

Вы также можете использовать другие методы создания элементов, такие как метод {{domxref("Document.createElement", "createElement()")}} объекта {{domxref("document")}}, для создания нового {{domxref("HTMLAudioElement")}} объекта.

- -

Определение, когда воспроизведение может начаться

- -

Существует три способа определить насколько аудио-файл загружен, чтобы начать воспроизведение:

- -
    -
  • Проверьте значение свойства {{domxref("HTMLMediaElement.readyState", "readyState")}}. Если оно равняется HTMLMediaElement.HAVE_FUTURE_DATA, значит загружено достаточно данных, чтобы начать воспроизведение и проиграть хотя бы короткое время. Если HTMLMediaElement.HAVE_ENOUGH_DATA — доступно достаточно данных, чтобы воспроизводить аудио до конца без прерываний, учитывая текущую скорость загрузки.
  • -
  • Прослушайте событие {{domxref("HTMLMediaElement.canplay_event", "canplay")}}. Оно отправляется элементу <audio>, когда достаточно данных для воспроизведения (хотя возможны прерывания).
  • -
  • Прослушайте событие {{domxref("HTMLMediaElement.canplaythrough_event", "canplaythrough")}}. Оно отправляется, когда предполагается, что аудио должно воспроизводиться до конца без прерываний.
  • -
- -

Лучший подход, основанный на событии:

- -
myAudioElement.addEventListener("canplaythrough", event => {
-  /* аудио может быть воспроизведено; проиграть, если позволяют разрешения */
-  myAudioElement.play();
-});
- -

Использование памяти и управление

- -

Если все ссылки на аудиоэлемент, созданные с помощью конструктора Audio() удалены, сам элемент не будет удален из памяти механизмом сборщика мусора JavaScript, если в данный момент идет воспроизведение. Вместо этого продолжится воспроизведение и объект останется в памяти до тех пор, пока не закончится аудио или оно не будет приостановлено (например, путем вызова {{domxref("HTMLMediaElement.pause", "pause()")}}). В этот момент объект подлежит уничтожению сборщиком мусора.

- -

Спецификации

- - - - - - - - - - - - - - - - -
СпецификацияСтатусКомментарий
{{SpecName('HTML WHATWG', "#dom-audio", "Audio()")}}{{Spec2('HTML WHATWG')}}
- -

Поддержка браузерами

- -

Таблица совместимости на этой странице генерируется из структурированных данных. Если Вы хотите внести свой вклад в эти данные, просмотрите https://github.com/mdn/browser-compat-data и отправте нам Pull-запрос.

- -

{{Compat("api.HTMLAudioElement.Audio")}}

- -

Смотрите также

- -
    -
  • Web media technologies
  • -
  • HTML-элемент, реализующий этот интерфейс: {{HTMLElement("audio")}}.
  • -
diff --git a/files/ru/web/api/htmlaudioelement/audio/index.html b/files/ru/web/api/htmlaudioelement/audio/index.html new file mode 100644 index 0000000000..4d9e39dfab --- /dev/null +++ b/files/ru/web/api/htmlaudioelement/audio/index.html @@ -0,0 +1,85 @@ +--- +title: Audio() +slug: Web/API/HTMLAudioElement/Audio() +tags: + - аудио +translation_of: Web/API/HTMLAudioElement/Audio +--- +

{{APIRef("HTML DOM")}}

+ +

Конструктор Audio() создает и возвращает новый {{domxref("HTMLAudioElement")}} объект, который может быть прикреплен к документу, чтобы пользователь мог взаимодействовать и/или слушать его, либо может использоваться вне экрана для управления и воспроизведения звука.

+ +

Синтаксис

+ +
audioObj = new Audio(url);
+ +

Параметры

+ +
+
url {{optional_inline}}
+
Необязательный параметр {{domxref("DOMString")}}, содержащий URL-адрес аудиофайла, который будет связан с новым аудиоэлементом.
+
+ +

Возвращаемое значение

+ +

Новый {{domxref("HTMLAudioElement")}} объект, настроенный для воспроизведения файла, указанного в url. Свойство {{domxref("HTMLMediaElement.preload", "preload")}} нового объекта имеет значение по умолчанию auto, а его свойство src — указанный URL-адрес или null, если адрес не указан. Если указан URL-адрес, браузер начинает асинхронно загружать медиаресурс перед возвратом нового объекта.

+ +
    +
+ +

Примечания по использованию

+ +

Вы также можете использовать другие методы создания элементов, такие как метод {{domxref("Document.createElement", "createElement()")}} объекта {{domxref("document")}}, для создания нового {{domxref("HTMLAudioElement")}} объекта.

+ +

Определение, когда воспроизведение может начаться

+ +

Существует три способа определить насколько аудио-файл загружен, чтобы начать воспроизведение:

+ +
    +
  • Проверьте значение свойства {{domxref("HTMLMediaElement.readyState", "readyState")}}. Если оно равняется HTMLMediaElement.HAVE_FUTURE_DATA, значит загружено достаточно данных, чтобы начать воспроизведение и проиграть хотя бы короткое время. Если HTMLMediaElement.HAVE_ENOUGH_DATA — доступно достаточно данных, чтобы воспроизводить аудио до конца без прерываний, учитывая текущую скорость загрузки.
  • +
  • Прослушайте событие {{domxref("HTMLMediaElement.canplay_event", "canplay")}}. Оно отправляется элементу <audio>, когда достаточно данных для воспроизведения (хотя возможны прерывания).
  • +
  • Прослушайте событие {{domxref("HTMLMediaElement.canplaythrough_event", "canplaythrough")}}. Оно отправляется, когда предполагается, что аудио должно воспроизводиться до конца без прерываний.
  • +
+ +

Лучший подход, основанный на событии:

+ +
myAudioElement.addEventListener("canplaythrough", event => {
+  /* аудио может быть воспроизведено; проиграть, если позволяют разрешения */
+  myAudioElement.play();
+});
+ +

Использование памяти и управление

+ +

Если все ссылки на аудиоэлемент, созданные с помощью конструктора Audio() удалены, сам элемент не будет удален из памяти механизмом сборщика мусора JavaScript, если в данный момент идет воспроизведение. Вместо этого продолжится воспроизведение и объект останется в памяти до тех пор, пока не закончится аудио или оно не будет приостановлено (например, путем вызова {{domxref("HTMLMediaElement.pause", "pause()")}}). В этот момент объект подлежит уничтожению сборщиком мусора.

+ +

Спецификации

+ + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('HTML WHATWG', "#dom-audio", "Audio()")}}{{Spec2('HTML WHATWG')}}
+ +

Поддержка браузерами

+ +

Таблица совместимости на этой странице генерируется из структурированных данных. Если Вы хотите внести свой вклад в эти данные, просмотрите https://github.com/mdn/browser-compat-data и отправте нам Pull-запрос.

+ +

{{Compat("api.HTMLAudioElement.Audio")}}

+ +

Смотрите также

+ +
    +
  • Web media technologies
  • +
  • HTML-элемент, реализующий этот интерфейс: {{HTMLElement("audio")}}.
  • +
diff --git a/files/ru/web/api/htmlelement/accesskey/index.html b/files/ru/web/api/htmlelement/accesskey/index.html new file mode 100644 index 0000000000..0230ecc9e0 --- /dev/null +++ b/files/ru/web/api/htmlelement/accesskey/index.html @@ -0,0 +1,74 @@ +--- +title: Element.accessKey +slug: Web/API/Element/accessKey +translation_of: Web/API/HTMLElement/accessKey +translation_of_original: Web/API/Element/accessKey +--- +
{{APIRef("DOM")}}
+ +
 
+ +

Описание

+ +

Свойство accessKey позволяет перейти к элементу с помощью сочетания клавиш - заданной им и тех, что назначит браузер.

+ +
+

По сути, accessKey задает значение для одноименного атрибута...

+
+ +
+

Данное свойство использовать не рекоммендуется, поскольку в браузерах уже заданы подобные привязки и неосторожное обращение может привести к жестокому конфликту.

+
+ +

 

+ +

Синтаксис

+ +
var key = elem.accessKey;
+elem.accessKey = key;
+
+ +

 

+ +

Пример

+ +
var elem = document.getElementById("id");
+elem.accessKey = "w";
+
+ +

Немного информации

+ +

Фокусировка на элемент произойдет при нажатии следующих клавиш (,где acesskey - значение свойства acessKey).

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

      Браузер

+
+

      Сочетание

+
Firefox[Alt] [Shift] + accesskey
Internet Explorer[Alt] + accesskey
Chrome[Alt] + accesskey
Safari[Alt] + accesskey
Opera[Shift] [Esc] + accesskey
diff --git a/files/ru/web/api/htmlelement/dataset/index.html b/files/ru/web/api/htmlelement/dataset/index.html deleted file mode 100644 index 328b265afa..0000000000 --- a/files/ru/web/api/htmlelement/dataset/index.html +++ /dev/null @@ -1,114 +0,0 @@ ---- -title: HTMLElement.dataset -slug: Web/API/HTMLElement/dataset -translation_of: Web/API/HTMLOrForeignElement/dataset ---- -

{{ APIRef("HTML DOM") }}

- -

Свойство HTMLElement.dataset предоставляет доступ как для чтения, так и для изменения всех пользовательских дата-атрибутов custom data attributes (data-*) , установленных у элемента. Это map of DOMString, одна запись для каждого пользовательского атрибута данных. Обратите внимание, свойство dataset доступно только для чтения. Для записи должны использоваться  его "свойства", которые представлены data-атрибутами. Также обратите внимание, что HTML data-атрибут и соответствующий ему DOM-dataset.property не имеют одно и то же имя, но они всегда похожи:

- -
    -
  • Имя пользовательского дата атрибута в HTML начинается с "data-". Оно может состоять из букв, цифр и символов: дефис-минус (-, U+002D), точка (.), двоеточие (:), подчеркивание (_). Имя НЕ МОЖЕТ включать в себя заглавные буквы.
  • -
  • Имя пользовательского дата-атрибута в Javascript — это имя того же атрибута в HTML, но с использованием нотации camelCase и без дефисов, точек и т.д.
    -
    - В дополнение к приведенной ниже информации вы найдете руководство по использованию HTML data-атрибутов в нашей статье Использование data-атрибутов.
  • -
- -

Преобразование имён

- -

dash-style в camelCase: имя пользовательского дата-атрибута преобразуется в ключ для {{ domxref("DOMStringMap") }} по следующим правилам:

- -
    -
  • удаляется префикс data- (вместе с дефисом);
  • -
  • дефисы (U+002D) со следующими за ними ASCII-символами a-z в нижнем регистре: черта удаляется, а символ преобразуется в верхний регистр;
  • -
  • остальные символы (включая дефисы) остаются без изменений.
  • -
- -

camelCase в dash-style: обратное преобразование ключа в имя атрибута производится по следующим правилам:

- -
    -
  • Ограничение: сразу после дефиса не может быть ASCII-символа a-z в нижнем регистре (до преобразования);
  • -
  • добавляется префикс data-;
  • -
  • все ASCII-символы A-Z в верхнем регистре заменяются на дефис с символом в нижнем регистре;
  • -
  • остальные символы остаются без изменений.
  • -
- -

Ограничение в правилах гарантирует, что эти два преобразования являются обратными друг другу.

- -

Например, атрибуту data-abc-def соответствует ключ abcDef.

- -

Доступ к значениям

- -
    -
  • Атрибуты можно устанавливать и считывать по имени в camelCase (ключ) как свойство объекта dataset, например element.dataset.keyname
  • -
  • Атрибуты также можно устанавливать и считывать с использованием доступа к свойствам объекта через квадратные скобки, например element.dataset[keyname]
  • -
  • Оператор in может быть использован для проверки существования атрибута.
  • -
- -

Синтаксис

- -
    -
  • string = element.dataset.camelCasedName;
  • -
  • element.dataset.camelCasedName = string;
  • -
    -
  • string = element.dataset[camelCasedName];
  • -
  • element.dataset[camelCasedName] = string;
  • -
    -
  • Custom data attributes can also be set directly on HTML elements, but attribute names must use the data- syntax above.
  • -
- -

Примеры

- -
<div id="user" data-id="1234567890" data-user="johndoe" data-date-of-birth>John Doe</div>
-
-let el = document.querySelector('#user');
-
-// el.id == 'user'
-// el.dataset.id === '1234567890'
-// el.dataset.user === 'johndoe'
-// el.dataset.dateOfBirth === ''
-
-el.dataset.dateOfBirth = '1960-10-03'; // set the DOB.
-
-// 'someDataAttr' in el.dataset === false
-el.dataset.someDataAttr = 'mydata';
-// 'someDataAttr' in el.dataset === true
-
- -

Specifications

- - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', "dom.html#dom-dataset", "HTMLElement.dataset")}}{{Spec2('HTML WHATWG')}}No change from latest snapshot, {{SpecName('HTML5.1')}}
{{SpecName('HTML5.1', "dom.html#dom-dataset", "HTMLElement.dataset")}}{{Spec2('HTML5.1')}}Snapshot of {{SpecName('HTML WHATWG')}}, no change from {{SpecName('HTML5 W3C')}}
{{SpecName('HTML5 W3C', "dom.html#dom-dataset", "HTMLElement.dataset")}}{{Spec2('HTML5 W3C')}}Snapshot of  {{SpecName('HTML WHATWG')}}, initial definition.
- -

Совместимость с браузерами

- -

{{Compat("api.HTMLElement.dataset")}}

- -

См. также

- - diff --git a/files/ru/web/api/htmlelement/innertext/index.html b/files/ru/web/api/htmlelement/innertext/index.html new file mode 100644 index 0000000000..ef23b48d59 --- /dev/null +++ b/files/ru/web/api/htmlelement/innertext/index.html @@ -0,0 +1,46 @@ +--- +title: Node.innerText +slug: Web/API/Node/innerText +translation_of: Web/API/HTMLElement/innerText +--- +
{{APIRef("DOM")}}
+ +

Node.innerText - это свойство, позволяющее задавать или получать текстовое содержимое элемента и его потомков. В качестве геттера, свойство приближается к тексту, который пользователь получит, если он выделит содержимое элемента курсором, затем копирует его в буфер обмена.

+ +

Изначально, данное поведение было представленно Internet Explorer, и было формально специализированно в стандарте HTML в 2016 после того, как было адаптированно всеми ведущими браузерами.

+ +

{{domxref("Node.textContent")}} - это альтернативное свойство, которое имеет ряд отличий:

+ +
    +
  • textContent получает содержимое всех элементов, включая  <script> и <style>, тогда как innerText этого не делает.
  • +
  • innerText умеет считывать стили и не возвращает содержимое скрытых элементов, тогда как textContent этого не делает.
  • +
  • Метод innerText позволяет получить CSS, а textContent — нет.
  • +
+ +

Спецификация

+ + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('HTML WHATWG', 'dom.html#the-innertext-idl-attribute', 'innerText')}}{{Spec2('HTML WHATWG')}}Представлено, основываясь на черновике спецификации innerText. См. whatwg/html#465 и whatwg/compat#5.
+ +

Поддержка браузерами

+ +

{{Compat("api.Node.innerText")}}

+ +

Смотрите также

+ +
    +
  • {{domxref("HTMLElement.outerText")}}
  • +
  • {{domxref("Element.innerHTML")}}
  • +
diff --git a/files/ru/web/api/htmlelement/nonce/index.html b/files/ru/web/api/htmlelement/nonce/index.html deleted file mode 100644 index e47f3aea23..0000000000 --- a/files/ru/web/api/htmlelement/nonce/index.html +++ /dev/null @@ -1,44 +0,0 @@ ---- -title: HTMLElement.nonce -slug: Web/API/HTMLElement/nonce -translation_of: Web/API/HTMLOrForeignElement/nonce ---- -

{{SeeCompatTable}}{{APIRef("HTML DOM")}}

- -

Свойство nonce интерфейса {{domxref("HTMLElement")}} возвращает криптографический номер, который используется политикой безопасности содержимого для определения того, будет ли разрешена дальнейшая работа с данной выборкой.

- -

В более поздних реализациях элементы, имеющие атрибут nonce, предоставляют его только скриптам (а не сторонним каналам, таким как селекторы атрибутов CSS).

- -

Syntax

- -
var nonce = HTMLElement.nonce
-HTMLElement.nonce = nonce
- -

Value

- -

Криптографический код.

- -

Specifications

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG','#attr-nonce','nonce')}}{{Spec2('HTML WHATWG')}}Первоначальное определение.
- -

Browser Compatibility

- -
- - -

{{Compat("api.HTMLElement.nonce")}}

-
diff --git a/files/ru/web/api/htmlelement/style/index.html b/files/ru/web/api/htmlelement/style/index.html deleted file mode 100644 index 683bfa1101..0000000000 --- a/files/ru/web/api/htmlelement/style/index.html +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: HTMLElement.style -slug: Web/API/HTMLElement/style -tags: - - API - - HTML DOM - - HTMLElement - - NeedsBrowserAgnosticism - - NeedsBrowserCompatibility - - NeedsMarkupWork - - NeedsSpecTable - - Свойство - - Ссылки -translation_of: Web/API/ElementCSSInlineStyle/style ---- -

Кратко

- -
-
{{ APIRef("HTML DOM") }}
-
- -

Свойство HTMLElement.style используется для получения и установки инлайновых стилей. При получении возвращается объект CSSStyleDeclaration , который содержит список из всех свойств стилей для этого элемента с значениями заданными  для атрибутов , что определенны  в инлайновом стиле (см. атрибут стиля) элемента. См. CSS Properties Reference для получения списка CSS свойств применимых вместе со style.  

- -

Настройка стилей

- -

Свойство style имеет тот же приоритет (и выше) в каскаде CSS как и прямая декларация стиля через атрибут style, полезен для настройки стиля отдельного специфичного элемента.

- -

Стили не следует устанавливать непосредственно через свойство style (например elt.style = "color: blue;"), поскольку оно считается доступным только для чтения и атрибут style возвращает объект CSSStyleDeclaration который доступен только для чтения. Вместо этого стили могут быть установлены путем присвоения значений свойствам style. Для добавления определенных стилей для элемента без изменения других свойств стилей предпочтительно использовать отдельные свойства style (например elt.style.color = '...'). -При использовании
elt.style.cssText = '...' или elt.setAttribute('style','...') устанавливаются стили перезаписывая уже существующие. Обратите внимание, что имена свойств стилей задаются в camel-case а не в kebab-case elt.style.<property> (т.е., elt.style.fontSize, а не elt.style.font-size).

- -

Объявленные стили сбрасываются присваиванием значения null,
elt.style.color = null

- -

Примеры

- -
// Устанавливает несколько стилей в одном выражении
-elt.style.cssText = "color: blue; border: 1px solid black";
-// Или
-elt.setAttribute("style", "color:red; border: 1px solid blue;");
-
-// Устанавливает определенный стиль оставляя другие значения стиля нетронутыми
-elt.style.color = "blue";
- -

Получение стиль-информации

- -

Свойство style в основном не имеет пользы в части информации о стиле элемента, оно только олицетворяет собой набор CSS деклараций атрибутов style элемента, а не тех которые проистекают из стиль-правил откуда-либо ещё, таких как стилевые правила раздела {{HTMLElement("head")}}, или внешней таблицы стилей. Для получения значений всех CSS свойств элемента вы должны использовать вместо этого {{domxref("window.getComputedStyle()")}}.

- -
-
var div = document.getElementById("div1");
-div.style.marginTop = ".25in";
-
- -

Следующий код показывает имена всех свойств стиля, значений, заданных явно для элемента elt и унаследованных "расчитанных" значений:

- -
var elt = document.getElementById("elementIdHere");
-var out = "";
-var st = elt.style;
-var cs = window.getComputedStyle(elt, null);
-for (x in st) {
-  out += "  " + x + " = '" + st[x] + "' > '" + cs[x] + "'\n";
-}
- -

Спецификация

- -

DOM Level 2 Style: ElementCSSInlineStyle.style

- -

CSSOM: ElementCSSInlineStyle

- -

Совместимость

- - - -

{{Compat("api.HTMLElement.style")}}

- -

См. также

- - diff --git a/files/ru/web/api/htmlelement/tabindex/index.html b/files/ru/web/api/htmlelement/tabindex/index.html deleted file mode 100644 index fe41116fe4..0000000000 --- a/files/ru/web/api/htmlelement/tabindex/index.html +++ /dev/null @@ -1,134 +0,0 @@ ---- -title: HTMLElement.tabIndex -slug: Web/API/HTMLElement/tabIndex -translation_of: Web/API/HTMLOrForeignElement/tabIndex ---- -
-
{{ APIRef("HTML DOM") }}
-
- -

Свойство HTMLElement.tabIndex предоставляет возможность вызова по кнопке Tab текущего элемента.

- -
-
Вызов по табуляции происходит в следующем порядке:
- -
    -
  1. элементы с положительным tabIndex. Элементы, имеющие одинаковое значение tabIndex вызываются в порядке появления в коде.  Переход осуществляется от меньших tabIndex до больших tabIndex. 
  2. -
  3. Элементы, которые не поддерживают атрибут tabIndex или поддерживают но tabIndex установлен в "0", выбираются по Tab в порядке их появления в коде.
  4. -
- -
Элементы для которых установлена блокировка (disabled) не могут быть выбраны кнопкой Tab и не могут быть в фокусе.
- -
 
- -
Значения могут начинаться с любого числа, могут быть отрицательными и могут быть непоследовательными, однако разные браузеры можгут неправильно сработать при очень больших значениях.
- -
 
-
- -

Синтаксис

- -
elt.tabIndex = index;
-var index = elt.tabIndex;
-
- -
    -
  • index - целое число
  • -
- -

Пример

- -
var b1 = document.getElementById("button1");
-
-b1.tabIndex = 1;
-
- -

Спецификация

- -

 

- - - - - - - - - - - - - - - - - - - - - - - - - - -
СпецификацияСтатусКоментарии
{{SpecName('HTML WHATWG', '#dom-tabindex', 'tabindex')}}{{Spec2('HTML WHATWG')}}Не было изменений с {{SpecName('DOM2 HTML')}}.
{{SpecName('DOM2 HTML', 'html.html#ID-40676705', 'tabindex')}}{{Spec2('DOM2 HTML')}}Не было изменений с {{SpecName('DOM1')}}.
{{SpecName('DOM1', 'level-one-html.html#ID-40676705', 'tabindex')}}{{Spec2('DOM1')}}Начальное определение
- -

Поддержка в браузерах

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
-
- -

Смотрите также

- - diff --git a/files/ru/web/api/htmlelement/transitionend_event/index.html b/files/ru/web/api/htmlelement/transitionend_event/index.html new file mode 100644 index 0000000000..dfb8542da6 --- /dev/null +++ b/files/ru/web/api/htmlelement/transitionend_event/index.html @@ -0,0 +1,165 @@ +--- +title: transitionend +slug: Web/Events/transitionend +tags: + - CSS +translation_of: Web/API/HTMLElement/transitionend_event +--- +

Событие transitionend срабатывает, когда CSS transition закончил свое выполнение. В случае, когда анимация удаляется до ее завершения(например, если transition-property [en-US] удаляется), то событие не срабатывает.

+ +

Общая информация

+ +
+
Интерфейс
+
{{domxref("TransitionEvent")}}
+
Всплывает
+
Да
+
Отменяемое
+
Да
+
Элемент
+
{{domxref("document")}}, {{domxref("element")}}
+
Действие по умолчанию
+
Нет
+
+ +

Свойства

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeDescription
target {{readonlyInline}}{{domxref("EventTarget")}}The event target (the topmost target in the DOM tree).
type {{readonlyInline}}{{domxref("DOMString")}}The type of event.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Whether the event normally bubbles or not.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Whether the event is cancellable or not.
propertyName {{readonlyInline}}{{domxref("DOMString")}}The name of the CSS property associated with the transition.
elapsedTime {{readonlyInline}}FloatThe amount of time the transition has been running, in seconds, as of the time the event was generated. This value is not affected by the value of transition-delay.
pseudoElement {{readonlyInline}}{{domxref("DOMString")}}The name (beginning with two colons) of the CSS pseudo-element on which the transition occured (in which case the target of the event is that pseudo-element's corresponding element), or the empty string if the transition occurred on an element (which means the target of the event is that element).
+ +

Пример

+ +
/*
+ * Прослушивать событие transitionend на определенном элементе, т.е. #slidingMenu
+ * Затем, вызвать определенную функцию, т.е. showMessage()
+ */
+function showMessage() {
+    alert('Transition закончил свое выполнение');
+}
+
+var element = document.getElementById("slidingMenu");
+element.addEventListener("transitionend", showMessage, false);
+
+ +

Спецификация

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName("CSS3 Transitions", "#transition-events", "transitionend")}}{{ Spec2('CSS3 Transitions') }}Initial definition.
+ +

Совместимость с браузерами

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support1.0 as webkitTransitionEnd{{ CompatGeckoDesktop("2.0") }}1010.5 as oTransitionEnd
+ 12 as otransitionend
+ 12.10 as transitionend
3.2 as webkitTransitionEnd
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support2.1 as webkitTransitionEnd{{ CompatGeckoMobile("2.0") }}{{ CompatUnknown() }}10 as oTransitionEnd
+ 12 as otransitionend
+ 12.10 as transitionend
3.2 as webkitTransitionEnd
+
+ +

Также

+ +
    +
  • The {{ domxref("TransitionEvent") }} interface and the transitionend event.
  • +
diff --git a/files/ru/web/api/htmlmediaelement/seeking_event/index.html b/files/ru/web/api/htmlmediaelement/seeking_event/index.html new file mode 100644 index 0000000000..5802aecadb --- /dev/null +++ b/files/ru/web/api/htmlmediaelement/seeking_event/index.html @@ -0,0 +1,80 @@ +--- +title: стримится +slug: Web/HTML/Element/video/seeking_event +translation_of: Web/API/HTMLMediaElement/seeking_event +--- +

Событие 'seeking' в случае, когда идет подгрузка видео

+ +

General info

+ +
+
Specification
+
HTML5 media
+
Interface
+
Event
+
Bubbles
+
No
+
Cancelable
+
No
+
Target
+
Element
+
Default Action
+
None.
+
+ +

Properties

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeDescription
target {{readonlyInline}}{{domxref("EventTarget")}}The event target (the topmost target in the DOM tree).
type {{readonlyInline}}{{domxref("DOMString")}}The type of event.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Whether the event normally bubbles or not.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Whether the event is cancellable or not.
+ + + +
    +
  • {{event("playing")}}
  • +
  • {{event("waiting")}}
  • +
  • {{event("seeking")}}
  • +
  • {{event("seeked")}}
  • +
  • {{event("ended")}}
  • +
  • {{event("loadedmetadata")}}
  • +
  • {{event("loadeddata")}}
  • +
  • {{event("canplay")}}
  • +
  • {{event("canplaythrough")}}
  • +
  • {{event("durationchange")}}
  • +
  • {{event("timeupdate")}}
  • +
  • {{event("play")}}
  • +
  • {{event("pause")}}
  • +
  • {{event("ratechange")}}
  • +
  • {{event("volumechange")}}
  • +
  • {{event("suspend")}}
  • +
  • {{event("emptied")}}
  • +
  • {{event("stalled")}}
  • +
diff --git a/files/ru/web/api/htmlorforeignelement/dataset/index.html b/files/ru/web/api/htmlorforeignelement/dataset/index.html new file mode 100644 index 0000000000..328b265afa --- /dev/null +++ b/files/ru/web/api/htmlorforeignelement/dataset/index.html @@ -0,0 +1,114 @@ +--- +title: HTMLElement.dataset +slug: Web/API/HTMLElement/dataset +translation_of: Web/API/HTMLOrForeignElement/dataset +--- +

{{ APIRef("HTML DOM") }}

+ +

Свойство HTMLElement.dataset предоставляет доступ как для чтения, так и для изменения всех пользовательских дата-атрибутов custom data attributes (data-*) , установленных у элемента. Это map of DOMString, одна запись для каждого пользовательского атрибута данных. Обратите внимание, свойство dataset доступно только для чтения. Для записи должны использоваться  его "свойства", которые представлены data-атрибутами. Также обратите внимание, что HTML data-атрибут и соответствующий ему DOM-dataset.property не имеют одно и то же имя, но они всегда похожи:

+ +
    +
  • Имя пользовательского дата атрибута в HTML начинается с "data-". Оно может состоять из букв, цифр и символов: дефис-минус (-, U+002D), точка (.), двоеточие (:), подчеркивание (_). Имя НЕ МОЖЕТ включать в себя заглавные буквы.
  • +
  • Имя пользовательского дата-атрибута в Javascript — это имя того же атрибута в HTML, но с использованием нотации camelCase и без дефисов, точек и т.д.
    +
    + В дополнение к приведенной ниже информации вы найдете руководство по использованию HTML data-атрибутов в нашей статье Использование data-атрибутов.
  • +
+ +

Преобразование имён

+ +

dash-style в camelCase: имя пользовательского дата-атрибута преобразуется в ключ для {{ domxref("DOMStringMap") }} по следующим правилам:

+ +
    +
  • удаляется префикс data- (вместе с дефисом);
  • +
  • дефисы (U+002D) со следующими за ними ASCII-символами a-z в нижнем регистре: черта удаляется, а символ преобразуется в верхний регистр;
  • +
  • остальные символы (включая дефисы) остаются без изменений.
  • +
+ +

camelCase в dash-style: обратное преобразование ключа в имя атрибута производится по следующим правилам:

+ +
    +
  • Ограничение: сразу после дефиса не может быть ASCII-символа a-z в нижнем регистре (до преобразования);
  • +
  • добавляется префикс data-;
  • +
  • все ASCII-символы A-Z в верхнем регистре заменяются на дефис с символом в нижнем регистре;
  • +
  • остальные символы остаются без изменений.
  • +
+ +

Ограничение в правилах гарантирует, что эти два преобразования являются обратными друг другу.

+ +

Например, атрибуту data-abc-def соответствует ключ abcDef.

+ +

Доступ к значениям

+ +
    +
  • Атрибуты можно устанавливать и считывать по имени в camelCase (ключ) как свойство объекта dataset, например element.dataset.keyname
  • +
  • Атрибуты также можно устанавливать и считывать с использованием доступа к свойствам объекта через квадратные скобки, например element.dataset[keyname]
  • +
  • Оператор in может быть использован для проверки существования атрибута.
  • +
+ +

Синтаксис

+ +
    +
  • string = element.dataset.camelCasedName;
  • +
  • element.dataset.camelCasedName = string;
  • +
    +
  • string = element.dataset[camelCasedName];
  • +
  • element.dataset[camelCasedName] = string;
  • +
    +
  • Custom data attributes can also be set directly on HTML elements, but attribute names must use the data- syntax above.
  • +
+ +

Примеры

+ +
<div id="user" data-id="1234567890" data-user="johndoe" data-date-of-birth>John Doe</div>
+
+let el = document.querySelector('#user');
+
+// el.id == 'user'
+// el.dataset.id === '1234567890'
+// el.dataset.user === 'johndoe'
+// el.dataset.dateOfBirth === ''
+
+el.dataset.dateOfBirth = '1960-10-03'; // set the DOB.
+
+// 'someDataAttr' in el.dataset === false
+el.dataset.someDataAttr = 'mydata';
+// 'someDataAttr' in el.dataset === true
+
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', "dom.html#dom-dataset", "HTMLElement.dataset")}}{{Spec2('HTML WHATWG')}}No change from latest snapshot, {{SpecName('HTML5.1')}}
{{SpecName('HTML5.1', "dom.html#dom-dataset", "HTMLElement.dataset")}}{{Spec2('HTML5.1')}}Snapshot of {{SpecName('HTML WHATWG')}}, no change from {{SpecName('HTML5 W3C')}}
{{SpecName('HTML5 W3C', "dom.html#dom-dataset", "HTMLElement.dataset")}}{{Spec2('HTML5 W3C')}}Snapshot of  {{SpecName('HTML WHATWG')}}, initial definition.
+ +

Совместимость с браузерами

+ +

{{Compat("api.HTMLElement.dataset")}}

+ +

См. также

+ + diff --git a/files/ru/web/api/htmlorforeignelement/nonce/index.html b/files/ru/web/api/htmlorforeignelement/nonce/index.html new file mode 100644 index 0000000000..e47f3aea23 --- /dev/null +++ b/files/ru/web/api/htmlorforeignelement/nonce/index.html @@ -0,0 +1,44 @@ +--- +title: HTMLElement.nonce +slug: Web/API/HTMLElement/nonce +translation_of: Web/API/HTMLOrForeignElement/nonce +--- +

{{SeeCompatTable}}{{APIRef("HTML DOM")}}

+ +

Свойство nonce интерфейса {{domxref("HTMLElement")}} возвращает криптографический номер, который используется политикой безопасности содержимого для определения того, будет ли разрешена дальнейшая работа с данной выборкой.

+ +

В более поздних реализациях элементы, имеющие атрибут nonce, предоставляют его только скриптам (а не сторонним каналам, таким как селекторы атрибутов CSS).

+ +

Syntax

+ +
var nonce = HTMLElement.nonce
+HTMLElement.nonce = nonce
+ +

Value

+ +

Криптографический код.

+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG','#attr-nonce','nonce')}}{{Spec2('HTML WHATWG')}}Первоначальное определение.
+ +

Browser Compatibility

+ +
+ + +

{{Compat("api.HTMLElement.nonce")}}

+
diff --git a/files/ru/web/api/htmlorforeignelement/tabindex/index.html b/files/ru/web/api/htmlorforeignelement/tabindex/index.html new file mode 100644 index 0000000000..fe41116fe4 --- /dev/null +++ b/files/ru/web/api/htmlorforeignelement/tabindex/index.html @@ -0,0 +1,134 @@ +--- +title: HTMLElement.tabIndex +slug: Web/API/HTMLElement/tabIndex +translation_of: Web/API/HTMLOrForeignElement/tabIndex +--- +
+
{{ APIRef("HTML DOM") }}
+
+ +

Свойство HTMLElement.tabIndex предоставляет возможность вызова по кнопке Tab текущего элемента.

+ +
+
Вызов по табуляции происходит в следующем порядке:
+ +
    +
  1. элементы с положительным tabIndex. Элементы, имеющие одинаковое значение tabIndex вызываются в порядке появления в коде.  Переход осуществляется от меньших tabIndex до больших tabIndex. 
  2. +
  3. Элементы, которые не поддерживают атрибут tabIndex или поддерживают но tabIndex установлен в "0", выбираются по Tab в порядке их появления в коде.
  4. +
+ +
Элементы для которых установлена блокировка (disabled) не могут быть выбраны кнопкой Tab и не могут быть в фокусе.
+ +
 
+ +
Значения могут начинаться с любого числа, могут быть отрицательными и могут быть непоследовательными, однако разные браузеры можгут неправильно сработать при очень больших значениях.
+ +
 
+
+ +

Синтаксис

+ +
elt.tabIndex = index;
+var index = elt.tabIndex;
+
+ +
    +
  • index - целое число
  • +
+ +

Пример

+ +
var b1 = document.getElementById("button1");
+
+b1.tabIndex = 1;
+
+ +

Спецификация

+ +

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКоментарии
{{SpecName('HTML WHATWG', '#dom-tabindex', 'tabindex')}}{{Spec2('HTML WHATWG')}}Не было изменений с {{SpecName('DOM2 HTML')}}.
{{SpecName('DOM2 HTML', 'html.html#ID-40676705', 'tabindex')}}{{Spec2('DOM2 HTML')}}Не было изменений с {{SpecName('DOM1')}}.
{{SpecName('DOM1', 'level-one-html.html#ID-40676705', 'tabindex')}}{{Spec2('DOM1')}}Начальное определение
+ +

Поддержка в браузерах

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

Смотрите также

+ + diff --git a/files/ru/web/api/mediatrackconstraints/echocancellation/index.html b/files/ru/web/api/mediatrackconstraints/echocancellation/index.html new file mode 100644 index 0000000000..3e8d1f1a4e --- /dev/null +++ b/files/ru/web/api/mediatrackconstraints/echocancellation/index.html @@ -0,0 +1,77 @@ +--- +title: MediaTrackConstraints.echoCancellation +slug: Web/API/MediaTrackConstraints/Эхоподавление +tags: + - API + - Media Capture and Streams API + - Media Streams API + - MediaTrackConstrains + - WebRTC + - Медиа + - Ограничения + - Свойство + - Эхоподавление + - справочник +translation_of: Web/API/MediaTrackConstraints/echoCancellation +--- +
{{APIRef("Media Capture and Streams")}}
+ +

Свойство echoCancellation объекта {{domxref("MediaTrackConstraints")}} это {{domxref("ConstrainBoolean")}} описывающее запрашиваемые или обязательные ограничения накладываемые на ограничивающее свойство {{domxref("MediaTrackSettings.echoCancellation", "echoCancellation")}}.

+ +

При необходимости вы можете определить, поддерживается ли это ограничение, проверив значение {{domxref("MediaTrackSupportedConstraints.echoCancellation")}} как результат вызова {{domxref("MediaDevices.getSupportedConstraints()")}}. Однако, обычно в этом нет необходимости, поскольку браузеры просто игнорируют любые незнакомые им ограничения.

+ +

Поскольку {{Glossary("RTP")}} не содержит эту информцию, медиа-треки связанные с WebRTC {{domxref("RTCPeerConnection")}} некогда не будут включать это свойство.

+ +

Синтаксис

+ +
const constraintsObject = {
+  echoCancellation: constraint,
+};
+
+constraintsObject.echoCancellation = constraint;
+
+ +

Значение

+ +

Если это значение является простым true или false, пользовательский агент попытается получить медиа с включенным или отключенным эхоподавлением, если это возможно, но не вернет ошибку, если это невозможно сделать. Иначе если значение передано как объект с полем exact , то логическое значение этого поля указывает обязательную настройку для эхоподавления; если это не может быть выполненым - запрос вернет ошибку.

+ +

Пример

+ +

Смотрите {{SectionOnPage("/en-US/docs/Web/API/Media_Streams_API/Constraints", "Example: Constraint exerciser")}} для примера.

+ +

Спецификации

+ + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{ SpecName('Media Capture', '#dom-mediatrackconstraintset-echocancellation', 'echoCancellation') }}{{ Spec2('Media Capture') }}Initial specification.
+ +

Совместимость с браузерами

+ + + +

{{Compat("api.MediaTrackConstraints.echoCancellation")}}

+ +

Смотрите также

+ + diff --git "a/files/ru/web/api/mediatrackconstraints/\321\215\321\205\320\276\320\277\320\276\320\264\320\260\320\262\320\273\320\265\320\275\320\270\320\265/index.html" "b/files/ru/web/api/mediatrackconstraints/\321\215\321\205\320\276\320\277\320\276\320\264\320\260\320\262\320\273\320\265\320\275\320\270\320\265/index.html" deleted file mode 100644 index 3e8d1f1a4e..0000000000 --- "a/files/ru/web/api/mediatrackconstraints/\321\215\321\205\320\276\320\277\320\276\320\264\320\260\320\262\320\273\320\265\320\275\320\270\320\265/index.html" +++ /dev/null @@ -1,77 +0,0 @@ ---- -title: MediaTrackConstraints.echoCancellation -slug: Web/API/MediaTrackConstraints/Эхоподавление -tags: - - API - - Media Capture and Streams API - - Media Streams API - - MediaTrackConstrains - - WebRTC - - Медиа - - Ограничения - - Свойство - - Эхоподавление - - справочник -translation_of: Web/API/MediaTrackConstraints/echoCancellation ---- -
{{APIRef("Media Capture and Streams")}}
- -

Свойство echoCancellation объекта {{domxref("MediaTrackConstraints")}} это {{domxref("ConstrainBoolean")}} описывающее запрашиваемые или обязательные ограничения накладываемые на ограничивающее свойство {{domxref("MediaTrackSettings.echoCancellation", "echoCancellation")}}.

- -

При необходимости вы можете определить, поддерживается ли это ограничение, проверив значение {{domxref("MediaTrackSupportedConstraints.echoCancellation")}} как результат вызова {{domxref("MediaDevices.getSupportedConstraints()")}}. Однако, обычно в этом нет необходимости, поскольку браузеры просто игнорируют любые незнакомые им ограничения.

- -

Поскольку {{Glossary("RTP")}} не содержит эту информцию, медиа-треки связанные с WebRTC {{domxref("RTCPeerConnection")}} некогда не будут включать это свойство.

- -

Синтаксис

- -
const constraintsObject = {
-  echoCancellation: constraint,
-};
-
-constraintsObject.echoCancellation = constraint;
-
- -

Значение

- -

Если это значение является простым true или false, пользовательский агент попытается получить медиа с включенным или отключенным эхоподавлением, если это возможно, но не вернет ошибку, если это невозможно сделать. Иначе если значение передано как объект с полем exact , то логическое значение этого поля указывает обязательную настройку для эхоподавления; если это не может быть выполненым - запрос вернет ошибку.

- -

Пример

- -

Смотрите {{SectionOnPage("/en-US/docs/Web/API/Media_Streams_API/Constraints", "Example: Constraint exerciser")}} для примера.

- -

Спецификации

- - - - - - - - - - - - - - - - -
СпецификацияСтатусКомментарий
{{ SpecName('Media Capture', '#dom-mediatrackconstraintset-echocancellation', 'echoCancellation') }}{{ Spec2('Media Capture') }}Initial specification.
- -

Совместимость с браузерами

- - - -

{{Compat("api.MediaTrackConstraints.echoCancellation")}}

- -

Смотрите также

- - diff --git a/files/ru/web/api/navigator/connection/index.html b/files/ru/web/api/navigator/connection/index.html new file mode 100644 index 0000000000..607101a911 --- /dev/null +++ b/files/ru/web/api/navigator/connection/index.html @@ -0,0 +1,100 @@ +--- +title: NetworkInformation.connection +slug: Web/API/NetworkInformation/connection +translation_of: Web/API/Navigator/connection +--- +

{{ apiref("Network Information API") }}

+ +

{{ SeeCompatTable() }}

+ +

NetworkInformation.connection свойство только для чтения представляющее собой {{domxref("Connection")}} содержащий информацию о системном подключении, таких как текущая пропускная способность пользовательского устройства или определено ли соеденение. Это может быть использовано для выбора контента высокой плотности или контента низкой плотности в соединении пользователя.

+ +

Синтаксис

+ +
connectionInfo = navigator.connection
+ +

Спецификации

+ + + + + + + + + + + + + + + + +
СпецификацияСтатусКоментарий
{{ SpecName('Network Information', '#h-the-connection-attribute', 'NetworkInformation.connection') }}{{ Spec2('Network Information') }}Первоначальная спецификация.
+ +

Доступность в браузере

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
СвойствоChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка{{ CompatNo() }}12.0
+ behind the flag
{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
СвойствоAndroidFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari Mobile
Базовая поддержка2.2 {{ property_prefix("webkit") }}12.01.4{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
+
+ +

Заметка для Gecko

+ +
    +
  • Network API может быть отключена  используя dom.netinfo.enabled.
  • +
+ +

Смотрите также

+ + diff --git a/files/ru/web/api/navigatorgeolocation/index.html b/files/ru/web/api/navigatorgeolocation/index.html deleted file mode 100644 index 7287eee669..0000000000 --- a/files/ru/web/api/navigatorgeolocation/index.html +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: NavigatorGeolocation -slug: Web/API/NavigatorGeolocation -translation_of: Web/API/Geolocation -translation_of_original: Web/API/NavigatorGeolocation ---- -
{{APIRef("Geolocation API")}}
- -

NavigatorGeolocation содержит метод, позволяющий объектам реализовывать его,, получая {{domxref("Geolocation")}} экземпляр объекта.

- -

Здесь нет объектов типа NavigatorGeolocation, но некоторые интерфейсы, например, {{domxref("Navigator")}} реализуют его.

- -

Свойства

- -

Интерфейс NavigatorGeolocation не наследует каких-либо свойств.

- -
-
{{domxref("NavigatorGeolocation.geolocation")}} {{readonlyInline}}
-
Возвращает объект {{domxref("Geolocation")}} позволяющий получить доступ к местоположению устройства.
-
- -

Методы

- -

Интерфейс NavigatorGeolocation ни реализует, ни наследует  никаких методов.

- -

Спецификации

- - - - - - - - - - - - - - - - -
СпецификацияСтатусКомментарий
{{SpecName('Geolocation', '#navi-geo', 'NavigatorGeolocation')}}{{Spec2('Geolocation')}}Изначальное описание
- -

Совместимость с браузерами

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
СвойствоChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка5{{CompatGeckoDesktop("1.9.1")}}910.60
- {{CompatNo}} 15.0
- 16.0
5
-
- -
- - - - - - - - - - - - - - - - - - - - - -
СвойствоAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("4")}}{{CompatUnknown}}10.60{{CompatUnknown}}
-
- -

Смотрите также

- - diff --git a/files/ru/web/api/networkinformation/connection/index.html b/files/ru/web/api/networkinformation/connection/index.html deleted file mode 100644 index 607101a911..0000000000 --- a/files/ru/web/api/networkinformation/connection/index.html +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: NetworkInformation.connection -slug: Web/API/NetworkInformation/connection -translation_of: Web/API/Navigator/connection ---- -

{{ apiref("Network Information API") }}

- -

{{ SeeCompatTable() }}

- -

NetworkInformation.connection свойство только для чтения представляющее собой {{domxref("Connection")}} содержащий информацию о системном подключении, таких как текущая пропускная способность пользовательского устройства или определено ли соеденение. Это может быть использовано для выбора контента высокой плотности или контента низкой плотности в соединении пользователя.

- -

Синтаксис

- -
connectionInfo = navigator.connection
- -

Спецификации

- - - - - - - - - - - - - - - - -
СпецификацияСтатусКоментарий
{{ SpecName('Network Information', '#h-the-connection-attribute', 'NetworkInformation.connection') }}{{ Spec2('Network Information') }}Первоначальная спецификация.
- -

Доступность в браузере

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - -
СвойствоChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка{{ CompatNo() }}12.0
- behind the flag
{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
СвойствоAndroidFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari Mobile
Базовая поддержка2.2 {{ property_prefix("webkit") }}12.01.4{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
-
- -

Заметка для Gecko

- -
    -
  • Network API может быть отключена  используя dom.netinfo.enabled.
  • -
- -

Смотрите также

- - diff --git a/files/ru/web/api/node.replacechild/index.html b/files/ru/web/api/node.replacechild/index.html deleted file mode 100644 index 6d69392c57..0000000000 --- a/files/ru/web/api/node.replacechild/index.html +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: Node.replaceChild -slug: Web/API/Node.replaceChild -tags: - - API - - DOM - - DOM Elements Method - - Gecko - - Method - - Node -translation_of: Web/API/Node/replaceChild ---- -
- {{ApiRef}}
-

Аннотация

-

Заменяет дочерний элемент на выбранный. Возвращает замененный элемент.

-

Синтаксис

-
replacedNode = parentNode.replaceChild(newChild, oldChild);
-
-
    -
  • newChild элемент на который будет заменен oldChild. В случает если он уже есть в DOM, то сначала он будет удален.
  • -
  • oldChild элемент который будет заменен.
  • -
  • replacedNode замененный элемент. Тоже самое что и oldChild.
  • -
-

Пример

-
// <div>
-//  <span id="childSpan">foo bar</span>
-// </div>
-
-// Создаем новый пустой элемент
-// without an ID, any attributes, or any content
-var sp1 = document.createElement("span");
-
-// Присваиваем ему id 'newSpan'
-sp1.setAttribute("id", "newSpan");
-
-// Создаем строку.
-var sp1_content = document.createTextNode("new replacement span element.");
-
-// Добавляем контент в созданный нами узел
-sp1.appendChild(sp1_content);
-
-// создаем ссылку на существующий элемент который будем заменять
-var sp2 = document.getElementById("childSpan");
-var parentDiv = sp2.parentNode;
-
-// заменяем существующий элемент sp2 на созданный нами sp1
-parentDiv.replaceChild(sp1, sp2);
-
-// Результат:
-// <div>
-//   <span id="newSpan">new replacement span element.</span>
-// </div>
-
-

Спецификация

- -

См. также

-
    -
  • {{domxref("Node.removeChild")}}
  • -
diff --git a/files/ru/web/api/node/baseuriobject/index.html b/files/ru/web/api/node/baseuriobject/index.html deleted file mode 100644 index 7f7dbfb782..0000000000 --- a/files/ru/web/api/node/baseuriobject/index.html +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: Node.baseURIObject -slug: Web/API/Node/baseURIObject -translation_of: Web/API/Node -translation_of_original: Web/API/Node/baseURIObject ---- -
{{APIRef("DOM")}} {{Non-standard_header}}
- -

Свойство Node.baseURIObject возвращает {{Interface("nsIURI")}} представляющий базовый URL узла (обычно документ или элемент). Это похоже на {{domxref("Node.baseURI")}}, за исключением того, что возвращает nsIURI вместо строки.

- -

Это свойство существует на всех узлах (HTML, XUL, SVG, MathML, и т.д.), но только если скрипт пытается использовать его имея привилегии UniversalXPConnect.

- -

Смотрите {{domxref("Node.baseURI")}} для уточнения деталей что такое базовый URL.

- -

Синтаксис

- -
uriObj = node.baseURIObject
-
- -

Примечания

- -

Это свойство только для чтения; попытка записать информацию в него, будет сбрасывать исключения. Кроме того, это свойство может быть доступно только для привилегированного кода.

- -

Спецификация

- -

Нет какой-либо спецификации.

diff --git a/files/ru/web/api/node/innertext/index.html b/files/ru/web/api/node/innertext/index.html deleted file mode 100644 index ef23b48d59..0000000000 --- a/files/ru/web/api/node/innertext/index.html +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: Node.innerText -slug: Web/API/Node/innerText -translation_of: Web/API/HTMLElement/innerText ---- -
{{APIRef("DOM")}}
- -

Node.innerText - это свойство, позволяющее задавать или получать текстовое содержимое элемента и его потомков. В качестве геттера, свойство приближается к тексту, который пользователь получит, если он выделит содержимое элемента курсором, затем копирует его в буфер обмена.

- -

Изначально, данное поведение было представленно Internet Explorer, и было формально специализированно в стандарте HTML в 2016 после того, как было адаптированно всеми ведущими браузерами.

- -

{{domxref("Node.textContent")}} - это альтернативное свойство, которое имеет ряд отличий:

- -
    -
  • textContent получает содержимое всех элементов, включая  <script> и <style>, тогда как innerText этого не делает.
  • -
  • innerText умеет считывать стили и не возвращает содержимое скрытых элементов, тогда как textContent этого не делает.
  • -
  • Метод innerText позволяет получить CSS, а textContent — нет.
  • -
- -

Спецификация

- - - - - - - - - - - - - - -
СпецификацияСтатусКомментарий
{{SpecName('HTML WHATWG', 'dom.html#the-innertext-idl-attribute', 'innerText')}}{{Spec2('HTML WHATWG')}}Представлено, основываясь на черновике спецификации innerText. См. whatwg/html#465 и whatwg/compat#5.
- -

Поддержка браузерами

- -

{{Compat("api.Node.innerText")}}

- -

Смотрите также

- -
    -
  • {{domxref("HTMLElement.outerText")}}
  • -
  • {{domxref("Element.innerHTML")}}
  • -
diff --git a/files/ru/web/api/node/nodeprincipal/index.html b/files/ru/web/api/node/nodeprincipal/index.html deleted file mode 100644 index 11b342e6c3..0000000000 --- a/files/ru/web/api/node/nodeprincipal/index.html +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: Node.nodePrincipal -slug: Web/API/Node/nodePrincipal -translation_of: Web/API/Node -translation_of_original: Web/API/Node/nodePrincipal ---- -
-
{{APIRef("DOM")}}
-{{Non-standard_header}} - -

Свойство Node.nodePrincipal только для чтения, возвращающее объект {{Interface("nsIPrincipal")}}, представляющий текущий контекст безопасности узла.

- -

{{Note("Это свойство существует во всех узлах (HTML, XUL, SVG, MathML, и т.д.), но только если скрипт пытается использовать chrome привилегии.")}}

- -

Синтаксис

- -
principalObj = element.nodePrincipal
-
- -

Примечания

- -

Это свойство только для чтения; пытаясь вводить информацию в него, будет сбрасывать исключение.Кроме того, это свойство может быть доступно только для привилегированного кода.

- -

Спецификация

- -

Нет никакой спецификации.

-
- -

 

diff --git a/files/ru/web/api/node/replacechild/index.html b/files/ru/web/api/node/replacechild/index.html new file mode 100644 index 0000000000..6d69392c57 --- /dev/null +++ b/files/ru/web/api/node/replacechild/index.html @@ -0,0 +1,64 @@ +--- +title: Node.replaceChild +slug: Web/API/Node.replaceChild +tags: + - API + - DOM + - DOM Elements Method + - Gecko + - Method + - Node +translation_of: Web/API/Node/replaceChild +--- +
+ {{ApiRef}}
+

Аннотация

+

Заменяет дочерний элемент на выбранный. Возвращает замененный элемент.

+

Синтаксис

+
replacedNode = parentNode.replaceChild(newChild, oldChild);
+
+
    +
  • newChild элемент на который будет заменен oldChild. В случает если он уже есть в DOM, то сначала он будет удален.
  • +
  • oldChild элемент который будет заменен.
  • +
  • replacedNode замененный элемент. Тоже самое что и oldChild.
  • +
+

Пример

+
// <div>
+//  <span id="childSpan">foo bar</span>
+// </div>
+
+// Создаем новый пустой элемент
+// without an ID, any attributes, or any content
+var sp1 = document.createElement("span");
+
+// Присваиваем ему id 'newSpan'
+sp1.setAttribute("id", "newSpan");
+
+// Создаем строку.
+var sp1_content = document.createTextNode("new replacement span element.");
+
+// Добавляем контент в созданный нами узел
+sp1.appendChild(sp1_content);
+
+// создаем ссылку на существующий элемент который будем заменять
+var sp2 = document.getElementById("childSpan");
+var parentDiv = sp2.parentNode;
+
+// заменяем существующий элемент sp2 на созданный нами sp1
+parentDiv.replaceChild(sp1, sp2);
+
+// Результат:
+// <div>
+//   <span id="newSpan">new replacement span element.</span>
+// </div>
+
+

Спецификация

+ +

См. также

+
    +
  • {{domxref("Node.removeChild")}}
  • +
diff --git a/files/ru/web/api/nondocumenttypechildnode/nextelementsibling/index.html b/files/ru/web/api/nondocumenttypechildnode/nextelementsibling/index.html new file mode 100644 index 0000000000..84c40445d8 --- /dev/null +++ b/files/ru/web/api/nondocumenttypechildnode/nextelementsibling/index.html @@ -0,0 +1,173 @@ +--- +title: NonDocumentTypeChildNode.nextElementSibling +slug: Web/API/NonDocumentTypeChildNode/NonDocumentTypeChildNode.nextElementSibling +translation_of: Web/API/NonDocumentTypeChildNode/nextElementSibling +--- +
{{APIRef("DOM")}}
+ +

NonDocumentTypeChildNode.nextElementSibling свойство только для чтения, возвращающее последующий элемент перед текущим, или null, если элемент является последним в своём родительском узле.

+ +

Синтаксис

+ +
var nextNode = elementNodeReference.nextElementSibling; 
+ +

Пример

+ +
<div id="div-01">Это div-01</div>
+<div id="div-02">Это div-02</div>
+
+<script type="text/javascript">
+  var el = document.getElementById('div-01').nextElementSibling;
+  console.log('Сосед div-01:');
+  while (el) {
+    console.log(el.nodeName);
+    el = el.nextElementSibling;
+  }
+</script>
+
+ +

Этот пример выведет в консоль следующее:

+ +
Сосед div-01:
+DIV
+SCRIPT
+ +

Полифилл для IE8

+ +

Данное свойство не пожддерживается до IE9. Используйте следующий полифилл, чтобы обойти этот недостаток:

+ +
// Источник: https://github.com/Alhadis/Snippets/blob/master/js/polyfills/IE8-child-elements.js
+if (!('nextElementSibling' in document.documentElement)) {
+    Object.defineProperty(Element.prototype, 'nextElementSibling', {
+        get: function() {
+            var e = this.nextSibling;
+            while (e && 1 !== e.nodeType) {
+                e = e.nextSibling;
+            }
+            return e;
+        }
+    });
+}
+ +

Полифилл для IE9+ и Safari

+ +
// Источник: https://github.com/jserz/js_piece/blob/master/DOM/NonDocumentTypeChildNode/nextElementSibling/nextElementSibling.md
+(function(arr) {
+    arr.forEach(function(item) {
+        if (item.hasOwnProperty('nextElementSibling')) {
+            return;
+        }
+        Object.defineProperty(item, 'nextElementSibling', {
+            configurable: true,
+            enumerable: true,
+            get: function() {
+                var el = this;
+                while (el = el.nextSibling) {
+                    if (el.nodeType === 1) {
+                        return el;
+                    }
+                }
+                return null;
+            },
+            set: undefined
+        });
+    });
+})([Element.prototype, CharacterData.prototype]);
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('DOM WHATWG', '#dom-nondocumenttypechildnode-nextelementsibling', 'ChildNodenextElementSibling')}}{{Spec2('DOM WHATWG')}}Split the ElementTraversal interface in {{domxref("ChildNode")}}, {{domxref("ParentNode")}}, and {{domxref("NonDocumentTypeChildNode")}}. This method is now defined on the former.
+ The {{domxref("Element")}} and {{domxref("CharacterData")}} interfaces implemented the new interface.
{{SpecName('Element Traversal', '#attribute-nextElementSibling', 'ElementTraversal.nextElementSibling')}}{{Spec2('Element Traversal')}}Added its initial definition to the ElementTraversal pure interface and use it on {{domxref("Element")}}.
+ +

Совместимость с браузерами

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
БраузерыChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка ({{domxref("Element")}})4{{CompatGeckoDesktop("1.9.1")}}99.84
Поддержка {{domxref("CharacterData")}}29.0{{CompatGeckoDesktop("25")}} [1]{{CompatNo}}16.0{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
БраузерыAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка ( {{domxref("Element")}}){{CompatVersionUnknown}}{{CompatGeckoMobile("1.9.1")}}{{CompatVersionUnknown}}9.8{{CompatVersionUnknown}}
Поддержка {{domxref("CharacterData")}}{{CompatVersionUnknown}}{{CompatGeckoMobile("25")}}{{CompatNo}}16.0{{CompatNo}}
+
+ +

[1] Firefox 25 также добавил это свойство в {{domxref("DocumentType")}}, но оно было удалено в Firefox 28, из-за проблем совместимости.

+ +

См. также

+ +
    +
  • Чистый интерфейс {{domxref("ChildNode")}}.
  • +
  • Типы объектов, реализующих этот чистый интерфейс: {{domxref("CharacterData")}}, {{domxref("Element")}}, и {{domxref("DocumentType")}}. 
  • +
diff --git a/files/ru/web/api/nondocumenttypechildnode/nondocumenttypechildnode.nextelementsibling/index.html b/files/ru/web/api/nondocumenttypechildnode/nondocumenttypechildnode.nextelementsibling/index.html deleted file mode 100644 index 84c40445d8..0000000000 --- a/files/ru/web/api/nondocumenttypechildnode/nondocumenttypechildnode.nextelementsibling/index.html +++ /dev/null @@ -1,173 +0,0 @@ ---- -title: NonDocumentTypeChildNode.nextElementSibling -slug: Web/API/NonDocumentTypeChildNode/NonDocumentTypeChildNode.nextElementSibling -translation_of: Web/API/NonDocumentTypeChildNode/nextElementSibling ---- -
{{APIRef("DOM")}}
- -

NonDocumentTypeChildNode.nextElementSibling свойство только для чтения, возвращающее последующий элемент перед текущим, или null, если элемент является последним в своём родительском узле.

- -

Синтаксис

- -
var nextNode = elementNodeReference.nextElementSibling; 
- -

Пример

- -
<div id="div-01">Это div-01</div>
-<div id="div-02">Это div-02</div>
-
-<script type="text/javascript">
-  var el = document.getElementById('div-01').nextElementSibling;
-  console.log('Сосед div-01:');
-  while (el) {
-    console.log(el.nodeName);
-    el = el.nextElementSibling;
-  }
-</script>
-
- -

Этот пример выведет в консоль следующее:

- -
Сосед div-01:
-DIV
-SCRIPT
- -

Полифилл для IE8

- -

Данное свойство не пожддерживается до IE9. Используйте следующий полифилл, чтобы обойти этот недостаток:

- -
// Источник: https://github.com/Alhadis/Snippets/blob/master/js/polyfills/IE8-child-elements.js
-if (!('nextElementSibling' in document.documentElement)) {
-    Object.defineProperty(Element.prototype, 'nextElementSibling', {
-        get: function() {
-            var e = this.nextSibling;
-            while (e && 1 !== e.nodeType) {
-                e = e.nextSibling;
-            }
-            return e;
-        }
-    });
-}
- -

Полифилл для IE9+ и Safari

- -
// Источник: https://github.com/jserz/js_piece/blob/master/DOM/NonDocumentTypeChildNode/nextElementSibling/nextElementSibling.md
-(function(arr) {
-    arr.forEach(function(item) {
-        if (item.hasOwnProperty('nextElementSibling')) {
-            return;
-        }
-        Object.defineProperty(item, 'nextElementSibling', {
-            configurable: true,
-            enumerable: true,
-            get: function() {
-                var el = this;
-                while (el = el.nextSibling) {
-                    if (el.nodeType === 1) {
-                        return el;
-                    }
-                }
-                return null;
-            },
-            set: undefined
-        });
-    });
-})([Element.prototype, CharacterData.prototype]);
- -

Спецификации

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('DOM WHATWG', '#dom-nondocumenttypechildnode-nextelementsibling', 'ChildNodenextElementSibling')}}{{Spec2('DOM WHATWG')}}Split the ElementTraversal interface in {{domxref("ChildNode")}}, {{domxref("ParentNode")}}, and {{domxref("NonDocumentTypeChildNode")}}. This method is now defined on the former.
- The {{domxref("Element")}} and {{domxref("CharacterData")}} interfaces implemented the new interface.
{{SpecName('Element Traversal', '#attribute-nextElementSibling', 'ElementTraversal.nextElementSibling')}}{{Spec2('Element Traversal')}}Added its initial definition to the ElementTraversal pure interface and use it on {{domxref("Element")}}.
- -

Совместимость с браузерами

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
БраузерыChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка ({{domxref("Element")}})4{{CompatGeckoDesktop("1.9.1")}}99.84
Поддержка {{domxref("CharacterData")}}29.0{{CompatGeckoDesktop("25")}} [1]{{CompatNo}}16.0{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
БраузерыAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка ( {{domxref("Element")}}){{CompatVersionUnknown}}{{CompatGeckoMobile("1.9.1")}}{{CompatVersionUnknown}}9.8{{CompatVersionUnknown}}
Поддержка {{domxref("CharacterData")}}{{CompatVersionUnknown}}{{CompatGeckoMobile("25")}}{{CompatNo}}16.0{{CompatNo}}
-
- -

[1] Firefox 25 также добавил это свойство в {{domxref("DocumentType")}}, но оно было удалено в Firefox 28, из-за проблем совместимости.

- -

См. также

- -
    -
  • Чистый интерфейс {{domxref("ChildNode")}}.
  • -
  • Типы объектов, реализующих этот чистый интерфейс: {{domxref("CharacterData")}}, {{domxref("Element")}}, и {{domxref("DocumentType")}}. 
  • -
diff --git a/files/ru/web/api/notation/index.html b/files/ru/web/api/notation/index.html new file mode 100644 index 0000000000..a1f468a55d --- /dev/null +++ b/files/ru/web/api/notation/index.html @@ -0,0 +1,52 @@ +--- +title: Нотация +slug: Web/API/Нотация +tags: + - Нотация +translation_of: Web/API/Notation +--- +
{{APIRef("DOM")}}{{draft}}{{obsolete_header}}
+ +

Представляет нотацию DTD (только для чтения). Может объявлять формат неразобранного объекта или формально объявлять цели инструкции по обработке документа. Наследует методы и свойства от Node. Его nodeName - это имя нотации. Не имеет родителя.

+ +

Свойства

+ +
+
{{domxref("Notation.publicId")}} {{ReadOnlyInline}}
+
Это {{domxref("DOMString")}}.
+
{{domxref("Notation.systemId")}} {{ReadOnlyInline}}
+
Это {{domxref("DOMString")}}.
+
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарии
{{SpecName("DOM3 Core", "core.html#ID-5431D1B9", "Notation")}}{{Spec2("DOM3 Core")}}Без изменений
{{SpecName("DOM2 Core", "core.html#ID-5431D1B9", "Notation")}}{{Spec2("DOM2 Core")}}Без изменений
{{SpecName('DOM1', 'level-one-core.html#ID-5431D1B9', 'Notation')}}{{Spec2('DOM1')}}Первое определение
+ +

Поддержка браузерами

+ + + +

{{Compat("api.Notation")}}

diff --git a/files/ru/web/api/page_visibility_api/index.html b/files/ru/web/api/page_visibility_api/index.html new file mode 100644 index 0000000000..9b181e92d1 --- /dev/null +++ b/files/ru/web/api/page_visibility_api/index.html @@ -0,0 +1,195 @@ +--- +title: Видимость страницы API +slug: Web/API/Видимость_страницы_API +tags: + - API + - DOM + - Документ + - Показать страницу + - Скрыть страницу +translation_of: Web/API/Page_Visibility_API +--- +
{{DefaultAPISidebar("Page Visibility API")}}
+ +

При переключении между вкладками, web страница переходит в фоновый режим и поэтому не видна пользователю. Page Visibility API предоставляет события, которые вы можете отслеживать, чтобы узнать, когда страница станет видимой или скрытой, а так же возможность наблюдать текущее состояние видимости страницы.

+ +
+

Notes: The Page Visibility API особенно полезно для сбережения ресурсов и улучшения производительности, позволяя странице остановить выполнение не нужных задач, когда она не видна.

+
+ +

Когда пользователь сворачивает окно или переключается на другую вкладку, API отправляет {{event("visibilitychange")}} событие обработчикам, что состояние страницы изменилось. Вы можете отследить это событие и выполнить какие-то действия. Например, если ваше app проигрывает видео, его можно поставить на паузу, когда пользователь переключил вкладку (страница ушла в фон), а затем возобновить видео, когда пользователь вернулся на вкладку. Пользователь не теряет место на котором остановил просмотр, звук от видео не конфликтует с аудио новой вкладки, пользователь комфортно просмотрить оба видео.

+ +

Состояния видимости для {{HTMLElement("iframe")}} такие же как и для родительской страницы. Скрытие <iframe> используя CSS стили (такие как {{cssxref("display", "display: none;")}}) не вызывают события видимости и не изменяют состояние документа, содержащегося во фрейме.

+ +

Использование

+ +

Давайте рассмотрим несколько способов использования Page Visibility API.

+ +
    +
  • На сайте есть слайдер изображений с автопрокрутрой, которую можно поставить на паузу, когда пользователь перешел на другую вкладку
  • +
  • Приложение выводит информацию в реальном времени, которую можно не обновлять, пока страница не видна, тем самым уменьшить количество запросов на сервер
  • +
  • Странице нужно понять, когда она должна быть отрисована, так что можно вести точный подсчет количества просмотров
  • +
  • Сайту нужно выключить звук, когда устройство в режиме ожидания (пользователь нажал кнопку включения, чтобы погасить экран)
  • +
+ +

Раньше у разработчиков были не удобные способы. Например, обработка {{event("blur")}} и {{event("focus")}} событий на объекте window - помогала узнать когда страница становилась не активной, но это не давало возможность понять когда страница действительно скрыта от пользователя. Page Visibility API решает эту проблему.

+ +
+

Note: Когда {{domxref("GlobalEventHandlers.onblur", "onblur")}} и {{domxref("GlobalEventHandlers.onfocus", "onfocus")}} уведомляют, что пользователь переключил окна, это не означает, что оно действительно скрыто. Страница действительно скрыта, когда пользователь переключил вкладки или свернул окно браузера с этой вкладкой.

+
+ +

Policies in place to aid background page performance

+ +

Separately from the Page Visibility API, user agents typically have a number of policies in place to mitigate the performance impact of background or hidden tabs. These may include:

+ +
    +
  • Most browsers stop sending {{domxref("Window.requestAnimationFrame", "requestAnimationFrame()")}} callbacks to background tabs or hidden {{ HTMLElement("iframe") }}s in order to improve performance and battery life.
  • +
  • Timers such as {{domxref("WindowOrWorkerGlobalScope.setTimeout", "setTimeout()")}} are throttled in background/inactive tabs to help improve performance. See Reasons for delays longer than specified for more details.
  • +
  • Budget-based background timeout throttling is now available in modern browsers (Firefox 58+, Chrome 57+), placing an additional limit on background timer CPU usage. This operates in a similar way across modern browsers, with the details being as follows: +
      +
    • In Firefox, windows in background tabs each have their own time budget in milliseconds — a max and a min value of +50 ms and -150 ms, respectively. Chrome is very similar except that the budget is specified in seconds.
    • +
    • Windows are subjected to throttling after 30 seconds, with the same throttling delay rules as specified for window timers (again, see Reasons for delays longer than specified). In Chrome, this value is 10 seconds.
    • +
    • Timer tasks are only permitted when the budget is non-negative.
    • +
    • Once a timer's code has finished running, the duration of time it took to execute is subtracted from its window's timeout budget.
    • +
    • The budget regenerates at a rate of 10 ms per second, in both Firefox and Chrome.
    • +
    +
  • +
+ +

Some processes are exempt from this throttling behavior. In these cases, you can use the Page Visibility API to reduce the tabs' performance impact while they're hidden.

+ +
    +
  • Tabs which are playing audio are considered foreground and aren’t throttled.
  • +
  • Tabs running code that's using real-time network connections (WebSockets and WebRTC) go unthrottled in order to avoid closing these connections timing out and getting unexpectedly closed.
  • +
  • IndexedDB processes are also left unthrottled in order to avoid timeouts.
  • +
+ +

Example

+ +

View live example (video with sound).

+ +

The example, which pauses the video when you switch to another tab and plays again when you return to its tab, was created with the following code:

+ +
// Set the name of the hidden property and the change event for visibility
+var hidden, visibilityChange;
+if (typeof document.hidden !== "undefined") { // Opera 12.10 and Firefox 18 and later support
+  hidden = "hidden";
+  visibilityChange = "visibilitychange";
+} else if (typeof document.msHidden !== "undefined") {
+  hidden = "msHidden";
+  visibilityChange = "msvisibilitychange";
+} else if (typeof document.webkitHidden !== "undefined") {
+  hidden = "webkitHidden";
+  visibilityChange = "webkitvisibilitychange";
+}
+
+var videoElement = document.getElementById("videoElement");
+
+// If the page is hidden, pause the video;
+// if the page is shown, play the video
+function handleVisibilityChange() {
+  if (document[hidden]) {
+    videoElement.pause();
+  } else {
+    videoElement.play();
+  }
+}
+
+// Warn if the browser doesn't support addEventListener or the Page Visibility API
+if (typeof document.addEventListener === "undefined" || hidden === undefined) {
+  console.log("This demo requires a browser, such as Google Chrome or Firefox, that supports the Page Visibility API.");
+} else {
+  // Handle page visibility change
+  document.addEventListener(visibilityChange, handleVisibilityChange, false);
+
+  // When the video pauses, set the title.
+  // This shows the paused
+  videoElement.addEventListener("pause", function(){
+    document.title = 'Paused';
+  }, false);
+
+  // When the video plays, set the title.
+  videoElement.addEventListener("play", function(){
+    document.title = 'Playing';
+  }, false);
+
+}
+
+ +

Properties added to the Document interface

+ +

The Page Visibility API adds the following properties to the {{domxref("Document")}} interface:

+ +
+
{{domxref("Document.hidden")}} {{ReadOnlyInline}}
+
Returns true if the page is in a state considered to be hidden to the user, and false otherwise.
+
{{domxref("Document.visibilityState")}} {{ReadOnlyInline}}
+
A {{domxref("DOMString")}} indicating the document's current visibility state. Possible values are: +
+
visible
+
The page content may be at least partially visible. In practice this means that the page is the foreground tab of a non-minimized window.
+
hidden
+
The page's content is not visible to the user, either due to the document's tab being in the background or part of a window that is minimized, or because the device's screen is off.
+
prerender
+
The page's content is being prerendered and is not visible to the user. A document may start in the prerender state, but will never switch to this state from any other state, since a document can only prerender once. +
Note: Not all browsers support prerendering.
+
+
unloaded
+
The page is in the process of being unloaded from memory. +
Note: Not all browsers support the unloaded value.
+
+
+
+
{{domxref("Document.onvisibilitychange")}}
+
An {{domxref("EventListener")}} providing the code to be called when the {{event("visibilitychange")}} event is fired.
+
+ +
//startSimulation and pauseSimulation defined elsewhere
+function handleVisibilityChange() {
+  if (document.hidden) {
+    pauseSimulation();
+  } else  {
+    startSimulation();
+  }
+}
+
+document.addEventListener("visibilitychange", handleVisibilityChange, false);
+
+ +

Specifications

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Page Visibility API')}}{{Spec2('Page Visibility API')}}Initial definition.
+ +

Browser compatibility

+ +
+

Document.visibilityState

+ +
+ + +

{{Compat("api.Document.visibilityState")}}

+
+
+ +

See also

+ + diff --git a/files/ru/web/api/push_api/using_the_push_api/index.html b/files/ru/web/api/push_api/using_the_push_api/index.html deleted file mode 100644 index 40086e4e91..0000000000 --- a/files/ru/web/api/push_api/using_the_push_api/index.html +++ /dev/null @@ -1,420 +0,0 @@ ---- -title: Использование Push API -slug: Web/API/Push_API/Using_the_Push_API -translation_of: Web/API/Push_API -translation_of_original: Web/API/Push_API/Using_the_Push_API ---- -

W3C Push API предоставляет некоторый захватывающий новый функционал для разработчиков для использования в web-приложениях: эта статья предлагает вводную информацию о том, как настроить Push-уведомления и управлять ими, с помощью простого демо.

- -

Возможность посылать сообщения или уведомления от сервера клиенту в любое время — независимо от того, активно приложение или нет — было прерогативой нативных приложений некоторое время, и наконец пришло в Web! Поддерживается большинства возможностей Push сейчас возможна в браузерах Firefox 43+ и Chrome 42+ на настольных компьютерах, мобильные платформы, возможно, скоро присоединятся. {{domxref("PushMessageData")}} на данный момент экспериментально поддерживаются только в Firefox Nightly (44+), и реализация может меняться.

- -
-

Примечание: Ранние версии Firefox OS использовали проприетарную версию этого API вызывая Simple Push. Считается устаревшим по стандартам Push API.

-
- -

Демо: основы простого сервера чат-приложения

- -

Демо, котрые мы создали, представляет начальное описание простого чат-приложения. Оно представляет собой форму, в которую вводятся данные, и кнопку для подписки на push-сообщения . Как только кнопка будет нажата, вы подпишитесь на push-сообщения, ваши данные будут записаны на сервере, а отправленное push-сообщение сообщит всем текущим подписчикам, что кто-то подписался.

- -

На данном этапе, имя нового подписчика появится в списке подписчиков, вместе с текстовым полем и кнопкой рассылки, чтобы позволить подписчику отправить сообщение.

- -

- -

Чтобы запустить демо, следуйте инструкциям на странице push-api-demo README. Заметте, что серверная компонента все еще нуждается в небольшой доработке для запуска в Chrome и в общем запусается более разумным путем. Но аспекты Push все еще могут быть полностью понятны; мы углубимся в это после того, как просмотрим технологии в процессе.

- -

Обзор технологии

- -

Эта секция предоставляет описание того, какие технологии учавствуют в примере.

- -

Web Push-сообщения это часть семейства технологий сервис воркеров; в первую очередь, для получения push-сообщений сервис воркер должен быть активирован на странице. Сервис воркер получает push-сообщения, и затем вы сами решаете, как уведомить об этом страницу. Вы можете:

- -
    -
  • Отправить Web-уведомление, которое вызовет всплытие системного уведомления. Для этого необходимо подтверждение разрешения на отправку push-сообщений.
  • -
  • Отправить сообщение обратно главной странице через {{domxref("MessageChannel")}}.
  • -
- -

Обычно необходима комбинация этих двух решений; демо внизу включает пример обоих.

- -
-

Примечание: Вам необходим некоторый код, запущенный на сервере, для управления конечной точкой/шифроманием данных и отправки запросов push-сообщений. В нашем демо мы собрали на скорую руку сервер, используя NodeJS.

-
- -

Сервис воркер так же должен подписаться на сервис push-сообщений. Каждой сессии предоставляется собственная уникальная конечная точка, когда она подписывается на сервис push-сообщений. Эта конечная точка получается из свойства  ({{domxref("PushSubscription.endpoint")}}) объекта подписчика. Она может быть отправлена серверу и использоваться для пересылки сообщений активному сервис воркеру сессии. Каждый браузер имеет свой собсвтенный сервер push-сообщений для  управления отправкой push-сообщений.

- -

Шифрование

- -
-

Примечание: Для интерактивного краткого обзора, попробуйте JR Conlin's Web Push Data Encryption Test Page.

-
- -

Для отправки данных с помошью push-сообщений необходимо шифрование. Для этого необходим публичный ключ, созданный с использованием метода  {{domxref("PushSubscription.getKey()")}}, который основывается на некотором комплексе механизмов шифрования, которые выполняются на стороне сервера; читайте Message Encryption for Web Push. Со временем появятся библиотеки для управления генерацией ключей и шифроманием/дешифрованием push-сообщений; для этого демо мы используем Marco Castelluccio's NodeJS web-push library.

- -
-

Примечание: Есть так же другая библиотека для управления шифрованием с помошью Node и Python, смотри encrypted-content-encoding.

-
- -

Обобщение рабочего процесса Push

- -

Общие сведения ниже это то, что необходимо для реализации push-сообщений. Вы можете найти больше информации о некоторых частях демо в последующих частях.

- -
    -
  1. Запрос на разрешение web-уведомлений или что-то другое, что вы используете и для чего необходимо разрешение.
  2. -
  3. Регистрация сервис воркера для контроля над страницей с помошью вызова {{domxref("ServiceWorkerContainer.register()")}}.
  4. -
  5. Подписка на сервис push-уведомлений с помошью {{domxref("PushManager.subscribe()")}}.
  6. -
  7. Запрашивание конечной точки, соответствующей подписчику, и генерация публичного ключа клиента ({{domxref("PushSubscription.endpoint")}} и {{domxref("PushSubscription.getKey()")}}. Заметте, что getKey() на данный момент эксперементальная технологий и доступна только в Firefox.)
  8. -
  9. Отправка данных на сервер, чтобы тот мог присылать push-сообщения, когда необходимо. Это демо использует {{domxref("XMLHttpRequest")}}, но вы можете использовать Fetch.
  10. -
  11. Если вы используете Channel Messaging API для связи с сервис воркером, установите новый канал связи ({{domxref("MessageChannel.MessageChannel()")}}) и отправте port2 сервис воркеру с помошью вызова {{domxref("Worker.postMessage()")}} для того, чтобы открыть канал связи. Вы так же должны настроить слушателя для ответов на сообщения, которые будут отправляться обратно с сервис воркера.
  12. -
  13. На стороне сервера сохраните конечную точку и все остальные необходимые данные, чтобы они были доступны, когда будет необходимо отправить push-сообщение добавленному подписчику (мы используем простой текстовый файл, но вы можете использовать базу данных или все что угодно на ваш вкус). В приложении на продакшене убедитесь, что скрываете эти данные, так что злоумышленники не смогут украсть конечную точку и разослать спам подписчикам в push-сообщениях.
  14. -
  15. Для отправки push-сообщений необходимо отослать HTTP POST конечному URL. Запрос должен включать TTL заголовок, который ограничивает время пребывания сообщения в очереди, если пользователь не в сети. Для добавления полезной информации в запросе, необходимо зашифровать ее (что включает публичнй ключ клиента). В нашем примере мы используем web-push модуль, который управляет всей тяжелой работой.
  16. -
  17. Поверх в сервис воркере настройте обработчик событий push для ответов на полученные push-сообщения. -
      -
    1. Если вы хотите отвечать отправкой сообщения канала обратно основному контексту (смотри шаг 6), необходимо сначала получить ссылку на port2, который был отправлен контексту сервис воркера ({{domxref("MessagePort")}}). Это доступно в объекте  {{domxref("MessageEvent")}}, передаваемого обработчику onmessage ({{domxref("ServiceWorkerGlobalScope.onmessage")}}). Конкретнее, он находится в свойстве ports, индекс 0. Когда это сделано, вы можете отправить сообщение обратно port1, используя {{domxref("MessagePort.postMessage()")}}.
    2. -
    3. Если вы хотитет ответить запуском системного уведомления, вы можете сделать это, вызвав {{domxref("ServiceWorkerRegistration.showNotification()")}}. Заметте, что в нашем коде мы вызываем его внутри метода {{domxref("ExtendableEvent.waitUntil()")}} — это растягивает время жизни события, пока уведомление не будет запущено, так что мы можем убедиться, что все, что мы хотели, чтобы произошло, действительно произошло.
    4. -
    -
  18. -
- -

Сборка демо

- -

Давайте пройдемся по коду для демо, чтобы понять, как все работает.

- -

HTML и CSS

- -

Нет ничего примечательного в HTML и CSS демо; HTML содержит простую форму для ввода данных для фхода в чат, кнопку для подписки на push-уведомления и двух списков, в которых перечислены подписчики и сообщения чата. После подписки появляются дополнительные средства для того, чтобы пользователь мог ввести сообщение в чат.

- -

CSS был оставлен очень минимальным, чтобы не отвлекать от объяснения того, как функционируют Push API.

- -

Основной файл JavaScript

- -

 JavaScript очевидно намного более существенный. Давайте взглянем на основной файл JavaScript.

- -

Переменные и начальные настройки

- -

Для начала определим некоторые переменные, которые будем использовать в нашем приложении:

- -
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';
- -

Сначала нам необходимо создать две булевы переменные, для того чтобы отслеживать подписку на push-сообщения и подтверждение разрешения на рассылку уведомлений.

- -

Далее, мы перехватываем ссылку на {{htmlelement("button")}} подписки/отписки и задаем переменные для сохранения ссылок на наши кнопку отправки сообщения/ввода (который создастся только после успешной подписки).
-
- Следующие переменные перехватывают ссылки на три основные {{htmlelement("div")}} элемента, так что мы можем включить в них элементы (к примеру, когда появится кнопка Отправки Сообщения Чата или сообщение появится с писке Сообщений).

- -

Finally we grab references to our name selection form and {{htmlelement("input")}} element, give the input a default value, and use preventDefault() to stop the form submitting when the form is submitted by pressing return.

- -

Next, we request permission to send web notifications, using {{domxref("Notification.requestPermission","requestPermission()")}}:

- -
Notification.requestPermission();
- -

Now we run a section of code when onload is fired, to start up the process of inialising the app when it is first loaded. First of all we add a click event listener to the subscribe/unsubscribe button that runs our unsubscribe() function if we are already subscribed (isPushEnabled is true), and subscribe() otherwise:

- -
window.addEventListener('load', function() {
-  subBtn.addEventListener('click', function() {
-    if (isPushEnabled) {
-      unsubscribe();
-    } else {
-      subscribe();
-    }
-  });
- -

Next we check to see if service workers are supported. If so, we register a service worker using {{domxref("ServiceWorkerContainer.register()")}}, and run our initialiseState() function. If not, we deliver an error message to the console.

- -
  // 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.');
-  }
-});
-
- -

The next thing in the source code is the initialiseState() function — for the full commented code, look at the initialiseState() source on Github (we are not repeating it here for brevity's sake.)

- -

initialiseState() first checks whether notifications are supported on service workers, then sets the useNotifications variable to true if so. Next, it checks whether said notifications are permitted by the user, and if push messages are supported, and reacts accordingly to each.

- -

Finally, it uses {{domxref("ServiceWorkerContainer.ready()")}} to wait until the service worker is active and ready to start doing things. Once its promise resolves, we retrieve our subscription to push messaging using the {{domxref("ServiceWorkerRegistration.pushManager")}} property, which returns a {{domxref("PushManager")}} object that we then call {{domxref("PushManager.getSubscription()")}} on. Once this second inner promise resolves, we enable the subscribe/unsubscribe button (subBtn.disabled = false;), and check that we have a subscription object to work with.

- -

If we do, then we are already subscribed. This is possible when the app is not open in the browser; the service worker can still be active in the background. If we're subscribed, we update the UI to show that we are subscribed by updating the button label, then we set isPushEnabled to true, grab the subscription endpoint from {{domxref("PushSubscription.endpoint")}}, generate a public key using {{domxref("PushSubscription.getKey()")}}, and run our updateStatus() function, which as you'll see later communicates with the server.

- -

As an added bonus, we set up a new {{domxref("MessageChannel")}} using the {{domxref("MessageChannel.MessageChannel()")}} constructor, grab a reference to the active service worker using {{domxref("ServiceworkerRegistration.active")}}, then set up a channel betweeen the main browser context and the service worker context using {{domxref("Worker.postMessage()")}}. The browser context receives messages on {{domxref("MessageChannel.port1")}}; whenever that happens, we run the handleChannelMessage() function to decide what to do with that data (see the {{anch("Handling channel messages sent from the service worker")}} section).

- -

Subscribing and unsubscribing

- -

Let's now turn our attention to the subscribe() and unsubscribe() functions used to subscribe/unsubscribe to the push notification service.

- -

In the case of subscription, we again check that our service worker is active and ready by calling {{domxref("ServiceWorkerContainer.ready()")}}. When the promise resolves, we subscribe to the service using {{domxref("PushManager.subscribe()")}}. If the subscription is successful, we get a {{domxref("PushSubscription")}} object, extract the subscription endpoint from this and generate a public key (again, {{domxref("PushSubscription.endpoint")}} and {{domxref("PushSubscription.getKey()")}}), and pass them to our updateStatus() function along with the update type (subscribe) to send the necessary details to the server.

- -

We also make the necessary updates to the app state (set isPushEnabled to true) and UI (enable the subscribe/unsubscribe button and set its label text to show that the next time it is pressed it will unsubscribe.)

- -

The unsubscribe() function is pretty similar in structure, but it basically does the opposite; the most notable difference is that it gets the current subscription using {{domxref("PushManager.getSubscription()")}}, and when that promise resolves it unsubscribes using {{domxref("PushSubscription.unsubscribe()")}}.

- -

Appropriate error handling is also provided in both functions.  

- -

We only show the subscribe() code below, for brevity; see the full subscribe/unsubscribe code on Github.

- -
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';
-        }
-      });
-  });
-}
- -

Updating the status in the app and server

- -

The next function in our main JavaScript is updateStatus(), which updates the UI for sending chat messages when subscribing/unsubscribing and sends a request to update this information on the server.

- -

The function does one of three different things, depending on the value of the statusType parameter passed into it:

- -
    -
  • subscribe: The button and text input for sending chat messages are created and inserted into the UI, and an object is sent to the server via XHR containing the status type (subscribe), username of the subscriber, subscription endpoint, and client public key.
  • -
  • unsubscribe: This basically works in the opposite way to subscribe — the chat UI elements are removed, and an object is sent to the server to tell it that the user has unsubscribed.
  • -
  • init: This is run when the app is first loaded/initialised — it creates the chat UI elements, and sends an object to the server to tell it that which user has reinitialised (reloaded.)
  • -
- -

Again, we have not included the entire function listing for brevity. Examine the full updateStatus() code on Github.

- -

Handling channel messages sent from the service worker

- -

As mentioned earlier, when a channel message is received from the service worker, our handleChannelMessage() function is called to handle it. This is done by our handler for the {{event("message")}} event, {{domxref("channel.port1.onmessage")}}:

- -
channel.port1.onmessage = function(e) {
-  handleChannelMessage(e.data);
-}
- -

This occurs when the service worker sends a channel message over.

- -

The handleChannelMessage() function looks like this:

- -
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 = '';
-  }
-}
- -

What happens here depends on what the action property on the data object is set to:

- -
    -
  • subscribe or init (at both startup and restart, we need to do the same thing in this sample): An {{htmlelement("li")}} element is created, its text content is set to data.name (the name of the subscriber), and it is appended to the subscribers list (a simple {{htmlelement("ul")}} element) so there is visual feedback that a subscriber has (re)joined the chat.
  • -
  • unsubscribe: We loop through the children of the subscribers list, find the one whose text content is equal to data.name (the name of the unsubscriber), and delete that node to provide visual feedback that someone has unsubscribed.
  • -
  • chatMsg: In a similar manner to the first case, an {{htmlelement("li")}} element is created, its text content is set to data.name + ": " + data.msg (so for example "Chris: This is my message"), and it is appended to the chat messages list; this is how the chat messages appear on the UI for each user.
  • -
- -
-

Note: We have to pass the data back to the main context before we do DOM updates because service workers don't have access to the DOM. You should be aware of the limitations of service workers before attemping to ue them. Read Using Service Workers for more details.

-
- -

Sending chat messages

- -

When the Send Chat Message button is clicked, the content of the associated text field is sent as a chat message. This is handled by the sendChatMessage() function (again, not shown in full for brevity). This works in a similar way to the different parts of the updateStatus() function (see {{anch("Updating the status in the app and server")}}) — we retrieve an endpoint and public key via a {{domxref("PushSubscription")}} object, which is itself retrieved via {{domxref("ServiceWorkerContainer.ready()")}} and {{domxref("PushManager.subscribe()")}}. These are sent to the server via {{domxref("XMLHttpRequest")}} in a message object, along with the name of the subscribed user, the chat message to send, and a statusType of chatMsg.

- -

The server

- -

As mentioned above, we need a server-side component in our app, to handle storing subscription details, and send out push messages when updates occur. We've hacked together a quick-and-dirty server using NodeJS (server.js), which handles the XHR requests sent by our client-side JavaScript code.

- -

It uses a text file (endpoint.txt) to store subscription details; this file starts out empty. There are four different types of request, marked by the statusType property of the object sent over in the request; these are the same as those understood client-side, and perform the required server actions for that same situation. Here's what each means in the context of the server:

- -
    -
  • subscribe: The server adds the new subscriber's details into the subscription data store (endpoint.txt), including the endpoint, and then sends a push message to all the endpoints it has stored to tell each subscriber that someone new has joined the chat.
  • -
  • unsubscribe: The server finds the sending subscriber's details in the subscription store and removes it, then sends a push message to all remaining subscribers telling them the user has unsubscribed.
  • -
  • init: The server reads all the current subscribers from the text file, and sends each one a push message to tell them a user has initialized (rejoined) the chat.
  • -
  • chatMsg: Sent by a subscriber that wishes to deliver a message to all users; the server reads the list of all current subscribers from the subscription store file, then sends each one a push message containing the new chat message they should display.
  • -
- -

A couple more things to note:

- -
    -
  • We are using the Node.js https module to create the server, because for security purposes, service workers only work on a secure connection. This is why we need to include the .pfx security cert in the app, and reference it when creating the server in the Node code.
  • -
  • When you send a push message without data, you simply send it to the endpoint URL using an HTTP POST request. However, when the push message contains data, you need to encrypt it, which is quite a complex process. As time goes on, libraries will appear to do this kind of thing for you; for this demo we used Marco Castelluccio's NodeJS web-push library. Have a look at the source code to get more of an idea of how the encryption is done (and read Message Encryption for Web Push for more details.) The library makes sending a push message simple.
  • -
- -

The service worker

- -

Now let's have a look at the service worker code (sw.js), which responds to the push messages, represented by {{Event("push")}} events. These are handled on the service worker's scope by the ({{domxref("ServiceWorkerGlobalScope.onpush")}}) event handler; its job is to work out what to do in response to each received message. We first convert the received message back into an object by calling {{domxref("PushMessageData.json()")}}. Next, we check what type of push message it is, by looking at the object's action property:

- -
    -
  • subscribe or unsubscribe: We send a system notification via the fireNotification() function, but also send a message back to the main context on our {{domxref("MessageChannel")}} so we can update the subscriber list accordingly (see {{anch("Handling channel messages sent from the service worker")}} for more details).
  • -
  • init or chatMsg: We just send a channel message back to the main context to handle the init and chatMsg cases (these don't need a system notification).
  • -
- -
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);
-  }
-});
- -

Next, let's look at the fireNotification() function (which is blissfully pretty simple).

- -
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
-  }));
-}
- -

Here we assemble the assets needed by the notification box: the title, body, and icon. Then we send a notification via the {{domxref("ServiceWorkerRegistration.showNotification()")}} method, providing that information as well as the tag "push", which we can use to identify this notification among any other notifications we might be using. When the notification is successfully sent, it manifests as a system notification dialog on the users computers/devices in whatever style system notifications look like on those systems (the following image shows a Mac OSX system notification.)

- -

- -

Note that we do this from inside an {{domxref("ExtendableEvent.waitUntil()")}} method; this is to make sure the service worker remains active until the notification has been sent. waitUntil() will extend the life cycle of the service worker until everything inside this method has completed.

- -
-

Note: Web notifications from service workers were introduced around Firefox version 42, but are likely to be removed again while the surrounding functionality (such as Clients.openWindow()) is properly implemented (see {{bug(1203324)}} for more details.)

-
- -

Handling premature subscription expiration

- -

Sometimes push subscriptions expire prematurely, without {{domxref("PushSubscription.unsubscribe()")}} being called. This can happen when the server gets overloaded, or if you are offline for a long time, for example.  This is highly server-dependent, so the exact behavior is difficult to predict. In any case, you can handle this problem by watching for the {{Event("pushsubscriptionchange")}} event, which you can listen for by providing a {{domxref("ServiceWorkerGlobalScope.onpushsubscriptionchange")}} event handler; this event is fired only in this specific case.

- -
self.addEventListener('pushsubscriptionchange', function() {
-  // do something, usually resubscribe to push and
-  // send the new subscription details back to the
-  // server via XHR or Fetch
-});
- -

Note that we don't cover this case in our demo, as a subscription ending is not a big deal for a simple chat server. But for a more complex example you'd probably want to resubscribe the user.

- -

Extra steps for Chrome support

- -

To get the app working on Chrome, we need a few extra steps, as Chrome currently relies on Google's Cloud Messaging service to work.

- -

Setting up Google Cloud Messaging

- -

To get this set up, follow these steps:

- -
    -
  1. Navigate to the Google Developers Console  and set up a new project.
  2. -
  3. Go to your project's homepage (ours is at https://console.developers.google.com/project/push-project-978, for example), then -
      -
    1. Select the Enable Google APIs for use in your apps option.
    2. -
    3. In the next screen, click Cloud Messaging for Android under the Mobile APIs section.
    4. -
    5. Click the Enable API button.
    6. -
    -
  4. -
  5. Now you need to make a note of your project number and API key because you'll need them later. To find them: -
      -
    1. Project number: click Home on the left; the project number is clearly marked at the top of your project's home page.
    2. -
    3. API key: click Credentials on the left hand menu; the API key can be found on that screen.
    4. -
    -
  6. -
- -

manifest.json

- -

You need to include a Google app-style manifest.json file in your app, which references the project number you made a note of earlier in the gcm_sender_id parameter. Here is our simple example manifest.json:

- -
{
-  "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"
-}
- -

You also need to reference your manifest using a {{HTMLElement("link")}} element in your HTML:

- -
<link rel="manifest" href="manifest.json">
- -

userVisibleOnly

- -

Chrome requires you to set the userVisibleOnly parameter to true when subscribing to the push service, which indicates that we are promising to show a notification whenever a push is received. This can be seen in action in our subscribe() function.

- -

See also

- - - -
-

Note: Some of the client-side code in our Push demo is heavily influenced by Matt Gaunt's excellent examples in Push Notifications on the Open Web. Thanks for the awesome work, Matt!

-
diff --git a/files/ru/web/api/randomsource/getrandomvalues/index.html b/files/ru/web/api/randomsource/getrandomvalues/index.html deleted file mode 100644 index c59f5dde54..0000000000 --- a/files/ru/web/api/randomsource/getrandomvalues/index.html +++ /dev/null @@ -1,73 +0,0 @@ ---- -title: RandomSource.getRandomValues() -slug: Web/API/RandomSource/getRandomValues -tags: - - АПИ - - Криптография - - Справка - - метод -translation_of: Web/API/Crypto/getRandomValues ---- -

{{APIRef("Web Crypto API")}}

- -

Метод RandomSource.getRandomValues() позволяет вам получать криптографически стойкие числа. Массив, переданный как параметр, заполняется случайными числами (случайными в криптографическом смысле).

- -

Для того, чтобы гарантировать достаточную производительность, реализации используют не настоящий генератор случайных чисел (RNG, en - Random Number Generator), а генератор псевдо-случайных чисел, которому предоставлено начальное зерно (wiki - https://en.wikipedia.org/wiki/Random_seed) с достаточной энтропией (http://cryptography.ru/ref/энтропия). Реализация генератора псевдо-случайных чисел (PRNG, en - PseudoRandom Number Generator) отличается от других реализаций RNG, но она больше подходит для использования в криптографии. Реализации также требуют использование начального зерна с достаточной энтропией, как источник системно-уровневой энтропии.

- -

Синтаксис

- -
cryptoObj.getRandomValues(typedArray);
- -

Параметры

- -
-
typedArray
-
Целочисленный массив {{jsxref("TypedArray")}}, например {{jsxref("Int8Array")}}, {{jsxref("Uint8Array")}}, {{jsxref("Uint16Array")}}, {{jsxref("Int32Array")}}, или {{jsxref("Uint32Array")}}. Все элементы массива замещаются случайными числами.
-
- -

Исключения

- -
    -
  • Исключение {{exception("QuotaExceededError")}} {{domxref("DOMException")}} выбрасывается если запрошенная длина больше чем 65536 байт.
  • -
- -

Пример

- -
/* Предполагается что функция window.crypto.getRandomValues доступна */
-
-var array = new Uint32Array(10);
-window.crypto.getRandomValues(array);
-
-console.log("Ваше счастливое число:");
-for (var i = 0; i < array.length; i++) {
-    console.log(array[i]);
-}
-
- -

Спецификация

- - - - - - - - - - - - - - -
СпецификацияСтатусКомментарий
{{SpecName('Web Crypto API', '#RandomSource-method-getRandomValues')}}{{Spec2('Web Crypto API')}}Изначальное определение
- -

Совместимость с браузерами

- -

{{Compat("api.Crypto.getRandomValues")}}

- -

Смотрите также

- -
    -
  • {{ domxref("Window.crypto") }} чтобы получить объект {{domxref("Crypto")}}.
  • -
  • {{jsxref("Math.random")}}, не криптографический способ получения случайных чисел.
  • -
diff --git a/files/ru/web/api/randomsource/index.html b/files/ru/web/api/randomsource/index.html deleted file mode 100644 index d56506a90a..0000000000 --- a/files/ru/web/api/randomsource/index.html +++ /dev/null @@ -1,111 +0,0 @@ ---- -title: RandomSource -slug: Web/API/RandomSource -tags: - - API - - Interface - - NeedsTranslation - - RandomSource - - Reference - - TopicStub - - Web Crypto API -translation_of: Web/API/Crypto/getRandomValues -translation_of_original: Web/API/RandomSource ---- -

{{APIRef("Web Crypto API")}}

- -

RandomSource представляет собой источник криптографически безопасных случайных чисел. Он доступен через {{domxref("Crypto")}} объект глобального объекта: {{domxref("Window.crypto")}} на веб страницах, {{domxref("WorkerGlobalScope.crypto")}} для воркеров.

- -

RandomSource не является интерфейсом и объект этого типа не может быть создан.

- -

Свойства

- -

RandomSource не объявляет и не наследует никаких свойств.

- -
-
- -

Методы

- -
-
{{ domxref("RandomSource.getRandomValues()") }}
-
Наполняет {{ domxref("ArrayBufferView") }} криптографически безопасными случайными числовыми значениями.
-
- -

Спецификации

- - - - - - - - - - - - - - -
СпецификацияСтатусКоммент
{{SpecName('Web Crypto API', '#dfn-RandomSource')}}{{Spec2('Web Crypto API')}}Изначальное определение
- -

Совместимость с браузерами

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - -
ВозможностьChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка11.0 {{ webkitbug("22049") }}{{CompatGeckoDesktop(21)}} [1]11.015.03.1
-
- -
- - - - - - - - - - - - - - - - - - - - - -
ВозможностьAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{ CompatNo() }}23{{CompatGeckoMobile(21)}}{{ CompatNo() }}{{ CompatNo() }}6
-
- -

[1] Although the transparent RandomSource is only available since Firefox 26, the feature was available in Firefox 21.

- -

Смотрите также

- -
    -
  • {{ domxref("Window.crypto") }} to get a {{domxref("Crypto")}} object.
  • -
  • {{jsxref("Math.random")}}, не криптографический источник случайных чисел.
  • -
diff --git a/files/ru/web/api/slotable/index.html b/files/ru/web/api/slotable/index.html deleted file mode 100644 index af6ec4765c..0000000000 --- a/files/ru/web/api/slotable/index.html +++ /dev/null @@ -1,45 +0,0 @@ ---- -title: Slotable -slug: Web/API/Slotable -tags: - - миксины -translation_of: Web/API/Slottable -translation_of_original: Web/API/Slotable ---- -

{{APIRef("Shadow DOM")}}

- -

Миксин Slotable определяет возможности, которые позволяют нодам становиться контентом элемента {{htmlelement("slot")}} — следующие возможности включены в  {{domxref("Element")}} и {{domxref("Text")}}.

- -

Свойства

- -
-
{{domxref("Slotable.assignedSlot")}} {{readonlyInline}}
-
Возвращает {{htmlelement("slot")}}, в который вставлена нода.
-
- -

Методы

- -

Нет.

- -

Спецификации

- - - - - - - - - - - - - - -
СпецификацияСтатусКомментарии
{{SpecName('DOM WHATWG','#slotable','Slotable')}}{{Spec2('DOM WHATWG')}}Первое определение.
- -

Поддержка браузерами

- - - -

{{Compat("api.Slotable")}}

diff --git a/files/ru/web/api/storage/localstorage/index.html b/files/ru/web/api/storage/localstorage/index.html deleted file mode 100644 index f0fab82609..0000000000 --- a/files/ru/web/api/storage/localstorage/index.html +++ /dev/null @@ -1,146 +0,0 @@ ---- -title: LocalStorage -slug: Web/API/Storage/LocalStorage -translation_of: Web/API/Window/localStorage -translation_of_original: Web/API/Web_Storage_API/Local_storage ---- -

localStorage это аналог sessionStorage, с некоторыми same-origin правилами, но значения хранятся постоянно (в отличии от sessions). localStorage появился в Firefox 3.5.

- -
Примечание: Когда браузер переходит в режим приватного просмотра, создается новое временное хранилище. Изначально оно пустое. После выхода из режима приватного просмотра временное хранилище очищается.
- -
// Сохраняет данные в текущий local store
-localStorage.setItem("username", "John");
-
-// Извлекает ранее сохраненные данные
-alert( "username = " + localStorage.getItem("username"));
- -

localStorage's позволяет постоянно хранить некоторую полезную информацию, включая счетчики посещения страницы, как показано в примере this tutorial on Codepen.

- -

Совместимость

- -

Storage objects недавно добавлен в стандарт. Он может отсутствовать в некоторых браузерах. Вы можете работать с этой технологией добавив в страницу один из двух скриптов, которые представлены ниже. localStorage object реализуется програмно, если нет встроенной реализации.

- -

Этот алгоритм является точной имитацией localStorage object, но для хранения использует cookies.

- -
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
-    });
-    Object.defineProperty(oStorage, "clear", {
-      value: function () {
-        if(!aKeys.length) { return; }
-        for (var sKey in aKeys) {
-          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;
-  })());
-}
-
- -
Примечание: Максимальныйe размер данных, которые могут быть сохранены, ограничен возможностями cookies. Используйте functions localStorage.setItem() и localStorage.removeItem() для добавления, изменения, или удаления ключа. Использование прямого присвоения localStorage.yourKey = yourValue; и delete localStorage.yourKey; для установки и удаления ключа не безопасно с этим кодом. Вы также можете изменить это имя (вместо window.localStorage прописать другое имя) и использовать объект для управления document's cookies, не обращая внимания на localStorage object.
- -
Примечание: Если изменить строку "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/" на: "; path=/" (и изменить имя объекта), он превратится в sessionStorage polyfill больше, чем в localStorage polyfill. Однако эта реализация будет хранить общие значения для всех вкладок и окон браузера (and will only be cleared when all browser windows have been closed), в то время как полностью совместимая sessionStorage реализация хранит значения to the current browsing context only.
- -

Here is another, less exact, imitation of the localStorage object. It is simpler than the previous one, but it is compatible with old browsers, like Internet Explorer < 8 (tested and working even in Internet Explorer 6). It also makes use of cookies.

- -
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;
-}
-
- -
Note: The maximum size of data that can be saved is severely restricted by the use of cookies. With this algorithm, use the functions localStorage.getItem()localStorage.setItem(), and localStorage.removeItem() to get, add, change, or remove a key. The use of method localStorage.yourKey in order to get, set, or delete a key is not permitted with this code. You can also change its name and use it only to manage a document's cookies regardless of the localStorage object.
- -
Note: By changing the string "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/" to: "; path=/" (and changing the object's name), this will become a sessionStorage polyfill rather than a localStorage polyfill. However, this implementation will share stored values across browser tabs and windows (and will only be cleared when all browser windows have been closed), while a fully-compliant sessionStorage implementation restricts stored values to the current browsing context only.
- -

Compatibility and relation with globalStorage

- -

localStorage is also the same as globalStorage[location.hostname], with the exception of being scoped to an HTML5 origin (scheme + hostname + non-standard port) and localStorage being an instance of Storage as opposed to globalStorage[location.hostname] being an instance of StorageObsolete which is covered below. For example, http://example.com is not able to access the same localStorage object as https://example.com but they can access the same globalStorage item. localStorage is a standard interface while globalStorage is non-standard so you shouldn't rely on these.

- -

Please note that setting a property on globalStorage[location.hostname] does not set it on localStorage and extending Storage.prototype does not affect globalStorage items; only extending StorageObsolete.prototype does.

- -

Storage format

- -

Storage keys and values are both stored in the UTF-16 DOMString format, which uses 2 bytes per character.

- -

 

diff --git a/files/ru/web/api/svgaelement/svgalement.target/index.html b/files/ru/web/api/svgaelement/svgalement.target/index.html deleted file mode 100644 index dcd76310d4..0000000000 --- a/files/ru/web/api/svgaelement/svgalement.target/index.html +++ /dev/null @@ -1,107 +0,0 @@ ---- -title: SVGAElement.target -slug: Web/API/SVGAElement/SVGAlement.target -translation_of: Web/API/SVGAElement/target -translation_of_original: Web/API/SVGAElement/SVGAlement.target ---- -

{{APIRef("SVGAElement")}}

- -

 

- -

Свойство SVGAElement.target для чтения только {{domxref ("SVGAElement")}} возвращает объект {{domxref ("SVGAnimatedString")}}, который указывает часть целевого окна, фрейма, панель, в которую открывается при активации ссылки.

- -

Это свойство используется, когда существует множество возможных целей для конечного ресурса, например, когда родительский документ является документом HTML или HTML-документом mlti-frame.

- -

 

- -

Синтаксис

- -
myLink.target = 'value';
- -

Стоимость

- -

{{Domxref ("SVGAnimatedString")}}, указывающий конечную цель ресурса, которая открывает документ при активации ссылки.

- -

Значения для {{domxref ("target")}} можно увидеть here

- -

Пример

- -

Код  взят из "SVGAElement example code"

- -
...
-var linkRef = document.querySelector('a');
-linkRef.target ='_blank';
-...
- -

Характеристики

- - - - - - - - - - - - - - -
СпецификацияСтатусКомментарий
{{SpecName('SVG1.1', 'text.html#InterfaceSVGAElement', 'target')}}{{Spec2('SVG1.1')}} 
- -

Совместимость с браузером

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}9.0{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{ CompatVersionUnknown() }}{{ CompatUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
-
- -

Смотрите также

- -
    -
  • {{ SVGAttr("target") }}
  • -
diff --git a/files/ru/web/api/web_crypto_api/checking_authenticity_with_password/index.html b/files/ru/web/api/web_crypto_api/checking_authenticity_with_password/index.html deleted file mode 100644 index ea8ec86586..0000000000 --- a/files/ru/web/api/web_crypto_api/checking_authenticity_with_password/index.html +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: Проверка подлинности данных с паролем -slug: Web/API/Web_Crypto_API/Checking_authenticity_with_password -tags: - - HMAC - - Web Crypto -translation_of: Web/API/Web_Crypto_API/Checking_authenticity_with_password ---- -

{{APIRef("Web Crypto API")}}{{draft}}

- -

Проверка подлинности данных может быть выполнена с помощью Web Crypto API. В этой статье мы покажем как создавать и управлять подписями, используя хэш-функцию и пароль.

- -

HMAC алгоритм генерирует хэш на основе передаваемых ключа и данных, которые нужно подписать. Позже, идентичный хэш может быть вычислен заного любым пользователем, у которого имеется ключ. Необходимость ключа позволяет хранить данные и хэш вместе: злоумышленник не сможет создать хэш для измененных данных, не имея ключа.

- -

Стоит заметить, что алгоритм никак не связан с какой-либо другой информацией о владельце: знание ключа – необходимое и достаточное условие для изменения данных.

- -

Предположим, данные хранятся на компьютере. Чтобы получить доступ к записи или чтению, мы будем использовать localforage.js – библиотека-обертка над хранилищами браузера. Эта библиотека необязательна и используется в качестве примера для удобства, чтобы сосредоточиться на криптографии.

- -

Данные, доступ к которым мы хотим получить, имеют следующую форму:

- -

 

- -

где data – данные для подписания и signature – подпись, информация для проверки подлинности.

- -

Криптографические ключи невозможно выучить наизусть, а обычные пароли недостаточно безопасны. Чтобы решить эту проблему, криптографы создали алгоритмы для создания криптографических ключей из паролей. Знание пароля позволяет воссоздать ключ и использовать его.

- -

Запрашиваем пароль у пользователя для генерации ключа:

- -
 
- -

С этим ключом мы можем вычислить хэш данных.

- -
 
diff --git a/files/ru/web/api/web_workers_api/using_web_workers/index.html b/files/ru/web/api/web_workers_api/using_web_workers/index.html new file mode 100644 index 0000000000..7503eccacb --- /dev/null +++ b/files/ru/web/api/web_workers_api/using_web_workers/index.html @@ -0,0 +1,871 @@ +--- +title: Использование Web Workers +slug: DOM/Using_web_workers +tags: + - воркер + - поток +translation_of: Web/API/Web_Workers_API/Using_web_workers +--- +
{{DefaultAPISidebar("Web Workers API")}}
+ +

Web Worker-ы предоставляют простое средство для запуска скриптов в фоновом потоке. Поток Worker'а может выполнять задачи без вмешательства в пользовательский интерфейс. К тому же, они могут осуществлять ввод/вывод, используя XMLHttpRequest (хотя атрибуты responseXML и channel всегда будут равны null). Существующий Worker может отсылать сообщения JavaScript коду-создателю через обработчик событий, указанный этим кодом (и наоборот). Эта статья дает детальную инструкцию по использованию Web Workers.

+ +

Web Workers API

+ +

Worker - это объект, создаваемый конструктором (например, {{domxref("Worker.Worker", "Worker()")}}) и запускающий именной JavaScript файл — этот файл содержит код, который будет выполнен в потоке Worker'а; объекты же Workers запускаются в другом глобальном контексте, отличающемся от текущего, - {{domxref("window")}}. Поэтому использование переменной {{domxref("window")}} для получения текущего глобального контекста (вместо {{domxref("window.self","self")}}) внутри {{domxref("Worker")}} вернет ошибку.

+ +

Контекст Worker'а представлен объектом {{domxref("DedicatedWorkerGlobalScope")}} в случае выделенных Workers (обычные Workers используются одним скриптом; совместные Workers используют объект {{domxref("SharedWorkerGlobalScope")}}). Выделенный Worker доступен только из скрипта-родителя, в то время как совместные Workers могут быть доступны из нескольких сценариев.

+ +
+

Заметка: Смотрите страницу Web Workers API для справки по Workers и прочие руководства.

+
+ +

Вы можете запускать любой код внутри потока worker-а, за некоторыми исключениями. Например, вы не можете прямо манипулировать DOM внутри worker-а, или использовать некоторые методы по умолчанию и свойства объекта {{domxref("window")}}. Но вы можете использовать большой набор опций, доступный под Window, включая WebSockets, и механизмы хранения данных, таких как IndexedDB и относящихся только к Firefox OS Data Store API. Для дополнительной информации смотрите Functions and classes available to workers.

+ +

Данные передаются между worker-ами и главным потоком через систему сообщений — обе стороны передают свои сообщения, используя метод postMessage() и отвечают на сообщения при помощи обработчика событий onmessage (сообщение хранится в аттрибуте data события {{event("Message")}}). Данные при этом копируются, а не делятся.

+ +

Объекты Workers могут, в свою очередь, создавать новые объекты workers, и так до тех пор, пока всё работает в рамках текущей страницы. Плюс к этому, объекты workers могут использовать XMLHttpRequest для сетевого ввода/вывода, но есть исключение - атрибуты responseXML и channel объекта XMLHttpRequest всегда возвращают null.

+ +

Выделенные Workers

+ +

Как уже упоминалось выше, выделенный Worker доступен только для скрипта, который его вызвал. В этом разделе речь пойдет о JavaScript, который можно найти в нашем основном примере выделенного Worker (запустить скрипт): этот пример позволяет ввести два числа для умножения. Эти числа отправляются в Worker, перемножаются, а результат возвращается на страницу и отображается.

+ +

Этот пример достаточно тривиален, но для ознакомления с базовыми концепциями worker-ов мы решили его упростить. Более продвинутые детали описаны далее в статье.

+ +

Определение поддержки Worker

+ +

Для большего контроля над ошибками и обратной совместимости, рекомендуется обернуть ваш код доступа к worker-у в следующий (main.js):

+ +
if (window.Worker) {
+
+  ...
+
+}
+ +

Создание выделенного worker

+ +

Создание нового worker-а — это легко. Всё что вам нужно это вызвать конструктор {{domxref("Worker.Worker", "Worker()")}}, указав URI скрипта для выполнения в потоке worker-а (main.js):

+ +
+
var myWorker = new Worker("worker.js");
+
+
+ +

Передача сообщений в и из выделенного worker

+ +

Магия worker-ов происходит через {{domxref("Worker.postMessage", "postMessage()")}} метод и обработчик событий {{domxref("Worker.onmessage", "onmessage")}}. Когда вы хотите отправить сообщение в worker, вы доставляете сообщение к нему вот так (main.js):

+ +
first.onchange = function() {
+  myWorker.postMessage([first.value,second.value]);
+  console.log('Message posted to worker');
+}
+
+second.onchange = function() {
+  myWorker.postMessage([first.value,second.value]);
+  console.log('Message posted to worker');
+}
+ +

В приведенном фрагменте кода мы имеем два {{htmlelement("input")}} элемента, представленных переменными first и second; когда значение любой из переменных изменяется, myWorker.postMessage([first.value,second.value]) используется для отправки обоих значений, представленных в виде массива, в worker. Посредством аргумента message возможна передача практически любых данных в worker.

+ +

Внутри worker-a мы можем обрабатывать сообщения и отвечать на них при помощи добавления обработчика события onmessage подобным образом (worker.js):

+ +
onmessage = function(e) {
+  console.log('Message received from main script');
+  var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
+  console.log('Posting message back to main script');
+  postMessage(workerResult);
+}
+ +

Обработчик onmessage позволяет нам запустить некий код всякий раз, когда получен пакет с сообщением, доступным в атрибуте data события message. В примере выше мы просто перемножаем вместе две цифры, после чего используем postMessage() снова, чтобы отправить полученный результат назад в основной поток.

+ +

Возвращаясь в основной поток, мы используем onmessage снова, чтобы отреагировать на сообщение, отправленное нам назад из worker-а:

+ +
myWorker.onmessage = function(e) {
+  result.textContent = e.data;
+  console.log('Message received from worker');
+}
+ +

В примере выше мы берём данные из события сообщения и ставим их как textContent у результирующего абзаца, чтобы показать пользователю результат этой калькуляции.

+ +

Заметка: Обратите внимание, что onmessage()​ и postmessage() должны вызываться из экземпляра Worker в главном потоке, но не в потоке worker-а. Это связано с тем, что внутри потока worker-а, worker выступает в качестве глобального объекта.

+ +

Заметка: При передаче сообщения между основным потоком и потоком worker-а, оно копируется или "передается" (перемещается), не делится между потоками. Читайте {{anch("Transferring data to and from workers: further details")}} для более подробного объяснения.

+ +

Завершение работы worker-а

+ +

Прекращение работы worker-а главного потока достигается методом {{domxref("Worker", "terminate")}}:

+ +
myWorker.terminate();
+ +

Поток worker-а немедленно уничтожается.

+ +

Обработка ошибок

+ +

При ошибке во время выполнения worker-а, вызывается его обработчик событий onerror. Он принимает событие error, которое реализует интерфейс ErrorEvent.

+ +

Событие не всплывает и его можно отменить. Для отмены действия по умолчанию, worker может вызвать метод preventDefault() в обработчике события ошибки.

+ +

У события ошибки есть три поля, которые представляют интерес:

+ +
+
message
+
Сообщение об ошибке в читаемом виде.
+
filename
+
Имя файла со скриптом, в котором ошибка произошла.
+
lineno
+
Номер строки в файле, в котором произошла ошибка.
+
+ +

Создание subworkers

+ +

Worker-ы могут запускать другие worker-ы. Так называемые sub-worker'ы должны быть того же происхождения (same-origin), что и родительский документ. Кроме того, URI для subworker-ов рассчитываются относительно родительского worker'а, а не родительского документа. Это позволяет worker-ам проще следить за тем, где находятся их зависимости.

+ +

Импорт скриптов и библиотек

+ +

Worker потоки имеют доступ к глобальной функции, importScripts(), которая позволяет импортировать скрипты с того же домена в их область видимости. Функция принимает ноль и более URI параметров, как список ссылок на ресурсы для импорта; все нижеприведенные примеры верны:

+ +
importScripts();                        /* imports nothing */
+importScripts('foo.js');                /* imports just "foo.js" */
+importScripts('foo.js', 'bar.js');      /* imports two scripts */
+
+ +

Браузер загружает каждый указанный скрипт и исполняет его. Любые глобальные объекты, создаваемые каждым скриптом могут быть использованы в worker'е. Если скрипт не удалось загрузить, будет брошена ошибка NETWORK_ERROR, и последующий код не будет исполнен. Тем не менее код, исполненный ранее (включая отложенный при помощи {{domxref("window.setTimeout()")}}) останется функционален. Объявления функций идущие после вызова метода importScripts() также будут доступны, т.к. объявления функций всегда обрабатываются перед остальным кодом.

+ +
Заметка: Скрипты могут быть загружены в произвольном порядке, но их исполнение будет в  том порядке, в котором имена файлов были переданы в importScripts(). Функция выполняется синхронно; importScripts() не вернет исполнение, пока все скрипты не будут загружены и исполнены.
+ +

Разделяемые worker-ы (Shared workers)

+ +

Разделяемый worker доступен нескольким разным скриптам — даже если они находятся в разных окнах, фреймах или даже worker-ах. В этом разделе мы обсудим JavaScript, который можно найти в нашем базовом примере разделяемых worker-ов (запустить разделяемый worker): Он очень похож на базовый пример выделенных worker-ов, за исключением двух функций, которые доступны из разных скриптовых файлов: умножение двух чисел или возведение числа в степень. Оба скрипта используют один и тот же worker для необходимых вычислений.

+ +

Здесь мы сосредоточимся на разнице между выделенными и раздялемыми worker-ами. Обратите внимание, что в данном примере есть две HTML страницы с JavaScript кодом, которые используют один и тот же файл worker-а.

+ +
+

Заметка: Если разделяемый worker может быть доступен из нескольких контекстов просмотра, то все они должны иметь одно и то же происхождение (одни и те же протокол, хост и порт).

+
+ +
+

Заметка: В Firefox разделяемый worker не может быть использован совместно документами в приватном и неприватном окне ({{bug(1177621)}}).

+
+ +

Создание разделяемого worker-а

+ +

Запуск разделяемого worker-а очень похож на запуск выделенного worker-а, но используется другой конструктор (см. index.html и index2.html) — в каждом документе необходимо поднять worker, для этого следует написать такой код:

+ +
var myWorker = new SharedWorker("worker.js");
+ +

Большая разница заключается в том, что с разделяемым worker-ом необходимо взаимодействовать через объект port — явно открыв порт, с помощью которого скрипты могут взаимодействовать с worker-ом (в случае выделенного worker-а это происходит неявно).

+ +

Соединение с портом должно быть осуществлено либо неявно, используя обработчик событие onmessage, либо явно, вызвав метод start() перед тем, как отправлять любые сообщения. Вызов метода start() необходим только тогда, когда подписка на событие реализована через метод addEventListener().

+ +
+

Заметка: Когда используется метод start() чтобы открыть соединение с портом, его необходимо вызывать и в родительском потоке и в потоке worker-а, если необходима двухсторонняя коммуникация.

+
+ +
myWorker.port.start();  // в родительском потоке
+ +
port.start();  // в потоке worker-а, где переменная port является ссылкой на порт
+ +

Передача сообщений в/из разделяемого worker-а

+ +

Теперь сообщения могут быть отправлены worker-у, как и прежде, но метод postMessage() должен вызываться из объекта port (еще раз, вы можете увидеть схожие кострукции в multiply.js и square.js):

+ +
squareNumber.onchange = function() {
+  myWorker.port.postMessage([squareNumber.value,squareNumber.value]);
+  console.log('Message posted to worker');
+}
+ +

Теперь на стороне worker-а. Здесь код немного сложнее (worker.js):

+ +
self.addEventListener('connect', function(e) { // требуется addEventListener()
+  var port = e.ports[0];
+  port.onmessage = function(e) {
+    var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
+    port.postMessage(workerResult);
+  }
+  port.start();  // вызов необязательный, т.к. используется обработчик событий onmessage
+});
+ +

Первый этап состоит из события onconnect. Оно срабатывает, когда произошло подключение (т.е. когда в родительском потоке отработало событие onmessage или когда в нем был вызван метод start()).

+ +

Мы используем атрибут события ports, чтобы получить порт и сохранить его в переменной.

+ +

Второй этап — это обработчик события message на сохраненном порту. Он нужен для подсчета и вывода результата вычисления в основной поток. Установка обработчика message в потоке worker-а также открывает подключение к родительскому потоку, поэтому вызов на port.start() на самом деле не нужен (см. код обработчика onconnect).

+ +

Последний этап — возвращение в основной поток и обработка сообщения от worker‑а (еще раз, вы можете увидеть схожие конструкции в multiply.js и square.js):

+ +
myWorker.port.onmessage = function(e) {
+  result2.textContent = e.data[0];
+  console.log('Message received from worker');
+}
+ +

Когда сообщение приходит через порт от worker-а, мы проверяем тип результата вычислений и затем вставляем его в соответствующий абзац.

+ +

О потоковой безопасности

+ +

Интерфейс {{domxref("Worker")}} создаёт настоящие потоки на уровне операционной системы, что может смутить опытных программистов и навести их на мысли о проблемах, связанных с конфликтом доступа к общим объектам.

+ +

На самом деле создать такие проблемы достаточно сложно, так как worker-ы жёстко контролируются. У них нет доступа к непотокобезопасным объектам DOM, а все данные между потоками передаются в качестве сериализованных объектов. Придётся очень постараться, чтобы вызывать проблемы потокобезопасности в вашем коде.

+ +

Передача данных в и из worker-ов: другие детали

+ +

Передача данных между главной страницей и worker-ом происходит путем копирования, а не передачи по ссылке. Объекты сериализуются при передаче и затем десериализуются на другом конце. Страница и worker не используют совместно одни и те же экземпляры, для каждого создается свой. Большинство браузеров реализуют это структурированным клонированием (structured cloning).

+ +

Для иллюстрации этого мы создадим функцию emulateMessage(), которая будет имитировать поведение значения, которое клонируется, но не используется совместно при переходе от worker-а к главной странице или наоборот.

+ +
function emulateMessage (vVal) {
+    return eval("(" + JSON.stringify(vVal) + ")");
+}
+
+// Tests
+
+// test #1
+var example1 = new Number(3);
+console.log(typeof example1); // object
+console.log(typeof emulateMessage(example1)); // number
+
+// test #2
+var example2 = true;
+console.log(typeof example2); // boolean
+console.log(typeof emulateMessage(example2)); // boolean
+
+// test #3
+var example3 = new String("Hello World");
+console.log(typeof example3); // object
+console.log(typeof emulateMessage(example3)); // string
+
+// test #4
+var example4 = {
+    "name": "John Smith",
+    "age": 43
+};
+console.log(typeof example4); // object
+console.log(typeof emulateMessage(example4)); // object
+
+// test #5
+function Animal (sType, nAge) {
+    this.type = sType;
+    this.age = nAge;
+}
+var example5 = new Animal("Cat", 3);
+alert(example5.constructor); // Animal
+alert(emulateMessage(example5).constructor); // Object
+ +

Значения, которые клонируются и совместно не используются, называются сообщениями. Как вы, возможно, знаете, сообщения могут быть отправлены в главную страницу и из нее, используя postMessage(), и {{domxref("MessageEvent.data", "data")}}, содержа данные, передаваемые из worker-а.

+ +

example.html: (главная страница):

+ +
var myWorker = new Worker("my_task.js");
+
+myWorker.onmessage = function (oEvent) {
+  console.log("Worker said : " + oEvent.data);
+};
+
+myWorker.postMessage("ali");
+ +

my_task.js (worker):

+ +
postMessage("I\'m working before postMessage(\'ali\').");
+
+onmessage = function (oEvent) {
+  postMessage("Hi " + oEvent.data);
+};
+ +

Алгоритм структурированного клонирования может принять JSON и некоторые вещи, которые JSON не может принять, например, циклические ссылки.

+ +

Примеры передачи данных

+ +

Пример #1: Расширенная передача JSON данных и создание системы коммутации

+ +

Если вам нужно передать сложные данные и вызвать множество различных функций как на главной странице, так и в worker-е, вы можете создать следующую систему.

+ +

В первую очередь мы создаем класс QueryableWorker, который принимает url worker-а, стандартный обработчик событий (defaultListener) и обработчик ошибок. Этот класс будет отслеживать всех обработчиков и поможет нам общаться с воркером.

+ +
function QueryableWorker(url, defaultListener, onError) {
+    var instance = this,
+        worker = new Worker(url),
+        listeners = {};
+
+    this.defaultListener = defaultListener || function() {};
+
+    if (onError) {worker.onerror = onError;}
+
+    this.postMessage = function(message) {
+        worker.postMessage(message);
+    }
+
+    this.terminate = function() {
+        worker.terminate();
+    }
+}
+
+ +

Затем мы добавляем методы добавления/удаления обработчиков.

+ +
this.addListeners = function(name, listener) {
+    listeners[name] = listener;
+}
+
+this.removeListeners = function(name) {
+    delete listeners[name];
+}
+
+ +

Здесь мы создадим у worker-а два простых события для примера: получение разницы двух чисел и создание оповещения через три секунды. Но сначала нам нужно реализовать метод sendQuery, который проверит есть ли вообще у worker-а обработчик, который мы собираемся вызвать.

+ +
/*
+  Эта функция принимает по крайней мере один аргумент: имя метода, который мы хотим вызвать.
+  Далее мы можем передать методу необходимые ему аргументы.
+ */
+this.sendQuery = function() {
+    if (arguments.length < 1) {
+         throw new TypeError('QueryableWorker.sendQuery takes at least one argument');
+         return;
+    }
+    worker.postMessage({
+        'queryMethod': arguments[0],
+        'queryArguments': Array.prototype.slice.call(arguments, 1)
+    });
+}
+
+ +

Завершим QueryableWorker методом onmessage.  Если worker имеет соответствующий метод, который мы запросили, он также должен вернуть соответствующий обработчик и аргументы, которые нам нужны. Останется лишь найти его в listeners:

+ +
worker.onmessage = function(event) {
+    if (event.data instanceof Object &&
+        event.data.hasOwnProperty('queryMethodListener') &&
+        event.data.hasOwnProperty('queryMethodArguments')) {
+        listeners[event.data.queryMethodListener].apply(instance, event.data.queryMethodArguments);
+    } else {
+        this.defaultListener.call(instance, event.data);
+    }
+}
+
+ +

Теперь к самому worker-у. Сначала следует определить эти два простых метода:

+ +
var queryableFunctions = {
+    getDifference: function(a, b) {
+        reply('printStuff', a - b);
+    },
+    waitSomeTime: function() {
+        setTimeout(function() {
+            reply('doAlert', 3, 'seconds');
+        }, 3000);
+    }
+}
+
+function reply() {
+    if (arguments.length < 1) {
+        throw new TypeError('reply - takes at least one argument');
+        return;
+    }
+    postMessage({
+        queryMethodListener: arguments[0],
+        queryMethodArguments: Array.prototype.slice.call(arguments, 1)
+    });
+}
+
+/* This method is called when main page calls QueryWorker's postMessage method directly*/
+function defaultReply(message) {
+    // do something
+}
+
+ +

И onmessage:

+ +
onmessage = function(event) {
+    if (event.data instanceof Object &&
+        event.data.hasOwnProperty('queryMethod') &&
+        event.data.hasOwnProperty('queryMethodArguments')) {
+        queryableFunctions[event.data.queryMethod]
+            .apply(self, event.data.queryMethodArguments);
+    } else {
+        defaultReply(event.data);
+    }
+}
+ +

Полный код примера:

+ +

example.html (основная страница):

+ +
<!doctype html>
+  <html>
+    <head>
+      <meta charset="UTF-8"  />
+      <title>MDN Example - Queryable worker</title>
+    <script type="text/javascript">
+    /*
+      QueryableWorker instances methods:
+        * sendQuery(queryable function name, argument to pass 1, argument to pass 2, etc. etc): calls a Worker's queryable function
+        * postMessage(string or JSON Data): see Worker.prototype.postMessage()
+        * terminate(): terminates the Worker
+        * addListener(name, function): adds a listener
+        * removeListener(name): removes a listener
+      QueryableWorker instances properties:
+        * defaultListener: the default listener executed only when the Worker calls the postMessage() function directly
+     */
+    function QueryableWorker(url, defaultListener, onError) {
+      var instance = this,
+      worker = new Worker(url),
+      listeners = {};
+
+      this.defaultListener = defaultListener || function() {};
+
+      if (onError) {worker.onerror = onError;}
+
+      this.postMessage = function(message) {
+        worker.postMessage(message);
+      }
+
+      this.terminate = function() {
+        worker.terminate();
+      }
+
+      this.addListener = function(name, listener) {
+        listeners[name] = listener;
+      }
+
+      this.removeListener = function(name) {
+        delete listeners[name];
+      }
+
+      /*
+        This functions takes at least one argument, the method name we want to query.
+        Then we can pass in the arguments that the method needs.
+      */
+      this.sendQuery = function() {
+        if (arguments.length < 1) {
+          throw new TypeError('QueryableWorker.sendQuery takes at least one argument');
+          return;
+        }
+        worker.postMessage({
+          'queryMethod': arguments[0],
+          'queryMethodArguments': Array.prototype.slice.call(arguments, 1)
+        });
+      }
+
+      worker.onmessage = function(event) {
+        if (event.data instanceof Object &&
+          event.data.hasOwnProperty('queryMethodListener') &&
+          event.data.hasOwnProperty('queryMethodArguments')) {
+          listeners[event.data.queryMethodListener].apply(instance, event.data.queryMethodArguments);
+        } else {
+          this.defaultListener.call(instance, event.data);
+        }
+      }
+    }
+
+    // your custom "queryable" worker
+    var myTask = new QueryableWorker('my_task.js');
+
+    // your custom "listeners"
+    myTask.addListener('printStuff', function (result) {
+      document.getElementById('firstLink').parentNode.appendChild(document.createTextNode('The difference is ' + result + '!'));
+    });
+
+    myTask.addListener('doAlert', function (time, unit) {
+      alert('Worker waited for ' + time + ' ' + unit + ' :-)');
+    });
+</script>
+</head>
+<body>
+  <ul>
+    <li><a id="firstLink" href="javascript:myTask.sendQuery('getDifference', 5, 3);">What is the difference between 5 and 3?</a></li>
+    <li><a href="javascript:myTask.sendQuery('waitSomeTime');">Wait 3 seconds</a></li>
+    <li><a href="javascript:myTask.terminate();">terminate() the Worker</a></li>
+  </ul>
+</body>
+</html>
+ +

my_task.js (код worker-а):

+ +
var queryableFunctions = {
+  // пример #1: получить разницу между двумя числами
+  getDifference: function(nMinuend, nSubtrahend) {
+      reply('printStuff', nMinuend - nSubtrahend);
+  },
+  // пример #2: подождать три секунды
+  waitSomeTime: function() {
+      setTimeout(function() { reply('doAlert', 3, 'seconds'); }, 3000);
+  }
+};
+
+// системные функции
+
+function defaultReply(message) {
+  // your default PUBLIC function executed only when main page calls the queryableWorker.postMessage() method directly
+  // do something
+}
+
+function reply() {
+  if (arguments.length < 1) { throw new TypeError('reply - not enough arguments'); return; }
+  postMessage({ 'queryMethodListener': arguments[0], 'queryMethodArguments': Array.prototype.slice.call(arguments, 1) });
+}
+
+onmessage = function(oEvent) {
+  if (oEvent.data instanceof Object && oEvent.data.hasOwnProperty('queryMethod') && oEvent.data.hasOwnProperty('queryMethodArguments')) {
+    queryableFunctions[oEvent.data.queryMethod].apply(self, oEvent.data.queryMethodArguments);
+  } else {
+    defaultReply(oEvent.data);
+  }
+};
+
+ +

Можно переключать содержимое каждой главной страницы -> worker и worker -> сообщение главной страницы. И имена свойств "queryMethod", "queryMethodListeners", "queryMethodArguments" могут быть любыми пока они согласуются с QueryableWorker и worker.

+ +

Передача данных с помощью передачи владения (передаваемые объекты)

+ +

Google Chrome 17+ and Firefox 18+ имеют дополнительную возможность передачи определенных типов объектов (передаваемые объекты реализующие {{domxref("Transferable")}} интерфейс) к или из worker-а с высокой призводительностью. Эти объекты передаются из одного контекста в другой без операций копирования, что приводит к значительному повышению производительности при отправке больших наборов данных. Думайте об этом как о передаче по ссылке в мире C/C++. Однако в отличии от передачи по ссылке, "версия" из вызывающего контекста больше недоступна после передачи. Владельцем становится новый контекст.  Для примера, после передачи {{domxref("ArrayBuffer")}} из главной страницы к worker-у,  исходный {{domxref("ArrayBuffer")}} очищается и более недоступен для использования.  Его содержание (в буквальном смысле) переносится в рабочий контекст.

+ +
// Create a 32MB "file" and fill it.
+var uInt8Array = new Uint8Array(1024*1024*32); // 32MB
+for (var i = 0; i < uInt8Array.length; ++i) {
+  uInt8Array[i] = i;
+}
+
+worker.postMessage(uInt8Array.buffer, [uInt8Array.buffer]);
+
+ +
+

Заметка: Для дополнительной информации о передаваемых объектах, производительности и поддержки для этого метода, читайте  Transferable Objects: Lightning Fast! на HTML5 Rocks.

+
+ +

Встроенные worker-ы

+ +

Не существует утвержденного способа встроить код worker-а в рамках веб-страницы, как элемент {{HTMLElement("script")}} делает для обычных скриптов. Но элемент {{HTMLElement("script")}}, который не имеет аттрибута src и аттрибута  type, которому не назначен выполняемый MIME type, можно считать блоком данных для использования JavaScript. Блок данных "Data blocks" — это более общее свойство HTML5, может содержать любые текстовые данные. Так, worker может быть встроен следующим образом:

+ +
<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8" />
+<title>MDN Example - Embedded worker</title>
+<script type="text/js-worker">
+  // Этот script НЕ БУДЕТ анализироваться JS движками, потому что  его MIME-тип text/js-worker.
+  var myVar = 'Hello World!';
+  // Остальная часть кода вашего воркера идет сюда.
+</script>
+<script type="text/javascript">
+  // Этот script БУДЕТ проанализирован JS движкам, потому что его MIME-тип text/javascript.
+  function pageLog(sMsg) {
+    // Use a fragment: browser will only render/reflow once.
+    var oFragm = document.createDocumentFragment();
+    oFragm.appendChild(document.createTextNode(sMsg));
+    oFragm.appendChild(document.createElement('br'));
+    document.querySelector('#logDisplay').appendChild(oFragm);
+  }
+</script>
+<script type="text/js-worker">
+  // Этот script НЕ БУДЕТ анализироваться JS движками, потому что его MIME-тип text/js-worker.
+  onmessage = function(oEvent) {
+    postMessage(myVar);
+  };
+  // Остальная часть кода вашего воркера идет сюда.
+</script>
+<script type="text/javascript">
+  // Этот script БУДЕТ проанализирован JS движкам, потому что его MIME-тип text/javascript.
+
+  // В прошлом...:
+  // blob builder существовал
+  // ... но теперь мы используем Blob...:
+  var blob = new Blob(Array.prototype.map.call(document.querySelectorAll('script[type=\'text\/js-worker\']'), function (oScript) { return oScript.textContent; }),{type: 'text/javascript'});
+
+  // Создание нового свойства document.worker, содержащего все наши "text/js-worker" скрипты.
+  document.worker = new Worker(window.URL.createObjectURL(blob));
+
+  document.worker.onmessage = function(oEvent) {
+    pageLog('Received: ' + oEvent.data);
+  };
+
+  // Запуск воркера.
+  window.onload = function() { document.worker.postMessage(''); };
+</script>
+</head>
+<body><div id="logDisplay"></div></body>
+</html>
+
+ +
Встраиваемый worker теперь внесен в новое custom свойство document.worker
+ +
+ +
Также стоит отметить, что вы также можете преобразовать функцию в BLOB-объект, а затем сгенерировать URL объекта из этого BLOB-объекта. Например:
+ +
function fn2workerURL(fn) {
+  var blob = new Blob(['('+fn.toString()+')()'], {type: 'application/javascript'})
+  return URL.createObjectURL(blob)
+}
+
+ +

Другие примеры

+ +

В этой секции представлено еще несколько примеров как использовать worker-ы.

+ +

Выполнение вычислений в фоне

+ +

Worker-ы в основном полезны для того, чтобы позволить вашему коду выполнять ресурсоемкие вычисления, не блокируя поток пользовательского интерфейса. В этом примере, worker используется для вычисления числа Фибоначчи.

+ +

Код JavaScript

+ +

Следующий код JavaScript хранится в файле "fibonacci.js", на который ссылается HTML в следующем разделе.

+ +
var results = [];
+
+function resultReceiver(event) {
+  results.push(parseInt(event.data));
+  if (results.length == 2) {
+    postMessage(results[0] + results[1]);
+  }
+}
+
+function errorReceiver(event) {
+  throw event.data;
+}
+
+onmessage = function(event) {
+  var n = parseInt(event.data);
+
+  if (n == 0 || n == 1) {
+    postMessage(n);
+    return;
+  }
+
+  for (var i = 1; i <= 2; i++) {
+    var worker = new Worker("fibonacci.js");
+    worker.onmessage = resultReceiver;
+    worker.onerror = errorReceiver;
+    worker.postMessage(n - i);
+  }
+ };
+ +

Worker устанавливает свойство onmessage для функции,  которая будет получать сообщения, отправленные при вызове postMessage() рабочего объекта (обратите внимание, что это отличается от определения глобальной переменной с таким именем или определения функции с таким именем. var onmessage и function onmessage будет определять глобальные свойства с этими именами , но они не будут регистрировать функцию для получения сообщений, отправленных веб-страницей, которая создала worker). Это запускает рекурсию, порождая новые копии для обработки каждой итерации вычисления.

+ +

HTML код

+ +
<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="UTF-8"  />
+    <title>Test threads fibonacci</title>
+  </head>
+  <body>
+
+  <div id="result"></div>
+
+  <script language="javascript">
+
+    var worker = new Worker('fibonacci.js');
+
+    worker.onmessage = function(event) {
+      document.getElementById('result').textContent = event.data;
+      dump('Got: ' + event.data + '\n');
+    };
+
+    worker.onerror = function(error) {
+      dump('Worker error: ' + error.message + '\n');
+      throw error;
+    };
+
+    worker.postMessage('5');
+
+  </script>
+  </body>
+</html>
+ +

Веб-страница создает элемент div с ID result , который используется для отображения результата, а затем порождает worker. После порождения worker-а, обработчик onmessage настроен для отображения результатов путем установки содержимого элемента div, и обработчик onerror настроен на выброс сообщения об ошибке.

+ +

Наконец, сообщение отправляется worker-у, чтобы запустить его.

+ +

Попробуйте этот пример.

+ +

Выполнение веб I/O в фоне

+ +

Вы можете найти пример этого в статье Использование worker-ов в расширениях.

+ +

Разделение задач между множественными worker-ами

+ +

Поскольку многоядерные компьютеры становятся все более распространенными, часто бывает полезно разделить вычислительно сложные задачи между несколькими worker-ами, которые затем могут выполнить эти задачи на многопроцессорных ядрах.

+ +

Другие типы worker-ов

+ +

В дополнение к выделенным и совместно используемым web worker-ам доступны другие типы worker-ов:

+ +
    +
  • ServiceWorkers, по сути, действуют как прокси-серверы, которые размещаются между веб-приложениями, браузером и сетью (при наличии). Они предназначены (помимо прочего) для создания эффективного автономного взаимодействия, перехвата сетевых запросов и принятия соответствующих действий в зависимости от того, доступна ли сеть, и обновлены ли ресурсы на сервере. Они также разрешают доступ push-уведомлениям и API фоновой синхронизации.
  • +
  • Chrome Workers это worker типа Firefox-only, который вы можете использовать, если вы разрабатываете дополнения и хотите использовать worker-ы в расширениях и иметь доступ к js-ctypes в вашем worker-е. Смотрите {{domxref("ChromeWorker")}} для более подробной информации.
  • +
  • Audio Workers предоставляют возможность прямой обработки звука по сценарию в контексте web worker-а.
  • +
+ +

Функции и интерфейсы доступные в worker-ах

+ +

Внутри web worker-а вы можете использовать большинство стандартных функций JavaScript, включая:

+ +
    +
  • {{domxref("Navigator")}}
  • +
  • {{domxref("XMLHttpRequest")}}
  • +
  • {{jsxref("Global_Objects/Array", "Array")}}, {{jsxref("Global_Objects/Date", "Date")}}, {{jsxref("Global_Objects/Math", "Math")}}, и {{jsxref("Global_Objects/String", "String")}}
  • +
  • {{domxref("Window.requestAnimationFrame")}}, {{domxref("WindowTimers.setTimeout")}}, и {{domxref("WindowTimers.setInterval")}}
  • +
+ +

Главное, что вы не можете сделать в Worker это напрямую повлиять на родительскую страницу. Это включает в себя манипулирование DOM и использование объектов этой страницы. Вы должны сделать это косвенно, отправив сообщение обратно основному сценарию через {{domxref("DedicatedWorkerGlobalScope.postMessage")}}, а затем выполнив изменения оттуда.

+ +
+

Заметка: Для знакомства с  полным списком функций,  доступных для worker-ов, смотрите статью Функции и интерфейсы доступные worker-ам.

+
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('HTML WHATWG', '#toc-workers')}}{{Spec2('HTML WHATWG')}}Без изменений {{SpecName("Web Workers")}}.
{{SpecName('Web Workers')}}{{Spec2('Web Workers')}}Начальное определение.
+ +

Браузерная совместимость

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support4[1]{{CompatGeckoDesktop("1.9.1")}}10.010.6[1]4[2]
Shared workers4[1]{{CompatGeckoDesktop(29)}}{{CompatNo}}10.65
+ {{CompatNo}} 6.1[4]
Passing data using structured cloning13{{CompatGeckoDesktop(8)}}10.011.56
Passing data using transferable objects17 {{property_prefix("webkit")}}
+ 21
{{CompatGeckoDesktop(18)}}{{CompatNo}}156
Global {{domxref("window.URL", "URL")}}10[3]
+ 23
{{CompatGeckoDesktop(21)}}11156[3]
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)Firefox OS (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support4.44[1]3.51.0.110.011.5[1]5.1[2]
Shared workers{{CompatNo}}4[1]81.0.1{{CompatNo}}{{CompatNo}}{{CompatNo}}
Passing data using structured cloning{{CompatNo}}481.0.1{{CompatNo}}{{CompatNo}}{{CompatNo}}
Passing data using transferable objects{{CompatNo}}{{CompatNo}}181.0.1{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

[1] Chrome и Opera выдают ошибку "Uncaught SecurityError: Failed to construct 'Worker': Script at 'file:///Path/to/worker.js' cannot be accessed from origin 'null'." когда вы пытаетесь запустить worker локально. Нужно быть на надлежащем домене.

+ +

[2] Начиная с Safari 7.1.2, вы можете вызывать console.log изнутри worker-а, но он ничего не выведет в консоль. Более старые версии Safari не ползволяют вызывать console.log изнутри worker-а

+ +

[3] Эта функция реализована с префиксом как webkitURL.

+ +

[4] Safari удалил поддержку SharedWorker.

+ +

Смотрите также

+ + diff --git a/files/ru/web/api/webgl_api/tutorial/creating_3d_objects_using_webgl/index.html b/files/ru/web/api/webgl_api/tutorial/creating_3d_objects_using_webgl/index.html new file mode 100644 index 0000000000..b5abccbe14 --- /dev/null +++ b/files/ru/web/api/webgl_api/tutorial/creating_3d_objects_using_webgl/index.html @@ -0,0 +1,131 @@ +--- +title: Создание 3D объектов с помощью WebGL +slug: Web/API/WebGL_API/Tutorial/Создание_3D_объектов_с_помощью_WebGL +tags: + - WebGL + - Урок +translation_of: Web/API/WebGL_API/Tutorial/Creating_3D_objects_using_WebGL +--- +

{{WebGLSidebar("Tutorial")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Animating_objects_with_WebGL", "Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL")}}

+ +

Давайте поместим наш квадрат в трехмерное пространство, добавив еще 5 граней, чтобы получить куб. Чтобы сделать это наиболее продуктивно, вместо рисования вершин непосредственным вызовом метода {{domxref("WebGLRenderingContext.drawArrays()", "gl.drawArrays()")}} , мы будем использовать массив вершин в виде таблицы и ссылаться на каждую вершину в этой таблице, чтобы определить положение каждой вершины грани, вызывая {{domxref("WebGLRenderingContext.drawElements()", "gl.drawElements()")}}.

+ +

Заметим: чтобы определить каждую грань необходимо четыре вершины, но каждая вершина принадлежит трем граням. Мы можем передавать намного меньше данных, построив список всех 24-х вершин, затем ссылаться на каждую из них в этом списке по её индексу, вместо того чтобы передавать все множество вершин. Если вы удивлены, почему нам нужны 24 вершины, а не только 8, так это потому, что каждое ребро принадлежит трем граням разных цветов, и каждая отдельная вершина должна иметь конкретный отдельный цвет - поэтому мы создадим 3 копии каждой вершины трех разных цветов, по одной для каждой грани.

+ +

Определение позиций вершин куба

+ +

Во первых, давайте построим буффер позиций вершин куба, обновив код в initBuffers(). Это в значительной степени то же самое как это было для квадрата, но несколько длиннее, так как здесь 24 вершины (4 с каждой стороны):

+ +
var vertices = [
+  // Передняя грань
+  -1.0, -1.0,  1.0,
+   1.0, -1.0,  1.0,
+   1.0,  1.0,  1.0,
+  -1.0,  1.0,  1.0,
+
+  // Задняя грань
+  -1.0, -1.0, -1.0,
+  -1.0,  1.0, -1.0,
+   1.0,  1.0, -1.0,
+   1.0, -1.0, -1.0,
+
+  // Верхняя грань
+  -1.0,  1.0, -1.0,
+  -1.0,  1.0,  1.0,
+   1.0,  1.0,  1.0,
+   1.0,  1.0, -1.0,
+
+  // Нижняя грань
+  -1.0, -1.0, -1.0,
+   1.0, -1.0, -1.0,
+   1.0, -1.0,  1.0,
+  -1.0, -1.0,  1.0,
+
+  // Правая грань
+   1.0, -1.0, -1.0,
+   1.0,  1.0, -1.0,
+   1.0,  1.0,  1.0,
+   1.0, -1.0,  1.0,
+
+  // Левая грань
+  -1.0, -1.0, -1.0,
+  -1.0, -1.0,  1.0,
+  -1.0,  1.0,  1.0,
+  -1.0,  1.0, -1.0
+];
+
+ +

Определение цветов вершин

+ +

Нам также нужно построить массив цветов для каждой из 24-х вершин. Этот код начинается с определения цветов для каждой грани, затем используется цикл для составления массива все всех цветов для каждой из вершин.

+ +
var colors = [
+  [1.0,  1.0,  1.0,  1.0],    // Front face: white
+  [1.0,  0.0,  0.0,  1.0],    // Back face: red
+  [0.0,  1.0,  0.0,  1.0],    // Top face: green
+  [0.0,  0.0,  1.0,  1.0],    // Bottom face: blue
+  [1.0,  1.0,  0.0,  1.0],    // Right face: yellow
+  [1.0,  0.0,  1.0,  1.0]     // Left face: purple
+];
+
+var generatedColors = [];
+
+for (j=0; j<6; j++) {
+  var c = colors[j];
+
+  for (var i=0; i<4; i++) {
+    generatedColors = generatedColors.concat(c);
+  }
+}
+
+cubeVerticesColorBuffer = gl.createBuffer();
+gl.bindBuffer(gl.ARRAY_BUFFER, cubeVerticesColorBuffer);
+gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(generatedColors), gl.STATIC_DRAW);
+
+ +

Определение массива элементов

+ +

Как только массив вершин сгенерирован, нам нужно построить массив элементов.

+ +
cubeVerticesIndexBuffer = gl.createBuffer();
+gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVerticesIndexBuffer);
+
+// Этот массив определяет каждую грань как два треугольника,
+// используя индексы в массиве вершин, чтобы определить позицию
+// каждого треугольника.
+
+var cubeVertexIndices = [
+  0,  1,  2,      0,  2,  3,    // front
+  4,  5,  6,      4,  6,  7,    // back
+  8,  9,  10,     8,  10, 11,   // top
+  12, 13, 14,     12, 14, 15,   // bottom
+  16, 17, 18,     16, 18, 19,   // right
+  20, 21, 22,     20, 22, 23    // left
+];
+
+// Теперь отправим массив элементов в GL
+
+gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,
+    new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW);
+
+ +

Массив cubeVertexIndices определяет каждую грань как пару треугольников, сопоставляя каждой вершине треугольника индекс в массиве вершин куба. Таким образом куб можно представить как набор из 12 треугольников.

+ +

Рисование куба

+ +

Далее нам нужно обновить код нашей функции drawScene() , чтобы рисовать, используя буффер индексов куба, добавив новые вызовы {{domxref("WebGLRenderingContext.bindBuffer()", "gl.bindBuffer()")}} и {{domxref("WebGLRenderingContext.drawElements()", "gl.drawElements()")}}:

+ +
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVerticesIndexBuffer);
+setMatrixUniforms();
+gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_SHORT, 0);
+
+ +

Поскольку каждая грань нашего куба состоит из двух треугольников, где 6 вершин на каждой грани, или всего 36 вершин во всем кубе, даже если многие из них дублируются. Однако, поскольку наш массив индексов состоит из целых чисел, это не чрезмерное количество данных, посылаемых для каждого кадра анимации.

+ +

В данный момент у нас есть анимированный куб с гранями 6 разных цветов, который прыгает и вращается.

+ +

{{EmbedGHLiveSample('webgl-examples/tutorial/sample5/index.html', 670, 510) }}

+ +

View the complete code | Open this demo on a new page

+ +

{{PreviousNext("Web/API/WebGL_API/Tutorial/Animating_objects_with_WebGL", "Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL")}}

diff --git "a/files/ru/web/api/webgl_api/tutorial/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_3d_\320\276\320\261\321\212\320\265\320\272\321\202\320\276\320\262_\321\201_\320\277\320\276\320\274\320\276\321\211\321\214\321\216_webgl/index.html" "b/files/ru/web/api/webgl_api/tutorial/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_3d_\320\276\320\261\321\212\320\265\320\272\321\202\320\276\320\262_\321\201_\320\277\320\276\320\274\320\276\321\211\321\214\321\216_webgl/index.html" deleted file mode 100644 index b5abccbe14..0000000000 --- "a/files/ru/web/api/webgl_api/tutorial/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_3d_\320\276\320\261\321\212\320\265\320\272\321\202\320\276\320\262_\321\201_\320\277\320\276\320\274\320\276\321\211\321\214\321\216_webgl/index.html" +++ /dev/null @@ -1,131 +0,0 @@ ---- -title: Создание 3D объектов с помощью WebGL -slug: Web/API/WebGL_API/Tutorial/Создание_3D_объектов_с_помощью_WebGL -tags: - - WebGL - - Урок -translation_of: Web/API/WebGL_API/Tutorial/Creating_3D_objects_using_WebGL ---- -

{{WebGLSidebar("Tutorial")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Animating_objects_with_WebGL", "Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL")}}

- -

Давайте поместим наш квадрат в трехмерное пространство, добавив еще 5 граней, чтобы получить куб. Чтобы сделать это наиболее продуктивно, вместо рисования вершин непосредственным вызовом метода {{domxref("WebGLRenderingContext.drawArrays()", "gl.drawArrays()")}} , мы будем использовать массив вершин в виде таблицы и ссылаться на каждую вершину в этой таблице, чтобы определить положение каждой вершины грани, вызывая {{domxref("WebGLRenderingContext.drawElements()", "gl.drawElements()")}}.

- -

Заметим: чтобы определить каждую грань необходимо четыре вершины, но каждая вершина принадлежит трем граням. Мы можем передавать намного меньше данных, построив список всех 24-х вершин, затем ссылаться на каждую из них в этом списке по её индексу, вместо того чтобы передавать все множество вершин. Если вы удивлены, почему нам нужны 24 вершины, а не только 8, так это потому, что каждое ребро принадлежит трем граням разных цветов, и каждая отдельная вершина должна иметь конкретный отдельный цвет - поэтому мы создадим 3 копии каждой вершины трех разных цветов, по одной для каждой грани.

- -

Определение позиций вершин куба

- -

Во первых, давайте построим буффер позиций вершин куба, обновив код в initBuffers(). Это в значительной степени то же самое как это было для квадрата, но несколько длиннее, так как здесь 24 вершины (4 с каждой стороны):

- -
var vertices = [
-  // Передняя грань
-  -1.0, -1.0,  1.0,
-   1.0, -1.0,  1.0,
-   1.0,  1.0,  1.0,
-  -1.0,  1.0,  1.0,
-
-  // Задняя грань
-  -1.0, -1.0, -1.0,
-  -1.0,  1.0, -1.0,
-   1.0,  1.0, -1.0,
-   1.0, -1.0, -1.0,
-
-  // Верхняя грань
-  -1.0,  1.0, -1.0,
-  -1.0,  1.0,  1.0,
-   1.0,  1.0,  1.0,
-   1.0,  1.0, -1.0,
-
-  // Нижняя грань
-  -1.0, -1.0, -1.0,
-   1.0, -1.0, -1.0,
-   1.0, -1.0,  1.0,
-  -1.0, -1.0,  1.0,
-
-  // Правая грань
-   1.0, -1.0, -1.0,
-   1.0,  1.0, -1.0,
-   1.0,  1.0,  1.0,
-   1.0, -1.0,  1.0,
-
-  // Левая грань
-  -1.0, -1.0, -1.0,
-  -1.0, -1.0,  1.0,
-  -1.0,  1.0,  1.0,
-  -1.0,  1.0, -1.0
-];
-
- -

Определение цветов вершин

- -

Нам также нужно построить массив цветов для каждой из 24-х вершин. Этот код начинается с определения цветов для каждой грани, затем используется цикл для составления массива все всех цветов для каждой из вершин.

- -
var colors = [
-  [1.0,  1.0,  1.0,  1.0],    // Front face: white
-  [1.0,  0.0,  0.0,  1.0],    // Back face: red
-  [0.0,  1.0,  0.0,  1.0],    // Top face: green
-  [0.0,  0.0,  1.0,  1.0],    // Bottom face: blue
-  [1.0,  1.0,  0.0,  1.0],    // Right face: yellow
-  [1.0,  0.0,  1.0,  1.0]     // Left face: purple
-];
-
-var generatedColors = [];
-
-for (j=0; j<6; j++) {
-  var c = colors[j];
-
-  for (var i=0; i<4; i++) {
-    generatedColors = generatedColors.concat(c);
-  }
-}
-
-cubeVerticesColorBuffer = gl.createBuffer();
-gl.bindBuffer(gl.ARRAY_BUFFER, cubeVerticesColorBuffer);
-gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(generatedColors), gl.STATIC_DRAW);
-
- -

Определение массива элементов

- -

Как только массив вершин сгенерирован, нам нужно построить массив элементов.

- -
cubeVerticesIndexBuffer = gl.createBuffer();
-gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVerticesIndexBuffer);
-
-// Этот массив определяет каждую грань как два треугольника,
-// используя индексы в массиве вершин, чтобы определить позицию
-// каждого треугольника.
-
-var cubeVertexIndices = [
-  0,  1,  2,      0,  2,  3,    // front
-  4,  5,  6,      4,  6,  7,    // back
-  8,  9,  10,     8,  10, 11,   // top
-  12, 13, 14,     12, 14, 15,   // bottom
-  16, 17, 18,     16, 18, 19,   // right
-  20, 21, 22,     20, 22, 23    // left
-];
-
-// Теперь отправим массив элементов в GL
-
-gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,
-    new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW);
-
- -

Массив cubeVertexIndices определяет каждую грань как пару треугольников, сопоставляя каждой вершине треугольника индекс в массиве вершин куба. Таким образом куб можно представить как набор из 12 треугольников.

- -

Рисование куба

- -

Далее нам нужно обновить код нашей функции drawScene() , чтобы рисовать, используя буффер индексов куба, добавив новые вызовы {{domxref("WebGLRenderingContext.bindBuffer()", "gl.bindBuffer()")}} и {{domxref("WebGLRenderingContext.drawElements()", "gl.drawElements()")}}:

- -
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVerticesIndexBuffer);
-setMatrixUniforms();
-gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_SHORT, 0);
-
- -

Поскольку каждая грань нашего куба состоит из двух треугольников, где 6 вершин на каждой грани, или всего 36 вершин во всем кубе, даже если многие из них дублируются. Однако, поскольку наш массив индексов состоит из целых чисел, это не чрезмерное количество данных, посылаемых для каждого кадра анимации.

- -

В данный момент у нас есть анимированный куб с гранями 6 разных цветов, который прыгает и вращается.

- -

{{EmbedGHLiveSample('webgl-examples/tutorial/sample5/index.html', 670, 510) }}

- -

View the complete code | Open this demo on a new page

- -

{{PreviousNext("Web/API/WebGL_API/Tutorial/Animating_objects_with_WebGL", "Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL")}}

diff --git a/files/ru/web/api/webrtc_api/connectivity/index.html b/files/ru/web/api/webrtc_api/connectivity/index.html new file mode 100644 index 0000000000..7c4f173c05 --- /dev/null +++ b/files/ru/web/api/webrtc_api/connectivity/index.html @@ -0,0 +1,70 @@ +--- +title: WebRTC подключение +slug: Web/API/WebRTC_API/связь +translation_of: Web/API/WebRTC_API/Connectivity +--- +

{{WebRTCSidebar}}{{draft}}

+ +

Теперь, когда мы рассмотрели протоколы по отдельности, мы можем сложить их вместе. Эта статья описывает, как различные связанные с WebRTC протоколы взаимодействуют друг с другом для того, чтобы создать соединение и передать данные и/или медиа между узлами.

+ +
+

Эта страница требует серьёзной переделки для структурной целостности и полноты содержания. Много информации здесь - это хорошо, но организация являет собой путаницу, поскольку сейчас являет собой вид "местности разгрузки"(dumping ground).

+
+ +

Что  такое Предложение/Ответ и Канал сигнализации?

+ +

К сожалению, WebRTC не может создавать соединения без какого-либо сервера посередине. Мы называем его "каналом сигнализации". Это любого рода канал связи для обмена информацией перед установкой соединения, будь то электронная почта, почтовая открытка или почтовый голубь... Зависит от вас.
+  

+ +

Информация, которой мы должны обменяться - это "предложение" и "ответ", которые содержат SDP, упомянутую ниже.

+ +

Узел A, тот кто будет инициатором соединения, создаст "предложение". Затем отправит это "предложение" узлу B, используя выбранный "сигнальный канал". Узел B получит "предложение" от "сигнального канала" и создаст "ответ". Затем отправит его обратно узлу A посредством "сигнального канала".

+ +

Описания сессии

+ +

Конфигурация конечной точки WebRTC-соединения называется "описание сессии"(session description). Описание включает информацию о типе посылаемого медиа, его формате, используемом протоколе передачи, IP-адресе и порте конечной точки, и  другую информацию, необходимую для описания конечной точки передачи медиа. Эта информация обменивается и хранится с помощью "протокола описания сессии". Session Description Protocol({{Glossary("SDP")}}). Если вы хотите подробную информацию о формате данных SDP, вы можете найти её в {{RFC(2327)}}.

+ +

Когда пользователь запускает WebRTC вызов другого пользователя, создаётся специальное описание, называемое "предложение"(offer). Это описание включает всю информацию для соединения, о предлагаемой конфигурации вызывающего абонента. Получатель затем откликается "ответом"(answer), являющимся описанием его конца соединения. Таким образом, оба устройства разделяют друг с другом информацию, необходимую для того, чтобы обмениваться медиа данными. Этот обмен обрабатывается с помощью "интерактивного создания подключения". Interactive Connectivity Establishment{{Glossary("ICE")}}. ICE - протокол, который позволяет двум устройствам использовать посредника для обмена "предложениями"(offers) и "ответами"(answers), даже если эти два устройства разделены механизмом "преобразования сетевых адресов". ({{Glossary("NAT")}}(Network Address Translation).

+ +

Каждый узел, тогда, держит два описания под рукой: локальное описание (local description), описывающее себя и удалённое описание(remote description), описывающее другой конец соединения.

+ +

Процесс "предложение/ответ"(offer/answer) выполняется как, когда соединение впервые устанавливается, так и в любой момент, когда формат соединения или другая конфигурация нуждается в изменении. Независимо от того, является ли это новым соединением, или реконфигурированием существующего, это основные шаги, которые должны произойти для обмена "предложением"(offer) и "ответом"(answer). Пропустим ICE-слой на данный момент:

+ +
    +
  1. Вызывающий вызывает {{domxref("RTCPeerConnection.createOffer()")}} для создания "предложения"(offer)
  2. +
  3. Вызывающий вызывает {{domxref("RTCPeerConnection.setLocalDescription()")}} для установки этого "предложения" как локального описания (то есть описания локального конца соединения).
  4. +
  5. Вызывающий использует сигнальный сервер для передачи "предложения" к требуемому получателю вызова.
  6. +
  7. Получатель получает "предложение" и вызывает {{domxref("RTCPeerConnection.setRemoteDescription()")}} для записи его, как удалённого описания(описания другого конца соединения).
  8. +
  9. Получатель делает всякую настройку, которую должен сделать для его конца соединения, включая добавления исходящих потоков для соединения.
  10. +
  11. Получатель затем создаёт "ответ"(answer) посредством вызова {{domxref("RTCPeerConnection.createAnswer()")}}.
  12. +
  13. Получатель вызывает {{domxref("RTCPeerConnection.setLocalDescription()")}}, чтобы установить "ответ"(answer) в качестве локального описания. Получатель теперь знает конфигурацию обоих концов соединения.
  14. +
  15. Получатель использует сигнальный сервер для отправки "ответа"(answer) вызывающему.
  16. +
  17. Вызывающий получает "ответ"(answer).
  18. +
  19. Вызывающий вызывает {{domxref("RTCPeerConnection.setRemoteDescription()")}} для установки "ответа"(answer) как удалённого описания для его конца соединения. Теперь известна конфигурация обоих узлов. Медиа начинает течь в соответствии с настройками.
  20. +
+ +

Рассматриваемые и текущие описания

+ +

Спускаясь на один шаг глубже в процесс, мы находим, что localDescription и remoteDescription, свойства, возвращаемые эти двумя описаниями, не так просты, как выглядят. Потому что во время повторных переговоров(перезаключения) (renegotiation), "предложение"(offer) может быть отклонено, поскольку оно предлагает несовместимый формат. Необходимо, чтобы каждая конечная точка имела возможность предложить новый формат, но не переключаться на него, пока он не принят другим узлом. По этой причине, WebRTC использует "рассматриваемые" и "текущие" "описания".

+ +

"Текущее описание"(current description) (которое возвращается свойствами {{domxref("RTCPeerConnection.currentLocalDescription")}} и {{domxref("RTCPeerConnection.currentRemoteDescription")}}) представляет собой описание, в данный момент, фактически используемое соединением. Это самое недавнее соединение, которое обе стороны полностью согласились использовать.

+ +

"Рассматриваемое описание"(pending description) (возвращаемое {{domxref("RTCPeerConnection.pendingLocalDescription")}} и {{domxref("RTCPeerConnection.pendingRemoteDescription")}}) указывает на то описание, которое в настоящий момент находится на рассмотрении после вызова setLocalDescription() или setRemoteDescription(), соответственно.

+ +

При чтении описания (возвращаемого {{domxref("RTCPeerConnection.localDescription")}} и {{domxref("RTCPeerConnection.remoteDescription")}}), возвращаемым значением является значение pendingLocalDescription/pendingRemoteDescription, если есть рассматриваемое описание (то есть, рассматриваемое описание не null). В противном случае, возвращается текущее описание (currentLocalDescription/currentRemoteDescription).

+ +

При изменении описания путём вызова setLocalDescription() или setRemoteDescription(), указанное описание устанавливается как "рассматриваемое описание"(pending description), и WebRTC-слой начинает оценивать, действительно ли это приемлемо. После того, как предложенное описание было согласовано, значение currentLocalDescription или currentRemoteDescription изменяется на "рассматриваемое описание"(pending description), и pending description устанавливается снова в null, указывая, что "отложенного описания"(pending description) не существует.

+ +
+

pendingLocalDescription содержит не только "предложение" или "ответ" на стадии рассмотрения, но и каких-либо ICE-кандидатов, которые уже были собраны с тех пор, как "предложение" или "ответ" были созданы. Подобным образом, pendingRemoteDescription включает любых удалённых ICE-кандидатов, которые были предоставлены вызовами {{domxref("RTCPeerConnection.addIceCandidate()")}}.

+
+ +

Смотрите отдельные статьи по этим свойствам и методам для большей конкретики.

+ +

Что такое ICE-кандидат?

+ +

В дополнение к обмену информацией о медиа(обсуждённой выше в offer/answer и SDP), узлы должны обменяться информацией о сетевом соединении. Об этом известно как о ICE-кандидате и деталях доступных методов, которыми узел может общаться (непосредственно или через TURN-сервер).

+ +

Весь обмен в сложной схеме

+ +

A complete architectural diagram showing the whole WebRTC process.

diff --git a/files/ru/web/api/webrtc_api/protocols/index.html b/files/ru/web/api/webrtc_api/protocols/index.html new file mode 100644 index 0000000000..df618ab083 --- /dev/null +++ b/files/ru/web/api/webrtc_api/protocols/index.html @@ -0,0 +1,38 @@ +--- +title: Введение в протоколы WebRTC +slug: Web/API/WebRTC_API/протоколы +translation_of: Web/API/WebRTC_API/Protocols +--- +

{{APIRef("WebRTC")}}{{draft}}

+ +

В этой статье представлены протоколы, поверх которых построен WebRTC API.

+ +

ICE

+ +

Interactive Connectivity Establishment (ICE) "Установка интерактивного подключения" представляет собой каркас, позволяющий вашему веб-браузеру соединяться с узлами. Есть много причин, почему прямое соединение от узла A к узлу B просто не будет работать. Оно должно обойти межсетевые экраны, которые будут препятствовать открытию соединений, дать вам уникальный адрес, если, как в большинстве ситуаций, ваше устройство не имеет публичного IP-адреса, и передавать данные через сервер, если ваш маршрутизатор не позволяет вам напрямую соединяться с узлами. ICE использует некоторые из следующих технических приёмов, описанных ниже, для достижения этой цели:

+ +

STUN

+ +

Session Traversal Utilities for NAT (STUN) (акроним в акрониме) это протокол для нахождения и определения вашего публичного адреса и любых ограничений в вашем маршрутизаторе, которые препятствуют прямому соединению с узлом.

+ +

Клиент отправит запрос к STUN серверу в интернете, который ответит публичным адресом клиента и, доступен ли, или нет, клиент за NAT маршрутизатором.

+ +

An interaction between two users of a WebRTC application involving a STUN server.

+ +

NAT

+ +

Network Address Translation (NAT) используется для того, чтобы дать вашему устройству публичный IP-адрес. Маршрутизатор имеет публичный IP-адрес, а каждое устройство, подключённое к маршрутизатору имеет частный IP-адрес. Запросы будут транслированы от частного IP-адреса устройства к публичному IP-адресу маршрутизатора (с уникальным портом). Таким образом вам не нужен уникальный IP-адрес для каждого устройства, тем не менее, оно может быть обнаружено в интернете.

+ +

Некоторые маршрутизаторы имеют ограничения на то, кто может подключаться к устройствам в сети. Это может означать, что даже если мы имеем публичный IP-адрес, найденный STUN сервером, никто не может создать соединение. В этой ситуации нам нужно обратиться к TURN.

+ +

TURN

+ +

Некоторые маршрутизаторы, использующие NAT применяют ограничение, называемое "Симметричный NAT" (Symmetric NAT). Это означает, что маршрутизатор будет принимать соединения только от узлов, к которым вы ранее подключились.

+ +

Traversal Using Relays around NAT (TURN) предназначен для обхода ограничения "Симметричный NAT" путём открытия соединения с TURN сервером и ретрансляции всей информации через этот сервер. Вы создадите соединение с TURN сервером и сообщите всем узлам слать пакеты этому серверу, которые затем будут переправлены вам. Очевидно, что они приходят с некоторыми накладными расходами, поэтому это используется, только если нет других альтернатив.

+ +

An interaction between two users of a WebRTC application involving STUN and TURN servers.

+ +

SDP

+ +

Session Description Protocol (SDP)  - это стандарт для описания мультимедийного контента соединения,  как например: разрешение, форматы, кодеки, шифрование и т.д. Так, чтобы оба узла могли понять друг друга, после того как данные начнут передаваться. Это, в сущности, метаданные, описывающие содержимое, а не медиа контент сам по себе.

diff --git a/files/ru/web/api/webrtc_api/webrtc_basics/index.html b/files/ru/web/api/webrtc_api/webrtc_basics/index.html deleted file mode 100644 index 863dde7e14..0000000000 --- a/files/ru/web/api/webrtc_api/webrtc_basics/index.html +++ /dev/null @@ -1,351 +0,0 @@ ---- -title: Основы WebRTC -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 ---- -

{{WebRTCSidebar}}

- -

{{Draft}}

- -
-

После того, как вы понимаете WebRTC architecture, вы можете прочитать эту статью, которая сопроводит вас через создание кросс-браузерного RTC приложения. К концу этой документации, вы должны иметь рабочие каналы соединения равноправных узлов ЛВС и передачи данных средств массовой информации.

-
- -

Полу-старое содержание, из

- -

RTCPeerConnection

- -

Материал здесь происходит от RTCPeerConnection; она может остаться здесь, или же  может переместится в другое место.

- -

Основы использования
- Базовое использование RTCPeerConnection предполагает переговоры связь между локальной машиной и удаленной машиной один генерируя Session Description Protocol для обмена между ними. Вызывающая программа начинает процесс, отправив предложение на удаленное устройство, которое реагирует либо принять или отклонить запрос на соединение.

- -

Обе стороны (вызывающий и вызываемый абонент) необходимо настроить свои собственные экземпляры RTCPeerConnection, чтобы представить их конец соединения равноправных узлов ЛВС:

- -
var pc = new RTCPeerConnection();
-pc.onaddstream = function(obj) {
-  var vid = document.createElement("video");
-  document.appendChild(vid);
-  vid.srcObject = obj.stream;
-}
-
-// функция помощник
-function endCall() {
-  var videos = document.getElementsByTagName("video");
-  for (var i = 0; i < videos.length; i++) {
-    videos[i].pause();
-  }
-
-  pc.close();
-
-
-function error(err) {
-  endCall();
-}
-
- -

При инициализации вызова

- -

Если вы один инициирующий вызов, вы будете использовать navigator.getUserMedia(), чтобы получить видеопоток, а затем добавить поток в RTCPeerConnection. Как только это было сделано, вызов RTCPeerConnection, чтобы создать предложение, настроить предложение, а затем отправить его на сервер, через  соединение которое было создано.

- -
// Получить список людей с сервера
-// Пользователь выбирает список людей, чтобы установить соединение с нужным человеком
-navigator.getUserMedia({video: true}, function(stream) {
-  // Добавление локального потока не вызовет onaddstream обратного вызова,
-  // так называют его вручную.
-  pc.onaddstream = e => video.src = URL.createObjectURL(e.stream);
-  pc.addStream(stream);
-
-  pc.createOffer(function(offer) {
-    pc.setLocalDescription(offer, function() {
-      // send the offer to a server to be forwarded to the friend you're calling.
-    }, error);
-  }, error);
-});
-
- -

Ответ на вызов

- -

На противоположном конце, друг получит предложение от сервера, используя любой протокол используется для того чтобы сделать это. После того, как предложение прибывает, {{domxref ("navigator.getUserMedia ()")}} вновь используется для создания потока, который добавляется к RTCPeerConnection. {{Domxref ("RTCSessionDescription")}} объект создается и установить в качестве удаленного описания с помощью вызова {{domxref ("RTCPeerConnection.setRemoteDescription ()")}}.

- -

Тогда ответ создается с помощью RTCPeerConnection.createAnswer () и отправляется обратно на сервер, который направляет его к вызывающему абоненту.

- -
var offer = getOfferFromFriend();
-navigator.getUserMedia({video: true}, function(stream) {
-  pc.onaddstream = e => video.src = URL.createObjectURL(e.stream);
-  pc.addStream(stream);
-
-  pc.setRemoteDescription(new RTCSessionDescription(offer), function() {
-    pc.createAnswer(function(answer) {
-      pc.setLocalDescription(answer, function() {
-        // send the answer to a server to be forwarded back to the caller (you)
-      }, error);
-    }, error);
-  }, error);
-});
-
- -

Ответ на вызов

- -

На противоположном конце, человек получит предложение от сервера, используя любой протокол используется для того чтобы сделать это. После того, как предложение принято, navigator.getUserMedia () вновь используется для создания потока, который добавляется к RTCPeerConnection.  объект создается и установить в качестве удаленного описания с помощью вызова {{domxref ("RTCPeerConnection.setRemoteDescription ()")}}.

- -

Тогда ответ создается с помощью RTCPeerConnection.createAnswer () и отправляется обратно на сервер, который направляет его к вызывающему абоненту.

- -
// ПК был создан раньше, когда мы сделали первоначальное предложение
-var offer = getResponseFromFriend();
-pc.setRemoteDescription(new RTCSessionDescription(offer), function() { }, error);
- -

Old content follows!

- -

Все, что находится ниже этого пункта,  потенциально устарело. Это по-прежнему находится в стадии рассмотрения  и возможного включения в другие части документации, если они все еще актуальны.

- -
-

Не используйте примеры на этой странице. Смотрите статью Signaling and video calling для работы, актуальный пример с использованием WebRTC media.

-
- -

Note

- -

Due to recent changes in the API there are many old examples that require fixing:

- - - -

The currently working example is:

- - - -

Implementation may be inferred from the specification.

- -

This remainder of this page contains outdated information as noted on bugzilla.

- -

Shims

- -

As you can imagine, with such an early API, you must use the browser prefixes and shim it to a common variable.

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

RTCPeerConnection

- -

This is the starting point to creating a connection with a peer. It accepts configuration options about ICE servers to use to establish a connection.

- -
var pc = new RTCPeerConnection(configuration);
- -

RTCConfiguration

- -

The {{domxref("RTCConfiguration")}} object contains information about which TURN and/or STUN servers to use for ICE. This is required to ensure most users can actually create a connection by avoiding restrictions in NAT and firewalls.

- -
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"}
-    ]
-}
- -

Google runs a public STUN server that we can use. I also created an account at http://numb.viagenie.ca/ for a free TURN server to access. You may want to do the same and replace with your own credentials.

- -

ICECandidate

- - - -

After creating the PeerConnection and passing in the available STUN and TURN servers, an event will be fired once the ICE framework has found some “candidates” that will allow you to connect with a peer. This is known as an ICE Candidate and will execute a callback function on PeerConnection#onicecandidate.

- -
pc.onicecandidate = function (e) {
-    // candidate exists in e.candidate
-    if (!e.candidate) return;
-    send("icecandidate", JSON.stringify(e.candidate));
-};
- -

When the callback is executed, we must use the signal channel to send the Candidate to the peer. On Chrome, multiple ICE candidates are usually found, we only need one so I typically send the first one then remove the handler. Firefox includes the Candidate in the Offer SDP.

- -

Signal Channel

- -

Now that we have an ICE candidate, we need to send that to our peer so they know how to connect with us. However this leaves us with a chicken and egg situation; we want PeerConnection to send data to a peer but before that we need to send them metadata…

- -

This is where the signal channel comes in. It’s any method of data transport that allows two peers to exchange information. In this article, we’re going to use FireBase because it’s incredibly easy to setup and doesn't require any hosting or server-code.

- -

For now just imagine two methods exist: send() will take a key and assign data to it and recv() will call a handler when a key has a value.

- -

The structure of the database will look like this:

- -
{
-    "": {
-        "candidate:": …
-        "offer": …
-        "answer": …
-    }
-}
- -

Connections are divided by a roomId and will store 4 pieces of information, the ICE candidate from the offerer, the ICE candidate from the answerer, the offer SDP and the answer SDP.

- -

Offer

- -

An Offer SDP (Session Description Protocol) is metadata that describes to the other peer the format to expect (video, formats, codecs, encryption, resolution, size, etc etc).

- -

An exchange requires an offer from a peer, then the other peer must receive the offer and provide back an answer.

- -
pc.createOffer(function (offer) {
-    pc.setLocalDescription(offer, function() {
-        send("offer", JSON.stringify(pc.localDescription);
-    }, errorHandler);
-}, errorHandler, options);
- -

errorHandler

- -

If there was an issue generating an offer, this method will be executed with error details as the first argument.

- -
var errorHandler = function (err) {
-    console.error(err);
-};
- -
options
- -

Options for the offer SDP.

- -
var options = {
-    offerToReceiveAudio: true,
-    offerToReceiveVideo: true
-};
- -

offerToReceiveAudio/Video tells the other peer that you would like to receive video or audio from them. This is not needed for DataChannels.

- -

Once the offer has been generated we must set the local SDP to the new offer and send it through the signal channel to the other peer and await their Answer SDP.

- -

Answer

- -

An Answer SDP is just like an offer but a response; sort of like answering the phone. We can only generate an answer once we have received an offer.

- -
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);
-});
- -

DataChannel

- -

I will first explain how to use PeerConnection for the DataChannels API and transferring arbitrary data between peers.

- -

Note: At the time of this article, interoperability between Chrome and Firefox is not possible with DataChannels. Chrome supports a similar but private protocol and will be supporting the standard protocol soon.

- -
var channel = pc.createDataChannel(channelName, channelOptions);
- -

The offerer should be the peer who creates the channel. The answerer will receive the channel in the callback ondatachannel on PeerConnection. You must call createDataChannel() once before creating the offer.

- -

channelName

- -

This is a string that acts as a label for your channel name. Warning: Make sure your channel name has no spaces or Chrome will fail on createAnswer().

- -

channelOptions

- -
var channelOptions = {};
- -

Currently these options are not well supported on Chrome so you can leave this empty for now. Check the RFC for more information about the options.

- -

Channel Events and Methods

- -
onopen
- -

Executed when the connection is established.

- -
onerror
- -

Executed if there is an error creating the connection. First argument is an error object.

- -
channel.onerror = function (err) {
-    console.error("Channel Error:", err);
-};
- -
onmessage
- -
channel.onmessage = function (e) {
-    console.log("Got message:", e.data);
-}
- -

The heart of the connection. When you receive a message, this method will execute. The first argument is an event object which contains the data, time received and other information.

- -
onclose
- -

Executed if the other peer closes the connection.

- -

Binding the Events

- -

If you were the creator of the channel (meaning the offerer), you can bind events directly to the DataChannel you created with createChannel. If you are the answerer, you must use the ondatachannel callback on PeerConnection to access the same channel.

- -
pc.ondatachannel = function (e) {
-    e.channel.onmessage = function () { … };
-};
- -

The channel is available in the event object passed into the handler as e.channel.

- -
send()
- -
channel.send("Hi Peer!");
- -

This method allows you to send data directly to the peer! Amazing. You must send either String, Blob, ArrayBuffer or ArrayBufferView, so be sure to stringify objects.

- -
close()
- -

Close the channel once the connection should end. It is recommended to do this on page unload.

- -

Media

- -

Now we will cover transmitting media such as audio and video. To display the video and audio you must include a <video> tag on the document with the attribute autoplay.

- -

Get User Media

- -
<video id="preview" autoplay></video>
-
-var video = document.getElementById("preview");
-navigator.getUserMedia(constraints, function (stream) {
-    video.src = URL.createObjectURL(stream);
-}, errorHandler);
- -

constraints

- -

Constraints on what media types you want to return from the user.

- -
var constraints = {
-    video: true,
-    audio: true
-};
- -

If you just want an audio chat, remove the video member.

- -
errorHandler
- -

Executed if there is an error returning the requested media.

- -

Media Events and Methods

- -
addStream
- -

Add the stream from getUserMedia to the PeerConnection.

- -
pc.addStream(stream);
- -
onaddstream
- -
<video id="otherPeer" autoplay></video>
-
-var otherPeer = document.getElementById("otherPeer");
-pc.onaddstream = function (e) {
-    otherPeer.src = URL.createObjectURL(e.stream);
-};
- -

Executed when the connection has been setup and the other peer has added the stream to the peer connection with addStream. You need another <video> tag to display the other peer's media.

- -

The first argument is an event object with the other peer's media stream.

diff --git "a/files/ru/web/api/webrtc_api/\320\277\321\200\320\276\321\202\320\276\320\272\320\276\320\273\321\213/index.html" "b/files/ru/web/api/webrtc_api/\320\277\321\200\320\276\321\202\320\276\320\272\320\276\320\273\321\213/index.html" deleted file mode 100644 index df618ab083..0000000000 --- "a/files/ru/web/api/webrtc_api/\320\277\321\200\320\276\321\202\320\276\320\272\320\276\320\273\321\213/index.html" +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: Введение в протоколы WebRTC -slug: Web/API/WebRTC_API/протоколы -translation_of: Web/API/WebRTC_API/Protocols ---- -

{{APIRef("WebRTC")}}{{draft}}

- -

В этой статье представлены протоколы, поверх которых построен WebRTC API.

- -

ICE

- -

Interactive Connectivity Establishment (ICE) "Установка интерактивного подключения" представляет собой каркас, позволяющий вашему веб-браузеру соединяться с узлами. Есть много причин, почему прямое соединение от узла A к узлу B просто не будет работать. Оно должно обойти межсетевые экраны, которые будут препятствовать открытию соединений, дать вам уникальный адрес, если, как в большинстве ситуаций, ваше устройство не имеет публичного IP-адреса, и передавать данные через сервер, если ваш маршрутизатор не позволяет вам напрямую соединяться с узлами. ICE использует некоторые из следующих технических приёмов, описанных ниже, для достижения этой цели:

- -

STUN

- -

Session Traversal Utilities for NAT (STUN) (акроним в акрониме) это протокол для нахождения и определения вашего публичного адреса и любых ограничений в вашем маршрутизаторе, которые препятствуют прямому соединению с узлом.

- -

Клиент отправит запрос к STUN серверу в интернете, который ответит публичным адресом клиента и, доступен ли, или нет, клиент за NAT маршрутизатором.

- -

An interaction between two users of a WebRTC application involving a STUN server.

- -

NAT

- -

Network Address Translation (NAT) используется для того, чтобы дать вашему устройству публичный IP-адрес. Маршрутизатор имеет публичный IP-адрес, а каждое устройство, подключённое к маршрутизатору имеет частный IP-адрес. Запросы будут транслированы от частного IP-адреса устройства к публичному IP-адресу маршрутизатора (с уникальным портом). Таким образом вам не нужен уникальный IP-адрес для каждого устройства, тем не менее, оно может быть обнаружено в интернете.

- -

Некоторые маршрутизаторы имеют ограничения на то, кто может подключаться к устройствам в сети. Это может означать, что даже если мы имеем публичный IP-адрес, найденный STUN сервером, никто не может создать соединение. В этой ситуации нам нужно обратиться к TURN.

- -

TURN

- -

Некоторые маршрутизаторы, использующие NAT применяют ограничение, называемое "Симметричный NAT" (Symmetric NAT). Это означает, что маршрутизатор будет принимать соединения только от узлов, к которым вы ранее подключились.

- -

Traversal Using Relays around NAT (TURN) предназначен для обхода ограничения "Симметричный NAT" путём открытия соединения с TURN сервером и ретрансляции всей информации через этот сервер. Вы создадите соединение с TURN сервером и сообщите всем узлам слать пакеты этому серверу, которые затем будут переправлены вам. Очевидно, что они приходят с некоторыми накладными расходами, поэтому это используется, только если нет других альтернатив.

- -

An interaction between two users of a WebRTC application involving STUN and TURN servers.

- -

SDP

- -

Session Description Protocol (SDP)  - это стандарт для описания мультимедийного контента соединения,  как например: разрешение, форматы, кодеки, шифрование и т.д. Так, чтобы оба узла могли понять друг друга, после того как данные начнут передаваться. Это, в сущности, метаданные, описывающие содержимое, а не медиа контент сам по себе.

diff --git "a/files/ru/web/api/webrtc_api/\321\201\320\262\321\217\320\267\321\214/index.html" "b/files/ru/web/api/webrtc_api/\321\201\320\262\321\217\320\267\321\214/index.html" deleted file mode 100644 index 7c4f173c05..0000000000 --- "a/files/ru/web/api/webrtc_api/\321\201\320\262\321\217\320\267\321\214/index.html" +++ /dev/null @@ -1,70 +0,0 @@ ---- -title: WebRTC подключение -slug: Web/API/WebRTC_API/связь -translation_of: Web/API/WebRTC_API/Connectivity ---- -

{{WebRTCSidebar}}{{draft}}

- -

Теперь, когда мы рассмотрели протоколы по отдельности, мы можем сложить их вместе. Эта статья описывает, как различные связанные с WebRTC протоколы взаимодействуют друг с другом для того, чтобы создать соединение и передать данные и/или медиа между узлами.

- -
-

Эта страница требует серьёзной переделки для структурной целостности и полноты содержания. Много информации здесь - это хорошо, но организация являет собой путаницу, поскольку сейчас являет собой вид "местности разгрузки"(dumping ground).

-
- -

Что  такое Предложение/Ответ и Канал сигнализации?

- -

К сожалению, WebRTC не может создавать соединения без какого-либо сервера посередине. Мы называем его "каналом сигнализации". Это любого рода канал связи для обмена информацией перед установкой соединения, будь то электронная почта, почтовая открытка или почтовый голубь... Зависит от вас.
-  

- -

Информация, которой мы должны обменяться - это "предложение" и "ответ", которые содержат SDP, упомянутую ниже.

- -

Узел A, тот кто будет инициатором соединения, создаст "предложение". Затем отправит это "предложение" узлу B, используя выбранный "сигнальный канал". Узел B получит "предложение" от "сигнального канала" и создаст "ответ". Затем отправит его обратно узлу A посредством "сигнального канала".

- -

Описания сессии

- -

Конфигурация конечной точки WebRTC-соединения называется "описание сессии"(session description). Описание включает информацию о типе посылаемого медиа, его формате, используемом протоколе передачи, IP-адресе и порте конечной точки, и  другую информацию, необходимую для описания конечной точки передачи медиа. Эта информация обменивается и хранится с помощью "протокола описания сессии". Session Description Protocol({{Glossary("SDP")}}). Если вы хотите подробную информацию о формате данных SDP, вы можете найти её в {{RFC(2327)}}.

- -

Когда пользователь запускает WebRTC вызов другого пользователя, создаётся специальное описание, называемое "предложение"(offer). Это описание включает всю информацию для соединения, о предлагаемой конфигурации вызывающего абонента. Получатель затем откликается "ответом"(answer), являющимся описанием его конца соединения. Таким образом, оба устройства разделяют друг с другом информацию, необходимую для того, чтобы обмениваться медиа данными. Этот обмен обрабатывается с помощью "интерактивного создания подключения". Interactive Connectivity Establishment{{Glossary("ICE")}}. ICE - протокол, который позволяет двум устройствам использовать посредника для обмена "предложениями"(offers) и "ответами"(answers), даже если эти два устройства разделены механизмом "преобразования сетевых адресов". ({{Glossary("NAT")}}(Network Address Translation).

- -

Каждый узел, тогда, держит два описания под рукой: локальное описание (local description), описывающее себя и удалённое описание(remote description), описывающее другой конец соединения.

- -

Процесс "предложение/ответ"(offer/answer) выполняется как, когда соединение впервые устанавливается, так и в любой момент, когда формат соединения или другая конфигурация нуждается в изменении. Независимо от того, является ли это новым соединением, или реконфигурированием существующего, это основные шаги, которые должны произойти для обмена "предложением"(offer) и "ответом"(answer). Пропустим ICE-слой на данный момент:

- -
    -
  1. Вызывающий вызывает {{domxref("RTCPeerConnection.createOffer()")}} для создания "предложения"(offer)
  2. -
  3. Вызывающий вызывает {{domxref("RTCPeerConnection.setLocalDescription()")}} для установки этого "предложения" как локального описания (то есть описания локального конца соединения).
  4. -
  5. Вызывающий использует сигнальный сервер для передачи "предложения" к требуемому получателю вызова.
  6. -
  7. Получатель получает "предложение" и вызывает {{domxref("RTCPeerConnection.setRemoteDescription()")}} для записи его, как удалённого описания(описания другого конца соединения).
  8. -
  9. Получатель делает всякую настройку, которую должен сделать для его конца соединения, включая добавления исходящих потоков для соединения.
  10. -
  11. Получатель затем создаёт "ответ"(answer) посредством вызова {{domxref("RTCPeerConnection.createAnswer()")}}.
  12. -
  13. Получатель вызывает {{domxref("RTCPeerConnection.setLocalDescription()")}}, чтобы установить "ответ"(answer) в качестве локального описания. Получатель теперь знает конфигурацию обоих концов соединения.
  14. -
  15. Получатель использует сигнальный сервер для отправки "ответа"(answer) вызывающему.
  16. -
  17. Вызывающий получает "ответ"(answer).
  18. -
  19. Вызывающий вызывает {{domxref("RTCPeerConnection.setRemoteDescription()")}} для установки "ответа"(answer) как удалённого описания для его конца соединения. Теперь известна конфигурация обоих узлов. Медиа начинает течь в соответствии с настройками.
  20. -
- -

Рассматриваемые и текущие описания

- -

Спускаясь на один шаг глубже в процесс, мы находим, что localDescription и remoteDescription, свойства, возвращаемые эти двумя описаниями, не так просты, как выглядят. Потому что во время повторных переговоров(перезаключения) (renegotiation), "предложение"(offer) может быть отклонено, поскольку оно предлагает несовместимый формат. Необходимо, чтобы каждая конечная точка имела возможность предложить новый формат, но не переключаться на него, пока он не принят другим узлом. По этой причине, WebRTC использует "рассматриваемые" и "текущие" "описания".

- -

"Текущее описание"(current description) (которое возвращается свойствами {{domxref("RTCPeerConnection.currentLocalDescription")}} и {{domxref("RTCPeerConnection.currentRemoteDescription")}}) представляет собой описание, в данный момент, фактически используемое соединением. Это самое недавнее соединение, которое обе стороны полностью согласились использовать.

- -

"Рассматриваемое описание"(pending description) (возвращаемое {{domxref("RTCPeerConnection.pendingLocalDescription")}} и {{domxref("RTCPeerConnection.pendingRemoteDescription")}}) указывает на то описание, которое в настоящий момент находится на рассмотрении после вызова setLocalDescription() или setRemoteDescription(), соответственно.

- -

При чтении описания (возвращаемого {{domxref("RTCPeerConnection.localDescription")}} и {{domxref("RTCPeerConnection.remoteDescription")}}), возвращаемым значением является значение pendingLocalDescription/pendingRemoteDescription, если есть рассматриваемое описание (то есть, рассматриваемое описание не null). В противном случае, возвращается текущее описание (currentLocalDescription/currentRemoteDescription).

- -

При изменении описания путём вызова setLocalDescription() или setRemoteDescription(), указанное описание устанавливается как "рассматриваемое описание"(pending description), и WebRTC-слой начинает оценивать, действительно ли это приемлемо. После того, как предложенное описание было согласовано, значение currentLocalDescription или currentRemoteDescription изменяется на "рассматриваемое описание"(pending description), и pending description устанавливается снова в null, указывая, что "отложенного описания"(pending description) не существует.

- -
-

pendingLocalDescription содержит не только "предложение" или "ответ" на стадии рассмотрения, но и каких-либо ICE-кандидатов, которые уже были собраны с тех пор, как "предложение" или "ответ" были созданы. Подобным образом, pendingRemoteDescription включает любых удалённых ICE-кандидатов, которые были предоставлены вызовами {{domxref("RTCPeerConnection.addIceCandidate()")}}.

-
- -

Смотрите отдельные статьи по этим свойствам и методам для большей конкретики.

- -

Что такое ICE-кандидат?

- -

В дополнение к обмену информацией о медиа(обсуждённой выше в offer/answer и SDP), узлы должны обменяться информацией о сетевом соединении. Об этом известно как о ICE-кандидате и деталях доступных методов, которыми узел может общаться (непосредственно или через TURN-сервер).

- -

Весь обмен в сложной схеме

- -

A complete architectural diagram showing the whole WebRTC process.

diff --git a/files/ru/web/api/websockets_api/index.html b/files/ru/web/api/websockets_api/index.html new file mode 100644 index 0000000000..8e6c614a0b --- /dev/null +++ b/files/ru/web/api/websockets_api/index.html @@ -0,0 +1,58 @@ +--- +title: WebSockets +slug: WebSockets +tags: + - NeedsBrowserCompatibility + - NeedsTranslation + - References + - TopicStub + - WebSockets +translation_of: Web/API/WebSockets_API +--- +

Вебсокеты это продвинутая технология, позволяющая открыть постоянное двунаправленное сетевое соединение между браузером пользователя и сервером. С помощью его API вы можете отправить сообщение на сервер и получить ответ без выполнения http запроса, причем этот процесс будет событийно-управляемым.

+ +
+
+

Документация

+ +
+
Writing WebSocket client applications
+
Учебник описывающий как написать WebSocket клиента работающего в браузере.
+
Справочник по WebSocket
+
A reference to the client-side WebSocket API.
+
(TBD) Writing WebSocket servers
+
A guide to writing server-side code to handle the WebSocket protocol.
+
+ +

View All...

+
+ +
+

Tools

+ + + + + + +
+
+ +

Совместимость с браузерами

+ +

{{Compat("api.WebSocket")}}

+ +

Смотрите также

+ + diff --git a/files/ru/web/api/websockets_api/writing_websocket_client_applications/index.html b/files/ru/web/api/websockets_api/writing_websocket_client_applications/index.html new file mode 100644 index 0000000000..5eaca515c2 --- /dev/null +++ b/files/ru/web/api/websockets_api/writing_websocket_client_applications/index.html @@ -0,0 +1,195 @@ +--- +title: Написание клиентских приложений с помощью вебсокетов +slug: WebSockets/Writing_WebSocket_client_applications +translation_of: Web/API/WebSockets_API/Writing_WebSocket_client_applications +--- +

{{ draft() }}

+ +

Вебсокеты - технология, которя позволяет открыть интерактивную сессию общения между браузером пользователя и сервером. Соединяясь через вебсокеты, веб-приложения могут осуществлять взаимодействие в реальном времени вместо того, чтобы делать запросы к клиенту о входящих/исходящих изменениях.

+ +
Замечание: У нас есть работающий пример чата, части кода из которого используются в статье. Пример будет доступен, когда инфраструктура сайта сможет должным образом поддерживать хостинг примеров с использованием вебсокетов.
+ +

Доступность вебсокетов

+ +

API вебсокетов доступно в Javascript коде, область видимости которого включает объект DOM {{ domxref("Window") }} или любой объект, реализующий {{ domxref("WorkerUtils") }}; это означает, что вы можете использовать Web Workers.

+ +
Замечание: API вебсокетов (как и протокол лежащий в его основе) всё ещё проходят этап активной разработки; в настоящее время существует много проблем совместимости с разными браузерами (и даже с разными релизами одного и того же браузера).
+ +

Создание объекта WebSocket

+ +

Чтобы общаться через протокол вебсокетов необходимо создать объект WebSocket; при его создании автоматически происходит попытка открыть соединение с сервером.

+ +

Конструктор WebSocket принимает один обязательный и один необязательный параметр:

+ +
WebSocket WebSocket(
+  in DOMString url,
+  in optional DOMString protocols
+);
+
+WebSocket WebSocket(
+  in DOMString url,
+  in optional DOMString[] protocols
+);
+
+ +
+
url
+
URL, с которым происходит соединение; это должен быть URL вебсокет-сервера.
+
protocols {{ optional_inline() }}
+
Может быть одной строкой протокола или массивом таких строк. Эти строки используют для индикации под-протоколов; таким образом, один сервер может реализовывать несколько под-протоколов вебсокетов (к примеру, вам может потребоваться, чтобы сервер мог обрабатывать разные типы взаимодействий в зависимости от определённого под-протокола). Если вы не укажете строку протокола, то будет передана пустая строка.
+
+ +

В конструкторе могут возникать следующие исключения:

+ +
+
SECURITY_ERR
+
Порт, к которому проводится подключение, заблокирован.
+
+ +
+
+ +

Ошибки подключения

+ +

Если ошибка случается во время попытки подключения, то в объект WebSocket сначала посылается простое событие с именем «error» (таким образом, задействуя обработчик onerror), потом - событие CloseEvent  (таким образом, задействуя обработчик onclose) чтобы обозначить причину закрытия соединения.

+ +

Однако, начиная с версии Firefox 11, типичным является получение в консоль от платформы Mozilla расширенного сообщения об обшибке и кода завершения, как то определено в RFC 6455, Section 7.4 посредством CloseEvent.

+ +

Примеры

+ +

Этот простой пример создает новый WebSocket, подключаемый к серверу ws://www.example.com/socketserver. В данном примере в конструктор сокета в качестве дополнительного параметра передается пользовательский протокол "protocolOne", хотя эта часть может быть опущена.

+ +
var exampleSocket = new WebSocket("ws://www.example.com/socketserver", "protocolOne");
+
+ +

После выполнения функции, exampleSocket.readyState будет иметь значение CONNECTING. readyState изменится на OPEN как только соединение станет готовым к передаче данных.

+ +

Если нужно открыть соединение, поддерживающее несколько протоколов, можно передать массив протоколов:

+ +
var exampleSocket = new WebSocket("ws://www.example.com/socketserver", ["protocolOne", "protocolTwo"]);
+
+ +

Когда соединение установлено (что соответствует, readyState OPEN), exampleSocket.protocol сообщит, какой протокол выбрал сервер.

+ +

In the above examples ws has replaced http, similarly wss replaces https. Establishing a WebSocket relies on the HTTP Upgrade mechanism, so the request for the protocol upgrade is implicit when we address the HTTP server as ws://www.example.com or wss://www.example.com.

+ +

Отправка данных на сервер

+ +

Однажды открыв соединение, вы можете передавать данные на сервер. Для осуществления этого, вызовите метод send() объекта WebSocket  для каждого сообщение, которое желаете отправить:

+ +
exampleSocket.send("Here's some text that the server is urgently awaiting!");
+
+ +

Вы можете пересылать данные в виде строки, {{ domxref("Blob") }}, так и ArrayBuffer.

+ +
Note: Prior to version 11, Firefox only supported sending data as a string.
+ +

As establishing a connection is asynchronous and prone to failure there is no guarantee that calling the send() method immediately after creating a WebSocket object will be successful. We can at least be sure that attempting to send data only takes place once a connection is established by defining an onopen handler to do the work:

+ +
exampleSocket.onopen = function (event) {
+  exampleSocket.send("Here's some text that the server is urgently awaiting!");
+};
+
+ +

Using JSON to transmit objects

+ +

One handy thing you can do is use JSON to send reasonably complex data to the server. For example, a chat program can interact with a server using a protocol implemented using packets of JSON-encapsulated data:

+ +
// Send text to all users through the server
+function sendText() {
+  // Construct a msg object containing the data the server needs to process the message from the chat client.
+  var msg = {
+    type: "message",
+    text: document.getElementById("text").value,
+    id:   clientID,
+    date: Date.now()
+  };
+
+  // Send the msg object as a JSON-formatted string.
+  exampleSocket.send(JSON.stringify(msg));
+
+  // Blank the text input element, ready to receive the next line of text from the user.
+  document.getElementById("text").value = "";
+}
+
+ +

Receiving messages from the server

+ +

WebSockets is an event-driven API; when messages are received, a "message" event is delivered to the onmessage function. To begin listening for incoming data, you can do something like this:

+ +
exampleSocket.onmessage = function (event) {
+  console.log(event.data);
+}
+
+ +

Receiving and interpreting JSON objects

+ +

Let's consider the chat client application first alluded to in {{ anch("Using JSON to transmit objects") }}. There are assorted types of data packets the client might receive, such as:

+ +
    +
  • Login handshake
  • +
  • Message text
  • +
  • User list updates
  • +
+ +

The code that interprets these incoming messages might look like this:

+ +
exampleSocket.onmessage = function(event) {
+  var f = document.getElementById("chatbox").contentDocument;
+  var text = "";
+  var msg = JSON.parse(event.data);
+  var time = new Date(msg.date);
+  var timeStr = time.toLocaleTimeString();
+
+  switch(msg.type) {
+    case "id":
+      clientID = msg.id;
+      setUsername();
+      break;
+    case "username":
+      text = "<b>User <em>" + msg.name + "</em> signed in at " + timeStr + "</b><br>";
+      break;
+    case "message":
+      text = "(" + timeStr + ") <b>" + msg.name + "</b>: " + msg.text + "<br>";
+      break;
+    case "rejectusername":
+      text = "<b>Your username has been set to <em>" + msg.name + "</em> because the name you chose is in use.</b><br>"
+      break;
+    case "userlist":
+      var ul = "";
+      for (i=0; i < msg.users.length; i++) {
+        ul += msg.users[i] + "<br>";
+      }
+      document.getElementById("userlistbox").innerHTML = ul;
+      break;
+  }
+
+  if (text.length) {
+    f.write(text);
+    document.getElementById("chatbox").contentWindow.scrollByPages(1);
+  }
+};
+
+ +

Here we use JSON.parse() to convert the JSON object back into the original object, then examine and act upon its contents.

+ +

Text data format

+ +

Text received over a WebSocket connection is in UTF-8 format.

+ +

Prior to Gecko 9.0 {{ geckoRelease("9.0") }}, certain non-characters in otherwise valid UTF-8 text would cause the connection to be terminated. Now Gecko permits these values.

+ +

Closing the connection

+ +

When you've finished using the WebSocket connection, call the WebSocket method close():

+ +
exampleSocket.close();
+
+ +

It may be helpful to examine the socket's bufferedAmount attribute before attempting to close the connection to determine if any data has yet to be transmitted on the network.

+ +

Security considerations

+ +

WebSockets should not be used in a mixed content environment; that is, you shouldn't open a non-secure WebSocket connection from a page loaded using HTTPS or vice-versa. In fact, some browsers explicitly forbid this, including Firefox 8 and later.

+ +

{{ languages ( {"zh-tw": "zh_tw/WebSockets/Writing_WebSocket_client_applications"} ) }}

diff --git a/files/ru/web/api/window/domcontentloaded_event/index.html b/files/ru/web/api/window/domcontentloaded_event/index.html new file mode 100644 index 0000000000..7702dcfd24 --- /dev/null +++ b/files/ru/web/api/window/domcontentloaded_event/index.html @@ -0,0 +1,146 @@ +--- +title: DOMContentLoaded +slug: Web/Events/DOMContentLoaded +tags: + - события +translation_of: Web/API/Window/DOMContentLoaded_event +--- +

Событие DOMContentLoaded происходит когда весь HTML был полностью загружен и пройден парсером, не дожидаясь окончания загрузки таблиц стилей, изображений и фреймов. Значительно отличающееся от него событие load используется для отслеживания только полностью загруженной страницы. Широко распространённой ошибкой является использование load в ситуации когда DOMContentLoaded является более подходящим, будьте внимательны.

+ +

{{Note("Синхронный JavaScript останавливает парсинг DOM.")}}

+ +

{{Note("Существуют различные библиотеки, как общего назначения так и специализированные, предлагающие кросс-браузерные методы, позволяющие определить, что DOM готов к использованию.")}}

+ +

Ускорение работы

+ +

Если вы хотите чтобы DOM был пройден парсером насколько возможно быстро, сразу после запроса пользователем страницы, вы можете попробовать выполнять JavaScript асинхронно и оптимизировать загрузку таблиц стилей которые обычно замедляют загрузку документа поскольку загружаясь одновременно "крадут" трафик у основного документа.

+ +

Основная информация

+ +
+
Спецификация
+
HTML5
+
Интерфейс 
+
Event
+
Всплывает
+
Да
+
Отменяемое
+
Да (несмотря на то, что в спецификации указано как простое событие, которое не является отменяемым)
+
Цель 
+
Document
+
Default Action
+
Нет.
+
+ +

Свойства

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
СвойствоТипОписание
target {{readonlyInline}}{{domxref("EventTarget")}}The event target (the topmost target in the DOM tree).
type {{readonlyInline}}{{domxref("DOMString")}}Тип события.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Whether the event normally bubbles or not.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Возможно ли отменить событие.
+ +

Пример

+ +
<script>
+  document.addEventListener("DOMContentLoaded", function(event) {
+    console.log("DOM fully loaded and parsed");
+  });
+</script>
+
+ +
<script>
+  document.addEventListener("DOMContentLoaded", function(event) {
+    console.log("DOM fully loaded and parsed");
+  });
+
+for(var i=0; i<1000000000; i++)
+{} // this synchronous script is going to delay parsing of the DOM. So the DOMContentLoaded event is going to launch later.
+</script>
+
+ +

Поддержка браузерами

+ +

{{CompatibilityTable}}

+ + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка1.0[1]{{CompatGeckoDesktop("1")}}[1]9.0[2]9.03.1[1]
+ + + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{CompatVersionUnknown}}[1]{{CompatGeckoMobile("1")}}[1]{{CompatUnknown}}[2]{{CompatVersionUnknown}}{{CompatVersionUnknown}}[1]
+ +

[1] Всплытие для этого события поддерживается как минимум с версий Gecko 1.9.2, Chrome 6, и Safari 4.

+ +

[2] Internet Explorer 8 поддерживает событие readystatechange, которое можно использовать для определения готовности DOM. В более ранних версиях Internet Explorer,это событие можно определить циклическим выполнением document.documentElement.doScroll("left");, это событие будет выбрасывать ошибку если DOM не готов.

+ +

Связанные события

+ +
    +
  • {{event("DOMContentLoaded")}}
  • +
  • {{event("readystatechange")}}
  • +
  • {{event("load")}}
  • +
  • {{event("beforeunload")}}
  • +
  • {{event("unload")}}
  • +
diff --git a/files/ru/web/api/window/load_event/index.html b/files/ru/web/api/window/load_event/index.html new file mode 100644 index 0000000000..a8d456806d --- /dev/null +++ b/files/ru/web/api/window/load_event/index.html @@ -0,0 +1,88 @@ +--- +title: load +slug: Web/Events/load +translation_of: Web/API/Window/load_event +--- +

Событие load происходит когда ресурс и его зависимые ресурсы закончили загружаться.

+ +

General info

+ +
+
Спецификация
+
DOM L3
+
Интерфейс
+
UIEvent
+
Всплывает
+
Да
+
Отменяемое
+
Нет
+
Цель
+
Window
+
Default Action
+
Нет.
+
+ +

Свойства

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeDescription
target {{readonlyInline}}EventTargetThe event target (the topmost target in the DOM tree).
type {{readonlyInline}}DOMStringThe type of event.
bubbles {{readonlyInline}}BooleanWhether the event normally bubbles or not.
cancelable {{readonlyInline}}BooleanWhether the event is cancellable or not.
view {{readonlyInline}}WindowProxydocument.defaultView (window of the document)
detail {{readonlyInline}}long (float)0.
+ +

Пример

+ +
<script>
+  window.addEventListener("load", function(event) {
+    console.log("All resources finished loading!");
+  });
+</script>
+
+ +

 

+ +

Связанные события

+ +
    +
  • {{event("DOMContentLoaded")}}
  • +
  • {{event("readystatechange")}}
  • +
  • {{event("load")}}
  • +
  • {{event("beforeunload")}}
  • +
  • {{event("unload")}}
  • +
diff --git a/files/ru/web/api/window/requestanimationframe/index.html b/files/ru/web/api/window/requestanimationframe/index.html new file mode 100644 index 0000000000..d451cae62f --- /dev/null +++ b/files/ru/web/api/window/requestanimationframe/index.html @@ -0,0 +1,92 @@ +--- +title: window.requestAnimationFrame() +slug: DOM/window.requestAnimationFrame +tags: + - Анимация +translation_of: Web/API/window/requestAnimationFrame +--- +
{{APIRef}}
+ +

window.requestAnimationFrame указывает браузеру на то, что вы хотите произвести анимацию, и просит его запланировать перерисовку на следующем кадре анимации. В качестве параметра метод получает функцию, которая будет вызвана перед перерисовкой.

+ +
Заметка: Ваш callback метод сам должен вызвать requestAnimationFrame() иначе анимация остановится.
+ +

Вы должны вызывать этот метод всякий раз, когда готовы обновить анимацию на экране, чтобы запросить планирование анимации. Обычно запросы происходят 60 раз в секунду, но чаще всего совпадают с частотой обновления экрана. В большинстве браузеров в фоновых вкладках или скрытых <iframe>, вызовы requestAnimationFrame() приостанавливаются, для того, чтобы повысить производительность и время работы батареи.

+ +

Callback методу передаётся один аргумент, {{domxref("DOMHighResTimeStamp")}}, который содержит текущее время (количество миллисекунд, прошедших с момента time origin). Когда callback-и, отправленные в очередь с помощью requestAnimationFrame() начинают вызывать несколько callback-ов в одном кадре, каждый получает одинаковый timestamp, хотя для вычисления каждого callback было затрачено время. Этот timestamp - десятичное число в миллисекундах, но с минимальной точностью в 1ms (1000 µs).

+ +

Синтаксис

+ +
window.requestAnimationFrame(callback);
+ +

Параметры

+ +
+
callback
+
Функция, которая будет вызвана, когда придёт время обновить вашу анимацию на следующей перерисовке.
+
element {{ optional_inline() }}
+
Необязательный параметр (не используется в Firefox или IE), определяющий элемент, который визуально содержит всю анимацию. Для canvas'а и WebGL'a им должен быть {{ HTMLElement("canvas") }}. Для других элементов вы можете опустить этот параметр для чуть лучшего пользовательского опыта.
+
+ +

Возвращаемое значение

+ +

requestID — длинное целое, являющееся уникальным идентификатором для записи, содержащей callback. Оно не равно нулю, но других предположений о его значении делать не следует. Вы можете передать его в {{ domxref("window.cancelAnimationFrame()") }} для отмены вызова.

+ +

Пример

+ +
var start = null;
+var element = document.getElementById('SomeElementYouWantToAnimate');
+
+function step(timestamp) {
+  if (!start) start = timestamp;
+  var progress = timestamp - start;
+  element.style.transform = 'translateX(' + Math.min(progress / 10, 200) + 'px)';
+  if (progress < 2000) {
+    window.requestAnimationFrame(step);
+  }
+}
+
+window.requestAnimationFrame(step);
+ +

Примечание

+ +

В Edge версиях младше 17 и в Internet Explorer не надежно запускать requestAnimationFrame перед циклом рисования.

+ +

Спецификация

+ + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('HTML WHATWG', '#animation-frames', 'requestAnimationFrame')}}{{Spec2('HTML WHATWG')}}Без изменений, заменяет предыдущую.
{{SpecName('RequestAnimationFrame', '#dom-windowanimationtiming-requestanimationframe', 'requestAnimationFrame')}}{{Spec2('RequestAnimationFrame')}}Первоначальное описание.
+ +

Браузерная совместимость

+ +

{{Compat("api.Window.requestAnimationFrame")}}

+ +

Смотрите также

+ + diff --git a/files/ru/web/api/window/unhandledrejection_event/index.html b/files/ru/web/api/window/unhandledrejection_event/index.html new file mode 100644 index 0000000000..5248e75748 --- /dev/null +++ b/files/ru/web/api/window/unhandledrejection_event/index.html @@ -0,0 +1,49 @@ +--- +title: unhandledrejection +slug: Web/Events/unhandledrejection +translation_of: Web/API/Window/unhandledrejection_event +--- +

Событие unhandledrejection происходит, когда {{jsxref("Promise")}} завершен с ошибкой, но на данную ошибку не установлен обработчик.

+ + + + + + + + + + + + + + + + + + + + +
ВсплытиеНет
Возможность отменыНет
Target objectsdefaultView
Интерфейс{{domxref("PromiseRejectionEvent")}}
+ +

Пример

+ +
window.addEventListener("unhandledrejection", function (event) {
+  console.warn("Внимание: Необработанная ошибка Promise. Позор вам! Причина: "
+               + event.reason);
+});
+
+ +

Inheritance

+ +

Событие unhandledrejection реализует {{domxref("PromiseRejectionEvent")}} интерфейс, который наследуется от {{domxref("Event")}}. Вы можете использовать свойства и методы, определенные в данных интерфейсах.

+ +

{{InheritanceDiagram('','','', 'PromiseRejectionEvent')}}

+ +

Смотрите также

+ +
    +
  • {{Event("rejectionhandled")}}
  • +
  • {{domxref("PromiseRejectionEvent")}}
  • +
  • {{domxref("Promise")}}
  • +
diff --git a/files/ru/web/api/windowbase64/base64_encoding_and_decoding/index.html b/files/ru/web/api/windowbase64/base64_encoding_and_decoding/index.html deleted file mode 100644 index b85f3671ef..0000000000 --- a/files/ru/web/api/windowbase64/base64_encoding_and_decoding/index.html +++ /dev/null @@ -1,138 +0,0 @@ ---- -title: Кодирование и декодирование в формате Base64 -slug: Web/API/WindowBase64/Base64_encoding_and_decoding -translation_of: Glossary/Base64 ---- -

Base64 - это группа cхожих binary-to-text encoding схем, которые представляют двоичные данные в ASCII-формате методом перевода в radix-64 представление. Термин Base64 происходит от a specific MIME content transfer encoding.

- -

Кодирование Base64 широко используется в случаях, когда требуется перекодировать двоичные данные для передачи по каналу приспособленному для передачи текстовых данных. Это делается с целью защиты двоичных данных от любых возможных повреждений при передаче. Base64 широко используется во многих приложениях, включая электронную почту (MIME), и при сохранении больших объёмов данных в XML.

- -

В языке JavaScript существуют две функции, для кодирования и декодирования данных в/из формат Base64 соответственно:

- -
    -
  • {{domxref("WindowBase64.btoa","btoa()")}}
  • -
  • {{domxref("WindowBase64.atob","atob()")}}
  • -
- -

Функция atob() декодирует Base64-кодированную строку. В противоположность ей, функция btoa() создаёт Base64 кодированную ASCII строку из "строки" бинарных данных.

- -

Обе функции atob() и btoa() работают со строками. Если вам необходимо работать с ArrayBuffers, обратитесь к этому параграфу.

- - - - - - - - -
-

Документация

- -
-
data URIs
-
data URIs, описанные в RFC 2397, позволяют создателям контента встроить в документ маленькие файлы в виде строки (инлайном).
-
Base64
-
Wikipedia article about Base64 encoding.
-
{{domxref("WindowBase64.atob","atob()")}}
-
Decodes a string of data which has been encoded using base-64 encoding.
-
{{domxref("WindowBase64.btoa","btoa()")}}
-
Creates a base-64 encoded ASCII string from a "string" of binary data.
-
The "Unicode Problem"
-
In most browsers, calling btoa() on a Unicode string will cause a Character Out Of Range exception. This paragraph shows some solutions.
-
URIScheme
-
List of Mozilla supported URI schemes
-
StringView
-
In this article is published a library of ours whose aims are: -
    -
  • creating a C-like interface for strings (i.e. array of characters codes — ArrayBufferView in JavaScript) based upon the JavaScript ArrayBuffer interface,
  • -
  • creating a collection of methods for such string-like objects (since now: stringViews) which work strictly on array of numbers rather than on immutable JavaScript strings,
  • -
  • working with other Unicode encodings, different from default JavaScript's UTF-16 DOMStrings,
  • -
-
-
- -

View All...

-
-

Tools

- - - -

View All...

- - - - -
- -

The "Unicode Problem"

- -

Since DOMStrings are 16-bit-encoded strings, in most browsers calling window.btoa on a Unicode string will cause a Character Out Of Range exception if a character exceeds the range of a 8-bit byte (0x00~0xFF). There are two possible methods to solve this problem:

- -
    -
  • the first one is to escape the whole string (with UTF-8, see {{jsxref("encodeURIComponent")}}) and then encode it;
  • -
  • the second one is to convert the UTF-16 DOMString to an UTF-8 array of characters and then encode it.
  • -
- -

Here are the two possible methods.

- -

Solution #1 – escaping the string before encoding it

- -
function b64EncodeUnicode(str) {
-    // first we use encodeURIComponent to get percent-encoded UTF-8,
-    // then we convert the percent encodings into raw bytes which
-    // can be fed into btoa.
-    return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
-        function toSolidBytes(match, p1) {
-            return String.fromCharCode('0x' + p1);
-    }));
-}
-
-b64EncodeUnicode('✓ à la mode'); // "4pyTIMOgIGxhIG1vZGU="
-b64EncodeUnicode('\n'); // "Cg=="
-
- -

To decode the Base64-encoded value back into a String:

- -
function b64DecodeUnicode(str) {
-    // Going backwards: from bytestream, to percent-encoding, to original string.
-    return decodeURIComponent(atob(str).split('').map(function(c) {
-        return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
-    }).join(''));
-}
-
-b64DecodeUnicode('4pyTIMOgIGxhIG1vZGU='); // "✓ à la mode"
-b64DecodeUnicode('Cg=='); // "\n"
-
- -

Unibabel implements common conversions using this strategy.

- -

Solution #2 – rewrite the DOMs atob() and btoa() using JavaScript's TypedArrays and UTF-8

- -

Use a TextEncoder polyfill such as TextEncoding (also includes legacy windows, mac, and ISO encodings), TextEncoderLite, combined with a Buffer and a Base64 implementation such as base64-js.

- -

When a native TextEncoder implementation is not available, the most light-weight solution would be to use TextEncoderLite with base64-js. Use the browser implementation when you can.

- -

The following function implements such a strategy. It assumes base64-js imported as <script type="text/javascript" src="base64js.min.js"/>. Note that TextEncoderLite only works with UTF-8.

- -
function Base64Encode(str, encoding = 'utf-8') {
-    var bytes = new (TextEncoder || TextEncoderLite)(encoding).encode(str);
-    return base64js.fromByteArray(bytes);
-}
-
-function Base64Decode(str, encoding = 'utf-8') {
-    var bytes = base64js.toByteArray(str);
-    return new (TextDecoder || TextDecoderLite)(encoding).decode(bytes);
-}
-
diff --git a/files/ru/web/api/windowbase64/btoa/index.html b/files/ru/web/api/windowbase64/btoa/index.html deleted file mode 100644 index 06b76a6304..0000000000 --- a/files/ru/web/api/windowbase64/btoa/index.html +++ /dev/null @@ -1,141 +0,0 @@ ---- -title: WindowBase64.btoa() -slug: Web/API/WindowBase64/btoa -translation_of: Web/API/WindowOrWorkerGlobalScope/btoa ---- -
{{APIRef("HTML DOM")}}
- -

Создает ASCII строку закодированную в base-64 из "строки" бинарных данных.

- -

Будьте внимательней этот способ не подходит для Unicode строк! Описание работы с Unicode в секции ниже.

- -

Синтаксис

- -
var encodedData = window.btoa(stringToEncode);
- -

Пример

- -
var encodedData = window.btoa("Hello, world"); // encode a string
-var decodedData = window.atob(encodedData); // decode the string
-
- -

Замечания

- -

Вы можете воспользоваться этим способом, чтобы избежать проблем при передаче данных через сетевое соединение. Для этого нужно перекодировать данные в base64 и отправить их, и на другой стороне с помощью метода {{domxref("WindowBase64.atob","window.atob()")}} декодировать полученные данные в исходный вид. Например, вы можете перекодировать управляющие символы ASCII с 0 до 31.

- -

btoa() также доступна для XPCOM компонентов реализованных в JavaScript, даже если window не является глобальным объектом в компонентах.

- -

Строки Юникод

- -

В большинстве браузеров, вызов window.btoa() на Unicode строке выбросит исключение Character Out Of Range (Символ вне допустимого диапазона).

- -

Чтобы избежать этого, воспользуйтесь патерном, предложеным Johan Sundström:

- -
function utf8_to_b64(str) {
-    return window.btoa(unescape(encodeURIComponent(str)));
-}
-
-function b64_to_utf8(str) {
-    return decodeURIComponent(escape(window.atob(str)));
-}
-
-// Usage:
-utf8_to_b64('✓ à la mode'); // JTI1dTI3MTMlMjUyMCUyNUUwJTI1MjBsYSUyNTIwbW9kZQ==
-b64_to_utf8('JTI1dTI3MTMlMjUyMCUyNUUwJTI1MjBsYSUyNTIwbW9kZQ=='); // "✓ à la mode"
-
-utf8_to_b64('I \u2661 Unicode!'); // SSUyNTIwJTI1dTI2NjElMjUyMFVuaWNvZGUlMjUyMQ==
-b64_to_utf8('SSUyNTIwJTI1dTI2NjElMjUyMFVuaWNvZGUlMjUyMQ=='); // "I ♡ Unicode!"
-
-
- -

Более правильный и производительный способ - это конвертировать DOMString в UTF-8 строку передав typed arrays. Как это сделать узнать можно здесь в этом параграфе.

- -

Спецификации

- - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#dom-windowbase64-btoa', 'WindowBase64.btoa()')}}{{Spec2('HTML WHATWG')}}No change since the latest snapshot, {{SpecName("HTML5.1")}}.
{{SpecName('HTML5.1', '#dom-windowbase64-btoa', 'WindowBase64.btoa()')}}{{Spec2('HTML5.1')}}Snapshot of {{SpecName("HTML WHATWG")}}. No change.
{{SpecName("HTML5 W3C", "#dom-windowbase64-btoa", "WindowBase64.btoa()")}}{{Spec2('HTML5 W3C')}}Snapshot of {{SpecName("HTML WHATWG")}}. Creation of WindowBase64 (properties where on the target before it).
- -

Совместимость браузеров

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatVersionUnknown}}{{CompatGeckoDesktop(1)}}[1]10{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatGeckoMobile(1)}}{{CompatNo}}{{CompatUnknown}}{{CompatVersionUnknown}}
-
- -

[1] btoa() также доступна для XPCOM компонентов реализованных в JavaScript, даже если window не является глобальным объектом в компонентах.

- -

Смотрите также

- - diff --git a/files/ru/web/api/windowbase64/index.html b/files/ru/web/api/windowbase64/index.html deleted file mode 100644 index f51b72c102..0000000000 --- a/files/ru/web/api/windowbase64/index.html +++ /dev/null @@ -1,121 +0,0 @@ ---- -title: WindowBase64 -slug: Web/API/WindowBase64 -tags: - - API - - HTML-DOM - - Helper - - NeedsTranslation - - TopicStub - - WindowBase64 -translation_of: Web/API/WindowOrWorkerGlobalScope -translation_of_original: Web/API/WindowBase64 ---- -

{{APIRef("HTML DOM")}}

- -

The WindowBase64 helper contains utility methods to convert data to and from base64, a binary-to-text encoding scheme. For example it is used in data URIs.

- -

There is no object of this type, though the context object, either the {{domxref("Window")}} for regular browsing scope, or the {{domxref("WorkerGlobalScope")}}  for workers, implements it.

- -

Properties

- -

This helper neither defines nor inherits any properties.

- -

Methods

- -

This helper does not inherit any methods.

- -
-
{{domxref("WindowBase64.atob()")}}
-
Decodes a string of data which has been encoded using base-64 encoding.
-
{{domxref("WindowBase64.btoa()")}}
-
Creates a base-64 encoded ASCII string from a string of binary data.
-
- -

Specifications

- - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#windowbase64', 'WindowBase64')}}{{Spec2('HTML WHATWG')}}No change since the latest snapshot, {{SpecName("HTML5.1")}}.
{{SpecName('HTML5.1', '#windowbase64', 'WindowBase64')}}{{Spec2('HTML5.1')}}Snapshot of {{SpecName("HTML WHATWG")}}. No change.
{{SpecName("HTML5 W3C", "#windowbase64", "WindowBase64")}}{{Spec2('HTML5 W3C')}}Snapshot of {{SpecName("HTML WHATWG")}}. Creation of WindowBase64 (properties where on the target before it).
- -

Browser compatibility

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureFirefox (Gecko)ChromeInternet ExplorerOperaSafari
Basic support{{CompatGeckoDesktop(1)}} [1]{{CompatVersionUnknown}}10.0{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureFirefox Mobile (Gecko)AndroidIE MobileOpera MobileSafari Mobile
Basic support{{CompatGeckoMobile(1)}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -

[1]  atob() is also available to XPCOM components implemented in JavaScript, even though {{domxref("Window")}} is not the global object in components.

- -

See also

- -
    -
  • Base64 encoding and decoding
  • -
  • {{domxref("Window")}}, {{domxref("WorkerGlobalScope")}}, {{domxref("DedicatedWorkerGlobalScope")}}, {{domxref("SharedWorkerGlobalScope")}}, and {{domxref("ServiceWorkerGlobalScope")}}
  • -
diff --git a/files/ru/web/api/windoworworkerglobalscope/btoa/index.html b/files/ru/web/api/windoworworkerglobalscope/btoa/index.html new file mode 100644 index 0000000000..06b76a6304 --- /dev/null +++ b/files/ru/web/api/windoworworkerglobalscope/btoa/index.html @@ -0,0 +1,141 @@ +--- +title: WindowBase64.btoa() +slug: Web/API/WindowBase64/btoa +translation_of: Web/API/WindowOrWorkerGlobalScope/btoa +--- +
{{APIRef("HTML DOM")}}
+ +

Создает ASCII строку закодированную в base-64 из "строки" бинарных данных.

+ +

Будьте внимательней этот способ не подходит для Unicode строк! Описание работы с Unicode в секции ниже.

+ +

Синтаксис

+ +
var encodedData = window.btoa(stringToEncode);
+ +

Пример

+ +
var encodedData = window.btoa("Hello, world"); // encode a string
+var decodedData = window.atob(encodedData); // decode the string
+
+ +

Замечания

+ +

Вы можете воспользоваться этим способом, чтобы избежать проблем при передаче данных через сетевое соединение. Для этого нужно перекодировать данные в base64 и отправить их, и на другой стороне с помощью метода {{domxref("WindowBase64.atob","window.atob()")}} декодировать полученные данные в исходный вид. Например, вы можете перекодировать управляющие символы ASCII с 0 до 31.

+ +

btoa() также доступна для XPCOM компонентов реализованных в JavaScript, даже если window не является глобальным объектом в компонентах.

+ +

Строки Юникод

+ +

В большинстве браузеров, вызов window.btoa() на Unicode строке выбросит исключение Character Out Of Range (Символ вне допустимого диапазона).

+ +

Чтобы избежать этого, воспользуйтесь патерном, предложеным Johan Sundström:

+ +
function utf8_to_b64(str) {
+    return window.btoa(unescape(encodeURIComponent(str)));
+}
+
+function b64_to_utf8(str) {
+    return decodeURIComponent(escape(window.atob(str)));
+}
+
+// Usage:
+utf8_to_b64('✓ à la mode'); // JTI1dTI3MTMlMjUyMCUyNUUwJTI1MjBsYSUyNTIwbW9kZQ==
+b64_to_utf8('JTI1dTI3MTMlMjUyMCUyNUUwJTI1MjBsYSUyNTIwbW9kZQ=='); // "✓ à la mode"
+
+utf8_to_b64('I \u2661 Unicode!'); // SSUyNTIwJTI1dTI2NjElMjUyMFVuaWNvZGUlMjUyMQ==
+b64_to_utf8('SSUyNTIwJTI1dTI2NjElMjUyMFVuaWNvZGUlMjUyMQ=='); // "I ♡ Unicode!"
+
+
+ +

Более правильный и производительный способ - это конвертировать DOMString в UTF-8 строку передав typed arrays. Как это сделать узнать можно здесь в этом параграфе.

+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#dom-windowbase64-btoa', 'WindowBase64.btoa()')}}{{Spec2('HTML WHATWG')}}No change since the latest snapshot, {{SpecName("HTML5.1")}}.
{{SpecName('HTML5.1', '#dom-windowbase64-btoa', 'WindowBase64.btoa()')}}{{Spec2('HTML5.1')}}Snapshot of {{SpecName("HTML WHATWG")}}. No change.
{{SpecName("HTML5 W3C", "#dom-windowbase64-btoa", "WindowBase64.btoa()")}}{{Spec2('HTML5 W3C')}}Snapshot of {{SpecName("HTML WHATWG")}}. Creation of WindowBase64 (properties where on the target before it).
+ +

Совместимость браузеров

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatVersionUnknown}}{{CompatGeckoDesktop(1)}}[1]10{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatGeckoMobile(1)}}{{CompatNo}}{{CompatUnknown}}{{CompatVersionUnknown}}
+
+ +

[1] btoa() также доступна для XPCOM компонентов реализованных в JavaScript, даже если window не является глобальным объектом в компонентах.

+ +

Смотрите также

+ + diff --git a/files/ru/web/api/windoworworkerglobalscope/settimeout/index.html b/files/ru/web/api/windoworworkerglobalscope/settimeout/index.html new file mode 100644 index 0000000000..9e39020215 --- /dev/null +++ b/files/ru/web/api/windoworworkerglobalscope/settimeout/index.html @@ -0,0 +1,260 @@ +--- +title: WindowTimers.setTimeout() +slug: Web/API/WindowTimers/setTimeout +translation_of: Web/API/WindowOrWorkerGlobalScope/setTimeout +--- +
{{ APIRef() }}
+ +

Краткое изложение

+ +

Вызов функции или выполнение фрагмента кода после указанной задержки.

+ +

Синтаксис

+ +
var timeoutID = window.setTimeout(func, [, delay, param1, param2, ...]);
+var timeoutID = window.setTimeout(code [, delay]);
+
+ +

где

+ +
    +
  • timeoutID - это числовой ID, который может быть использован позже с {{domxref("window.clearTimeout()")}}.
  • +
  • func - это функция, которую требуется вызвать после delay миллисекунд.
  • +
  • code - в альтернативном варианте применения это строка, содержащая код, который вы хотите выполнить после delay миллисекунд (использовать этот метод не рекомендуется по тем же причинам, что и eval())
  • +
  • delay  {{optional_inline}} -  задержка в миллисекундах (тысячных долях секунды), после которой будет выполнен вызов функции. Реальная задержка может быть больше; см. {{anch("Notes")}} ниже.
  • +
+ +

Необходимо принять во внимание, что передача дополнительных параметров функции в первом варианте не работает в Internet Explorer 9 и ниже. Для использования этого функционала в таких браузерах, необходимо использовать код для совместимости (см. раздел Аргументы функции обратного вызова).

+ +
Important: Prior to Gecko 13 {{ geckoRelease("13.0") }}, Gecko passed an extra parameter to the callback routine, indicating the "actual lateness" of the timeout in milliseconds. This non-standard parameter is no longer passed.
+ +

Пример

+ +

В следующем примере на веб странице создаются две простые кнопки, к которым привязываются действия setTimeout и clearTimeout. Нажатие на первую кнопку установит таймаут, который вызовет диалоговое окно через две секунды. Также будет сохранен id для clearTimeout. Таймаут также может быть отменен по нажатию на вторую кнопку.

+ +

HTML Content

+ +
<p>Live Example</p>
+<button onclick="delayedAlert();">Show an alert box after two seconds</button>
+<p></p>
+<button onclick="clearAlert();">Cancel alert before it happens</button>
+
+ +

JavaScript Content

+ +
var timeoutID;
+
+function delayedAlert() {
+  timeoutID = window.setTimeout(slowAlert, 2000);
+}
+
+function slowAlert() {
+  alert("That was really slow!");
+}
+
+function clearAlert() {
+  window.clearTimeout(timeoutID);
+}
+
+ +

{{ EmbedLiveSample('Example') }}

+ +

Смотрите также пример clearTimeout().

+ +

Аргументы функции обратного вызова

+ +

Если вам нужно передать аргумент в вашу callback функцию, но нужно, чтобы это работало в Internet Explorer 9 и ниже, который не поддерживает передачу дополнительных параметров (ни с setTimeout() или setInterval()), то вы можете прописать специальный код для совместимости с IE, вставив этот код в начало ваших скриптов, который включит функцию передачи стандартных параметров HTML5 в Internet Explorer для обоих таймеров.

+ +
/*\
+|*|
+|*|  IE-specific polyfill which enables the passage of arbitrary arguments to the
+|*|  callback functions of JavaScript timers (HTML5 standard syntax).
+|*|
+|*|  https://developer.mozilla.org/en-US/docs/DOM/window.setInterval
+|*|
+|*|  Syntax:
+|*|  var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);
+|*|  var timeoutID = window.setTimeout(code, delay);
+|*|  var intervalID = window.setInterval(func, delay[, param1, param2, ...]);
+|*|  var intervalID = window.setInterval(code, delay);
+|*|
+\*/
+
+if (document.all && !window.setTimeout.isPolyfill) {
+  var __nativeST__ = window.setTimeout;
+  window.setTimeout = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
+    var aArgs = Array.prototype.slice.call(arguments, 2);
+    return __nativeST__(vCallback instanceof Function ? function () {
+      vCallback.apply(null, aArgs);
+    } : vCallback, nDelay);
+  };
+  window.setTimeout.isPolyfill = true;
+}
+
+if (document.all && !window.setInterval.isPolyfill) {
+  var __nativeSI__ = window.setInterval;
+  window.setInterval = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
+    var aArgs = Array.prototype.slice.call(arguments, 2);
+    return __nativeSI__(vCallback instanceof Function ? function () {
+      vCallback.apply(null, aArgs);
+    } : vCallback, nDelay);
+  };
+  window.setInterval.isPolyfill = true;
+}
+
+ +

Правка только для IE

+ +

If you want a completely unobtrusive hack for every other mobile or desktop browser, including IE 9 and below, you can either use JavaScript conditional comments:

+ +
/*@cc_on
+  // conditional IE < 9 only fix
+  @if (@_jscript_version <= 6)
+  (function(f){
+     window.setTimeout =f(window.setTimeout);
+     window.setInterval =f(window.setInterval);
+  })(function(f){return function(c,t){var a=[].slice.call(arguments,2);return f(function(){c.apply(this,a)},t)}});
+  @end
+@*/
+
+ +

Или используйте очень чистый подход, основанный на условном свойстве IE HTML:

+ +
<!--[if lte IE 9]><script>
+(function(f){
+window.setTimeout =f(window.setTimeout);
+window.setInterval =f(window.setInterval);
+})(function(f){return function(c,t){
+var a=[].slice.call(arguments,2);return f(function(){c.apply(this,a)},t)}
+});
+</script><![endif]-->
+
+ +

Another possibility is to use an anonymous function to call your callback, but this solution is a bit more expensive. Example:

+ +
var intervalID = setTimeout(function() { myFunc("one", "two", "three"); }, 1000);
+
+ +

Yet another possibility is to use function's bind. Example:

+ +
setTimeout(function(arg1){}.bind(undefined, 10));
+
+ +

Проблема с "this"

+ +

Когда вы передаете метод в setTimeout() (или в любую другую функцию, если на то пошло), то вызов будет осуществлен с неправильным значением this. Эта проблема разъясняется детально в JavaScript reference.

+ +

Объяснение

+ +

Code executed by setTimeout() is run in a separate execution context to the function from which it was called. As a consequence, the this keyword for the called function will be set to the window (or global) object; it will not be the same as the this value for the function that called setTimeout. See the following example:

+ +
myArray = ["zero", "one", "two"];
+myArray.myMethod = function (sProperty) {
+    alert(arguments.length > 0 ? this[sProperty] : this);
+};
+
+myArray.myMethod(); // prints "zero,one,two"
+myArray.myMethod(1); // prints "one"
+setTimeout(myArray.myMethod, 1000); // prints "[object Window]" after 1 second
+setTimeout(myArray.myMethod, 1500, "1"); // prints "undefined" after 1.5 seconds
+// let's try to pass the 'this' object
+setTimeout.call(myArray, myArray.myMethod, 2000); // error: "NS_ERROR_XPC_BAD_OP_ON_WN_PROTO: Illegal operation on WrappedNative prototype object"
+setTimeout.call(myArray, myArray.myMethod, 2500, 2); // same error
+ +

Как видите, нет способов передать объект this в функцию обратного вызова..

+ +

Возможное решение

+ +

A possible way to solve the "this" problem is to replace the two native setTimeout() or setInterval() global functions with two non-native ones which will enable their invocation through the Function.prototype.call method. The following example shows a possible replacement:

+ +
// Enable the passage of the 'this' object through the JavaScript timers
+
+var __nativeST__ = window.setTimeout, __nativeSI__ = window.setInterval;
+
+window.setTimeout = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
+  var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2);
+  return __nativeST__(vCallback instanceof Function ? function () {
+    vCallback.apply(oThis, aArgs);
+  } : vCallback, nDelay);
+};
+
+window.setInterval = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
+  var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2);
+  return __nativeSI__(vCallback instanceof Function ? function () {
+    vCallback.apply(oThis, aArgs);
+  } : vCallback, nDelay);
+};
+ +
Note: These two replacements will also enable the HTML5 standard passage of arbitrary arguments to the callback functions of timers in IE. So they can be used as polyfills also. See the Callback arguments paragraph.
+ +

Новая тестируемая особенность:

+ +
myArray = ["zero", "one", "two"];
+myArray.myMethod = function (sProperty) {
+    alert(arguments.length > 0 ? this[sProperty] : this);
+};
+
+setTimeout(alert, 1500, "Hello world!"); // the standard use of setTimeout and setInterval is preserved, but...
+setTimeout.call(myArray, myArray.myMethod, 2000); // prints "zero,one,two" after 2 seconds
+setTimeout.call(myArray, myArray.myMethod, 2500, 2); // prints "two" after 2.5 seconds
+
+ +

Это не нативные решения ad hoc для этой проблемы.

+ +
Note: JavaScript 1.8.5 introduces the Function.prototype.bind() method, which lets you specify the value that should be used as this for all calls to a given function. This lets you easily bypass problems where it's unclear what this will be, depending on the context from which your function was called.
+ +

Замечания

+ +

Отложенное выполнение кода можно отменить, используя window.clearTimeout(). Если функция должна вызываться неоднократно (например, каждые N миллисекунд), необходимо использовать window.setInterval().

+ +

Важно заметить, что функция или код не могут быть выполнены, пока не завершится поток, вызвавший setTimeout().

+ +

Passing string literals

+ +

Передача строки вместо функции в setTimeout() сопряжена с теми же опасностями, что и использование eval.

+ +
// Правильно
+window.setTimeout(function() {
+    alert("Hello World!");
+}, 500);
+
+// Неправильно
+window.setTimeout("alert(\"Hello World!\");", 500);
+
+
+ +

String literals are evaluated in the global context, so local symbols in the context where setTimeout() was called will not be available when the string is evaluated as code.

+ +

Минимальная/ максимальная задержка и вложенность таймаута

+ +

Historically browsers implement setTimeout() "clamping": successive setTimeout() calls with delay smaller than the "minimum delay" limit are forced to use at least the minimum delay. The minimum delay, DOM_MIN_TIMEOUT_VALUE, is 4 ms (stored in a preference in Firefox: dom.min_timeout_value), with a DOM_CLAMP_TIMEOUT_NESTING_LEVEL of 5ms.

+ +

In fact, 4ms is specified by the HTML5 spec and is consistent across browsers released in 2010 and onward. Prior to {{ geckoRelease("5.0") }}, the minimum timeout value for nested timeouts was 10 ms.

+ +

In addition to "clamping", the timeout can also fire later when the page (or the OS/browser itself) is busy with other tasks.

+ +

To implement a 0 ms timeout in a modern browser, you can use {{ domxref("window.postMessage()") }} as described here.

+ +

Browsers including Internet Explorer, Chrome, Safari, and Firefox store the delay as a 32-bit signed Integer internally. This causes an Integer overflow when using delays larger than 2147483647, resulting in the timeout being executed immediately.

+ +

Неактивные вкладки

+ +

In {{ geckoRelease("5.0") }} and Chrome 11, timeouts are clamped to firing no more often than once per second (1000ms) in inactive tabs; see {{ bug(633421) }} for more information about this in Mozilla or crbug.com/66078 for details about this in Chrome.

+ +

Совместимость с браузерами

+ +

{{Compat("api.WindowOrWorkerGlobalScope.setTimeout")}}

+ +

Спецификация

+ +

Part of DOM level 0, as specified in HTML5.

+ +

Также интересно

+ + diff --git a/files/ru/web/api/windowtimers/index.html b/files/ru/web/api/windowtimers/index.html deleted file mode 100644 index ac80f42b5f..0000000000 --- a/files/ru/web/api/windowtimers/index.html +++ /dev/null @@ -1,120 +0,0 @@ ---- -title: WindowTimers -slug: Web/API/WindowTimers -tags: - - API - - HTML DOM -translation_of: Web/API/WindowOrWorkerGlobalScope -translation_of_original: Web/API/WindowTimers ---- -
{{APIRef("HTML DOM")}}
- -

WindowTimers contains utility methods to set and clear timers.

- -

There is no object of this type, though the context object, either the {{domxref("Window")}} for regular browsing scope, or the {{domxref("WorkerGlobalScope")}}  for workers, implements it.

- -

Properties

- -

This interface do not define any property, nor inherit any.

- -

Methods

- -

This interface do not inherit any method.

- -
-
{{domxref("WindowTimers.clearInterval()")}}
-
Cancels the repeated execution set using {{domxref("WindowTimers.setInterval()")}}.
-
{{domxref("WindowTimers.clearTimeout()")}}
-
Cancels the repeated execution set using {{domxref("WindowTimers.setTimeout()")}}.
-
{{domxref("WindowTimers.setInterval()")}}
-
Schedules the execution of a function each X milliseconds.
-
{{domxref("WindowTimers.setTimeout()")}}
-
Sets a delay for executing a function.
-
- -

Specifications

- - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#windowtimers', 'WindowTimers')}}{{Spec2('HTML WHATWG')}}No change since the latest snapshot, {{SpecName("HTML5.1")}}.
{{SpecName('HTML5.1', '#windowtimers', 'WindowTimers')}}{{Spec2('HTML5.1')}}Snapshot of {{SpecName("HTML WHATWG")}}. No change.
{{SpecName("HTML5 W3C", "#windowtimers", "WindowTimers")}}{{Spec2('HTML5 W3C')}}Snapshot of {{SpecName("HTML WHATWG")}}. Creation of WindowBase64 (properties where on the target before it).
- -

Browser compatibility

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureFirefox (Gecko)ChromeInternet ExplorerOperaSafari
Basic support{{CompatGeckoDesktop(1)}}1.04.04.01.0
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureFirefox Mobile (Gecko)AndroidIE MobileOpera MobileSafari Mobile
Basic support{{CompatGeckoMobile(1)}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -

 

- -

See also

- -
    -
  • {{domxref("Window")}}, {{domxref("WorkerGlobalScope")}}, {{domxref("DedicatedWorkerGlobalScope")}}, {{domxref("SharedWorkerGlobalScope")}}, and {{domxref("ServiceWorkerGlobalScope")}}
  • -
diff --git a/files/ru/web/api/windowtimers/settimeout/index.html b/files/ru/web/api/windowtimers/settimeout/index.html deleted file mode 100644 index 9e39020215..0000000000 --- a/files/ru/web/api/windowtimers/settimeout/index.html +++ /dev/null @@ -1,260 +0,0 @@ ---- -title: WindowTimers.setTimeout() -slug: Web/API/WindowTimers/setTimeout -translation_of: Web/API/WindowOrWorkerGlobalScope/setTimeout ---- -
{{ APIRef() }}
- -

Краткое изложение

- -

Вызов функции или выполнение фрагмента кода после указанной задержки.

- -

Синтаксис

- -
var timeoutID = window.setTimeout(func, [, delay, param1, param2, ...]);
-var timeoutID = window.setTimeout(code [, delay]);
-
- -

где

- -
    -
  • timeoutID - это числовой ID, который может быть использован позже с {{domxref("window.clearTimeout()")}}.
  • -
  • func - это функция, которую требуется вызвать после delay миллисекунд.
  • -
  • code - в альтернативном варианте применения это строка, содержащая код, который вы хотите выполнить после delay миллисекунд (использовать этот метод не рекомендуется по тем же причинам, что и eval())
  • -
  • delay  {{optional_inline}} -  задержка в миллисекундах (тысячных долях секунды), после которой будет выполнен вызов функции. Реальная задержка может быть больше; см. {{anch("Notes")}} ниже.
  • -
- -

Необходимо принять во внимание, что передача дополнительных параметров функции в первом варианте не работает в Internet Explorer 9 и ниже. Для использования этого функционала в таких браузерах, необходимо использовать код для совместимости (см. раздел Аргументы функции обратного вызова).

- -
Important: Prior to Gecko 13 {{ geckoRelease("13.0") }}, Gecko passed an extra parameter to the callback routine, indicating the "actual lateness" of the timeout in milliseconds. This non-standard parameter is no longer passed.
- -

Пример

- -

В следующем примере на веб странице создаются две простые кнопки, к которым привязываются действия setTimeout и clearTimeout. Нажатие на первую кнопку установит таймаут, который вызовет диалоговое окно через две секунды. Также будет сохранен id для clearTimeout. Таймаут также может быть отменен по нажатию на вторую кнопку.

- -

HTML Content

- -
<p>Live Example</p>
-<button onclick="delayedAlert();">Show an alert box after two seconds</button>
-<p></p>
-<button onclick="clearAlert();">Cancel alert before it happens</button>
-
- -

JavaScript Content

- -
var timeoutID;
-
-function delayedAlert() {
-  timeoutID = window.setTimeout(slowAlert, 2000);
-}
-
-function slowAlert() {
-  alert("That was really slow!");
-}
-
-function clearAlert() {
-  window.clearTimeout(timeoutID);
-}
-
- -

{{ EmbedLiveSample('Example') }}

- -

Смотрите также пример clearTimeout().

- -

Аргументы функции обратного вызова

- -

Если вам нужно передать аргумент в вашу callback функцию, но нужно, чтобы это работало в Internet Explorer 9 и ниже, который не поддерживает передачу дополнительных параметров (ни с setTimeout() или setInterval()), то вы можете прописать специальный код для совместимости с IE, вставив этот код в начало ваших скриптов, который включит функцию передачи стандартных параметров HTML5 в Internet Explorer для обоих таймеров.

- -
/*\
-|*|
-|*|  IE-specific polyfill which enables the passage of arbitrary arguments to the
-|*|  callback functions of JavaScript timers (HTML5 standard syntax).
-|*|
-|*|  https://developer.mozilla.org/en-US/docs/DOM/window.setInterval
-|*|
-|*|  Syntax:
-|*|  var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);
-|*|  var timeoutID = window.setTimeout(code, delay);
-|*|  var intervalID = window.setInterval(func, delay[, param1, param2, ...]);
-|*|  var intervalID = window.setInterval(code, delay);
-|*|
-\*/
-
-if (document.all && !window.setTimeout.isPolyfill) {
-  var __nativeST__ = window.setTimeout;
-  window.setTimeout = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
-    var aArgs = Array.prototype.slice.call(arguments, 2);
-    return __nativeST__(vCallback instanceof Function ? function () {
-      vCallback.apply(null, aArgs);
-    } : vCallback, nDelay);
-  };
-  window.setTimeout.isPolyfill = true;
-}
-
-if (document.all && !window.setInterval.isPolyfill) {
-  var __nativeSI__ = window.setInterval;
-  window.setInterval = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
-    var aArgs = Array.prototype.slice.call(arguments, 2);
-    return __nativeSI__(vCallback instanceof Function ? function () {
-      vCallback.apply(null, aArgs);
-    } : vCallback, nDelay);
-  };
-  window.setInterval.isPolyfill = true;
-}
-
- -

Правка только для IE

- -

If you want a completely unobtrusive hack for every other mobile or desktop browser, including IE 9 and below, you can either use JavaScript conditional comments:

- -
/*@cc_on
-  // conditional IE < 9 only fix
-  @if (@_jscript_version <= 6)
-  (function(f){
-     window.setTimeout =f(window.setTimeout);
-     window.setInterval =f(window.setInterval);
-  })(function(f){return function(c,t){var a=[].slice.call(arguments,2);return f(function(){c.apply(this,a)},t)}});
-  @end
-@*/
-
- -

Или используйте очень чистый подход, основанный на условном свойстве IE HTML:

- -
<!--[if lte IE 9]><script>
-(function(f){
-window.setTimeout =f(window.setTimeout);
-window.setInterval =f(window.setInterval);
-})(function(f){return function(c,t){
-var a=[].slice.call(arguments,2);return f(function(){c.apply(this,a)},t)}
-});
-</script><![endif]-->
-
- -

Another possibility is to use an anonymous function to call your callback, but this solution is a bit more expensive. Example:

- -
var intervalID = setTimeout(function() { myFunc("one", "two", "three"); }, 1000);
-
- -

Yet another possibility is to use function's bind. Example:

- -
setTimeout(function(arg1){}.bind(undefined, 10));
-
- -

Проблема с "this"

- -

Когда вы передаете метод в setTimeout() (или в любую другую функцию, если на то пошло), то вызов будет осуществлен с неправильным значением this. Эта проблема разъясняется детально в JavaScript reference.

- -

Объяснение

- -

Code executed by setTimeout() is run in a separate execution context to the function from which it was called. As a consequence, the this keyword for the called function will be set to the window (or global) object; it will not be the same as the this value for the function that called setTimeout. See the following example:

- -
myArray = ["zero", "one", "two"];
-myArray.myMethod = function (sProperty) {
-    alert(arguments.length > 0 ? this[sProperty] : this);
-};
-
-myArray.myMethod(); // prints "zero,one,two"
-myArray.myMethod(1); // prints "one"
-setTimeout(myArray.myMethod, 1000); // prints "[object Window]" after 1 second
-setTimeout(myArray.myMethod, 1500, "1"); // prints "undefined" after 1.5 seconds
-// let's try to pass the 'this' object
-setTimeout.call(myArray, myArray.myMethod, 2000); // error: "NS_ERROR_XPC_BAD_OP_ON_WN_PROTO: Illegal operation on WrappedNative prototype object"
-setTimeout.call(myArray, myArray.myMethod, 2500, 2); // same error
- -

Как видите, нет способов передать объект this в функцию обратного вызова..

- -

Возможное решение

- -

A possible way to solve the "this" problem is to replace the two native setTimeout() or setInterval() global functions with two non-native ones which will enable their invocation through the Function.prototype.call method. The following example shows a possible replacement:

- -
// Enable the passage of the 'this' object through the JavaScript timers
-
-var __nativeST__ = window.setTimeout, __nativeSI__ = window.setInterval;
-
-window.setTimeout = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
-  var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2);
-  return __nativeST__(vCallback instanceof Function ? function () {
-    vCallback.apply(oThis, aArgs);
-  } : vCallback, nDelay);
-};
-
-window.setInterval = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
-  var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2);
-  return __nativeSI__(vCallback instanceof Function ? function () {
-    vCallback.apply(oThis, aArgs);
-  } : vCallback, nDelay);
-};
- -
Note: These two replacements will also enable the HTML5 standard passage of arbitrary arguments to the callback functions of timers in IE. So they can be used as polyfills also. See the Callback arguments paragraph.
- -

Новая тестируемая особенность:

- -
myArray = ["zero", "one", "two"];
-myArray.myMethod = function (sProperty) {
-    alert(arguments.length > 0 ? this[sProperty] : this);
-};
-
-setTimeout(alert, 1500, "Hello world!"); // the standard use of setTimeout and setInterval is preserved, but...
-setTimeout.call(myArray, myArray.myMethod, 2000); // prints "zero,one,two" after 2 seconds
-setTimeout.call(myArray, myArray.myMethod, 2500, 2); // prints "two" after 2.5 seconds
-
- -

Это не нативные решения ad hoc для этой проблемы.

- -
Note: JavaScript 1.8.5 introduces the Function.prototype.bind() method, which lets you specify the value that should be used as this for all calls to a given function. This lets you easily bypass problems where it's unclear what this will be, depending on the context from which your function was called.
- -

Замечания

- -

Отложенное выполнение кода можно отменить, используя window.clearTimeout(). Если функция должна вызываться неоднократно (например, каждые N миллисекунд), необходимо использовать window.setInterval().

- -

Важно заметить, что функция или код не могут быть выполнены, пока не завершится поток, вызвавший setTimeout().

- -

Passing string literals

- -

Передача строки вместо функции в setTimeout() сопряжена с теми же опасностями, что и использование eval.

- -
// Правильно
-window.setTimeout(function() {
-    alert("Hello World!");
-}, 500);
-
-// Неправильно
-window.setTimeout("alert(\"Hello World!\");", 500);
-
-
- -

String literals are evaluated in the global context, so local symbols in the context where setTimeout() was called will not be available when the string is evaluated as code.

- -

Минимальная/ максимальная задержка и вложенность таймаута

- -

Historically browsers implement setTimeout() "clamping": successive setTimeout() calls with delay smaller than the "minimum delay" limit are forced to use at least the minimum delay. The minimum delay, DOM_MIN_TIMEOUT_VALUE, is 4 ms (stored in a preference in Firefox: dom.min_timeout_value), with a DOM_CLAMP_TIMEOUT_NESTING_LEVEL of 5ms.

- -

In fact, 4ms is specified by the HTML5 spec and is consistent across browsers released in 2010 and onward. Prior to {{ geckoRelease("5.0") }}, the minimum timeout value for nested timeouts was 10 ms.

- -

In addition to "clamping", the timeout can also fire later when the page (or the OS/browser itself) is busy with other tasks.

- -

To implement a 0 ms timeout in a modern browser, you can use {{ domxref("window.postMessage()") }} as described here.

- -

Browsers including Internet Explorer, Chrome, Safari, and Firefox store the delay as a 32-bit signed Integer internally. This causes an Integer overflow when using delays larger than 2147483647, resulting in the timeout being executed immediately.

- -

Неактивные вкладки

- -

In {{ geckoRelease("5.0") }} and Chrome 11, timeouts are clamped to firing no more often than once per second (1000ms) in inactive tabs; see {{ bug(633421) }} for more information about this in Mozilla or crbug.com/66078 for details about this in Chrome.

- -

Совместимость с браузерами

- -

{{Compat("api.WindowOrWorkerGlobalScope.setTimeout")}}

- -

Спецификация

- -

Part of DOM level 0, as specified in HTML5.

- -

Также интересно

- - diff --git a/files/ru/web/api/xmldocument/async/index.html b/files/ru/web/api/xmldocument/async/index.html new file mode 100644 index 0000000000..2ff21f28af --- /dev/null +++ b/files/ru/web/api/xmldocument/async/index.html @@ -0,0 +1,35 @@ +--- +title: Document.async +slug: Web/API/Document/async +translation_of: Web/API/XMLDocument/async +--- +

{{APIRef("DOM")}}{{Deprecated_header}} {{Non-standard_header}}

+ +

document.async может быть установлен, для того, чтобы определить, что вызов {{domxref("document.load")}} должен быть выполнен синхронно или не синхронно. true - стандартное значение, определяющее, асинхронно ли должны быть загружены документы.

+ +

(Загружать документы синхронно стало возможно с версии 1.4 alpha.)

+ +

Пример

+ +
function loadXMLData(e) {
+  alert(new XMLSerializer().serializeToString(e.target)); // Gives querydata.xml contents as string
+}
+
+var xmlDoc = document.implementation.createDocument("", "test", null);
+
+xmlDoc.async = false;
+xmlDoc.onload = loadXMLData;
+xmlDoc.load('querydata.xml');
+ +

Спецификация

+ + + +

Смотрите также

+ + diff --git a/files/ru/web/api/xmlhttprequest/loadstart_event/index.html b/files/ru/web/api/xmlhttprequest/loadstart_event/index.html new file mode 100644 index 0000000000..b725b05b30 --- /dev/null +++ b/files/ru/web/api/xmlhttprequest/loadstart_event/index.html @@ -0,0 +1,89 @@ +--- +title: loadstart +slug: Web/Events/loadstart +translation_of: Web/API/XMLHttpRequest/loadstart_event +--- +

Событие loadstart происходит, когда начинается загрузка.

+ +

Общая информация

+ +
+
Спецификация
+
Progress
+
Интерфейс
+
ProgressEvent
+
Распространяется
+
Нет
+
Отменяемое
+
Нет
+
Цель
+
Element
+
Действие по умолчанию
+
Нет
+
+ +

Свойства

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeDescription
target {{readonlyInline}}{{domxref("EventTarget")}}The event target (the topmost target in the DOM tree).
type {{readonlyInline}}{{domxref("DOMString")}}The type of event.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Whether the event normally bubbles or not.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Whether the event is cancellable or not.
lengthComputable {{readonlyInline}}{{jsxref("Boolean")}}Specifies whether or not the total size of the transfer is known. Read only.
loaded {{readonlyInline}}unsigned long (long)The number of bytes transferred since the beginning of the operation. This doesn't include headers and other overhead, but only the content itself. Read only.
total {{readonlyInline}}unsigned long (long)The total number of bytes of content that will be transferred during the operation. If the total size is unknown, this value is zero. Read only.
+ +

Связанные свойства

+ +
    +
  • {{event("loadstart")}}
  • +
  • {{event("progress")}}
  • +
  • {{event("error")}}
  • +
  • {{event("abort")}}
  • +
  • {{event("load")}}
  • +
  • {{event("loadend")}}
  • +
+ +

См. также

+ + diff --git "a/files/ru/web/api/\320\262\320\270\320\264\320\270\320\274\320\276\321\201\321\202\321\214_\321\201\321\202\321\200\320\260\320\275\320\270\321\206\321\213_api/index.html" "b/files/ru/web/api/\320\262\320\270\320\264\320\270\320\274\320\276\321\201\321\202\321\214_\321\201\321\202\321\200\320\260\320\275\320\270\321\206\321\213_api/index.html" deleted file mode 100644 index 9b181e92d1..0000000000 --- "a/files/ru/web/api/\320\262\320\270\320\264\320\270\320\274\320\276\321\201\321\202\321\214_\321\201\321\202\321\200\320\260\320\275\320\270\321\206\321\213_api/index.html" +++ /dev/null @@ -1,195 +0,0 @@ ---- -title: Видимость страницы API -slug: Web/API/Видимость_страницы_API -tags: - - API - - DOM - - Документ - - Показать страницу - - Скрыть страницу -translation_of: Web/API/Page_Visibility_API ---- -
{{DefaultAPISidebar("Page Visibility API")}}
- -

При переключении между вкладками, web страница переходит в фоновый режим и поэтому не видна пользователю. Page Visibility API предоставляет события, которые вы можете отслеживать, чтобы узнать, когда страница станет видимой или скрытой, а так же возможность наблюдать текущее состояние видимости страницы.

- -
-

Notes: The Page Visibility API особенно полезно для сбережения ресурсов и улучшения производительности, позволяя странице остановить выполнение не нужных задач, когда она не видна.

-
- -

Когда пользователь сворачивает окно или переключается на другую вкладку, API отправляет {{event("visibilitychange")}} событие обработчикам, что состояние страницы изменилось. Вы можете отследить это событие и выполнить какие-то действия. Например, если ваше app проигрывает видео, его можно поставить на паузу, когда пользователь переключил вкладку (страница ушла в фон), а затем возобновить видео, когда пользователь вернулся на вкладку. Пользователь не теряет место на котором остановил просмотр, звук от видео не конфликтует с аудио новой вкладки, пользователь комфортно просмотрить оба видео.

- -

Состояния видимости для {{HTMLElement("iframe")}} такие же как и для родительской страницы. Скрытие <iframe> используя CSS стили (такие как {{cssxref("display", "display: none;")}}) не вызывают события видимости и не изменяют состояние документа, содержащегося во фрейме.

- -

Использование

- -

Давайте рассмотрим несколько способов использования Page Visibility API.

- -
    -
  • На сайте есть слайдер изображений с автопрокрутрой, которую можно поставить на паузу, когда пользователь перешел на другую вкладку
  • -
  • Приложение выводит информацию в реальном времени, которую можно не обновлять, пока страница не видна, тем самым уменьшить количество запросов на сервер
  • -
  • Странице нужно понять, когда она должна быть отрисована, так что можно вести точный подсчет количества просмотров
  • -
  • Сайту нужно выключить звук, когда устройство в режиме ожидания (пользователь нажал кнопку включения, чтобы погасить экран)
  • -
- -

Раньше у разработчиков были не удобные способы. Например, обработка {{event("blur")}} и {{event("focus")}} событий на объекте window - помогала узнать когда страница становилась не активной, но это не давало возможность понять когда страница действительно скрыта от пользователя. Page Visibility API решает эту проблему.

- -
-

Note: Когда {{domxref("GlobalEventHandlers.onblur", "onblur")}} и {{domxref("GlobalEventHandlers.onfocus", "onfocus")}} уведомляют, что пользователь переключил окна, это не означает, что оно действительно скрыто. Страница действительно скрыта, когда пользователь переключил вкладки или свернул окно браузера с этой вкладкой.

-
- -

Policies in place to aid background page performance

- -

Separately from the Page Visibility API, user agents typically have a number of policies in place to mitigate the performance impact of background or hidden tabs. These may include:

- -
    -
  • Most browsers stop sending {{domxref("Window.requestAnimationFrame", "requestAnimationFrame()")}} callbacks to background tabs or hidden {{ HTMLElement("iframe") }}s in order to improve performance and battery life.
  • -
  • Timers such as {{domxref("WindowOrWorkerGlobalScope.setTimeout", "setTimeout()")}} are throttled in background/inactive tabs to help improve performance. See Reasons for delays longer than specified for more details.
  • -
  • Budget-based background timeout throttling is now available in modern browsers (Firefox 58+, Chrome 57+), placing an additional limit on background timer CPU usage. This operates in a similar way across modern browsers, with the details being as follows: -
      -
    • In Firefox, windows in background tabs each have their own time budget in milliseconds — a max and a min value of +50 ms and -150 ms, respectively. Chrome is very similar except that the budget is specified in seconds.
    • -
    • Windows are subjected to throttling after 30 seconds, with the same throttling delay rules as specified for window timers (again, see Reasons for delays longer than specified). In Chrome, this value is 10 seconds.
    • -
    • Timer tasks are only permitted when the budget is non-negative.
    • -
    • Once a timer's code has finished running, the duration of time it took to execute is subtracted from its window's timeout budget.
    • -
    • The budget regenerates at a rate of 10 ms per second, in both Firefox and Chrome.
    • -
    -
  • -
- -

Some processes are exempt from this throttling behavior. In these cases, you can use the Page Visibility API to reduce the tabs' performance impact while they're hidden.

- -
    -
  • Tabs which are playing audio are considered foreground and aren’t throttled.
  • -
  • Tabs running code that's using real-time network connections (WebSockets and WebRTC) go unthrottled in order to avoid closing these connections timing out and getting unexpectedly closed.
  • -
  • IndexedDB processes are also left unthrottled in order to avoid timeouts.
  • -
- -

Example

- -

View live example (video with sound).

- -

The example, which pauses the video when you switch to another tab and plays again when you return to its tab, was created with the following code:

- -
// Set the name of the hidden property and the change event for visibility
-var hidden, visibilityChange;
-if (typeof document.hidden !== "undefined") { // Opera 12.10 and Firefox 18 and later support
-  hidden = "hidden";
-  visibilityChange = "visibilitychange";
-} else if (typeof document.msHidden !== "undefined") {
-  hidden = "msHidden";
-  visibilityChange = "msvisibilitychange";
-} else if (typeof document.webkitHidden !== "undefined") {
-  hidden = "webkitHidden";
-  visibilityChange = "webkitvisibilitychange";
-}
-
-var videoElement = document.getElementById("videoElement");
-
-// If the page is hidden, pause the video;
-// if the page is shown, play the video
-function handleVisibilityChange() {
-  if (document[hidden]) {
-    videoElement.pause();
-  } else {
-    videoElement.play();
-  }
-}
-
-// Warn if the browser doesn't support addEventListener or the Page Visibility API
-if (typeof document.addEventListener === "undefined" || hidden === undefined) {
-  console.log("This demo requires a browser, such as Google Chrome or Firefox, that supports the Page Visibility API.");
-} else {
-  // Handle page visibility change
-  document.addEventListener(visibilityChange, handleVisibilityChange, false);
-
-  // When the video pauses, set the title.
-  // This shows the paused
-  videoElement.addEventListener("pause", function(){
-    document.title = 'Paused';
-  }, false);
-
-  // When the video plays, set the title.
-  videoElement.addEventListener("play", function(){
-    document.title = 'Playing';
-  }, false);
-
-}
-
- -

Properties added to the Document interface

- -

The Page Visibility API adds the following properties to the {{domxref("Document")}} interface:

- -
-
{{domxref("Document.hidden")}} {{ReadOnlyInline}}
-
Returns true if the page is in a state considered to be hidden to the user, and false otherwise.
-
{{domxref("Document.visibilityState")}} {{ReadOnlyInline}}
-
A {{domxref("DOMString")}} indicating the document's current visibility state. Possible values are: -
-
visible
-
The page content may be at least partially visible. In practice this means that the page is the foreground tab of a non-minimized window.
-
hidden
-
The page's content is not visible to the user, either due to the document's tab being in the background or part of a window that is minimized, or because the device's screen is off.
-
prerender
-
The page's content is being prerendered and is not visible to the user. A document may start in the prerender state, but will never switch to this state from any other state, since a document can only prerender once. -
Note: Not all browsers support prerendering.
-
-
unloaded
-
The page is in the process of being unloaded from memory. -
Note: Not all browsers support the unloaded value.
-
-
-
-
{{domxref("Document.onvisibilitychange")}}
-
An {{domxref("EventListener")}} providing the code to be called when the {{event("visibilitychange")}} event is fired.
-
- -
//startSimulation and pauseSimulation defined elsewhere
-function handleVisibilityChange() {
-  if (document.hidden) {
-    pauseSimulation();
-  } else  {
-    startSimulation();
-  }
-}
-
-document.addEventListener("visibilitychange", handleVisibilityChange, false);
-
- -

Specifications

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Page Visibility API')}}{{Spec2('Page Visibility API')}}Initial definition.
- -

Browser compatibility

- -
-

Document.visibilityState

- -
- - -

{{Compat("api.Document.visibilityState")}}

-
-
- -

See also

- - diff --git "a/files/ru/web/api/\320\275\320\276\321\202\320\260\321\206\320\270\321\217/index.html" "b/files/ru/web/api/\320\275\320\276\321\202\320\260\321\206\320\270\321\217/index.html" deleted file mode 100644 index a1f468a55d..0000000000 --- "a/files/ru/web/api/\320\275\320\276\321\202\320\260\321\206\320\270\321\217/index.html" +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: Нотация -slug: Web/API/Нотация -tags: - - Нотация -translation_of: Web/API/Notation ---- -
{{APIRef("DOM")}}{{draft}}{{obsolete_header}}
- -

Представляет нотацию DTD (только для чтения). Может объявлять формат неразобранного объекта или формально объявлять цели инструкции по обработке документа. Наследует методы и свойства от Node. Его nodeName - это имя нотации. Не имеет родителя.

- -

Свойства

- -
-
{{domxref("Notation.publicId")}} {{ReadOnlyInline}}
-
Это {{domxref("DOMString")}}.
-
{{domxref("Notation.systemId")}} {{ReadOnlyInline}}
-
Это {{domxref("DOMString")}}.
-
- -

Спецификации

- - - - - - - - - - - - - - - - - - - - - - - - -
СпецификацияСтатусКомментарии
{{SpecName("DOM3 Core", "core.html#ID-5431D1B9", "Notation")}}{{Spec2("DOM3 Core")}}Без изменений
{{SpecName("DOM2 Core", "core.html#ID-5431D1B9", "Notation")}}{{Spec2("DOM2 Core")}}Без изменений
{{SpecName('DOM1', 'level-one-core.html#ID-5431D1B9', 'Notation')}}{{Spec2('DOM1')}}Первое определение
- -

Поддержка браузерами

- - - -

{{Compat("api.Notation")}}

diff --git a/files/ru/web/css/@viewport/user-zoom/index.html b/files/ru/web/css/@viewport/user-zoom/index.html deleted file mode 100644 index 3cb5768532..0000000000 --- a/files/ru/web/css/@viewport/user-zoom/index.html +++ /dev/null @@ -1,106 +0,0 @@ ---- -title: user-zoom -slug: Web/CSS/@viewport/user-zoom -translation_of: Web/CSS/@viewport -translation_of_original: Web/CSS/@viewport/user-zoom ---- -
{{ CSSRef }}
- -

Введение

- -

The user-zoom CSS descriptor controls whether or not the user should be able to change the zoom factor of a document defined by {{cssxref("@viewport")}}.

- -

{{cssinfo}}

- -

Синтаксис

- -
/* Keyword values */
-user-zoom: zoom;
-user-zoom: fixed;
-
- -

Значения

- -
-
zoom
-
The user can zoom in or out.
-
fixed
-
The user cannot zoom in or out.
-
- -

Формальный синтаксис

- -
{{csssyntax}}
- -

Спецфикации

- - - - - - - - - - - - - - - - -
СпецфикацииСтатусКомментарий
{{SpecName('CSS3 Device', '#the-lsquouser-zoomrsquo-descriptor', '"user-zoom" descriptor')}}{{Spec2('CSS3 Device')}}Initial definition
- -

Совместимость с браузерами

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
-
- -

 

diff --git a/files/ru/web/css/_colon_any/index.html b/files/ru/web/css/_colon_any/index.html deleted file mode 100644 index 6a9dab56ac..0000000000 --- a/files/ru/web/css/_colon_any/index.html +++ /dev/null @@ -1,190 +0,0 @@ ---- -title: ':any' -slug: 'Web/CSS/:any' -tags: - - CSS - - Experimental - - Псевдоклассы - - Руководство - - Экспериментальное -translation_of: 'Web/CSS/:is' -translation_of_original: 'Web/CSS/:any' ---- -
{{CSSRef}}{{SeeCompatTable}}
- -

Описание

- -

Псевдокласс :any() дает возможность быстрого конструирования наборов похожих селекторов путем составления групп, в которых каждый из входящих элементов будет комбинироваться с элементами из других групп. Это альтернатива для прописывания комбинаций селекторов для одного элемента, который может находится в разных родителях.

- -
Замечание: Этот псевдо-класс все еще находится в процессе стандартизации в CSS селекторах уровня 4 под именем :matches(). Вполне вероятно, что синтаксис и имя :-vendor-any() будут изменены в ближайшем будущем, чтобы соответствовать спецификации.
- -

Синтаксис

- -
:-moz-any( selector[, selector]* ) :-webkit-any( selector[, selector]* )
- -

Параметры

- -
-
selector
-
Селектор. Это может быть просто селектор или несколько селекторов, состоящих из CSS 3 простых селекторов и может включать комбинацию потомков.
-
- -
Замечание: Селекторы не могут содержать псевдо-элементы, допускается только комбинирование потомков.
- -

Примеры

- -

Например, следующий CSS:

- -
/* на глубине 3 (или больше) неупорядоченные списки используют square */
-ol ol ul,     ol ul ul,     ol menu ul,     ol dir ul,
-ol ol menu,   ol ul menu,   ol menu menu,   ol dir menu,
-ol ol dir,    ol ul dir,    ol menu dir,    ol dir dir,
-ul ol ul,     ul ul ul,     ul menu ul,     ul dir ul,
-ul ol menu,   ul ul menu,   ul menu menu,   ul dir menu,
-ul ol dir,    ul ul dir,    ul menu dir,    ul dir dir,
-menu ol ul,   menu ul ul,   menu menu ul,   menu dir ul,
-menu ol menu, menu ul menu, menu menu menu, menu dir menu,
-menu ol dir,  menu ul dir,  menu menu dir,  menu dir dir,
-dir ol ul,    dir ul ul,    dir menu ul,    dir dir ul,
-dir ol menu,  dir ul menu,  dir menu menu,  dir dir menu,
-dir ol dir,   dir ul dir,   dir menu dir,   dir dir dir {
-  list-style-type: square;
-}
-
- -

Может быть записано, как:

- -
/* на глубине 3 (или больше) неупорядоченные списки используют square */
-:-moz-any(ol, ul, menu, dir) :-moz-any(ol, ul, menu, dir) ul,
-:-moz-any(ol, ul, menu, dir) :-moz-any(ol, ul, menu, dir) menu,
-:-moz-any(ol, ul, menu, dir) :-moz-any(ol, ul, menu, dir) dir {
-  list-style-type: square;
-}
- -

Однако, не нужно использовать это так: (Смотрите раздел о производительности ниже.)

- -
:-moz-any(ol, ul, menu, dir) :-moz-any(ol, ul, menu, dir) :-moz-any(ul, menu, dir) {
-  list-style-type: square;
-}
- -

Примечания

- -

Особенно полезен при работе с разделами и заголовками в HTML5 . Теги {{HTMLElement("section")}}, {{HTMLElement("article")}}, {{HTMLElement("aside")}}, и {{HTMLElement("nav")}} могут быть вложенными, без :any() стилизация их соответствия друг другу может быть сложной.

- -

Например, без :any(), стилизация всех элементов {{HTMLElement("h1")}} на разной глубине будет очень сложна:

- -
/* Уровень 0 */
-h1 {
-  font-size: 30px;
-}
-/* Уровень 1 */
-section h1, article h1, aside h1, nav h1 {
-  font-size: 25px;
-}
-/* Уровень 2 */
-section section h1, section article h1, section aside h1, section nav h1,
-article section h1, article article h1, article aside h1, article nav h1,
-aside section h1, aside article h1, aside aside h1, aside nav h1,
-nav section h1, nav article h1, nav aside h1, nav nav h1, {
-  font-size: 20px;
-}
-/* Уровень 3 */
-/* ... даже не думайте о нём*/
-
- -

При использовании :-any(), это становится намного проще:

- -
/* Уровень 0 */
-h1 {
-  font-size: 30px;
-}
-/* Уровень 1 */
-:-moz-any(section, article, aside, nav) h1 {
-  font-size: 25px;
-}
-/* Уровень 2 */
-:-moz-any(section, article, aside, nav)
-:-moz-any(section, article, aside, nav) h1 {
-  font-size: 20px;
-}
-/* Уровень 3 */
-:-moz-any(section, article, aside, nav)
-:-moz-any(section, article, aside, nav)
-:-moz-any(section, article, aside, nav) h1 {
-  font-size: 15px;
-}
- -

Проблемы с производительностью и особенности

- -

{{ bug("561154") }} в Gecko, где специфика :-moz-any() не корректна. Текущая реализация (как в Firefox 12) ставит :-moz-any() в категорию универсальных правил, что означает, что использование его в качестве селектора справа будет медленнее, чем использование селекторов по ID, классу, или тегу.

- -

Например:

- -
.a > :-moz-any(.b, .c)
-
- -

медленнее, чем:

- -
.a > .b, .a > .c
-
- -

а следующее быстрее:

- -
:-moz-any(.a, .d) > .b, :-moz-any(.a, .d) > .c
-
- -

Поддержка браузерами

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
ВозможностьFirefox (Gecko)ChromeInternet ExplorerOperaSafari
Базовая поддержка{{CompatGeckoDesktop("2")}}{{property_prefix("-moz")}}12.0 (534.30){{property_prefix("-webkit")}}   -

5
- {{property_prefix("-webkit")}}

-
-
- -
- - - - - - - - - - - - - - - - - - - - - -
ВозможностьAndroidChrome for AndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Базовая поддержка{{CompatUnknown}}{{CompatVersionUnknown}}{{property_prefix("-webkit")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}5
- {{property_prefix("-webkit")}}
-
diff --git a/files/ru/web/css/actual_value/index.html b/files/ru/web/css/actual_value/index.html new file mode 100644 index 0000000000..da6231da1f --- /dev/null +++ b/files/ru/web/css/actual_value/index.html @@ -0,0 +1,40 @@ +--- +title: Действительное значение +slug: Web/CSS/Действительное_значение +tags: + - CSS + - Guide + - Web +translation_of: Web/CSS/actual_value +--- +

{{CSSRef}}

+ +

Описание

+ +

Действительное значение CSS свойства - используемое после всех приближений значение. Например, браузер может отображать рамки только с целым значением пикселей и будет прининудительно округлять ширину.

+ +

Спецификации

+ + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('CSS2.1', 'cascade.html#actual-value', 'actual value')}}{{Spec2('CSS2.1')}}Изначальное определение
+ +

Смотрите также

+ + diff --git a/files/ru/web/css/box_model/index.html b/files/ru/web/css/box_model/index.html deleted file mode 100644 index 6868871c5a..0000000000 --- a/files/ru/web/css/box_model/index.html +++ /dev/null @@ -1,66 +0,0 @@ ---- -title: 'Блоковая модель (боксовая модель, box model)' -slug: Web/CSS/box_model -tags: - - CSS - - Guide - - Веб -translation_of: Web/CSS/CSS_Box_Model/Introduction_to_the_CSS_box_model ---- -

Описание

- -

В HTML-документе каждому элементу на странице соответствует прямоугольная область (бокс или блок). Движок рендеринга в браузере определяет размеры и положение боксов на странице, а также их свойства вроде цвета, фоновой картинки для того, чтобы отобразить их на экране.

- -

В языке CSS есть специальная боксовая модель (также блоковая модель или блочная модель, англ. box model), которая описывает, из чего состоит бокс и какие свойства влияют на его размеры. В ней у каждого бокса есть 4 области: margin (внешние отступы), border (рамка), padding (внутренние поля), и content (контент или содержимое).

- -

CSS Box model

- -

Внутренняя область элемента (content area) содержит текст и другие элементы, расположенные внутри (контент или содержимое). У неё часто бывает фон, цвет или изображение (в таком порядке: фоновый цвет скрывается под непрозрачным изображением), и она находится внутри content edge; её размеры называются ширина контента (content width или content-box width), и высота контента (content height или content-box height). Иногда еще говорят «внутренняя ширина/высота элемента»

- -

По умолчанию, если CSS-свойство {{ cssxref("box-sizing") }} не задано, размер внутренней области с содержимым задается свойствами {{ cssxref("width") }}, {{ cssxref("min-width") }}, {{ cssxref("max-width") }}, {{ cssxref("height") }}, {{ cssxref("min-height") }} and {{ cssxref("max-height") }}. Если же свойство  {{ cssxref("box-sizing") }} задано, то оно определяет, для какой области указаны размеры.

- -

Поля элемента (padding area) — это пустая область, окружающая контент. Она может быть залита каким-то цветом, покрыта фоновый картинкой, а её границы называются края полей (padding edge).

- -

Размеры полей задаются по отдельности с разных сторон свойствами {{ cssxref("padding-top") }}, {{ cssxref("padding-right") }}, {{ cssxref("padding-bottom") }}, {{ cssxref("padding-left") }} или общим свойством {{ cssxref("padding") }}.

- -

Область рамки (border area) окружает поля элемента, а ее граница называется края рамки (border edge). Ширина рамки задается отдельным свойством  {{ cssxref("border-width") }} или в составе свойства {{ cssxref("border") }}. Размеры элемента с учетом полей и рамки иногда называют внешней шириной/высотой элемента.

- -

Отступы (margin area) добавляют пустое пространство вокруг элемента и определяют расстояние до соседних элементов.

- -

Величина отступов задается по отдельности в разных направлениях свойствами {{ cssxref("margin-top") }}, {{ cssxref("margin-right") }}, {{ cssxref("margin-bottom") }}, {{ cssxref("margin-left") }} или общим свойством {{ cssxref("margin") }}.

- -

Отступы двух соседних элементов, расположенных друг над другом или вложенных друг в друга, могут накладываться. Это называется схлопывание границ (margin collapsing). Схлопываются только вертикальные отступы.

- -

Для элементов с {{ cssxref("display") }}: inline (или inline-block, inline-table) на занимаемое по высоте место также влияет значение свойства {{ cssxref('line-height') }}.

- -

Стандарты

- - - - - - - - - - - - - - - - - - - - - -
СтандартСтатусПримечание
CSS Level 2 (revision 1){{ Spec2('CSS2.1') }}Though more precisely worded, there is no practical change
CSS Level 1{{ Spec2('CSS1') }} 
- -

Смотрите также

- -
    -
  • Справочник по CSS
  • -
  • {{ CSS_key_concepts() }}
  • -
  • Связанные свойства: {{ cssxref("box-sizing") }}, {{ cssxref("background-clip") }}, {{ cssxref("height") }}, {{ cssxref("max-height") }}, {{ cssxref("min-height") }}, {{ cssxref("width") }}, {{ cssxref("max-height") }}, {{ cssxref("min-height") }}, {{ cssxref("padding") }}, {{ cssxref("padding-top") }}, {{ cssxref("padding-right") }}, {{ cssxref("padding-bottom") }}, {{ cssxref("padding-left") }}, {{ cssxref("border") }}, {{ cssxref("border-top") }}, {{ cssxref("border-right") }}, {{ cssxref("border-bottom") }}, {{ cssxref("border-left") }}, {{ cssxref("border-width") }}, {{ cssxref("border-top-width") }}, {{ cssxref("border-right-width") }}, {{ cssxref("border-bottom-width") }}, {{ cssxref("border-left-width") }}, {{ cssxref("margin") }}, {{ cssxref("margin-top") }}, {{ cssxref("margin-right") }}, {{ cssxref("margin-bottom") }}, {{ cssxref("margin-left") }}
  • -
diff --git a/files/ru/web/css/comments/index.html b/files/ru/web/css/comments/index.html new file mode 100644 index 0000000000..1db7dd50b5 --- /dev/null +++ b/files/ru/web/css/comments/index.html @@ -0,0 +1,50 @@ +--- +title: Комментарии +slug: Web/CSS/Тихий +tags: + - Beginner + - CSS + - CSS Reference + - Комментарии + - Новичку + - Руководство +translation_of: Web/CSS/Comments +--- +
{{CSSRef}}
+ +

Описание

+ +

Комментарии используются для добавления поясняющих заметок или для того, чтобы предотвратить интеграцию части кода в браузер.

+ +

Синтаксис

+ +
/* Комментарий */
+ +

Примеры

+ +
/* Однострочный комментарий */
+
+/*
+Комментарий
+который содержит
+несколько
+строк
+*/
+
+ +

Замечания

+ +

Данный /* */ синтаксис комментария используется для обоих вариантов, и однострочного и многострочного комментария. Нет других способов добавить комментарий во внешнюю таблицу стилей. Также, когда используется элемент <style>, вы можете использовать <!-- -->, чтобы спрятать CSS от старых браузеров, но это не рекомендуется. Как и в большинстве языков программирования, которые используют синтаксис комментариев /* */ , комментарии нельзя вкладывать друг в друга. Другими словами, данная часть синтаксиса */, которая следует за /* закрывает комментарий.

+ +

Спецификации

+ + + +

Смотрите также

+ + diff --git a/files/ru/web/css/common_css_questions/index.html b/files/ru/web/css/common_css_questions/index.html deleted file mode 100644 index cecfb92b82..0000000000 --- a/files/ru/web/css/common_css_questions/index.html +++ /dev/null @@ -1,182 +0,0 @@ ---- -title: Common CSS questions -slug: Web/CSS/Common_CSS_Questions -translation_of: Learn/CSS/Howto/CSS_FAQ ---- -

Why doesn't my CSS, which is valid, render correctly?

- -

Браузер использует декларацию DOCTYPE чтобы выбрать, как именно отображать документ - в форме, более совместимой с современными стандартами или в форме,  которую будут поддерживать старые браузеры. Правильное использование декларациии DOCTYPE в начале вашего HTML кода повлияет на совместимость с современными стандартами веб браузеров.

- -

У современных браузеров есть два режима отображения веб-страниц:

- -
    -
  • Индивидуальный: его также называют backwards-compatibility mode, даёт возможность устаревшим страницам отображаться так, как планировал автор, следуя уже не стандартным правилам отображения, которые использовались ещё старыми браузерами. Документы  с неполной, некорректной или отстутвующей DOCTYPE декларацией или с тем видом DOCTYPE, который использовался до 2001 года, будет отображён в индивидуальном режиме.
  • -
  • Стандартный: в этом режиме браузер старается строго следовать стандартам W3C. Ожидается, что современные HTML страницы разработаны для браузеров, следуемых стандартам, и в результате, страницы с современным  DOCTYPE отображаются уже в стандартом режиме.
  • -
- -

Gecko-based browsers, have a third Almost Standards Mode that has only a few minor quirks.

- -

This is a list of the most commonly used DOCTYPE declarations that will trigger Standards or Almost Standards mode:

- -
<!DOCTYPE html> /* This is the HTML5 doctype. Given that each modern browser uses an HTML5
-                   parser, this is the recommended doctype */
-
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
-"http://www.w3.org/TR/html4/loose.dtd">
-
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-"http://www.w3.org/TR/html4/strict.dtd">
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-
- -

Why doesn't my CSS, which is valid, render at all?

- -

To be applied, a CSS stylesheet must be served with a text/css MIME type. If the Web server doesn't serve it with this type, it won't be applied.

- -

What is the difference between id and class?

- -

HTML elements can have an id and/or class attribute. The id attribute assigns a name to the element it is applied to, and for valid markup, there can be only one element with that name. The class attribute assigns a class name to the element, and that name can be used on many elements within the page. CSS allows you to apply styles to particular id and/or class names.
-
- Use an id-specific style when you want to restrict the applied styling rules to one specific block or element. This style will only be used by the element with that particular id.
-
- Use a class-specific style when you want to apply the styling rules to many blocks and elements within the page.

- -

Stylesheets with fewer rules are usually more performant. It is therefore recommended to use classes as much as possible, and to reserve the use of id for specific uses (like to connect label and form elements or for styling elements that must be semantically unique).

- -

See CSS selectors

- -

How do I restore the default value of a property?

- -

Initially CSS didn't provide a "default" keyword and the only way to restore the default value of a property is to explicitly re-declare that property.

- -

This has changed with CSS 2; the keyword initial is now a valid value for a CSS property. It resets it to its default value, which is defined in the CSS specification of the given property.

- -

How do I derive one style from another?

- -

CSS does not allow one style to be defined in terms of another. (See Eric Meyer's note about the Working Group's stance). However, assigning multiple classes to a single element can provide the same effect.

- -

How do I assign multiple classes to an element?

- -

HTML elements can be assigned multiple classes by listing the classes in the class attribute, with a blank space to separate them.

- -
<style type="text/css">
-.news { background: black; color: white; }
-.today { font-weight: bold; }
-</style>
-
-<div class="news today">
-... content of today's news ...
-</div>
-
- -

If the same property is declared in both rules, the conflict is resolved first through specificity, then according to the order of the CSS declarations. The order of classes in the class attribute is not relevant.

- -

Why don't my style rules work properly?

- -

Style rules that are syntactically correct may not apply in certain situations. You can use DOM Inspector's CSS Style Rules view to debug problems of this kind, but the most frequent instances of ignored style rules are listed below.

- -

HTML elements hierarchy

- -

The way CSS styles are applied to HTML elements depends also on the elements hierarchy. It is important to remember that a rule applied to a descendent overrides the style of the parent, in spite of any specificity or priority of CSS rules.

- -
.news { color: black; }
-.corpName { font-weight: bold; color: red; }
-
-<!-- news item text is black, but corporate name is red and in bold -->
-<div class="news">
-   (Reuters) <span class="corpName">General Electric</span> (GE.NYS) announced on Thursday...
-</div>
-
- -

In case of complex HTML hierarchies, if a rule seems to be ignored, check if the element is inside another element with a different style.

- -

Explicitly re-defined style rule

- -

In CSS stylesheets, order is important. If you define a rule and then you re-define the same rule, the last definition is used.

- -
#stockTicker { font-weight: bold; }
-.stockSymbol { color: red; }
-/*  other rules             */
-/*  other rules             */
-/*  other rules             */
-.stockSymbol { font-weight: normal; }
-
-<!-- most text is in bold, except "GE", which is red and not bold -->
-<div id="stockTicker">
-   NYS: <span class="stockSymbol">GE</span> +1.0 ...
-</div>
-
- -

To avoid this kind of error, try to define rules only once for a certain selector, and group all rules belonging to that selector.

- -

Use of a shorthand property

- -

Using shorthand properties for defining style rules is good because it uses a very compact syntax. Using shorthand with only some attributes is possible and correct, but it must be remembered that undeclared attributes are automatically reset to default. This means that a previous rule for a single attribute could be implicitly overridden.

- -
#stockTicker { font-size: 12px; font-family: Verdana; font-weight: bold; }
-.stockSymbol { font: 14px Arial; color: red; }
-
-<div id="stockTicker">
-   NYS: <span class="stockSymbol">GE</span> +1.0 ...
-</div>
-
- -

In the previous example the problem occurred on rules belonging to different elements, but it could happen also for the same element, because rule order is important.

- -
#stockTicker {
-   font-weight: bold;
-   font: 12px Verdana;  /* font-weight is now normal */
-}
-
- -

Use of the * selector

- -

The * wildcard selector refers to any element, and it has to be used with particular care.

- -
body * { font-weight: normal; }
-#stockTicker { font: 12px Verdana; }
-.corpName { font-weight: bold; }
-.stockUp { color: red; }
-
-<div id="section">
-   NYS: <span class="corpName"><span class="stockUp">GE</span></span> +1.0 ...
-</div>
-
- -

In this example the body * selector applies the rule to all elements inside body, at any hierarchy level, including the .stockUp class. So font-weight: bold; applied to the .corpName class is overridden by font-weight: normal; applied to all elements in the body.

- -

The use of the * selector should be minimized as it is a slow selector, especially when not used as the first element of a selector. Its use should be avoided as much as possible.

- -

Specificity in CSS

- -

When multiples rules apply to a certain element, the rule chosen depends on its style specificity. Inline style (in HTML style attributes) comes first, followed by ID selectors, then class selectors and eventually element-name selectors.

- -
div { color: black; }
-#orange { color: orange; }
-.green { color: green; }
-
-<div id="orange" class="green" style="color: red;">This is red</div>
-
- -

The rules are more complicated when the selector has multiple parts. More detailed information about how selector specificity is calculated can be found in the CSS 2.1 Specification chapter 6.4.3.

- -

What do the -moz-*, -ms-*, -webkit-*, -o-* and -khtml-* properties do?

- -

These properties, called prefixed properties, are extensions to the CSS standard. They are used to use experimental and non-standard features without polluting the regular namespace, preventing future incompatibilities to arise when the standard is extended.

- -

The use of such properties on production websites is not recommended. If nevertheless needed, you are hinted to make a plan for the website evolution: these prefixed properties can be modified or even suppressed when the standard evolves.

- -

Please see the Mozilla CSS Extensions page for more information on the Mozilla-prefixed CSS properties.

- -

How does z-index relate to positioning?

- -

The z-index property specifies the stack order of elements.

- -

An element with a higher z-index/stack order is always in front of an element with a lower z-index/stack order.

- -

Z-index will only work on elements that have a specified position (position:absolute, position:relative, or position:fixed).

diff --git a/files/ru/web/css/css_animations/ispolzovanie_css_animatciy/index.html b/files/ru/web/css/css_animations/ispolzovanie_css_animatciy/index.html deleted file mode 100644 index 05f6cb5cec..0000000000 --- a/files/ru/web/css/css_animations/ispolzovanie_css_animatciy/index.html +++ /dev/null @@ -1,388 +0,0 @@ ---- -title: Использование CSS-анимации -slug: Web/CSS/CSS_Animations/Ispolzovanie_CSS_animatciy -tags: - - Advanced - - CSS - - CSS Animations - - Example - - Experimental - - Guide -translation_of: Web/CSS/CSS_Animations/Using_CSS_animations ---- -

{{SeeCompatTable}}{{CSSRef}}

- -

CSS анимации позволяют анимировать переходы от одной конфигурации CSS стилей к другой. CSS-анимации состоят из двух компонентов: стилевое описание анимации и набор ключевых кадров, определяющих начальное, конечное и, возможно, промежуточное состояние анимируемых стилей.

- -

Есть три преимущества CSS-анимации перед традиционными способами:

- -
    -
  1. Простота использования для простых анимаций; Вы можете создать анимацию, не зная JavaScript.
  2. -
  3. Анимации будут хорошо работать даже при умеренных нагрузках системы. Простые анимации на JavaScript, если они плохо написаны, часто выполняются плохо. Движок может использовать frame-skipping и другие техники, чтобы сохранить производительность на таком высоком уровне .
  4. -
  5. Позволяет браузеру контролировать последовательность анимации, тем самым оптимизируя производительность и эффективность браузера. Например, уменьшая частоту обновления кадров анимации в непросматриваемых в данный момент вкладках.
  6. -
- -

Конфигурирование анимации

- -

Чтобы создать CSS-анимацию Вы должны добавить в стиль элемента, который хотите анимировать, свойство {{ cssxref("animation") }} или его подсвойства. Это позволит Вам настроить ускорение и продолжительность анимации, а также другие детали того, как анимация должна протекать. Это не поможет Вам настроить внешний вид анимации, который настраивается с помощью {{ cssxref("@keyframes") }}, рассматриваемой далее в {{ anch("Определение последовательности анимации с помощью ключевых кадров") }}.

- -

Свойство {{ cssxref("animation") }} имеет следующие подсвойства:

- -
-
{{ cssxref("animation-name") }}
-
Определяет имя {{ cssxref("@keyframes") }}, настраивающего кадры анимации.
-
{{ cssxref("animation-duration") }}
-
Определяет время, в течение которого должен пройти один цикл анимации.
-
{{ cssxref("animation-timing-function") }}
-
Настраивает ускорение анимации.
-
{{ cssxref("animation-delay") }}
-
Настраивает задержку между временем загрузки элемента и временем начала анимации.
-
{{ cssxref("animation-iteration-count") }}
-
Определяет количество повторений анимации; Вы можете использовать значение infinite для бесконечного повторения анимации.
-
{{ cssxref("animation-direction") }}
-
Дает возможность при каждом повторе анимации идти по альтернативному пути, либо сбросить все значения и повторить анимацию.
-
{{ cssxref("animation-fill-mode") }}
-
Настраивает значения, используемые анимацией, до и после исполнения.
-
{{ cssxref("animation-play-state") }}
-
Позволяет приостановить и возобновить анимацию.
-
- -

Определение последовательности анимации с помощью ключевых кадров

- -

После того, как вы настроили временные свойства (продолжительность, ускорение) анимации, вы должны определить внешний вид анимации. Это делается с помощью двух и более ключевых кадров после {{ cssxref("@keyframes") }}. Каждый кадр описывает, как должен выглядеть анимированный элемент в текущий момент.

- -

В то время, как временные характеристики (продолжительность анимации) указываются в стилях для анимируемого элемента, ключевые кадры используют {{ cssxref("percentage") }}, чтобы определить стадию протекания анимации. 0% означает начало анимации, а 100% ее конец. Так как эти значения очень важны, то для них придумали специальные слова: from и to.

- -

Вы также можете добавить ключевые кадры, характеризующие промежуточное состояние анимации.

- -

Примеры

- -
Внимание: Примеры ниже не используют префиксов для CSS стилей . Webkit-браузеры и старые версии других браузеров нуждаются в указании префиксов в CSS стилях. Примеры, на которые Вы можете кликнуть в своем браузере, также содержат префиксы -webkit-.
- -

Скольжение текста

- -

Этот простой пример анимирует скольжение текста в элементе {{ HTMLElement("p") }} от правого края окна браузера.

- -

Обратите внимание на то, что анимация может сделать страницу шире, чем окно браузера. Этого можно избежать, поместив элемент, который будет анимироваться, в контейнер и установив ему свойство {{cssxref("overflow")}}: hidden.

- -
p {
-  animation-duration: 3s;
-  animation-name: slidein;
-}
-
-@keyframes slidein {
-  from {
-    margin-left: 100%;
-    width: 300%;
-  }
-
-  to {
-    margin-left: 0%;
-    width: 100%;
-  }
-}
-
- -

В стиле для элемента {{ HTMLElement("p") }} с помощью свойства {{ cssxref("animation-duration") }} указано, что исполнение анимации от начала до конца должно занять 3 с , и что имя для  {{ cssxref("@keyframes") }}, описывающей саму анимацию, определено как "slidein".

- -

В элемент {{ HTMLElement("p") }} можно добавлять и другие пользовательские стили, чтобы как-то украсить его, однако здесь мы хотели продемонстрировать только эффект анимации.

- -

Kлючевые кадры определяются с помощью правила {{ cssxref("@keyframes") }}. В данном случае мы имеем только два ключевых кадра. Первый при 0% анимации (from). Здесь мы придаем элементу левый отступ в 100% и ширину в 300% (в три раза больше ширины родительского элемента). Это становится причиной того, что при первом кадре анимации заголовок {{ HTMLElement("p") }} находится за пределами правого края окна браузера .

- -

Второй ключевой кадр (to) определяет конец анимации, т.е (100%). Левый отступ устанавливается равным 0, а ширина 100%. Все выглядит так, будто заголовок {{ HTMLElement("p") }} приплывает к левому краю окна браузера.

- -
<p>The Caterpillar and Alice looked at each other for some time in silence:
-at last the Caterpillar took the hookah out of its mouth, and addressed
-her in a languid, sleepy voice.</p>
-
- -

(Обновите страницу, чтобы увидеть анимацию, или щелкните по кнопке CodePen, чтобы воспроизвести ее в окне CodePen)

- -

{{EmbedLiveSample("Скольжение_текста","100%","250")}}

- -

Добавление других ключевыч кадров

- -

Давайте добавим другие ключевые кадры в предыдущий пример. Скажем, мы хотим чтобы размер шрифта заголовка временно увеличивался по мере продвижения влево, а потом возращался к первоначальному значению . Это легко реализовать с помощью следующего ключевого кадра:

- -
75% {
-  font-size: 300%;
-  margin-left: 25%;
-  width: 150%;
-}
-
- -
p {
-  animation-duration: 3s;
-  animation-name: slidein;
-}
-
-@keyframes slidein {
-  from {
-    margin-left: 100%;
-    width: 300%;
-  }
-
-  to {
-    margin-left: 0%;
-    width: 100%;
-  }
-
-  75% {
-    font-size: 300%;
-    margin-left: 25%;
-    width: 150%;
-  }
-}
-
- -
<p>The Caterpillar and Alice looked at each other for some time in silence:
-at last the Caterpillar took the hookah out of its mouth, and addressed
-her in a languid, sleepy voice.</p>
-
- -

Это говорит браузеру о том, что при 75% выполнения анимации, шрифт должен быть 300%, а ширина 150%.

- -

(Обновите страницу, чтобы увидеть анимацию, или щелкните по кнопке CodePen, чтобы воспроизвести ее в окне CodePen)

- -

{{ EmbedLiveSample('Добавление_других_ключевыч_кадров', '100%', '250', '', 'Web/CSS/CSS_Animations/Ispolzovanie_CSS_animatciy') }}

- -

Настройка повторения

- -

Чтобы настроить повторение, нужно добавить свойство {{ cssxref("animation-iteration-count") }} и задать ему значение, равное нужному количеству повторений анимаций . В данном случае давайте установим значение infinite для бесконечного повторения:

- -
p {
-  animation-duration: 3s;
-  animation-name: slidein;
-  animation-iteration-count: infinite;
-}
-
- -
@keyframes slidein {
-  from {
-    margin-left: 100%;
-    width: 300%;
-  }
-
-  to {
-    margin-left: 0%;
-    width: 100%;
-  }
-}
-
- -
<p>The Caterpillar and Alice looked at each other for some time in silence:
-at last the Caterpillar took the hookah out of its mouth, and addressed
-her in a languid, sleepy voice.</p>
-
- -

{{EmbedLiveSample("Настройка_повторения","100%","250")}}

- -

Движение текста вправо и влево

- -

Итак, мы настроили повторение, но получили нечто странное: текст при каждом повторении снова "запрыгивает" за край окна браузера. То, чего мы хотим, так это чтобы текст двигался влево и вправо. Этого легко достичь с помощью установки свойству {{ cssxref("animation-direction") }} значения alternate:

- -
p {
-  animation-duration: 3s;
-  animation-name: slidein;
-  animation-iteration-count: infinite;
-  animation-direction: alternate;
-}
-
- -
@keyframes slidein {
-  from {
-    margin-left: 100%;
-    width: 300%;
-  }
-
-  to {
-    margin-left: 0%;
-    width: 100%;
-  }
-}
-
- -
<p>The Caterpillar and Alice looked at each other for some time in silence:
-at last the Caterpillar took the hookah out of its mouth, and addressed
-her in a languid, sleepy voice.</p>
-
- -

{{ EmbedLiveSample('Движение_текста_вправо_и_влево', '100%', '250', '', 'Web/CSS/CSS_Animations/Ispolzovanie_CSS_animatciy') }}

- -

Использование шорткодов

- -

Шорткод {{cssxref("animation")}} полезен для экономии места в коде. Например, правило, которое мы используем в этой статье:

- -
p {
-  animation-duration: 3s;
-  animation-name: slidein;
-  animation-iteration-count: infinite;
-  animation-direction: alternate;
-}
- -

можно заменить на:

- -
p {
-  animation: 3s infinite alternate slidein;
-}
- -
-

Внимание: подробнее об этом на странице раздела {{cssxref("animation")}} 

-
- -

Установка нескольких значений свойствам анимации  

- -

CSS cвойство анимации может иметь несколько значений, разделенных запятыми. Это используется, чтобы указать несколько значений анимации в одном правиле и установить разную продолжительность, число повторений и т.д., для различных анимаций. Рассмотрим несколько примеров, чтобы увидеть разницу.

- -

В первом примере у свойства имени анимации установлены три значения, у свойств продолжительности и количества повторений  — по одному. В этом случае у всех трех анимаций одинаковая продолжительность и число повторений:

- -
animation-name: fadeInOut, moveLeft300px, bounce;
-animation-duration: 3s;
-animation-iteration-count: 1;
- -

Во втором примере установлены три значения для каждого из свойств. В этом случае каждая анимация выполняется с соответствующими по порядку значениями в каждом свойстве, так, например, fadeInOut имеет продолжительность 2.5 с и количество повторений 2, и т.д.

- -
animation-name: fadeInOut, moveLeft300px, bounce;
-animation-duration: 2.5s, 5s, 1s;
-animation-iteration-count: 2, 1, 5;
- -

В третьем примере определены три значения имени анимации, но два значения продолжительности и количества повторений. В случае, когда количества значений недостаточно для каждой анимации, значения берутся циклически от начала до конца. Например, у fadeInOut длительность будет 2.5s,  а moveLeft300px — 5s. Значения продолжительности закончились, теперь они берутся сначала — bounce получит продолжительность 2.5s. Значение количества повторений (а также другие указанные свойства) будет определено таким же образом.

- -
animation-name: fadeInOut, moveLeft300px, bounce;
-animation-duration: 2.5s, 5s;
-animation-iteration-count: 2, 1;
- -

Использование событий анимации

- -

Вы можете получить дополнительный контроль над анимацией, а также полезную информацию о ней, с помощью событий анимации. Эти события, представленные объектом {{ domxref("event/AnimationEvent", "AnimationEvent") }}, можно использовать, чтобы определить, когда начинается и заканчивается анимация или начинается новая итерация. Каждое событие содержит момент времени, когда оно произошло, а также имя анимации, которая вызвала событие.

- -

Мы будем модифицировать текст, чтобы выводить некоторую информацию  о каждом событии анимации. Так мы сможем увидеть, как она работает.

- -

Добавление CSS

- -

Начнем с добавления CSS. Анимация будет длиться 3 секунды, будет называться "slidein", будет повторяться 3 раза, а также значение animation-direction установлено alternate. В ключевых кадрах {{ cssxref("@keyframes") }} установлены такие значения ширины и левого отступа, что элемент будет скользить по экрану.

- -
.slidein {
-  -moz-animation-duration: 3s;
-  -webkit-animation-duration: 3s;
-  animation-duration: 3s;
-  -moz-animation-name: slidein;
-  -webkit-animation-name: slidein;
-  animation-name: slidein;
-  -moz-animation-iteration-count: 3;
-  -webkit-animation-iteration-count: 3;
-  animation-iteration-count: 3;
-  -moz-animation-direction: alternate;
-  -webkit-animation-direction: alternate;
-  animation-direction: alternate;
-}
-
-@-moz-keyframes slidein {
-  from {
-    margin-left: 100%;
-    width: 300%
-  }
-
-  to {
-    margin-left: 0%;
-    width: 100%;
-  }
-}
-
-@-webkit-keyframes slidein {
-  from {
-    margin-left: 100%;
-    width: 300%
-  }
-
-  to {
-   margin-left: 0%;
-   width: 100%;
- }
-}
-
-@keyframes slidein {
-  from {
-    margin-left: 100%;
-    width: 300%
-  }
-
-  to {
-   margin-left: 0%;
-   width: 100%;
- }
-}
- -

Добавление обработчика события анимации

- -

Будем использовать JavaScript для отслеживания всех трех возможных событий анимации. Следующий код конфигурирует обработчик; мы вызываем его при первой загрузке документа.

- -
var e = document.getElementById("watchme");
-e.addEventListener("animationstart", listener, false);
-e.addEventListener("animationend", listener, false);
-e.addEventListener("animationiteration", listener, false);
-
-e.className = "slidein";
-
- -

Это довольно стандартный код; Вы можете получить дополнительную информацию в документации {{ domxref("element.addEventListener()") }}. Последнее, что делает этот код - это установка класса "slidein" для анимируемого элемента; мы делаем это, чтобы запустить анимацию.

- -

Почему? Потому что в нашем случае событие animationstart происходит как только анимация стартует, и это происходит раньше, чем исполняется наш сценарий. Так мы сможем контролировать начало анимации самостоятельно посредством вставки класса "slidein" для анимируемого элемента.

- -

Регистрация событий

- -

События будут передаваться функции listener(), показанной ниже.

- -
function listener(e) {
-  var l = document.createElement("li");
-  switch(e.type) {
-    case "animationstart":
-      l.innerHTML = "Started: elapsed time is " + e.elapsedTime;
-      break;
-    case "animationend":
-      l.innerHTML = "Ended: elapsed time is " + e.elapsedTime;
-      break;
-    case "animationiteration":
-      l.innerHTML = "New loop started at time " + e.elapsedTime;
-      break;
-  }
-  document.getElementById("output").appendChild(l);
-}
-
- -

Этот код также очень прост. Этот код следит за {{ domxref("event.type") }}, чтобы определить тип события, и добавляет элемент {{ HTMLElement("ul") }}, чтобы залогировать произошедшее событие.

- -

Вывод, когда анимация закончится, будет выглядеть примерно следующим образом:

- -
    -
  • Started: elapsed time is 0
  • -
  • New loop started at time 3.01200008392334
  • -
  • New loop started at time 6.00600004196167
  • -
  • Ended: elapsed time is 9.234000205993652
  • -
- -

Обратите внимание, что время, указанное в выводе, и время, которое мы указали в стилях, не совпадают. Также обратите внимание, что после окончания итерации не посылается событие animationiteration ; вместо него посылается событие animationend.

- -

HTML

- -

Ради полноты картины приведем код разметки HTML. В разметке имеется тег ul, в который и выводится вся информация:

- -
<body>
-  <h1 id="watchme">Watch me move</h1>
-  <p>This example shows how to use CSS animations to make <code>p</code> elements
-  move across the page.</p>
-  <p>In addition, we output some text each time an animation event fires, so you can see them in action.</p>
-  <ul id="output">
-  </ul>
-</body>
-
- -

{{ EmbedLiveSample('Использование_событий_анимации', '600', '300')}}

- -

Смотрите также

- - diff --git a/files/ru/web/css/css_animations/using_css_animations/index.html b/files/ru/web/css/css_animations/using_css_animations/index.html new file mode 100644 index 0000000000..05f6cb5cec --- /dev/null +++ b/files/ru/web/css/css_animations/using_css_animations/index.html @@ -0,0 +1,388 @@ +--- +title: Использование CSS-анимации +slug: Web/CSS/CSS_Animations/Ispolzovanie_CSS_animatciy +tags: + - Advanced + - CSS + - CSS Animations + - Example + - Experimental + - Guide +translation_of: Web/CSS/CSS_Animations/Using_CSS_animations +--- +

{{SeeCompatTable}}{{CSSRef}}

+ +

CSS анимации позволяют анимировать переходы от одной конфигурации CSS стилей к другой. CSS-анимации состоят из двух компонентов: стилевое описание анимации и набор ключевых кадров, определяющих начальное, конечное и, возможно, промежуточное состояние анимируемых стилей.

+ +

Есть три преимущества CSS-анимации перед традиционными способами:

+ +
    +
  1. Простота использования для простых анимаций; Вы можете создать анимацию, не зная JavaScript.
  2. +
  3. Анимации будут хорошо работать даже при умеренных нагрузках системы. Простые анимации на JavaScript, если они плохо написаны, часто выполняются плохо. Движок может использовать frame-skipping и другие техники, чтобы сохранить производительность на таком высоком уровне .
  4. +
  5. Позволяет браузеру контролировать последовательность анимации, тем самым оптимизируя производительность и эффективность браузера. Например, уменьшая частоту обновления кадров анимации в непросматриваемых в данный момент вкладках.
  6. +
+ +

Конфигурирование анимации

+ +

Чтобы создать CSS-анимацию Вы должны добавить в стиль элемента, который хотите анимировать, свойство {{ cssxref("animation") }} или его подсвойства. Это позволит Вам настроить ускорение и продолжительность анимации, а также другие детали того, как анимация должна протекать. Это не поможет Вам настроить внешний вид анимации, который настраивается с помощью {{ cssxref("@keyframes") }}, рассматриваемой далее в {{ anch("Определение последовательности анимации с помощью ключевых кадров") }}.

+ +

Свойство {{ cssxref("animation") }} имеет следующие подсвойства:

+ +
+
{{ cssxref("animation-name") }}
+
Определяет имя {{ cssxref("@keyframes") }}, настраивающего кадры анимации.
+
{{ cssxref("animation-duration") }}
+
Определяет время, в течение которого должен пройти один цикл анимации.
+
{{ cssxref("animation-timing-function") }}
+
Настраивает ускорение анимации.
+
{{ cssxref("animation-delay") }}
+
Настраивает задержку между временем загрузки элемента и временем начала анимации.
+
{{ cssxref("animation-iteration-count") }}
+
Определяет количество повторений анимации; Вы можете использовать значение infinite для бесконечного повторения анимации.
+
{{ cssxref("animation-direction") }}
+
Дает возможность при каждом повторе анимации идти по альтернативному пути, либо сбросить все значения и повторить анимацию.
+
{{ cssxref("animation-fill-mode") }}
+
Настраивает значения, используемые анимацией, до и после исполнения.
+
{{ cssxref("animation-play-state") }}
+
Позволяет приостановить и возобновить анимацию.
+
+ +

Определение последовательности анимации с помощью ключевых кадров

+ +

После того, как вы настроили временные свойства (продолжительность, ускорение) анимации, вы должны определить внешний вид анимации. Это делается с помощью двух и более ключевых кадров после {{ cssxref("@keyframes") }}. Каждый кадр описывает, как должен выглядеть анимированный элемент в текущий момент.

+ +

В то время, как временные характеристики (продолжительность анимации) указываются в стилях для анимируемого элемента, ключевые кадры используют {{ cssxref("percentage") }}, чтобы определить стадию протекания анимации. 0% означает начало анимации, а 100% ее конец. Так как эти значения очень важны, то для них придумали специальные слова: from и to.

+ +

Вы также можете добавить ключевые кадры, характеризующие промежуточное состояние анимации.

+ +

Примеры

+ +
Внимание: Примеры ниже не используют префиксов для CSS стилей . Webkit-браузеры и старые версии других браузеров нуждаются в указании префиксов в CSS стилях. Примеры, на которые Вы можете кликнуть в своем браузере, также содержат префиксы -webkit-.
+ +

Скольжение текста

+ +

Этот простой пример анимирует скольжение текста в элементе {{ HTMLElement("p") }} от правого края окна браузера.

+ +

Обратите внимание на то, что анимация может сделать страницу шире, чем окно браузера. Этого можно избежать, поместив элемент, который будет анимироваться, в контейнер и установив ему свойство {{cssxref("overflow")}}: hidden.

+ +
p {
+  animation-duration: 3s;
+  animation-name: slidein;
+}
+
+@keyframes slidein {
+  from {
+    margin-left: 100%;
+    width: 300%;
+  }
+
+  to {
+    margin-left: 0%;
+    width: 100%;
+  }
+}
+
+ +

В стиле для элемента {{ HTMLElement("p") }} с помощью свойства {{ cssxref("animation-duration") }} указано, что исполнение анимации от начала до конца должно занять 3 с , и что имя для  {{ cssxref("@keyframes") }}, описывающей саму анимацию, определено как "slidein".

+ +

В элемент {{ HTMLElement("p") }} можно добавлять и другие пользовательские стили, чтобы как-то украсить его, однако здесь мы хотели продемонстрировать только эффект анимации.

+ +

Kлючевые кадры определяются с помощью правила {{ cssxref("@keyframes") }}. В данном случае мы имеем только два ключевых кадра. Первый при 0% анимации (from). Здесь мы придаем элементу левый отступ в 100% и ширину в 300% (в три раза больше ширины родительского элемента). Это становится причиной того, что при первом кадре анимации заголовок {{ HTMLElement("p") }} находится за пределами правого края окна браузера .

+ +

Второй ключевой кадр (to) определяет конец анимации, т.е (100%). Левый отступ устанавливается равным 0, а ширина 100%. Все выглядит так, будто заголовок {{ HTMLElement("p") }} приплывает к левому краю окна браузера.

+ +
<p>The Caterpillar and Alice looked at each other for some time in silence:
+at last the Caterpillar took the hookah out of its mouth, and addressed
+her in a languid, sleepy voice.</p>
+
+ +

(Обновите страницу, чтобы увидеть анимацию, или щелкните по кнопке CodePen, чтобы воспроизвести ее в окне CodePen)

+ +

{{EmbedLiveSample("Скольжение_текста","100%","250")}}

+ +

Добавление других ключевыч кадров

+ +

Давайте добавим другие ключевые кадры в предыдущий пример. Скажем, мы хотим чтобы размер шрифта заголовка временно увеличивался по мере продвижения влево, а потом возращался к первоначальному значению . Это легко реализовать с помощью следующего ключевого кадра:

+ +
75% {
+  font-size: 300%;
+  margin-left: 25%;
+  width: 150%;
+}
+
+ +
p {
+  animation-duration: 3s;
+  animation-name: slidein;
+}
+
+@keyframes slidein {
+  from {
+    margin-left: 100%;
+    width: 300%;
+  }
+
+  to {
+    margin-left: 0%;
+    width: 100%;
+  }
+
+  75% {
+    font-size: 300%;
+    margin-left: 25%;
+    width: 150%;
+  }
+}
+
+ +
<p>The Caterpillar and Alice looked at each other for some time in silence:
+at last the Caterpillar took the hookah out of its mouth, and addressed
+her in a languid, sleepy voice.</p>
+
+ +

Это говорит браузеру о том, что при 75% выполнения анимации, шрифт должен быть 300%, а ширина 150%.

+ +

(Обновите страницу, чтобы увидеть анимацию, или щелкните по кнопке CodePen, чтобы воспроизвести ее в окне CodePen)

+ +

{{ EmbedLiveSample('Добавление_других_ключевыч_кадров', '100%', '250', '', 'Web/CSS/CSS_Animations/Ispolzovanie_CSS_animatciy') }}

+ +

Настройка повторения

+ +

Чтобы настроить повторение, нужно добавить свойство {{ cssxref("animation-iteration-count") }} и задать ему значение, равное нужному количеству повторений анимаций . В данном случае давайте установим значение infinite для бесконечного повторения:

+ +
p {
+  animation-duration: 3s;
+  animation-name: slidein;
+  animation-iteration-count: infinite;
+}
+
+ +
@keyframes slidein {
+  from {
+    margin-left: 100%;
+    width: 300%;
+  }
+
+  to {
+    margin-left: 0%;
+    width: 100%;
+  }
+}
+
+ +
<p>The Caterpillar and Alice looked at each other for some time in silence:
+at last the Caterpillar took the hookah out of its mouth, and addressed
+her in a languid, sleepy voice.</p>
+
+ +

{{EmbedLiveSample("Настройка_повторения","100%","250")}}

+ +

Движение текста вправо и влево

+ +

Итак, мы настроили повторение, но получили нечто странное: текст при каждом повторении снова "запрыгивает" за край окна браузера. То, чего мы хотим, так это чтобы текст двигался влево и вправо. Этого легко достичь с помощью установки свойству {{ cssxref("animation-direction") }} значения alternate:

+ +
p {
+  animation-duration: 3s;
+  animation-name: slidein;
+  animation-iteration-count: infinite;
+  animation-direction: alternate;
+}
+
+ +
@keyframes slidein {
+  from {
+    margin-left: 100%;
+    width: 300%;
+  }
+
+  to {
+    margin-left: 0%;
+    width: 100%;
+  }
+}
+
+ +
<p>The Caterpillar and Alice looked at each other for some time in silence:
+at last the Caterpillar took the hookah out of its mouth, and addressed
+her in a languid, sleepy voice.</p>
+
+ +

{{ EmbedLiveSample('Движение_текста_вправо_и_влево', '100%', '250', '', 'Web/CSS/CSS_Animations/Ispolzovanie_CSS_animatciy') }}

+ +

Использование шорткодов

+ +

Шорткод {{cssxref("animation")}} полезен для экономии места в коде. Например, правило, которое мы используем в этой статье:

+ +
p {
+  animation-duration: 3s;
+  animation-name: slidein;
+  animation-iteration-count: infinite;
+  animation-direction: alternate;
+}
+ +

можно заменить на:

+ +
p {
+  animation: 3s infinite alternate slidein;
+}
+ +
+

Внимание: подробнее об этом на странице раздела {{cssxref("animation")}} 

+
+ +

Установка нескольких значений свойствам анимации  

+ +

CSS cвойство анимации может иметь несколько значений, разделенных запятыми. Это используется, чтобы указать несколько значений анимации в одном правиле и установить разную продолжительность, число повторений и т.д., для различных анимаций. Рассмотрим несколько примеров, чтобы увидеть разницу.

+ +

В первом примере у свойства имени анимации установлены три значения, у свойств продолжительности и количества повторений  — по одному. В этом случае у всех трех анимаций одинаковая продолжительность и число повторений:

+ +
animation-name: fadeInOut, moveLeft300px, bounce;
+animation-duration: 3s;
+animation-iteration-count: 1;
+ +

Во втором примере установлены три значения для каждого из свойств. В этом случае каждая анимация выполняется с соответствующими по порядку значениями в каждом свойстве, так, например, fadeInOut имеет продолжительность 2.5 с и количество повторений 2, и т.д.

+ +
animation-name: fadeInOut, moveLeft300px, bounce;
+animation-duration: 2.5s, 5s, 1s;
+animation-iteration-count: 2, 1, 5;
+ +

В третьем примере определены три значения имени анимации, но два значения продолжительности и количества повторений. В случае, когда количества значений недостаточно для каждой анимации, значения берутся циклически от начала до конца. Например, у fadeInOut длительность будет 2.5s,  а moveLeft300px — 5s. Значения продолжительности закончились, теперь они берутся сначала — bounce получит продолжительность 2.5s. Значение количества повторений (а также другие указанные свойства) будет определено таким же образом.

+ +
animation-name: fadeInOut, moveLeft300px, bounce;
+animation-duration: 2.5s, 5s;
+animation-iteration-count: 2, 1;
+ +

Использование событий анимации

+ +

Вы можете получить дополнительный контроль над анимацией, а также полезную информацию о ней, с помощью событий анимации. Эти события, представленные объектом {{ domxref("event/AnimationEvent", "AnimationEvent") }}, можно использовать, чтобы определить, когда начинается и заканчивается анимация или начинается новая итерация. Каждое событие содержит момент времени, когда оно произошло, а также имя анимации, которая вызвала событие.

+ +

Мы будем модифицировать текст, чтобы выводить некоторую информацию  о каждом событии анимации. Так мы сможем увидеть, как она работает.

+ +

Добавление CSS

+ +

Начнем с добавления CSS. Анимация будет длиться 3 секунды, будет называться "slidein", будет повторяться 3 раза, а также значение animation-direction установлено alternate. В ключевых кадрах {{ cssxref("@keyframes") }} установлены такие значения ширины и левого отступа, что элемент будет скользить по экрану.

+ +
.slidein {
+  -moz-animation-duration: 3s;
+  -webkit-animation-duration: 3s;
+  animation-duration: 3s;
+  -moz-animation-name: slidein;
+  -webkit-animation-name: slidein;
+  animation-name: slidein;
+  -moz-animation-iteration-count: 3;
+  -webkit-animation-iteration-count: 3;
+  animation-iteration-count: 3;
+  -moz-animation-direction: alternate;
+  -webkit-animation-direction: alternate;
+  animation-direction: alternate;
+}
+
+@-moz-keyframes slidein {
+  from {
+    margin-left: 100%;
+    width: 300%
+  }
+
+  to {
+    margin-left: 0%;
+    width: 100%;
+  }
+}
+
+@-webkit-keyframes slidein {
+  from {
+    margin-left: 100%;
+    width: 300%
+  }
+
+  to {
+   margin-left: 0%;
+   width: 100%;
+ }
+}
+
+@keyframes slidein {
+  from {
+    margin-left: 100%;
+    width: 300%
+  }
+
+  to {
+   margin-left: 0%;
+   width: 100%;
+ }
+}
+ +

Добавление обработчика события анимации

+ +

Будем использовать JavaScript для отслеживания всех трех возможных событий анимации. Следующий код конфигурирует обработчик; мы вызываем его при первой загрузке документа.

+ +
var e = document.getElementById("watchme");
+e.addEventListener("animationstart", listener, false);
+e.addEventListener("animationend", listener, false);
+e.addEventListener("animationiteration", listener, false);
+
+e.className = "slidein";
+
+ +

Это довольно стандартный код; Вы можете получить дополнительную информацию в документации {{ domxref("element.addEventListener()") }}. Последнее, что делает этот код - это установка класса "slidein" для анимируемого элемента; мы делаем это, чтобы запустить анимацию.

+ +

Почему? Потому что в нашем случае событие animationstart происходит как только анимация стартует, и это происходит раньше, чем исполняется наш сценарий. Так мы сможем контролировать начало анимации самостоятельно посредством вставки класса "slidein" для анимируемого элемента.

+ +

Регистрация событий

+ +

События будут передаваться функции listener(), показанной ниже.

+ +
function listener(e) {
+  var l = document.createElement("li");
+  switch(e.type) {
+    case "animationstart":
+      l.innerHTML = "Started: elapsed time is " + e.elapsedTime;
+      break;
+    case "animationend":
+      l.innerHTML = "Ended: elapsed time is " + e.elapsedTime;
+      break;
+    case "animationiteration":
+      l.innerHTML = "New loop started at time " + e.elapsedTime;
+      break;
+  }
+  document.getElementById("output").appendChild(l);
+}
+
+ +

Этот код также очень прост. Этот код следит за {{ domxref("event.type") }}, чтобы определить тип события, и добавляет элемент {{ HTMLElement("ul") }}, чтобы залогировать произошедшее событие.

+ +

Вывод, когда анимация закончится, будет выглядеть примерно следующим образом:

+ +
    +
  • Started: elapsed time is 0
  • +
  • New loop started at time 3.01200008392334
  • +
  • New loop started at time 6.00600004196167
  • +
  • Ended: elapsed time is 9.234000205993652
  • +
+ +

Обратите внимание, что время, указанное в выводе, и время, которое мы указали в стилях, не совпадают. Также обратите внимание, что после окончания итерации не посылается событие animationiteration ; вместо него посылается событие animationend.

+ +

HTML

+ +

Ради полноты картины приведем код разметки HTML. В разметке имеется тег ul, в который и выводится вся информация:

+ +
<body>
+  <h1 id="watchme">Watch me move</h1>
+  <p>This example shows how to use CSS animations to make <code>p</code> elements
+  move across the page.</p>
+  <p>In addition, we output some text each time an animation event fires, so you can see them in action.</p>
+  <ul id="output">
+  </ul>
+</body>
+
+ +

{{ EmbedLiveSample('Использование_событий_анимации', '600', '300')}}

+ +

Смотрите также

+ + diff --git a/files/ru/web/css/css_background_and_borders/border-radius_generator/index.html b/files/ru/web/css/css_background_and_borders/border-radius_generator/index.html new file mode 100644 index 0000000000..71f94831f0 --- /dev/null +++ b/files/ru/web/css/css_background_and_borders/border-radius_generator/index.html @@ -0,0 +1,1599 @@ +--- +title: Border-radius генератор +slug: Web/CSS/CSS_Background_and_Borders/Border-radius_генератор +translation_of: Web/CSS/CSS_Background_and_Borders/Border-radius_generator +--- +

С помощью этого инструмента вы можете создать CSS3 {{cssxref("border-radius")}} эффекты.

+ +
+

border-radius

+ +

HTML Content

+ +
<div id="container">
+    <div class="group section">
+        <div id="preview" class="col span_12">
+            <div id="subject">
+                <div id="top-left" class="radius-container"
+                    data-X="left" data-Y="top">
+                </div>
+                <div id="top-right" class="radius-container"
+                    data-X="right" data-Y="top">
+                </div>
+                <div id="bottom-right" class="radius-container"
+                    data-X="right" data-Y="bottom">
+                </div>
+                <div id="bottom-left" class="radius-container"
+                    data-X="left" data-Y="bottom">
+                </div>
+
+                <div id="radius-ui-sliders">
+                    <div id="tlr" class="ui-input-slider" data-topic="top-left"
+                         data-unit=" px" data-sensivity="2"></div>
+
+                    <div id="tlw" class="ui-input-slider" data-topic="top-left-w"
+                         data-unit=" px" data-sensivity="2"></div>
+
+                    <div id="tlh" class="ui-input-slider" data-topic="top-left-h"
+                        data-unit=" px" data-sensivity="2"></div>
+
+                    <div id="trr" class="ui-input-slider" data-topic="top-right"
+                         data-unit=" px" data-sensivity="2"></div>
+
+                    <div id="trw" class="ui-input-slider" data-topic="top-right-w"
+                         data-unit=" px" data-sensivity="2"></div>
+
+                    <div id="trh" class="ui-input-slider" data-topic="top-right-h"
+                        data-unit=" px" data-sensivity="2"></div>
+
+                    <div id="brr" class="ui-input-slider" data-topic="bottom-right"
+                         data-unit=" px" data-sensivity="2"></div>
+
+                    <div id="brw" class="ui-input-slider" data-topic="bottom-right-w"
+                         data-unit=" px" data-sensivity="2"></div>
+
+                    <div id="brh" class="ui-input-slider" data-topic="bottom-right-h"
+                        data-unit=" px" data-sensivity="2"></div>
+
+                    <div id="blr" class="ui-input-slider" data-topic="bottom-left"
+                         data-unit=" px" data-sensivity="2"></div>
+
+                    <div id="blw" class="ui-input-slider" data-topic="bottom-left-w"
+                         data-unit=" px" data-sensivity="2"></div>
+
+                    <div id="blh" class="ui-input-slider" data-topic="bottom-left-h"
+                        data-unit=" px" data-sensivity="2"></div>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div id="controls" class="group section">
+
+        <div class="group section">
+            <div id="dimensions">
+                <div class="ui-input-slider" data-topic="width" data-info="width"
+                     data-unit=" px" data-min="150" data-max="700" data-sensivity="1"></div>
+
+                <div class="ui-input-slider" data-topic="height" data-info="height"
+                    data-unit=" px" data-min="75" data-max="350" data-sensivity="1"></div>
+            </div>
+
+            <div id="output"></div>
+        </div>
+
+        <div class="group section">
+            <div id="radius-lock">
+                <div class="info"> rounded corner </div>
+                <div class="ui-checkbox" data-topic='top-left'></div>
+                <div class="ui-checkbox" data-topic='top-right'></div>
+                <div class="ui-checkbox" data-topic='bottom-right'></div>
+                <div class="ui-checkbox" data-topic='bottom-left'></div>
+            </div>
+
+            <div id="unit-selection">
+                <div class="info"> select border units </div>
+            </div>
+        </div>
+
+    </div>
+</div>
+
+ +

CSS Content

+ +
/*  GRID OF TEN
+ * ========================================================================== */
+
+.span_12 {
+	width: 100%;
+}
+
+.span_11 {
+	width: 91.46%;
+}
+
+.span_10 {
+	width: 83%;
+}
+
+.span_9 {
+	width: 74.54%;
+}
+
+.span_8 {
+	width: 66.08%;
+}
+
+.span_7 {
+	width: 57.62%;
+}
+
+.span_6 {
+	width: 49.16%;
+}
+
+.span_5 {
+	width: 40.7%;
+}
+
+.span_4 {
+	width: 32.24%;
+}
+
+.span_3 {
+	width: 23.78%;
+}
+
+.span_2 {
+	width: 15.32%;
+}
+
+.span_1 {
+	width: 6.86%;
+}
+
+
+
+
+/*  SECTIONS
+ * ========================================================================== */
+
+.section {
+	clear: both;
+	padding: 0px;
+	margin: 0px;
+}
+
+/*  GROUPING
+ * ========================================================================== */
+
+
+.group:before, .group:after {
+    content: "";
+    display: table;
+}
+
+.group:after {
+    clear:both;
+}
+
+.group {
+    zoom: 1; /* For IE 6/7 (trigger hasLayout) */
+}
+
+/*  GRID COLUMN SETUP
+ * ========================================================================== */
+
+.col {
+	display: block;
+	float:left;
+	margin: 1% 0 1% 1.6%;
+}
+
+.col:first-child {
+	margin-left: 0;
+} /* all browsers except IE6 and lower */
+
+
+/*
+ * UI Component
+ */
+
+.ui-input-slider-container {
+	height: 20px;
+	margin: 10px 0;
+	font-family: "Segoe UI", Arial, Helvetica, sans-serif;
+	-moz-user-select: none;
+	user-select: none;
+}
+
+.ui-input-slider-container * {
+	float: left;
+	height: 100%;
+	line-height: 100%;
+}
+
+/* Input Slider */
+
+.ui-input-slider > input {
+	margin: 0;
+	padding: 0;
+	width: 50px;
+	text-align: center;
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+.ui-input-slider-info {
+	width: 90px;
+	padding: 0px 10px 0px 0px;
+	text-align: right;
+	text-transform: lowercase;
+}
+
+.ui-input-slider-left, .ui-input-slider-right {
+	width: 16px;
+	cursor: pointer;
+	background: url("https://mdn.mozillademos.org/files/5679/arrows.png") center left no-repeat;
+}
+
+.ui-input-slider-right {
+	background: url("https://mdn.mozillademos.org/files/5679/arrows.png") center right no-repeat;
+}
+
+.ui-input-slider-name {
+	width: 90px;
+	padding: 0 10px 0 0;
+	text-align: right;
+	text-transform: lowercase;
+}
+
+.ui-input-slider-btn-set {
+	width: 25px;
+	background-color: #2C9FC9;
+	border-radius: 5px;
+	color: #FFF;
+	font-weight: bold;
+	line-height: 14px;
+	text-align: center;
+}
+
+.ui-input-slider-btn-set:hover {
+	background-color: #379B4A;
+	cursor: pointer;
+}
+
+/*
+ * UI Component
+ */
+
+/* Checkbox */
+
+.ui-checkbox {
+	text-align: center;
+	font-size: 16px;
+	font-family: "Segoe UI", Arial, Helvetica, sans-serif;
+	line-height: 1.5em;
+	color: #FFF;
+
+	-moz-user-select: none;
+	-webkit-user-select: none;
+	-ms-user-select: none;
+	user-select: none;
+}
+
+.ui-checkbox > input {
+ 	display: none;
+}
+
+.ui-checkbox > label {
+	font-size: 12px;
+	padding: 0.333em 1.666em 0.5em;
+	height: 1em;
+	line-height: 1em;
+
+	background-color: #888;
+	background-image: url("https://mdn.mozillademos.org/files/5683/disabled.png");
+	background-position: center center;
+	background-repeat: no-repeat;
+
+	color: #FFF;
+	border-radius: 3px;
+	font-weight: bold;
+	float: left;
+}
+
+.ui-checkbox .text {
+	padding-left: 34px;
+	background-position: center left 10px;
+}
+
+.ui-checkbox .left {
+	padding-right: 34px;
+	padding-left: 1.666em;
+	background-position: center right 10px;
+}
+
+.ui-checkbox > label:hover {
+	cursor: pointer;
+}
+
+.ui-checkbox > input:checked + label {
+	background-image: url("https://mdn.mozillademos.org/files/5681/checked.png");
+	background-color: #379B4A;
+}
+
+body {
+	max-width: 1000px;
+	margin: 0 auto;
+
+	font-family: "Segoe UI", Arial, Helvetica, sans-serif;
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+
+	-moz-user-select: none;
+	-webkit-user-select: none;
+	-ms-user-select: none;
+	user-select: none;
+}
+
+#container {
+	width: 100%;
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+/******************************************************************************/
+/******************************************************************************/
+/*
+ * Preview Area
+ */
+
+#preview {
+	height: 500px;
+	border: 1px solid #CCC;
+	border-radius: 3px;
+	text-align: center;
+	overflow: hidden;
+	position: relative;
+}
+
+#preview .content {
+	width: 100%;
+	height: 100%;
+	display: block;
+}
+
+#preview input {
+	color: #333;
+	border: 1px solid #CCC;
+	border-radius: 3px;
+}
+
+#subject {
+	width: 400px;
+	height: 150px;
+	margin: 0 auto;
+	border: 3px solid #C60;
+	background: #FFF;
+	position: relative;
+}
+
+.radius {
+	width: 50%;
+	height: 50%;
+	border: 1px solid #CCC;
+	display: none;
+	position: absolute;
+	z-index: 1;
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+.handle {
+	width: 16px;
+	height: 16px;
+	position: absolute;
+	z-index: 2;
+}
+
+.handle-top-left {
+	top: -12px;
+	left: -12px;
+	cursor: se-resize;
+	background: url("https://mdn.mozillademos.org/files/5677/resize-handle.png") top left no-repeat;
+}
+
+.handle-top-right {
+	top: -12px;
+	right: -12px;
+	cursor: sw-resize;
+	background: url("https://mdn.mozillademos.org/files/5677/resize-handle.png") top right no-repeat;
+}
+
+.handle-bottom-right {
+	bottom: -12px;
+	right: -12px;
+	cursor: nw-resize;
+	background: url("https://mdn.mozillademos.org/files/5677/resize-handle.png") bottom right no-repeat;
+}
+
+.handle-bottom-left {
+	bottom: -12px;
+	left: -12px;
+	cursor: ne-resize;
+	background: url("https://mdn.mozillademos.org/files/5677/resize-handle.png") bottom left no-repeat;
+}
+
+
+.radius-container {
+	position: absolute;
+	display : block;
+	z-index: 1;
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+
+/* TOP LEFT */
+#top-left {
+	top: 0;
+	left: 0;
+}
+
+#top-left .radius {
+	border-top-left-radius: 100%;
+	top: 0;
+	left: 0;
+}
+
+/* TOP RIGHT */
+#top-right {
+	top: 0;
+	right: 0;
+}
+
+#top-right .radius {
+	border-top-right-radius: 100%;
+	top: 0;
+	right: 0;
+}
+
+/* BOTTOM RIGHT */
+#bottom-right {
+	bottom: 0;
+	right: 0;
+}
+
+#bottom-right .radius {
+	border-bottom-right-radius: 100%;
+	bottom: 0;
+	right: 0;
+}
+
+/* BOTTOM lEFT */
+#bottom-left {
+	bottom: 0;
+	left: 0;
+}
+
+#bottom-left .radius {
+	border-bottom-left-radius: 100%;
+	bottom: 0;
+}
+
+/* INPUT SLIDERS */
+
+#preview .ui-input-slider {
+	margin: 10px;
+	position: absolute;
+	z-index: 10;
+}
+
+#radius-ui-sliders {
+	width: 100%;
+	height: 100%;
+	min-height: 75px;
+	min-width: 150px;
+	padding: 20px 50px;
+	top: -20px;
+	left: -50px;
+	position: relative;
+}
+
+#tlr {
+	top: -30px;
+	left: -50px;
+	display: none;
+}
+
+#tlw {
+	top: -30px;
+	left: 30px;
+}
+
+#tlh {
+	top: 20px;
+	left: -50px;
+}
+
+#trr {
+	top: -30px;
+	right: -50px;
+	display: none;
+}
+
+#trw {
+	top: -30px;
+	right: 30px;
+}
+
+#trh {
+	top: 20px;
+	right: -50px;
+}
+
+#brr {
+	bottom: -30px;
+	right: -50px;
+	display: none;
+}
+
+#brw {
+	bottom: -30px;
+	right: 30px;
+}
+
+#brh {
+	bottom: 20px;
+	right: -50px;
+}
+
+#blr {
+	bottom: -30px;
+	left: -50px;
+	display: none;
+}
+
+#blw {
+	bottom: -30px;
+	left: 30px;
+}
+
+#blh {
+	bottom: 20px;
+	left: -50px;
+}
+
+#preview .ui-input-slider-left, #preview .ui-input-slider-right {
+	visibility: hidden;
+}
+
+#preview .ui-input-slider-container:hover .ui-input-slider-left {
+	visibility: visible;
+}
+
+#preview .ui-input-slider-container:hover .ui-input-slider-right {
+	visibility: visible;
+}
+
+/*
+ *
+ */
+
+#unit-selection {
+	width: 200px;
+	height: 75px;
+	margin: 30px 30px 0 0;
+	padding: 30px;
+	border: 3px solid #555;
+	border-radius: 10px;
+	position: relative;
+	float: right;
+}
+
+#unit-selection .info {
+	height: 20%;
+	width: 100%;
+	line-height: 20%;
+	font-size: 20px;
+	text-align: center;
+	position: relative;
+	top: 40%;
+}
+
+#unit-selection .dropdown {
+	width: 50px;
+	height: 20px;
+	margin: 10px;
+	padding: 0;
+	border-radius: 3px;
+	position: absolute;
+	overflow: hidden;
+}
+
+#unit-selection select {
+	width: 50px;
+	height: 20px;
+	marign: 0;
+	padding: 0 0 0 10px;
+	background: #555;
+	border: 1px solid #555;
+	border: none;
+	color: #FFF;
+	float: left;
+}
+
+#unit-selection select option {
+	background: #FFF;
+	color: #333;
+}
+
+#unit-selection select:hover {
+	cursor: pointer;
+}
+
+#unit-selection .dropdown:before {
+	content: "";
+	width: 18px;
+	height: 20px;
+	display: block;
+	background-color: #555;
+	background-image: url("https://mdn.mozillademos.org/files/5675/dropdown.png");
+	background-position: center center;
+	background-repeat: no-repeat;
+	top: 0px;
+	right: 0px;
+	position: absolute;
+	z-index: 1;
+	pointer-events: none;
+}
+
+#unit-selection .unit-top-left {
+	top: 0;
+	left: 0;
+	display: none;
+}
+
+#unit-selection .unit-top-left-w {
+	top: -22px;
+	left: 30px;
+}
+
+#unit-selection .unit-top-left-h {
+	top: 20px;
+	left: -37px;
+}
+
+#unit-selection .unit-top-right {
+	top: 0;
+	right: 0;
+	display: none;
+}
+
+#unit-selection .unit-top-right-w {
+	top: -22px;
+	right: 30px;
+}
+
+#unit-selection .unit-top-right-h {
+	top: 20px;
+	right: -37px;
+}
+
+#unit-selection .unit-bottom-right {
+	bottom: 0;
+	right: 0;
+	display: none;
+}
+
+#unit-selection .unit-bottom-right-w {
+	bottom: -22px;
+	right: 30px;
+}
+
+#unit-selection .unit-bottom-right-h {
+	bottom: 20px;
+	right: -37px;
+}
+
+#unit-selection .unit-bottom-left {
+	bottom: 0;
+	left: 0;
+	display: none;
+}
+
+#unit-selection .unit-bottom-left-w {
+	bottom: -22px;
+	left: 30px;
+}
+
+#unit-selection .unit-bottom-left-h {
+	bottom: 20px;
+	left: -37px;
+}
+
+/******************************************************************************/
+/******************************************************************************/
+
+
+#radius-lock {
+	width: 200px;
+	height: 75px;
+	margin: 30px 0 0 30px;
+	padding: 30px;
+	border: 3px solid #555;
+	border-radius: 10px;
+	position: relative;
+	float: left;
+}
+
+#radius-lock .ui-checkbox {
+	color: #FFF;
+	position: absolute;
+}
+
+#radius-lock .ui-checkbox > label {
+	height: 20px;
+	width: 34px;
+	padding: 0;
+}
+
+#radius-lock .info {
+	height: 20%;
+	width: 100%;
+	line-height: 20%;
+	font-size: 20px;
+	text-align: center;
+	position: relative;
+	top: 40%;
+}
+
+#radius-lock [data-topic="top-left"] {
+	top: 10px;
+	left: 10px;
+}
+
+#radius-lock [data-topic="top-right"] {
+	top: 10px;
+	right: 10px;
+}
+
+#radius-lock [data-topic="bottom-right"] {
+	bottom: 10px;
+	right: 10px;
+}
+
+#radius-lock [data-topic="bottom-left"] {
+	bottom: 10px;
+	left: 10px;
+}
+
+/**
+ * Controls
+ */
+
+#dimensions {
+	width: 200px;
+	color: #444;
+	float:left;
+}
+
+#dimensions input {
+	background: #555;
+	color: #FFF;
+	border: none;
+	border-radius: 3px;
+}
+
+#output {
+	width: 500px;
+	padding: 10px 0;
+	margin: 10px 0;
+	color: #555;
+	text-align: center;
+	border: 1px dashed #999;
+	border-radius: 3px;
+	-moz-user-select: text;
+	-webkit-user-select: text;
+	-ms-user-select: text;
+	user-select: text;
+
+	float: right;
+}
+
+
+
+ +

JavaScript Content

+ +
'use strict';
+
+
+/**
+ * UI-InputSliderManager
+ */
+
+var InputSliderManager = (function InputSliderManager() {
+
+	var subscribers = {};
+	var sliders = [];
+
+	var InputComponent = function InputComponent(obj) {
+		var input = document.createElement('input');
+		input.setAttribute('type', 'text');
+
+		input.addEventListener('click', function(e) {
+			this.select();
+		});
+
+		input.addEventListener('change', function(e) {
+			var value = parseInt(e.target.value);
+
+			if (isNaN(value) === true)
+				setValue(obj.topic, obj.value);
+			else
+				setValue(obj.topic, value);
+		});
+
+		subscribe(obj.topic, function(value) {
+			input.value = value + obj.unit;
+		});
+
+		return input;
+	}
+
+	var SliderComponent = function SliderComponent(obj, sign) {
+		var slider = document.createElement('div');
+		var startX = null;
+		var start_value = 0;
+
+		slider.addEventListener("click", function(e) {
+			setValue(obj.topic, obj.value + obj.step * sign);
+		});
+
+		slider.addEventListener("mousedown", function(e) {
+			startX = e.clientX;
+			start_value = obj.value;
+			document.body.style.cursor = "e-resize";
+			document.addEventListener("mousemove", sliderMotion);
+		});
+
+		document.addEventListener("mouseup", function(e) {
+			document.removeEventListener("mousemove", sliderMotion);
+			document.body.style.cursor = "auto";
+			slider.style.cursor = "pointer";
+		});
+
+		var sliderMotion = function sliderMotion(e) {
+			slider.style.cursor = "e-resize";
+			var delta = (e.clientX - startX) / obj.sensivity | 0;
+			var value = delta * obj.step + start_value;
+			setValue(obj.topic, value);
+		}
+
+		return slider;
+	}
+
+	var InputSlider = function(node) {
+		var min		= node.getAttribute('data-min') | 0;
+		var max		= node.getAttribute('data-max') | 0;
+		var step	= node.getAttribute('data-step') | 0;
+		var value	= node.getAttribute('data-value') | 0;
+		var topic	= node.getAttribute('data-topic');
+		var unit	= node.getAttribute('data-unit');
+		var name 	= node.getAttribute('data-info');
+		var sensivity = node.getAttribute('data-sensivity') | 0;
+
+		this.min = min;
+		this.max = max > 0 ? max : 100;
+		this.step = step === 0 ? 1 : step;
+		this.topic = topic;
+		this.node = node;
+		this.unit = unit;
+		this.sensivity = sensivity > 0 ? sensivity : 5;
+
+		var input = new InputComponent(this);
+		var slider_left  = new SliderComponent(this, -1);
+		var slider_right = new SliderComponent(this,  1);
+
+		slider_left.className = 'ui-input-slider-left';
+		slider_right.className = 'ui-input-slider-right';
+
+		if (name) {
+			var info = document.createElement('span');
+			info.className = 'ui-input-slider-info';
+			info.textContent = name;
+			node.appendChild(info);
+		}
+
+		node.appendChild(slider_left);
+		node.appendChild(input);
+		node.appendChild(slider_right);
+		node.className = 'ui-input-slider ui-input-slider-container';
+
+		this.input = input;
+		sliders[topic] = this;
+		setValue(topic, value);
+	}
+
+	var setValue = function setValue(topic, value, send_notify) {
+		var slider = sliders[topic];
+		if (slider === undefined)
+			return;
+
+		if (value > slider.max) value = slider.max;
+		if (value < slider.min)	value = slider.min;
+
+		slider.value = value;
+		slider.node.setAttribute('data-value', value);
+
+		if (send_notify !== undefined && send_notify === false) {
+			slider.input.value = value + slider.unit;
+			return;
+		}
+
+		notify.call(slider);
+	}
+
+	var setMax = function setMax(topic, value) {
+		var slider = sliders[topic];
+		if (slider === undefined)
+			return;
+
+		slider.max = value;
+		setValue(topic, slider.value);
+	}
+
+	var setMin = function setMin(topic, value) {
+		var slider = sliders[topic];
+		if (slider === undefined)
+			return;
+
+		slider.min = value;
+		setValue(topic, slider.value);
+	}
+
+	var setUnit = function setUnit(topic, unit) {
+		var slider = sliders[topic];
+		if (slider === undefined)
+			return;
+
+		slider.unit = unit;
+		setValue(topic, slider.value);
+	}
+
+	var getNode =  function getNode(topic) {
+		return sliders[topic].node;
+	}
+
+	var subscribe = function subscribe(topic, callback) {
+		if (subscribers[topic] === undefined)
+			subscribers[topic] = [];
+		subscribers[topic].push(callback);
+	}
+
+	var unsubscribe = function unsubscribe(topic, callback) {
+		subscribers[topic].indexOf(callback);
+		subscribers[topic].splice(index, 1);
+	}
+
+	var notify = function notify() {
+		for (var i in subscribers[this.topic]) {
+			subscribers[this.topic][i](this.value);
+		}
+	}
+
+	var init = function init() {
+		var elem = document.querySelectorAll('.ui-input-slider');
+		var size = elem.length;
+		for (var i = 0; i < size; i++)
+			new InputSlider(elem[i]);
+	}
+
+	return {
+		init : init,
+		setMax : setMax,
+		setMin : setMin,
+		setUnit : setUnit,
+		getNode : getNode,
+		setValue : setValue,
+		subscribe : subscribe,
+		unsubscribe : unsubscribe
+	}
+
+})();
+
+/**
+ * UI-ButtonManager
+ */
+
+var ButtonManager = (function CheckBoxManager() {
+
+	var subscribers = [];
+	var buttons = [];
+
+	var CheckBox = function CheckBox(node) {
+		var topic = node.getAttribute('data-topic');
+		var state = node.getAttribute('data-state');
+		var name = node.getAttribute('data-label');
+		var align = node.getAttribute('data-text-on');
+
+		state = (state === "true");
+
+		var checkbox = document.createElement("input");
+		var label = document.createElement("label");
+
+		var id = 'checkbox-' + topic;
+		checkbox.id = id;
+		checkbox.setAttribute('type', 'checkbox');
+		checkbox.checked = state;
+
+		label.setAttribute('for', id);
+		if (name) {
+			label.className = 'text';
+			if (align)
+				label.className += ' ' + align;
+			label.textContent = name;
+		}
+
+		node.appendChild(checkbox);
+		node.appendChild(label);
+
+		this.node = node;
+		this.topic = topic;
+		this.checkbox = checkbox;
+
+		checkbox.addEventListener('change', function(e) {
+			notify.call(this);
+		}.bind(this));
+
+		buttons[topic] = this;
+	}
+
+	var getNode =  function getNode(topic) {
+		return buttons[topic].node;
+	}
+
+	var setValue = function setValue(topic, value) {
+		try {
+			buttons[topic].checkbox.checked = value;
+		}
+		catch(error) {
+			console.log(error);
+		}
+	}
+
+	var subscribe = function subscribe(topic, callback) {
+		if (subscribers[topic] === undefined)
+			subscribers[topic] = [];
+
+		subscribers[topic].push(callback);
+	}
+
+	var unsubscribe = function unsubscribe(topic, callback) {
+		subscribers[topic].indexOf(callback);
+		subscribers[topic].splice(index, 1);
+	}
+
+	var notify = function notify() {
+		for (var i = 0; i < subscribers[this.topic].length; i++)
+			subscribers[this.topic][i](this.checkbox.checked);
+	}
+
+	var init = function init() {
+		var elem = document.querySelectorAll('.ui-checkbox');
+		var size = elem.length;
+		for (var i = 0; i < size; i++)
+			new CheckBox(elem[i]);
+	}
+
+	return {
+		init : init,
+		setValue : setValue,
+		subscribe : subscribe,
+		unsubscribe : unsubscribe
+	}
+
+})();
+
+
+window.addEventListener("load", function() {
+	BorderRadius.init();
+});
+
+var BorderRadius = (function BorderRadius() {
+
+	function getElemById(id) {
+		return document.getElementById(id);
+	}
+
+	/**
+	 * Shadow dragging
+	 */
+	var PreviewMouseTracking = (function Drag() {
+		var active = false;
+		var lastX = 0;
+		var lastY = 0;
+		var subscribers = [];
+
+		var init = function init(id) {
+			var elem = getElemById(id);
+			elem.addEventListener('mousedown', dragStart, false);
+			document.addEventListener('mouseup', dragEnd, false);
+		}
+
+		var dragStart = function dragStart(e) {
+			if (e.button !== 0)
+				return;
+
+			active = true;
+			lastX = e.clientX;
+			lastY = e.clientY;
+			document.addEventListener('mousemove', mouseDrag, false);
+		}
+
+		var dragEnd = function dragEnd(e) {
+			if (e.button !== 0)
+				return;
+
+			if (active === true) {
+				active = false;
+				document.removeEventListener('mousemove', mouseDrag, false);
+			}
+		}
+
+		var mouseDrag = function mouseDrag(e) {
+			notify(e.clientX - lastX, e.clientY - lastY);
+			lastX = e.clientX;
+			lastY = e.clientY;
+		}
+
+		var subscribe = function subscribe(callback) {
+			subscribers.push(callback);
+		}
+
+		var unsubscribe = function unsubscribe(callback) {
+			var index = subscribers.indexOf(callback);
+			subscribers.splice(index, 1);
+		}
+
+		var notify = function notify(deltaX, deltaY) {
+			for (var i in subscribers)
+				subscribers[i](deltaX, deltaY);
+		}
+
+		return {
+			init : init,
+			subscribe : subscribe,
+			unsubscribe : unsubscribe
+		}
+
+	})();
+
+	var subject;
+	var units = ['px', '%'];
+	var output = null;
+
+	var UnitSelector = function UnitSelector(topic) {
+
+		this.container = document.createElement("div");
+		this.select = document.createElement("select");
+		for (var i in units) {
+			var option = document.createElement("option");
+			option.value = i;
+			option.textContent = units[i];
+			this.select.appendChild(option);
+		}
+
+		this.container.className = 'dropdown ' + 'unit-' + topic;
+		this.container.appendChild(this.select);
+	}
+
+	UnitSelector.prototype.setValue = function setValue(value) {
+		this.salect.value = value;
+	}
+
+
+	var RadiusContainer = function RadiusContainer(node) {
+		var radius = document.createElement('div');
+		var handle = document.createElement('div');
+		var x = node.getAttribute('data-x');
+		var y = node.getAttribute('data-y');
+		var active = false;
+
+		this.id = node.id;
+		this.node = node;
+		this.radius = radius;
+		this.handle = handle;
+		this.width = 100;
+		this.height = 50;
+		this.size = 0;
+		this.rounded = false;
+
+		this.unitX = 0;
+		this.unitY = 0;
+		this.unitR = 0;
+
+		this.maxW = 100;
+		this.maxH = 100;
+		this.maxR = 100;
+
+		this.topic = y + '-' + x;
+
+		var sliderW = InputSliderManager.getNode(this.topic + '-w');
+		var sliderH = InputSliderManager.getNode(this.topic + '-h');
+		var sliderR = InputSliderManager.getNode(this.topic);
+
+		this.setUnitX(this.unitX);
+		this.setUnitY(this.unitY);
+		this.setUnitR(this.unitR);
+
+		this.updateWidth();
+		this.updateHeight();
+		this.updateRadius();
+
+		if (x === 'left')	this.resizeX =  1;
+		if (x === 'right')	this.resizeX = -1;
+		if (y === 'top')	this.resizeY =  1;
+		if (y === 'bottom')	this.resizeY = -1;
+
+		radius.className = 'radius';
+
+		var unit_selector = document.getElementById("unit-selection");
+		var unitW = new UnitSelector(this.topic + '-w');
+		var unitH = new UnitSelector(this.topic + '-h');
+		var unitR = new UnitSelector(this.topic);
+
+		unit_selector.appendChild(unitW.container);
+		unit_selector.appendChild(unitH.container);
+		unit_selector.appendChild(unitR.container);
+		node.appendChild(radius);
+		subject.appendChild(handle);
+
+		unitW.select.addEventListener('change', function(e) {
+			this.setUnitX(e.target.value | 0);
+		}.bind(this));
+
+		unitH.select.addEventListener('change', function(e) {
+			this.setUnitY(e.target.value | 0);
+		}.bind(this));
+
+		unitR.select.addEventListener('change', function(e) {
+			this.setUnitR(e.target.value | 0);
+		}.bind(this));
+
+		if (x === 'left' && y == 'top') handle.className = 'handle handle-top-left'
+		if (x === 'right' && y == 'top') handle.className = 'handle handle-top-right';
+		if (x === 'right' && y == 'bottom') handle.className = 'handle handle-bottom-right';
+		if (x === 'left' && y == 'bottom') 	handle.className = 'handle handle-bottom-left';
+
+		handle.addEventListener("mousedown", function(e) {
+			active = true;
+			this.radius.style.display = 'block';
+			PreviewMouseTracking.subscribe(this.updateContainer.bind(this));
+		}.bind(this));
+
+		document.addEventListener("mouseup", function(e) {
+			this.radius.style.display = 'none';
+			if (active === true)
+				PreviewMouseTracking.unsubscribe(this.updateContainer.bind(this));
+		}.bind(this));
+
+		InputSliderManager.subscribe(this.topic + '-w', this.setWidth.bind(this));
+		InputSliderManager.subscribe(this.topic + '-h', this.setHeight.bind(this));
+		InputSliderManager.subscribe(this.topic, this.setRadius.bind(this));
+
+		ButtonManager.subscribe(this.topic, function(value) {
+			this.rounded = value;
+			if (value === true) {
+				unitW.container.style.display = 'none';
+				unitH.container.style.display = 'none';
+				unitR.container.style.display = 'block';
+				sliderW.style.display = 'none';
+				sliderH.style.display = 'none';
+				sliderR.style.display = 'block';
+				this.setUnitR(this.unitR);
+				this.updateRadius();
+			}
+
+			if (value === false) {
+				unitW.container.style.display = 'block';
+				unitH.container.style.display = 'block';
+				unitR.container.style.display = 'none';
+				sliderW.style.display = 'block';
+				sliderH.style.display = 'block';
+				sliderR.style.display = 'none';
+				this.setUnitX(this.unitX);
+				this.setUnitY(this.unitY);
+				this.updateWidth();
+				this.updateHeight();
+			}
+
+			this.updateBorderRadius();
+
+		}.bind(this));
+
+		this.updateBorderRadius();
+	}
+
+	RadiusContainer.prototype.updateWidth = function updateWidth() {
+		this.node.style.width = this.width + units[this.unitX];
+		var value = Math.round(this.width / 2);
+		InputSliderManager.setValue(this.topic + '-w', value, false);
+	}
+
+	RadiusContainer.prototype.updateHeight = function updateHeight() {
+		this.node.style.height = this.height + units[this.unitY];
+		var value = Math.round(this.height / 2);
+		InputSliderManager.setValue(this.topic + '-h', value, false);
+	}
+
+	RadiusContainer.prototype.updateRadius = function updateRadius() {
+		var value = Math.round(this.size / 2);
+		this.node.style.width = this.size + units[this.unitR];
+		this.node.style.height = this.size + units[this.unitR];
+		InputSliderManager.setValue(this.topic, value, false);
+	}
+
+	RadiusContainer.prototype.setWidth = function setWidth(value) {
+		this.radius.style.display = 'block';
+		this.width = 2 * value;
+		this.node.style.width = this.width + units[this.unitX];
+		this.updateBorderRadius();
+	}
+
+	RadiusContainer.prototype.setHeight = function setHeight(value) {
+		this.radius.style.display = 'block';
+		this.height = 2 * value;
+		this.node.style.height = this.height + units[this.unitY];
+		this.updateBorderRadius();
+	}
+
+	RadiusContainer.prototype.setRadius = function setRadius(value) {
+		this.radius.style.display = 'block';
+		this.size = 2 * value;
+		this.node.style.width = this.size + units[this.unitR];
+		this.node.style.height = this.size + units[this.unitR];
+		this.updateBorderRadius();
+	}
+
+	RadiusContainer.prototype.setUnitX = function setUnitX(value) {
+		this.unitX = value;
+		if (this.unitX === 0) this.maxW = 2 * subject.clientWidth;
+		if (this.unitX === 1) this.maxW = 200;
+		InputSliderManager.setUnit(this.topic + '-w', units[this.unitX]);
+		InputSliderManager.setMax(this.topic + '-w', this.maxW / 2);
+	}
+
+	RadiusContainer.prototype.setUnitY = function setUnitY(value) {
+		this.unitY = value;
+		if (this.unitY === 0) this.maxH = 2 * subject.clientHeight;
+		if (this.unitY === 1) this.maxH = 200;
+		InputSliderManager.setUnit(this.topic + '-h', units[this.unitY]);
+		InputSliderManager.setMax(this.topic + '-h', this.maxH / 2);
+	}
+
+	RadiusContainer.prototype.setUnitR = function setUnitR(value) {
+		this.unitR = value;
+
+		if (this.unitR === 0)
+			this.maxR = 2 * Math.min(subject.clientHeight , subject.clientWidth);
+
+		if (this.unitR === 1)
+			this.maxR = 200;
+
+		InputSliderManager.setUnit(this.topic, units[this.unitR]);
+		InputSliderManager.setMax(this.topic, this.maxR / 2);
+	}
+
+	RadiusContainer.prototype.updateUnits = function updateUnits(unit) {
+		if (this.rounded) {
+			this.setUnitR(this.unitR);
+			return;
+		}
+
+		if (unit === 0)
+			this.setUnitX(this.unitX);
+
+		if (unit === 1)
+			this.setUnitY(this.unitY);
+	}
+
+	RadiusContainer.prototype.composeBorderRadius = function composeBorderRadius () {
+
+		if (this.rounded === true) {
+			var unit = units[this.unitR];
+			var value = Math.round(this.size / 2);
+			return value + unit;
+		}
+
+		var unitX = units[this.unitX];
+		var unitY = units[this.unitY];
+		var valueX = Math.round(this.width / 2);
+		var valueY = Math.round(this.height / 2);
+
+		if (valueX === valueY && this.unitX === this.unitY)
+			return valueX + unitX;
+
+		return valueX + unitX + ' ' + valueY + unitY;
+	}
+
+	RadiusContainer.prototype.updateBorderRadius = function updateBorderRadius () {
+		var radius = this.composeBorderRadius();
+		var corner = 0;
+
+		if (this.topic === 'top-left') {
+			subject.style.borderTopLeftRadius = radius;
+			corner = 0;
+		}
+
+		if (this.topic === 'top-right') {
+			subject.style.borderTopRightRadius = radius;
+			corner = 1;
+		}
+
+		if (this.topic === 'bottom-right') {
+			subject.style.borderBottomRightRadius = radius;
+			corner = 2;
+		}
+
+		if (this.topic === 'bottom-left') {
+			subject.style.borderBottomLeftRadius = radius;
+			corner = 3;
+		}
+
+		Tool.updateOutput(corner, radius);
+	}
+
+	RadiusContainer.prototype.updateContainer = function updateContainer(deltaX, deltaY) {
+
+		if (this.rounded === true) {
+			this.size += this.resizeX * deltaX + this.resizeY * deltaY;
+			if (this.size < 0)	this.size = 0;
+			if (this.size > this.maxR)	this.size = this.maxR;
+			this.updateRadius();
+			this.updateBorderRadius();
+			return;
+		}
+
+		if (deltaX) {
+			this.width += this.resizeX * deltaX;
+			if (this.width < 0)	this.width = 0;
+			if (this.width > this.maxW)	this.width = this.maxW;
+			this.updateWidth();
+		}
+
+		if (deltaY) {
+			this.height += this.resizeY * deltaY;
+			if (this.height < 0) this.height = 0;
+			if (this.height > this.maxH)	this.height = this.maxH;
+			this.updateHeight();
+		}
+
+		if (deltaX || deltaY)
+			this.updateBorderRadius();
+	}
+
+
+	/**
+	 * Tool Manager
+	 */
+	var Tool = (function Tool() {
+		var preview;
+		var preview_ui;
+		var radius_containers = [];
+		var border_width = 3;
+		var borders1 = [null, null, null, null];
+		var borders2 = [0, 0, 0, 0];
+
+		var updateUIWidth = function updateUIWidth(value) {
+			var pwidth = subject.parentElement.clientWidth;
+			var left = (pwidth - value) / 2;
+			subject.style.width = value + "px";
+
+			for (var i = 0; i < 4; i++)
+				radius_containers[i].updateUnits(0);
+		}
+
+		var updateUIHeight = function updateUIHeight(value) {
+			var pheight = subject.parentElement.clientHeight;
+			var top = (pheight - value) / 2;
+			subject.style.height = value + "px";
+			subject.style.top = top - border_width + "px";
+
+			for (var i = 0; i < 4; i++)
+				radius_containers[i].updateUnits(1);
+		}
+
+		var updatePreviewUIWidth = function updatePreviewUIWidth() {
+			var p = subject.parentElement.clientWidth;
+			var v = preview_ui.clientWidth;
+			console.log(p, v, (p - v ) / 2);
+			preview_ui.style.left = (p - v) / 2 + "px" ;
+		}
+
+		var updatePreviewUIHeight = function updatePreviewUIHeight() {
+			var p = subject.parentElement.clientHeight;
+			var v = preview_ui.clientHeight;
+			console.log(p, v, (p - v ) / 2);
+			preview_ui.style.top = (p - v) / 2 + "px" ;
+		}
+
+		var updateOutput = function updateOutput(corner, radius) {
+			var values = radius.split(" ");
+
+			borders1[corner] = values[0];
+			borders2[corner] = values[0];
+
+			if (values.length === 2)
+				borders2[corner] = values[1];
+
+			var border_1_value = borders1.join(" ");
+			var border_2_value = borders2.join(" ");
+			var border_radius = 'border-radius: ' + border_1_value;
+
+			if (border_2_value !== border_1_value)
+				border_radius += ' / ' + border_2_value;
+
+			border_radius += ';';
+			output.textContent = border_radius;
+		}
+
+		var init = function init() {
+			preview = getElemById("preview");
+			subject = getElemById("subject");
+			output = getElemById("output");
+			preview_ui = getElemById("radius-ui-sliders");
+
+			var elem = document.querySelectorAll('.radius-container');
+			var size = elem.length;
+			for (var i = 0; i < size; i++)
+				radius_containers[i] = new RadiusContainer(elem[i]);
+
+			InputSliderManager.subscribe("width", updateUIWidth);
+			InputSliderManager.subscribe("height", updateUIHeight);
+
+			InputSliderManager.setValue("width", subject.clientWidth);
+			InputSliderManager.setValue("height", subject.clientHeight);
+		}
+
+		return {
+			init : init,
+			updateOutput : updateOutput
+		}
+
+	})();
+
+	/**
+	 * Init Tool
+	 */
+	var init = function init() {
+		ButtonManager.init();
+		InputSliderManager.init();
+		PreviewMouseTracking.init("preview");
+		Tool.init();
+	}
+
+	return {
+		init : init
+	}
+
+})();
+
+
+
+
+ +

{{ EmbedLiveSample('border-radius-generator', '100%', '800px', '') }}

+ +

 

diff --git "a/files/ru/web/css/css_background_and_borders/border-radius_\320\263\320\265\320\275\320\265\321\200\320\260\321\202\320\276\321\200/index.html" "b/files/ru/web/css/css_background_and_borders/border-radius_\320\263\320\265\320\275\320\265\321\200\320\260\321\202\320\276\321\200/index.html" deleted file mode 100644 index 71f94831f0..0000000000 --- "a/files/ru/web/css/css_background_and_borders/border-radius_\320\263\320\265\320\275\320\265\321\200\320\260\321\202\320\276\321\200/index.html" +++ /dev/null @@ -1,1599 +0,0 @@ ---- -title: Border-radius генератор -slug: Web/CSS/CSS_Background_and_Borders/Border-radius_генератор -translation_of: Web/CSS/CSS_Background_and_Borders/Border-radius_generator ---- -

С помощью этого инструмента вы можете создать CSS3 {{cssxref("border-radius")}} эффекты.

- -
-

border-radius

- -

HTML Content

- -
<div id="container">
-    <div class="group section">
-        <div id="preview" class="col span_12">
-            <div id="subject">
-                <div id="top-left" class="radius-container"
-                    data-X="left" data-Y="top">
-                </div>
-                <div id="top-right" class="radius-container"
-                    data-X="right" data-Y="top">
-                </div>
-                <div id="bottom-right" class="radius-container"
-                    data-X="right" data-Y="bottom">
-                </div>
-                <div id="bottom-left" class="radius-container"
-                    data-X="left" data-Y="bottom">
-                </div>
-
-                <div id="radius-ui-sliders">
-                    <div id="tlr" class="ui-input-slider" data-topic="top-left"
-                         data-unit=" px" data-sensivity="2"></div>
-
-                    <div id="tlw" class="ui-input-slider" data-topic="top-left-w"
-                         data-unit=" px" data-sensivity="2"></div>
-
-                    <div id="tlh" class="ui-input-slider" data-topic="top-left-h"
-                        data-unit=" px" data-sensivity="2"></div>
-
-                    <div id="trr" class="ui-input-slider" data-topic="top-right"
-                         data-unit=" px" data-sensivity="2"></div>
-
-                    <div id="trw" class="ui-input-slider" data-topic="top-right-w"
-                         data-unit=" px" data-sensivity="2"></div>
-
-                    <div id="trh" class="ui-input-slider" data-topic="top-right-h"
-                        data-unit=" px" data-sensivity="2"></div>
-
-                    <div id="brr" class="ui-input-slider" data-topic="bottom-right"
-                         data-unit=" px" data-sensivity="2"></div>
-
-                    <div id="brw" class="ui-input-slider" data-topic="bottom-right-w"
-                         data-unit=" px" data-sensivity="2"></div>
-
-                    <div id="brh" class="ui-input-slider" data-topic="bottom-right-h"
-                        data-unit=" px" data-sensivity="2"></div>
-
-                    <div id="blr" class="ui-input-slider" data-topic="bottom-left"
-                         data-unit=" px" data-sensivity="2"></div>
-
-                    <div id="blw" class="ui-input-slider" data-topic="bottom-left-w"
-                         data-unit=" px" data-sensivity="2"></div>
-
-                    <div id="blh" class="ui-input-slider" data-topic="bottom-left-h"
-                        data-unit=" px" data-sensivity="2"></div>
-                </div>
-            </div>
-        </div>
-    </div>
-    <div id="controls" class="group section">
-
-        <div class="group section">
-            <div id="dimensions">
-                <div class="ui-input-slider" data-topic="width" data-info="width"
-                     data-unit=" px" data-min="150" data-max="700" data-sensivity="1"></div>
-
-                <div class="ui-input-slider" data-topic="height" data-info="height"
-                    data-unit=" px" data-min="75" data-max="350" data-sensivity="1"></div>
-            </div>
-
-            <div id="output"></div>
-        </div>
-
-        <div class="group section">
-            <div id="radius-lock">
-                <div class="info"> rounded corner </div>
-                <div class="ui-checkbox" data-topic='top-left'></div>
-                <div class="ui-checkbox" data-topic='top-right'></div>
-                <div class="ui-checkbox" data-topic='bottom-right'></div>
-                <div class="ui-checkbox" data-topic='bottom-left'></div>
-            </div>
-
-            <div id="unit-selection">
-                <div class="info"> select border units </div>
-            </div>
-        </div>
-
-    </div>
-</div>
-
- -

CSS Content

- -
/*  GRID OF TEN
- * ========================================================================== */
-
-.span_12 {
-	width: 100%;
-}
-
-.span_11 {
-	width: 91.46%;
-}
-
-.span_10 {
-	width: 83%;
-}
-
-.span_9 {
-	width: 74.54%;
-}
-
-.span_8 {
-	width: 66.08%;
-}
-
-.span_7 {
-	width: 57.62%;
-}
-
-.span_6 {
-	width: 49.16%;
-}
-
-.span_5 {
-	width: 40.7%;
-}
-
-.span_4 {
-	width: 32.24%;
-}
-
-.span_3 {
-	width: 23.78%;
-}
-
-.span_2 {
-	width: 15.32%;
-}
-
-.span_1 {
-	width: 6.86%;
-}
-
-
-
-
-/*  SECTIONS
- * ========================================================================== */
-
-.section {
-	clear: both;
-	padding: 0px;
-	margin: 0px;
-}
-
-/*  GROUPING
- * ========================================================================== */
-
-
-.group:before, .group:after {
-    content: "";
-    display: table;
-}
-
-.group:after {
-    clear:both;
-}
-
-.group {
-    zoom: 1; /* For IE 6/7 (trigger hasLayout) */
-}
-
-/*  GRID COLUMN SETUP
- * ========================================================================== */
-
-.col {
-	display: block;
-	float:left;
-	margin: 1% 0 1% 1.6%;
-}
-
-.col:first-child {
-	margin-left: 0;
-} /* all browsers except IE6 and lower */
-
-
-/*
- * UI Component
- */
-
-.ui-input-slider-container {
-	height: 20px;
-	margin: 10px 0;
-	font-family: "Segoe UI", Arial, Helvetica, sans-serif;
-	-moz-user-select: none;
-	user-select: none;
-}
-
-.ui-input-slider-container * {
-	float: left;
-	height: 100%;
-	line-height: 100%;
-}
-
-/* Input Slider */
-
-.ui-input-slider > input {
-	margin: 0;
-	padding: 0;
-	width: 50px;
-	text-align: center;
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-}
-
-.ui-input-slider-info {
-	width: 90px;
-	padding: 0px 10px 0px 0px;
-	text-align: right;
-	text-transform: lowercase;
-}
-
-.ui-input-slider-left, .ui-input-slider-right {
-	width: 16px;
-	cursor: pointer;
-	background: url("https://mdn.mozillademos.org/files/5679/arrows.png") center left no-repeat;
-}
-
-.ui-input-slider-right {
-	background: url("https://mdn.mozillademos.org/files/5679/arrows.png") center right no-repeat;
-}
-
-.ui-input-slider-name {
-	width: 90px;
-	padding: 0 10px 0 0;
-	text-align: right;
-	text-transform: lowercase;
-}
-
-.ui-input-slider-btn-set {
-	width: 25px;
-	background-color: #2C9FC9;
-	border-radius: 5px;
-	color: #FFF;
-	font-weight: bold;
-	line-height: 14px;
-	text-align: center;
-}
-
-.ui-input-slider-btn-set:hover {
-	background-color: #379B4A;
-	cursor: pointer;
-}
-
-/*
- * UI Component
- */
-
-/* Checkbox */
-
-.ui-checkbox {
-	text-align: center;
-	font-size: 16px;
-	font-family: "Segoe UI", Arial, Helvetica, sans-serif;
-	line-height: 1.5em;
-	color: #FFF;
-
-	-moz-user-select: none;
-	-webkit-user-select: none;
-	-ms-user-select: none;
-	user-select: none;
-}
-
-.ui-checkbox > input {
- 	display: none;
-}
-
-.ui-checkbox > label {
-	font-size: 12px;
-	padding: 0.333em 1.666em 0.5em;
-	height: 1em;
-	line-height: 1em;
-
-	background-color: #888;
-	background-image: url("https://mdn.mozillademos.org/files/5683/disabled.png");
-	background-position: center center;
-	background-repeat: no-repeat;
-
-	color: #FFF;
-	border-radius: 3px;
-	font-weight: bold;
-	float: left;
-}
-
-.ui-checkbox .text {
-	padding-left: 34px;
-	background-position: center left 10px;
-}
-
-.ui-checkbox .left {
-	padding-right: 34px;
-	padding-left: 1.666em;
-	background-position: center right 10px;
-}
-
-.ui-checkbox > label:hover {
-	cursor: pointer;
-}
-
-.ui-checkbox > input:checked + label {
-	background-image: url("https://mdn.mozillademos.org/files/5681/checked.png");
-	background-color: #379B4A;
-}
-
-body {
-	max-width: 1000px;
-	margin: 0 auto;
-
-	font-family: "Segoe UI", Arial, Helvetica, sans-serif;
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-
-	-moz-user-select: none;
-	-webkit-user-select: none;
-	-ms-user-select: none;
-	user-select: none;
-}
-
-#container {
-	width: 100%;
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-}
-
-/******************************************************************************/
-/******************************************************************************/
-/*
- * Preview Area
- */
-
-#preview {
-	height: 500px;
-	border: 1px solid #CCC;
-	border-radius: 3px;
-	text-align: center;
-	overflow: hidden;
-	position: relative;
-}
-
-#preview .content {
-	width: 100%;
-	height: 100%;
-	display: block;
-}
-
-#preview input {
-	color: #333;
-	border: 1px solid #CCC;
-	border-radius: 3px;
-}
-
-#subject {
-	width: 400px;
-	height: 150px;
-	margin: 0 auto;
-	border: 3px solid #C60;
-	background: #FFF;
-	position: relative;
-}
-
-.radius {
-	width: 50%;
-	height: 50%;
-	border: 1px solid #CCC;
-	display: none;
-	position: absolute;
-	z-index: 1;
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-}
-
-.handle {
-	width: 16px;
-	height: 16px;
-	position: absolute;
-	z-index: 2;
-}
-
-.handle-top-left {
-	top: -12px;
-	left: -12px;
-	cursor: se-resize;
-	background: url("https://mdn.mozillademos.org/files/5677/resize-handle.png") top left no-repeat;
-}
-
-.handle-top-right {
-	top: -12px;
-	right: -12px;
-	cursor: sw-resize;
-	background: url("https://mdn.mozillademos.org/files/5677/resize-handle.png") top right no-repeat;
-}
-
-.handle-bottom-right {
-	bottom: -12px;
-	right: -12px;
-	cursor: nw-resize;
-	background: url("https://mdn.mozillademos.org/files/5677/resize-handle.png") bottom right no-repeat;
-}
-
-.handle-bottom-left {
-	bottom: -12px;
-	left: -12px;
-	cursor: ne-resize;
-	background: url("https://mdn.mozillademos.org/files/5677/resize-handle.png") bottom left no-repeat;
-}
-
-
-.radius-container {
-	position: absolute;
-	display : block;
-	z-index: 1;
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-}
-
-
-/* TOP LEFT */
-#top-left {
-	top: 0;
-	left: 0;
-}
-
-#top-left .radius {
-	border-top-left-radius: 100%;
-	top: 0;
-	left: 0;
-}
-
-/* TOP RIGHT */
-#top-right {
-	top: 0;
-	right: 0;
-}
-
-#top-right .radius {
-	border-top-right-radius: 100%;
-	top: 0;
-	right: 0;
-}
-
-/* BOTTOM RIGHT */
-#bottom-right {
-	bottom: 0;
-	right: 0;
-}
-
-#bottom-right .radius {
-	border-bottom-right-radius: 100%;
-	bottom: 0;
-	right: 0;
-}
-
-/* BOTTOM lEFT */
-#bottom-left {
-	bottom: 0;
-	left: 0;
-}
-
-#bottom-left .radius {
-	border-bottom-left-radius: 100%;
-	bottom: 0;
-}
-
-/* INPUT SLIDERS */
-
-#preview .ui-input-slider {
-	margin: 10px;
-	position: absolute;
-	z-index: 10;
-}
-
-#radius-ui-sliders {
-	width: 100%;
-	height: 100%;
-	min-height: 75px;
-	min-width: 150px;
-	padding: 20px 50px;
-	top: -20px;
-	left: -50px;
-	position: relative;
-}
-
-#tlr {
-	top: -30px;
-	left: -50px;
-	display: none;
-}
-
-#tlw {
-	top: -30px;
-	left: 30px;
-}
-
-#tlh {
-	top: 20px;
-	left: -50px;
-}
-
-#trr {
-	top: -30px;
-	right: -50px;
-	display: none;
-}
-
-#trw {
-	top: -30px;
-	right: 30px;
-}
-
-#trh {
-	top: 20px;
-	right: -50px;
-}
-
-#brr {
-	bottom: -30px;
-	right: -50px;
-	display: none;
-}
-
-#brw {
-	bottom: -30px;
-	right: 30px;
-}
-
-#brh {
-	bottom: 20px;
-	right: -50px;
-}
-
-#blr {
-	bottom: -30px;
-	left: -50px;
-	display: none;
-}
-
-#blw {
-	bottom: -30px;
-	left: 30px;
-}
-
-#blh {
-	bottom: 20px;
-	left: -50px;
-}
-
-#preview .ui-input-slider-left, #preview .ui-input-slider-right {
-	visibility: hidden;
-}
-
-#preview .ui-input-slider-container:hover .ui-input-slider-left {
-	visibility: visible;
-}
-
-#preview .ui-input-slider-container:hover .ui-input-slider-right {
-	visibility: visible;
-}
-
-/*
- *
- */
-
-#unit-selection {
-	width: 200px;
-	height: 75px;
-	margin: 30px 30px 0 0;
-	padding: 30px;
-	border: 3px solid #555;
-	border-radius: 10px;
-	position: relative;
-	float: right;
-}
-
-#unit-selection .info {
-	height: 20%;
-	width: 100%;
-	line-height: 20%;
-	font-size: 20px;
-	text-align: center;
-	position: relative;
-	top: 40%;
-}
-
-#unit-selection .dropdown {
-	width: 50px;
-	height: 20px;
-	margin: 10px;
-	padding: 0;
-	border-radius: 3px;
-	position: absolute;
-	overflow: hidden;
-}
-
-#unit-selection select {
-	width: 50px;
-	height: 20px;
-	marign: 0;
-	padding: 0 0 0 10px;
-	background: #555;
-	border: 1px solid #555;
-	border: none;
-	color: #FFF;
-	float: left;
-}
-
-#unit-selection select option {
-	background: #FFF;
-	color: #333;
-}
-
-#unit-selection select:hover {
-	cursor: pointer;
-}
-
-#unit-selection .dropdown:before {
-	content: "";
-	width: 18px;
-	height: 20px;
-	display: block;
-	background-color: #555;
-	background-image: url("https://mdn.mozillademos.org/files/5675/dropdown.png");
-	background-position: center center;
-	background-repeat: no-repeat;
-	top: 0px;
-	right: 0px;
-	position: absolute;
-	z-index: 1;
-	pointer-events: none;
-}
-
-#unit-selection .unit-top-left {
-	top: 0;
-	left: 0;
-	display: none;
-}
-
-#unit-selection .unit-top-left-w {
-	top: -22px;
-	left: 30px;
-}
-
-#unit-selection .unit-top-left-h {
-	top: 20px;
-	left: -37px;
-}
-
-#unit-selection .unit-top-right {
-	top: 0;
-	right: 0;
-	display: none;
-}
-
-#unit-selection .unit-top-right-w {
-	top: -22px;
-	right: 30px;
-}
-
-#unit-selection .unit-top-right-h {
-	top: 20px;
-	right: -37px;
-}
-
-#unit-selection .unit-bottom-right {
-	bottom: 0;
-	right: 0;
-	display: none;
-}
-
-#unit-selection .unit-bottom-right-w {
-	bottom: -22px;
-	right: 30px;
-}
-
-#unit-selection .unit-bottom-right-h {
-	bottom: 20px;
-	right: -37px;
-}
-
-#unit-selection .unit-bottom-left {
-	bottom: 0;
-	left: 0;
-	display: none;
-}
-
-#unit-selection .unit-bottom-left-w {
-	bottom: -22px;
-	left: 30px;
-}
-
-#unit-selection .unit-bottom-left-h {
-	bottom: 20px;
-	left: -37px;
-}
-
-/******************************************************************************/
-/******************************************************************************/
-
-
-#radius-lock {
-	width: 200px;
-	height: 75px;
-	margin: 30px 0 0 30px;
-	padding: 30px;
-	border: 3px solid #555;
-	border-radius: 10px;
-	position: relative;
-	float: left;
-}
-
-#radius-lock .ui-checkbox {
-	color: #FFF;
-	position: absolute;
-}
-
-#radius-lock .ui-checkbox > label {
-	height: 20px;
-	width: 34px;
-	padding: 0;
-}
-
-#radius-lock .info {
-	height: 20%;
-	width: 100%;
-	line-height: 20%;
-	font-size: 20px;
-	text-align: center;
-	position: relative;
-	top: 40%;
-}
-
-#radius-lock [data-topic="top-left"] {
-	top: 10px;
-	left: 10px;
-}
-
-#radius-lock [data-topic="top-right"] {
-	top: 10px;
-	right: 10px;
-}
-
-#radius-lock [data-topic="bottom-right"] {
-	bottom: 10px;
-	right: 10px;
-}
-
-#radius-lock [data-topic="bottom-left"] {
-	bottom: 10px;
-	left: 10px;
-}
-
-/**
- * Controls
- */
-
-#dimensions {
-	width: 200px;
-	color: #444;
-	float:left;
-}
-
-#dimensions input {
-	background: #555;
-	color: #FFF;
-	border: none;
-	border-radius: 3px;
-}
-
-#output {
-	width: 500px;
-	padding: 10px 0;
-	margin: 10px 0;
-	color: #555;
-	text-align: center;
-	border: 1px dashed #999;
-	border-radius: 3px;
-	-moz-user-select: text;
-	-webkit-user-select: text;
-	-ms-user-select: text;
-	user-select: text;
-
-	float: right;
-}
-
-
-
- -

JavaScript Content

- -
'use strict';
-
-
-/**
- * UI-InputSliderManager
- */
-
-var InputSliderManager = (function InputSliderManager() {
-
-	var subscribers = {};
-	var sliders = [];
-
-	var InputComponent = function InputComponent(obj) {
-		var input = document.createElement('input');
-		input.setAttribute('type', 'text');
-
-		input.addEventListener('click', function(e) {
-			this.select();
-		});
-
-		input.addEventListener('change', function(e) {
-			var value = parseInt(e.target.value);
-
-			if (isNaN(value) === true)
-				setValue(obj.topic, obj.value);
-			else
-				setValue(obj.topic, value);
-		});
-
-		subscribe(obj.topic, function(value) {
-			input.value = value + obj.unit;
-		});
-
-		return input;
-	}
-
-	var SliderComponent = function SliderComponent(obj, sign) {
-		var slider = document.createElement('div');
-		var startX = null;
-		var start_value = 0;
-
-		slider.addEventListener("click", function(e) {
-			setValue(obj.topic, obj.value + obj.step * sign);
-		});
-
-		slider.addEventListener("mousedown", function(e) {
-			startX = e.clientX;
-			start_value = obj.value;
-			document.body.style.cursor = "e-resize";
-			document.addEventListener("mousemove", sliderMotion);
-		});
-
-		document.addEventListener("mouseup", function(e) {
-			document.removeEventListener("mousemove", sliderMotion);
-			document.body.style.cursor = "auto";
-			slider.style.cursor = "pointer";
-		});
-
-		var sliderMotion = function sliderMotion(e) {
-			slider.style.cursor = "e-resize";
-			var delta = (e.clientX - startX) / obj.sensivity | 0;
-			var value = delta * obj.step + start_value;
-			setValue(obj.topic, value);
-		}
-
-		return slider;
-	}
-
-	var InputSlider = function(node) {
-		var min		= node.getAttribute('data-min') | 0;
-		var max		= node.getAttribute('data-max') | 0;
-		var step	= node.getAttribute('data-step') | 0;
-		var value	= node.getAttribute('data-value') | 0;
-		var topic	= node.getAttribute('data-topic');
-		var unit	= node.getAttribute('data-unit');
-		var name 	= node.getAttribute('data-info');
-		var sensivity = node.getAttribute('data-sensivity') | 0;
-
-		this.min = min;
-		this.max = max > 0 ? max : 100;
-		this.step = step === 0 ? 1 : step;
-		this.topic = topic;
-		this.node = node;
-		this.unit = unit;
-		this.sensivity = sensivity > 0 ? sensivity : 5;
-
-		var input = new InputComponent(this);
-		var slider_left  = new SliderComponent(this, -1);
-		var slider_right = new SliderComponent(this,  1);
-
-		slider_left.className = 'ui-input-slider-left';
-		slider_right.className = 'ui-input-slider-right';
-
-		if (name) {
-			var info = document.createElement('span');
-			info.className = 'ui-input-slider-info';
-			info.textContent = name;
-			node.appendChild(info);
-		}
-
-		node.appendChild(slider_left);
-		node.appendChild(input);
-		node.appendChild(slider_right);
-		node.className = 'ui-input-slider ui-input-slider-container';
-
-		this.input = input;
-		sliders[topic] = this;
-		setValue(topic, value);
-	}
-
-	var setValue = function setValue(topic, value, send_notify) {
-		var slider = sliders[topic];
-		if (slider === undefined)
-			return;
-
-		if (value > slider.max) value = slider.max;
-		if (value < slider.min)	value = slider.min;
-
-		slider.value = value;
-		slider.node.setAttribute('data-value', value);
-
-		if (send_notify !== undefined && send_notify === false) {
-			slider.input.value = value + slider.unit;
-			return;
-		}
-
-		notify.call(slider);
-	}
-
-	var setMax = function setMax(topic, value) {
-		var slider = sliders[topic];
-		if (slider === undefined)
-			return;
-
-		slider.max = value;
-		setValue(topic, slider.value);
-	}
-
-	var setMin = function setMin(topic, value) {
-		var slider = sliders[topic];
-		if (slider === undefined)
-			return;
-
-		slider.min = value;
-		setValue(topic, slider.value);
-	}
-
-	var setUnit = function setUnit(topic, unit) {
-		var slider = sliders[topic];
-		if (slider === undefined)
-			return;
-
-		slider.unit = unit;
-		setValue(topic, slider.value);
-	}
-
-	var getNode =  function getNode(topic) {
-		return sliders[topic].node;
-	}
-
-	var subscribe = function subscribe(topic, callback) {
-		if (subscribers[topic] === undefined)
-			subscribers[topic] = [];
-		subscribers[topic].push(callback);
-	}
-
-	var unsubscribe = function unsubscribe(topic, callback) {
-		subscribers[topic].indexOf(callback);
-		subscribers[topic].splice(index, 1);
-	}
-
-	var notify = function notify() {
-		for (var i in subscribers[this.topic]) {
-			subscribers[this.topic][i](this.value);
-		}
-	}
-
-	var init = function init() {
-		var elem = document.querySelectorAll('.ui-input-slider');
-		var size = elem.length;
-		for (var i = 0; i < size; i++)
-			new InputSlider(elem[i]);
-	}
-
-	return {
-		init : init,
-		setMax : setMax,
-		setMin : setMin,
-		setUnit : setUnit,
-		getNode : getNode,
-		setValue : setValue,
-		subscribe : subscribe,
-		unsubscribe : unsubscribe
-	}
-
-})();
-
-/**
- * UI-ButtonManager
- */
-
-var ButtonManager = (function CheckBoxManager() {
-
-	var subscribers = [];
-	var buttons = [];
-
-	var CheckBox = function CheckBox(node) {
-		var topic = node.getAttribute('data-topic');
-		var state = node.getAttribute('data-state');
-		var name = node.getAttribute('data-label');
-		var align = node.getAttribute('data-text-on');
-
-		state = (state === "true");
-
-		var checkbox = document.createElement("input");
-		var label = document.createElement("label");
-
-		var id = 'checkbox-' + topic;
-		checkbox.id = id;
-		checkbox.setAttribute('type', 'checkbox');
-		checkbox.checked = state;
-
-		label.setAttribute('for', id);
-		if (name) {
-			label.className = 'text';
-			if (align)
-				label.className += ' ' + align;
-			label.textContent = name;
-		}
-
-		node.appendChild(checkbox);
-		node.appendChild(label);
-
-		this.node = node;
-		this.topic = topic;
-		this.checkbox = checkbox;
-
-		checkbox.addEventListener('change', function(e) {
-			notify.call(this);
-		}.bind(this));
-
-		buttons[topic] = this;
-	}
-
-	var getNode =  function getNode(topic) {
-		return buttons[topic].node;
-	}
-
-	var setValue = function setValue(topic, value) {
-		try {
-			buttons[topic].checkbox.checked = value;
-		}
-		catch(error) {
-			console.log(error);
-		}
-	}
-
-	var subscribe = function subscribe(topic, callback) {
-		if (subscribers[topic] === undefined)
-			subscribers[topic] = [];
-
-		subscribers[topic].push(callback);
-	}
-
-	var unsubscribe = function unsubscribe(topic, callback) {
-		subscribers[topic].indexOf(callback);
-		subscribers[topic].splice(index, 1);
-	}
-
-	var notify = function notify() {
-		for (var i = 0; i < subscribers[this.topic].length; i++)
-			subscribers[this.topic][i](this.checkbox.checked);
-	}
-
-	var init = function init() {
-		var elem = document.querySelectorAll('.ui-checkbox');
-		var size = elem.length;
-		for (var i = 0; i < size; i++)
-			new CheckBox(elem[i]);
-	}
-
-	return {
-		init : init,
-		setValue : setValue,
-		subscribe : subscribe,
-		unsubscribe : unsubscribe
-	}
-
-})();
-
-
-window.addEventListener("load", function() {
-	BorderRadius.init();
-});
-
-var BorderRadius = (function BorderRadius() {
-
-	function getElemById(id) {
-		return document.getElementById(id);
-	}
-
-	/**
-	 * Shadow dragging
-	 */
-	var PreviewMouseTracking = (function Drag() {
-		var active = false;
-		var lastX = 0;
-		var lastY = 0;
-		var subscribers = [];
-
-		var init = function init(id) {
-			var elem = getElemById(id);
-			elem.addEventListener('mousedown', dragStart, false);
-			document.addEventListener('mouseup', dragEnd, false);
-		}
-
-		var dragStart = function dragStart(e) {
-			if (e.button !== 0)
-				return;
-
-			active = true;
-			lastX = e.clientX;
-			lastY = e.clientY;
-			document.addEventListener('mousemove', mouseDrag, false);
-		}
-
-		var dragEnd = function dragEnd(e) {
-			if (e.button !== 0)
-				return;
-
-			if (active === true) {
-				active = false;
-				document.removeEventListener('mousemove', mouseDrag, false);
-			}
-		}
-
-		var mouseDrag = function mouseDrag(e) {
-			notify(e.clientX - lastX, e.clientY - lastY);
-			lastX = e.clientX;
-			lastY = e.clientY;
-		}
-
-		var subscribe = function subscribe(callback) {
-			subscribers.push(callback);
-		}
-
-		var unsubscribe = function unsubscribe(callback) {
-			var index = subscribers.indexOf(callback);
-			subscribers.splice(index, 1);
-		}
-
-		var notify = function notify(deltaX, deltaY) {
-			for (var i in subscribers)
-				subscribers[i](deltaX, deltaY);
-		}
-
-		return {
-			init : init,
-			subscribe : subscribe,
-			unsubscribe : unsubscribe
-		}
-
-	})();
-
-	var subject;
-	var units = ['px', '%'];
-	var output = null;
-
-	var UnitSelector = function UnitSelector(topic) {
-
-		this.container = document.createElement("div");
-		this.select = document.createElement("select");
-		for (var i in units) {
-			var option = document.createElement("option");
-			option.value = i;
-			option.textContent = units[i];
-			this.select.appendChild(option);
-		}
-
-		this.container.className = 'dropdown ' + 'unit-' + topic;
-		this.container.appendChild(this.select);
-	}
-
-	UnitSelector.prototype.setValue = function setValue(value) {
-		this.salect.value = value;
-	}
-
-
-	var RadiusContainer = function RadiusContainer(node) {
-		var radius = document.createElement('div');
-		var handle = document.createElement('div');
-		var x = node.getAttribute('data-x');
-		var y = node.getAttribute('data-y');
-		var active = false;
-
-		this.id = node.id;
-		this.node = node;
-		this.radius = radius;
-		this.handle = handle;
-		this.width = 100;
-		this.height = 50;
-		this.size = 0;
-		this.rounded = false;
-
-		this.unitX = 0;
-		this.unitY = 0;
-		this.unitR = 0;
-
-		this.maxW = 100;
-		this.maxH = 100;
-		this.maxR = 100;
-
-		this.topic = y + '-' + x;
-
-		var sliderW = InputSliderManager.getNode(this.topic + '-w');
-		var sliderH = InputSliderManager.getNode(this.topic + '-h');
-		var sliderR = InputSliderManager.getNode(this.topic);
-
-		this.setUnitX(this.unitX);
-		this.setUnitY(this.unitY);
-		this.setUnitR(this.unitR);
-
-		this.updateWidth();
-		this.updateHeight();
-		this.updateRadius();
-
-		if (x === 'left')	this.resizeX =  1;
-		if (x === 'right')	this.resizeX = -1;
-		if (y === 'top')	this.resizeY =  1;
-		if (y === 'bottom')	this.resizeY = -1;
-
-		radius.className = 'radius';
-
-		var unit_selector = document.getElementById("unit-selection");
-		var unitW = new UnitSelector(this.topic + '-w');
-		var unitH = new UnitSelector(this.topic + '-h');
-		var unitR = new UnitSelector(this.topic);
-
-		unit_selector.appendChild(unitW.container);
-		unit_selector.appendChild(unitH.container);
-		unit_selector.appendChild(unitR.container);
-		node.appendChild(radius);
-		subject.appendChild(handle);
-
-		unitW.select.addEventListener('change', function(e) {
-			this.setUnitX(e.target.value | 0);
-		}.bind(this));
-
-		unitH.select.addEventListener('change', function(e) {
-			this.setUnitY(e.target.value | 0);
-		}.bind(this));
-
-		unitR.select.addEventListener('change', function(e) {
-			this.setUnitR(e.target.value | 0);
-		}.bind(this));
-
-		if (x === 'left' && y == 'top') handle.className = 'handle handle-top-left'
-		if (x === 'right' && y == 'top') handle.className = 'handle handle-top-right';
-		if (x === 'right' && y == 'bottom') handle.className = 'handle handle-bottom-right';
-		if (x === 'left' && y == 'bottom') 	handle.className = 'handle handle-bottom-left';
-
-		handle.addEventListener("mousedown", function(e) {
-			active = true;
-			this.radius.style.display = 'block';
-			PreviewMouseTracking.subscribe(this.updateContainer.bind(this));
-		}.bind(this));
-
-		document.addEventListener("mouseup", function(e) {
-			this.radius.style.display = 'none';
-			if (active === true)
-				PreviewMouseTracking.unsubscribe(this.updateContainer.bind(this));
-		}.bind(this));
-
-		InputSliderManager.subscribe(this.topic + '-w', this.setWidth.bind(this));
-		InputSliderManager.subscribe(this.topic + '-h', this.setHeight.bind(this));
-		InputSliderManager.subscribe(this.topic, this.setRadius.bind(this));
-
-		ButtonManager.subscribe(this.topic, function(value) {
-			this.rounded = value;
-			if (value === true) {
-				unitW.container.style.display = 'none';
-				unitH.container.style.display = 'none';
-				unitR.container.style.display = 'block';
-				sliderW.style.display = 'none';
-				sliderH.style.display = 'none';
-				sliderR.style.display = 'block';
-				this.setUnitR(this.unitR);
-				this.updateRadius();
-			}
-
-			if (value === false) {
-				unitW.container.style.display = 'block';
-				unitH.container.style.display = 'block';
-				unitR.container.style.display = 'none';
-				sliderW.style.display = 'block';
-				sliderH.style.display = 'block';
-				sliderR.style.display = 'none';
-				this.setUnitX(this.unitX);
-				this.setUnitY(this.unitY);
-				this.updateWidth();
-				this.updateHeight();
-			}
-
-			this.updateBorderRadius();
-
-		}.bind(this));
-
-		this.updateBorderRadius();
-	}
-
-	RadiusContainer.prototype.updateWidth = function updateWidth() {
-		this.node.style.width = this.width + units[this.unitX];
-		var value = Math.round(this.width / 2);
-		InputSliderManager.setValue(this.topic + '-w', value, false);
-	}
-
-	RadiusContainer.prototype.updateHeight = function updateHeight() {
-		this.node.style.height = this.height + units[this.unitY];
-		var value = Math.round(this.height / 2);
-		InputSliderManager.setValue(this.topic + '-h', value, false);
-	}
-
-	RadiusContainer.prototype.updateRadius = function updateRadius() {
-		var value = Math.round(this.size / 2);
-		this.node.style.width = this.size + units[this.unitR];
-		this.node.style.height = this.size + units[this.unitR];
-		InputSliderManager.setValue(this.topic, value, false);
-	}
-
-	RadiusContainer.prototype.setWidth = function setWidth(value) {
-		this.radius.style.display = 'block';
-		this.width = 2 * value;
-		this.node.style.width = this.width + units[this.unitX];
-		this.updateBorderRadius();
-	}
-
-	RadiusContainer.prototype.setHeight = function setHeight(value) {
-		this.radius.style.display = 'block';
-		this.height = 2 * value;
-		this.node.style.height = this.height + units[this.unitY];
-		this.updateBorderRadius();
-	}
-
-	RadiusContainer.prototype.setRadius = function setRadius(value) {
-		this.radius.style.display = 'block';
-		this.size = 2 * value;
-		this.node.style.width = this.size + units[this.unitR];
-		this.node.style.height = this.size + units[this.unitR];
-		this.updateBorderRadius();
-	}
-
-	RadiusContainer.prototype.setUnitX = function setUnitX(value) {
-		this.unitX = value;
-		if (this.unitX === 0) this.maxW = 2 * subject.clientWidth;
-		if (this.unitX === 1) this.maxW = 200;
-		InputSliderManager.setUnit(this.topic + '-w', units[this.unitX]);
-		InputSliderManager.setMax(this.topic + '-w', this.maxW / 2);
-	}
-
-	RadiusContainer.prototype.setUnitY = function setUnitY(value) {
-		this.unitY = value;
-		if (this.unitY === 0) this.maxH = 2 * subject.clientHeight;
-		if (this.unitY === 1) this.maxH = 200;
-		InputSliderManager.setUnit(this.topic + '-h', units[this.unitY]);
-		InputSliderManager.setMax(this.topic + '-h', this.maxH / 2);
-	}
-
-	RadiusContainer.prototype.setUnitR = function setUnitR(value) {
-		this.unitR = value;
-
-		if (this.unitR === 0)
-			this.maxR = 2 * Math.min(subject.clientHeight , subject.clientWidth);
-
-		if (this.unitR === 1)
-			this.maxR = 200;
-
-		InputSliderManager.setUnit(this.topic, units[this.unitR]);
-		InputSliderManager.setMax(this.topic, this.maxR / 2);
-	}
-
-	RadiusContainer.prototype.updateUnits = function updateUnits(unit) {
-		if (this.rounded) {
-			this.setUnitR(this.unitR);
-			return;
-		}
-
-		if (unit === 0)
-			this.setUnitX(this.unitX);
-
-		if (unit === 1)
-			this.setUnitY(this.unitY);
-	}
-
-	RadiusContainer.prototype.composeBorderRadius = function composeBorderRadius () {
-
-		if (this.rounded === true) {
-			var unit = units[this.unitR];
-			var value = Math.round(this.size / 2);
-			return value + unit;
-		}
-
-		var unitX = units[this.unitX];
-		var unitY = units[this.unitY];
-		var valueX = Math.round(this.width / 2);
-		var valueY = Math.round(this.height / 2);
-
-		if (valueX === valueY && this.unitX === this.unitY)
-			return valueX + unitX;
-
-		return valueX + unitX + ' ' + valueY + unitY;
-	}
-
-	RadiusContainer.prototype.updateBorderRadius = function updateBorderRadius () {
-		var radius = this.composeBorderRadius();
-		var corner = 0;
-
-		if (this.topic === 'top-left') {
-			subject.style.borderTopLeftRadius = radius;
-			corner = 0;
-		}
-
-		if (this.topic === 'top-right') {
-			subject.style.borderTopRightRadius = radius;
-			corner = 1;
-		}
-
-		if (this.topic === 'bottom-right') {
-			subject.style.borderBottomRightRadius = radius;
-			corner = 2;
-		}
-
-		if (this.topic === 'bottom-left') {
-			subject.style.borderBottomLeftRadius = radius;
-			corner = 3;
-		}
-
-		Tool.updateOutput(corner, radius);
-	}
-
-	RadiusContainer.prototype.updateContainer = function updateContainer(deltaX, deltaY) {
-
-		if (this.rounded === true) {
-			this.size += this.resizeX * deltaX + this.resizeY * deltaY;
-			if (this.size < 0)	this.size = 0;
-			if (this.size > this.maxR)	this.size = this.maxR;
-			this.updateRadius();
-			this.updateBorderRadius();
-			return;
-		}
-
-		if (deltaX) {
-			this.width += this.resizeX * deltaX;
-			if (this.width < 0)	this.width = 0;
-			if (this.width > this.maxW)	this.width = this.maxW;
-			this.updateWidth();
-		}
-
-		if (deltaY) {
-			this.height += this.resizeY * deltaY;
-			if (this.height < 0) this.height = 0;
-			if (this.height > this.maxH)	this.height = this.maxH;
-			this.updateHeight();
-		}
-
-		if (deltaX || deltaY)
-			this.updateBorderRadius();
-	}
-
-
-	/**
-	 * Tool Manager
-	 */
-	var Tool = (function Tool() {
-		var preview;
-		var preview_ui;
-		var radius_containers = [];
-		var border_width = 3;
-		var borders1 = [null, null, null, null];
-		var borders2 = [0, 0, 0, 0];
-
-		var updateUIWidth = function updateUIWidth(value) {
-			var pwidth = subject.parentElement.clientWidth;
-			var left = (pwidth - value) / 2;
-			subject.style.width = value + "px";
-
-			for (var i = 0; i < 4; i++)
-				radius_containers[i].updateUnits(0);
-		}
-
-		var updateUIHeight = function updateUIHeight(value) {
-			var pheight = subject.parentElement.clientHeight;
-			var top = (pheight - value) / 2;
-			subject.style.height = value + "px";
-			subject.style.top = top - border_width + "px";
-
-			for (var i = 0; i < 4; i++)
-				radius_containers[i].updateUnits(1);
-		}
-
-		var updatePreviewUIWidth = function updatePreviewUIWidth() {
-			var p = subject.parentElement.clientWidth;
-			var v = preview_ui.clientWidth;
-			console.log(p, v, (p - v ) / 2);
-			preview_ui.style.left = (p - v) / 2 + "px" ;
-		}
-
-		var updatePreviewUIHeight = function updatePreviewUIHeight() {
-			var p = subject.parentElement.clientHeight;
-			var v = preview_ui.clientHeight;
-			console.log(p, v, (p - v ) / 2);
-			preview_ui.style.top = (p - v) / 2 + "px" ;
-		}
-
-		var updateOutput = function updateOutput(corner, radius) {
-			var values = radius.split(" ");
-
-			borders1[corner] = values[0];
-			borders2[corner] = values[0];
-
-			if (values.length === 2)
-				borders2[corner] = values[1];
-
-			var border_1_value = borders1.join(" ");
-			var border_2_value = borders2.join(" ");
-			var border_radius = 'border-radius: ' + border_1_value;
-
-			if (border_2_value !== border_1_value)
-				border_radius += ' / ' + border_2_value;
-
-			border_radius += ';';
-			output.textContent = border_radius;
-		}
-
-		var init = function init() {
-			preview = getElemById("preview");
-			subject = getElemById("subject");
-			output = getElemById("output");
-			preview_ui = getElemById("radius-ui-sliders");
-
-			var elem = document.querySelectorAll('.radius-container');
-			var size = elem.length;
-			for (var i = 0; i < size; i++)
-				radius_containers[i] = new RadiusContainer(elem[i]);
-
-			InputSliderManager.subscribe("width", updateUIWidth);
-			InputSliderManager.subscribe("height", updateUIHeight);
-
-			InputSliderManager.setValue("width", subject.clientWidth);
-			InputSliderManager.setValue("height", subject.clientHeight);
-		}
-
-		return {
-			init : init,
-			updateOutput : updateOutput
-		}
-
-	})();
-
-	/**
-	 * Init Tool
-	 */
-	var init = function init() {
-		ButtonManager.init();
-		InputSliderManager.init();
-		PreviewMouseTracking.init("preview");
-		Tool.init();
-	}
-
-	return {
-		init : init
-	}
-
-})();
-
-
-
-
- -

{{ EmbedLiveSample('border-radius-generator', '100%', '800px', '') }}

- -

 

diff --git a/files/ru/web/css/css_background_and_borders/box-shadow_generator/index.html b/files/ru/web/css/css_background_and_borders/box-shadow_generator/index.html new file mode 100644 index 0000000000..3f46cf53ba --- /dev/null +++ b/files/ru/web/css/css_background_and_borders/box-shadow_generator/index.html @@ -0,0 +1,2884 @@ +--- +title: Генератор теней +slug: Web/CSS/CSS_Box_Model/Box-shadow_generator +tags: + - CSS3 + - Тень + - инструменты +translation_of: Web/CSS/CSS_Background_and_Borders/Box-shadow_generator +--- +

Этот инструмент позволяет вам создавать CSS {{cssxref("box-shadow")}} эффекты, добавлять тени вашим элементам.

+ +
+

Генератор box-shadow generator

+ +

HTML Content

+ +
<div id="container">
+    <div class="group section">
+        <div id="layer_manager">
+            <div class="group section">
+                <div class="button" data-type="add"> </div>
+                <div class="button" data-type="move-up"> </div>
+                <div class="button" data-type="move-down"> </div>
+            </div>
+            <div id="stack_container"></div>
+        </div>
+
+        <div id="preview_zone">
+            <div id="layer_menu" class="col span_12">
+                <div class="button" id="element" data-type="subject" data-title="element"> элементы </div>
+                <div class="button" id="before" data-type="subject" data-title=":before">
+                    :before
+                    <span class="delete" data-type="disable"></span>
+                </div>
+                <div class="button" id="after" data-type="subject" data-title=":after">
+                    :after
+                    <span class="delete" data-type="disable"></span>
+                </div>
+                <div class="ui-checkbox" data-topic='before' data-label=":before"></div>
+                <div class="ui-checkbox" data-topic='after' data-label=":after"></div>
+            </div>
+
+            <div id="preview">
+                <div id="obj-element">
+                    <div class="content"> </div>
+                    <div id="obj-before"> </div>
+                    <div id="obj-after"> </div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <div id="controls" class="group section">
+        <div class="wrap-left">
+            <div class="colorpicker category">
+                <div class="title"> </div>
+                <div id="colorpicker" class="group">
+                    <div id="gradient" class="gradient">
+                        <div id="gradient_picker"> </div>
+                    </div>
+                    <div id="hue" data-topic="hue" class="hue">
+                        <div id="hue_selector"> </div>
+                    </div>
+                    <div class="info">
+                        <div class="input" data-topic="hue" data-title='H:' data-action="HSV"></div>
+                        <div class="input" data-topic="saturation" data-title='S:' data-action="HSV"></div>
+                        <div class="input" data-topic="value" data-title='V:' data-action="HSV"></div>
+                    </div>
+                    <div class="alpha">
+                        <div id="alpha" data-topic="alpha">
+                            <div id="alpha_selector"> </div>
+                        </div>
+                    </div>
+                    <div class="info">
+                        <div class="input" data-topic="r" data-title='R:' data-action="RGB"></div>
+                        <div class="input" data-topic="g" data-title='G:' data-action="RGB"></div>
+                        <div class="input" data-topic="b" data-title='B:' data-action="RGB"></div>
+                    </div>
+                    <div class="preview block">
+                        <div id="output_color"> </div>
+                    </div>
+                    <div class="block info">
+                        <div class="input" data-topic="a" data-title='alpha:' data-action="alpha"></div>
+                        <div class="input" data-topic="hexa" data-title='' data-action="hexa"></div>
+                    </div>
+                </div>
+            </div>
+        </div>
+
+        <div class="wrap-right">
+
+            <div id="shadow_properties" class="category">
+                <div class="title"> Shadow properties </div>
+                <div class="group">
+                    <div class="group property">
+                        <div class="ui-slider-name"> inset </div>
+                        <div class="ui-checkbox" data-topic='inset'></div>
+                    </div>
+                    <div class="slidergroup">
+                        <div class="ui-slider-name"> Position x </div>
+                        <div class="ui-slider-btn-set" data-topic="posX" data-type="sub"></div>
+                        <div class="ui-slider" data-topic="posX"
+                            data-min="-500" data-max="500" data-step="1"> </div>
+                        <div class="ui-slider-btn-set" data-topic="posX" data-type="add"></div>
+                        <div class="ui-slider-input" data-topic="posX" data-unit="px"></div>
+                    </div>
+                    <div class="slidergroup">
+                        <div class="ui-slider-name"> Position y </div>
+                        <div class="ui-slider-btn-set" data-topic="posY" data-type="sub"></div>
+                        <div class="ui-slider" data-topic="posY"
+                            data-min="-500" data-max="500" data-step="1"> </div>
+                        <div class="ui-slider-btn-set" data-topic="posY" data-type="add"></div>
+                        <div class="ui-slider-input" data-topic="posY" data-unit="px"></div>
+                    </div>
+                    <div class="slidergroup">
+                        <div class="ui-slider-name"> Blur </div>
+                        <div class="ui-slider-btn-set" data-topic="blur" data-type="sub"></div>
+                        <div class="ui-slider" data-topic="blur"
+                            data-min="0" data-max="200" data-step="1"> </div>
+                        <div class="ui-slider-btn-set" data-topic="blur" data-type="add"></div>
+                        <div class="ui-slider-input" data-topic="blur" data-unit="px"></div>
+                    </div>
+                    <div class="slidergroup">
+                        <div class="ui-slider-name"> Spread </div>
+                        <div class="ui-slider-btn-set" data-topic="spread" data-type="sub"></div>
+                        <div class="ui-slider" data-topic="spread"
+                            data-min="-100"    data-max="100" data-step="1" data-value="50">
+                        </div>
+                        <div class="ui-slider-btn-set" data-topic="spread" data-type="add"></div>
+                        <div class="ui-slider-input" data-topic="spread" data-unit="px"></div>
+                    </div>
+                </div>
+            </div>
+
+            <div id="element_properties" class="category">
+                <div class="title"> Параметры элемента</div>
+                <div class="group">
+                    <div class="group property">
+                        <div class="ui-slider-name"> border </div>
+                        <div class="ui-checkbox" data-topic='border-state' data-state="true"></div>
+                    </div>
+                    <div id="z-index" class="slidergroup">
+                        <div class="ui-slider-name"> z-index </div>
+                        <div class="ui-slider-btn-set" data-topic="z-index" data-type="sub"></div>
+                        <div class="ui-slider" data-topic="z-index"
+                            data-min="-10" data-max="10" data-step="1"></div>
+                        <div class="ui-slider-btn-set" data-topic="z-index" data-type="add"></div>
+                        <div class="ui-slider-input" data-topic="z-index"></div>
+                    </div>
+                    <div class="slidergroup">
+                        <div class="ui-slider-name"> top </div>
+                        <div class="ui-slider-btn-set" data-topic="top" data-type="sub"></div>
+                        <div class="ui-slider" data-topic="top"
+                            data-min="-500" data-max="500" data-step="1"> </div>
+                        <div class="ui-slider-btn-set" data-topic="top" data-type="add"></div>
+                        <div class="ui-slider-input" data-topic="top" data-unit="px"></div>
+                    </div>
+                    <div class="slidergroup">
+                        <div class="ui-slider-name"> left </div>
+                        <div class="ui-slider-btn-set" data-topic="left" data-type="sub"></div>
+                        <div class="ui-slider" data-topic="left"
+                            data-min="-300" data-max="700" data-step="1"> </div>
+                        <div class="ui-slider-btn-set" data-topic="left" data-type="add"></div>
+                        <div class="ui-slider-input" data-topic="left" data-unit="px"></div>
+                    </div>
+                    <div id="transform_rotate" class="slidergroup">
+                        <div class="ui-slider-name"> Rotate </div>
+                        <div class="ui-slider-btn-set" data-topic="rotate" data-type="sub"></div>
+                        <div class="ui-slider" data-topic="rotate"
+                            data-min="-360" data-max="360" data-step="1" data-value="0">
+                        </div>
+                        <div class="ui-slider-btn-set" data-topic="rotate" data-type="add"></div>
+                        <div class="ui-slider-input" data-topic="rotate" data-unit="deg"></div>
+                    </div>
+                    <div class="slidergroup">
+                        <div class="ui-slider-name"> Width </div>
+                        <div class="ui-slider-btn-set" data-topic="width" data-type="sub"></div>
+                        <div class="ui-slider" data-topic="width"
+                            data-min="0" data-max="1000" data-step="1" data-value="200">
+                        </div>
+                        <div class="ui-slider-btn-set" data-topic="width" data-type="add"></div>
+                        <div class="ui-slider-input" data-topic="width"  data-unit="px"></div>
+                    </div>
+                    <div class="slidergroup">
+                        <div class="ui-slider-name"> Height </div>
+                        <div class="ui-slider-btn-set" data-topic="height" data-type="sub"></div>
+                        <div class="ui-slider" data-topic="height"
+                            data-min="0" data-max="400" data-step="1" data-value="200">
+                        </div>
+                        <div class="ui-slider-btn-set" data-topic="height" data-type="add"></div>
+                        <div class="ui-slider-input" data-topic="height" data-unit="px"></div>
+                    </div>
+                </div>
+            </div>
+
+            <div id="output" class="category">
+                <div id="menu" class="menu"></div>
+                <div class="title">    CSS-код </div>
+                <div class="group" style="border-top-left-radius: 0;">
+                    <div class="output" data-topic="element" data-name="element"
+                        data-prop="width height background-color position=[relative] box-shadow">
+                    </div>
+                    <div class="output" data-topic="before" data-name="element:before"
+                        data-prop="content=[&quot;&quot;] position=[absolute] width height top left z-index background-color box-shadow transform -webkit-transform -ms-transform">
+                    </div>
+                    <div class="output" data-topic="after" data-name="element:after"
+                        data-prop="content=[&quot;&quot;] position=[absolute] width height top left z-index background-color box-shadow transform -webkit-transform -ms-transform">
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+
+ +

CSS Content

+ +
/*  GRID OF TWELVE
+ * ========================================================================== */
+
+.span_12 {
+	width: 100%;
+}
+
+.span_11 {
+	width: 91.46%;
+}
+
+.span_10 {
+	width: 83%;
+}
+
+.span_9 {
+	width: 74.54%;
+}
+
+.span_8 {
+	width: 66.08%;
+}
+
+.span_7 {
+	width: 57.62%;
+}
+
+.span_6 {
+	width: 49.16%;
+}
+
+.span_5 {
+	width: 40.7%;
+}
+
+.span_4 {
+	width: 32.24%;
+}
+
+.span_3 {
+	width: 23.78%;
+}
+
+.span_2 {
+	width: 15.32%;
+}
+
+.span_1 {
+	width: 6.86%;
+}
+
+
+/*  SECTIONS
+ * ========================================================================== */
+
+.section {
+	clear: both;
+	padding: 0px;
+	margin: 0px;
+}
+
+/*  GROUPING
+ * ========================================================================== */
+
+
+.group:before, .group:after {
+    content: "";
+    display: table;
+}
+
+.group:after {
+    clear:both;
+}
+
+.group {
+    zoom: 1; /* For IE 6/7 (trigger hasLayout) */
+}
+
+/*  GRID COLUMN SETUP
+ * ========================================================================== */
+
+.col {
+	display: block;
+	float:left;
+	margin: 1% 0 1% 1.6%;
+}
+
+.col:first-child {
+	margin-left: 0;
+} /* all browsers except IE6 and lower */
+
+/*
+ * UI Slider
+ */
+
+.slidergroup {
+	height: 20px;
+	margin: 10px 0;
+	font-family: "Segoe UI", Arial, Helvetica, sans-serif;
+	-moz-user-select: none;
+	user-select: none;
+}
+
+.slidergroup * {
+	float: left;
+	height: 100%;
+	line-height: 100%;
+}
+
+/* Slider */
+
+.ui-slider {
+	height: 10px;
+	width: 200px;
+	margin: 4px 10px;
+	display: block;
+	border: 1px solid #999;
+	border-radius: 3px;
+	background: #EEE;
+}
+
+.ui-slider:hover {
+	cursor: pointer;
+}
+
+.ui-slider-name {
+	width: 90px;
+	padding: 0 10px 0 0;
+	text-align: right;
+	text-transform: lowercase;
+}
+
+.ui-slider-pointer {
+	width: 13px;
+	height: 13px;
+	background-color: #EEE;
+	border: 1px solid #2C9FC9;
+	border-radius: 3px;
+	position: relative;
+	top: -3px;
+	left: 0%;
+}
+
+.ui-slider-btn-set {
+	width: 25px;
+	background-color: #2C9FC9;
+	border-radius: 3px;
+	color: #FFF;
+	font-weight: bold;
+	text-align: center;
+}
+
+.ui-slider-btn-set:hover {
+	background-color: #379B4A;
+	cursor: pointer;
+}
+
+.ui-slider-input > input {
+	margin: 0 10px;
+	padding: 0;
+	width: 50px;
+	text-align: center;
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+/*
+ * UI Button
+ */
+
+/* Checkbox */
+
+.ui-checkbox {
+	text-align: center;
+	font-size: 16px;
+	font-family: "Segoe UI", Arial, Helvetica, sans-serif;
+	line-height: 1.5em;
+	color: #FFF;
+
+	-moz-user-select: none;
+	-webkit-user-select: none;
+	-ms-user-select: none;
+	user-select: none;
+}
+
+.ui-checkbox > input {
+ 	display: none;
+}
+
+.ui-checkbox > label {
+	font-size: 12px;
+	padding: 0.333em 1.666em 0.5em;
+	height: 1em;
+	line-height: 1em;
+
+	background-color: #888;
+	background-image: url("https://mdn.mozillademos.org/files/5683/disabled.png");
+	background-position: center center;
+	background-repeat: no-repeat;
+
+	color: #FFF;
+	border-radius: 3px;
+	font-weight: bold;
+	float: left;
+}
+
+.ui-checkbox .text {
+	padding-left: 34px;
+	background-position: center left 10px;
+}
+
+.ui-checkbox .left {
+	padding-right: 34px;
+	padding-left: 1.666em;
+	background-position: center right 10px;
+}
+
+.ui-checkbox > label:hover {
+	cursor: pointer;
+}
+
+.ui-checkbox > input:checked + label {
+	background-image: url("https://mdn.mozillademos.org/files/5681/checked.png");
+	background-color: #379B4A;
+}
+
+/*
+ * BOX SHADOW GENERATOR TOOL
+ */
+
+body {
+	max-width: 1000px;
+	height: 800px;
+	margin: 20px auto 0;
+
+	font-family: "Segoe UI", Arial, Helvetica, sans-serif;
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+
+	-moz-user-select: none;
+	-webkit-user-select: none;
+	-ms-user-select: none;
+}
+
+#container {
+	width: 100%;
+	padding: 2px;
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+
+/* container with shadows stacks */
+#stack_container {
+	height: 400px;
+	overflow: hidden;
+	position: relative;
+	border: 1px solid #CCC;
+	border-radius: 3px;
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+#stack_container .container {
+	height: 100%;
+	width: 100%;
+	position: absolute;
+	left: 100%;
+	transition-property: left;
+	transition-duration: 0.5s;
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+
+#stack_container .title {
+	text-align: center;
+	font-weight: bold;
+	line-height: 2em;
+	border-bottom: 1px solid #43A6E1;
+	color: #666;
+}
+
+
+/*
+ * Stack of Layers for shadow
+ */
+
+#layer_manager {
+	width: 17%;
+	background-color: #FEFEFE;
+	margin: 0 1% 0 0;
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+	float: left;
+}
+
+
+#layer_manager .button {
+	width: 30%;
+	height: 25px;
+	margin:0 0 10px;
+	color: #333;
+	background-color: #EEE;
+	text-align: center;
+	font-size: 0.75em;
+	line-height: 1.5em;
+	border: 1px solid #CCC;
+	border-radius: 3px;
+
+	display: block;
+	background-position: center center;
+	background-repeat: no-repeat;
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+	float: left;
+}
+
+#layer_manager .button:hover {
+	background-color: #3380C4;
+	border: 1px solid #3380C4;
+	cursor: pointer;
+}
+
+#layer_manager [data-type='add'] {
+	background-image: url("https://mdn.mozillademos.org/files/5685/add-black.png");
+}
+
+#layer_manager [data-type='add']:hover {
+	background-image: url("https://mdn.mozillademos.org/files/5687/add-white.png");
+}
+
+#layer_manager [data-type='move-up'] {
+	background-image: url("https://mdn.mozillademos.org/files/5697/up-black.png");
+	margin-left: 5%;
+	margin-right: 5%;
+}
+
+#layer_manager [data-type='move-up']:hover {
+	background-image: url("https://mdn.mozillademos.org/files/5709/up-white.png");
+}
+
+#layer_manager [data-type='move-down'] {
+	background-image: url("https://mdn.mozillademos.org/files/5693/down-black.png");
+}
+
+#layer_manager [data-type='move-down']:hover {
+	background-image: url("https://mdn.mozillademos.org/files/5695/down-white.png");
+}
+
+/* shadows classes */
+
+#layer_manager .node {
+	width: 100%;
+	margin: 5px 0;
+	padding: 5px;
+	text-align: center;
+	background-color: #EEE;
+	border: 1px solid #DDD;
+	font-size: 0.75em;
+	line-height: 1.5em;
+	color: #333;
+	border-radius: 3px;
+
+	position: relative;
+	display: block;
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+#layer_manager .node:hover {
+	color: #FFF;
+	background-color: #3380C4;
+	cursor: pointer;
+}
+
+/* active element styling */
+
+#layer_manager [data-active='layer'] {
+	color: #FFF;
+	border: none;
+	background-color: #379B4A;
+}
+
+#layer_manager [data-active='subject'] {
+	color: #FFF;
+	background-color: #467FC9;
+}
+
+/* delete button */
+
+#layer_manager .delete {
+	width: 1.5em;
+	height: 100%;
+	float: right;
+	border-radius: 3px;
+	background-image: url("https://mdn.mozillademos.org/files/5689/delete-white.png");
+	background-position: center center;
+	background-repeat: no-repeat;
+	position: absolute;
+	top: 0;
+	right: 10px;
+	display: none;
+}
+
+#layer_manager .delete:hover {
+	background-image: url("https://mdn.mozillademos.org/files/5691/delete-yellow.png");
+}
+
+#layer_manager .node:hover .delete {
+	display: block;
+}
+
+
+#layer_manager .stack {
+	padding: 0 5px;
+	max-height: 90%;
+	overflow: auto;
+	overflow-x: hidden;
+}
+
+
+/*
+ * Layer Menu
+ */
+
+#layer_menu {
+	margin: 0 0 10px 0;
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+#layer_menu .button {
+	width: 100px;
+	margin: 0 5px 0 0;
+	padding: 2.5px;
+	color: #333;
+	background-color: #EEE;
+	border: 1px solid #CCC;
+	border-radius: 3px;
+	text-align: center;
+	font-size: 0.75em;
+	line-height: 1.5em;
+
+	position: relative;
+	display: block;
+	float: left;
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+#layer_menu .button:hover {
+	color: #FFF;
+	background-color: #3380C4;
+	border: 1px solid #3380C4;
+	cursor: pointer;
+}
+
+#layer_menu .delete {
+	width: 1.5em;
+	height: 100%;
+	float: right;
+	border-radius: 3px;
+	background-image: url("https://mdn.mozillademos.org/files/5689/delete-white.png");
+	background-position: center center;
+	background-repeat: no-repeat;
+	position: absolute;
+	top: 0;
+	right: 5px;
+	display: none;
+}
+
+#layer_menu .delete:hover {
+	background-image: url("https://mdn.mozillademos.org/files/5691/delete-yellow.png");
+}
+
+#layer_menu .button:hover .delete {
+	display: block;
+}
+
+
+/*
+ * active element styling
+ */
+
+#layer_menu [data-active='subject'] {
+	color: #FFF;
+	background-color: #379B4A;
+	border: 1px solid #379B4A;
+}
+
+
+/* Checkbox */
+
+#layer_menu .ui-checkbox > label {
+	height: 15px;
+	line-height: 17px;
+	font-weight: normal;
+	width: 46px;
+	margin: 0 5px 0 0;
+}
+
+#layer_menu .ui-checkbox > input:checked + label {
+	display: none;
+}
+
+
+/******************************************************************************/
+/******************************************************************************/
+/*
+ * Preview Area
+ */
+
+#preview_zone {
+	width: 82%;
+	float: left;
+
+}
+
+
+#preview {
+	width: 100%;
+	height: 400px;
+	border: 1px solid #CCC;
+	border-radius: 3px;
+	text-align: center;
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+	cursor: move;
+	float: left;
+}
+
+#preview .content {
+	width: 100%;
+	height: 100%;
+	display: block;
+}
+
+#obj-element {
+	width: 300px;
+	height: 100px;
+	border: 1px solid #CCC;
+	background: #FFF;
+	position: relative;
+}
+
+
+#obj-before {
+	height: 100%;
+	width: 100%;
+	background: #999;
+	border: 1px solid #CCC;
+	text-align: left;
+	display : block;
+	position: absolute;
+	z-index: -1;
+}
+
+#obj-after {
+	height: 100%;
+	width: 100%;
+	background: #DDD;
+	border: 1px solid #CCC;
+	text-align: right;
+	display : block;
+	position: absolute;
+	z-index: -1;
+}
+
+
+/******************************************************************************/
+/******************************************************************************/
+
+/**
+ * Controls
+ */
+
+.wrap-left {
+	float: left;
+	overflow: hidden;
+}
+
+.wrap-right {
+	float: right;
+	overflow: hidden;
+}
+
+.wrap-left > * {
+	float: left;
+}
+
+.wrap-right > * {
+	float: right;
+}
+
+@media (min-width: 960px) {
+
+	.wrap-left {
+		width: 45%;
+	}
+
+	.wrap-right {
+		width: 55%;
+	}
+}
+
+
+@media (max-width: 959px) {
+
+	.wrap-left {
+		width: 30%;
+	}
+
+	.wrap-right {
+		width: 70%;
+	}
+}
+
+
+#controls {
+	color: #444;
+	margin: 10px 0 0 0;
+}
+
+
+#controls .category {
+	width: 500px;
+	margin: 0 auto 20px;
+	padding: 0;
+
+}
+
+#controls .category .title {
+	width: 100%;
+	height: 1.5em;
+	line-height: 1.5em;
+	color: #AAA;
+	text-align: right;
+}
+
+#controls .category > .group {
+	border: 1px solid #CCC;
+	border-radius: 3px;
+}
+
+
+/**
+ * 	Color Picker
+ */
+
+@media (min-width: 960px) {
+	#controls .colorpicker {
+		width: 420px;
+	}
+}
+
+@media (max-width: 959px) {
+	#controls .colorpicker {
+		width: 210px;
+	}
+}
+
+#colorpicker {
+	width: 100%;
+	margin: 0 auto;
+}
+
+#colorpicker .gradient {
+	width: 200px;
+	height: 200px;
+	margin: 5px;
+	background: url("https://mdn.mozillademos.org/files/5707/picker_mask_200.png");
+	background: -moz-linear-gradient(bottom, #000 0%, rgba(0, 0, 0, 0) 100%),
+				-moz-linear-gradient(left, #FFF 0%, rgba(255, 255, 255, 0) 100%);
+	background: -webkit-linear-gradient(bottom, #000 0%, rgba(0, 0, 0, 0) 100%),
+				-webkit-linear-gradient(left, #FFF 0%, rgba(255, 255, 255, 0) 100%);
+	background-color: #F00;
+	float: left;
+}
+
+#colorpicker .hue {
+	width: 200px;
+	height: 30px;
+	margin: 5px;
+	background: url("https://mdn.mozillademos.org/files/5701/hue.png");
+	background: -moz-linear-gradient(left, #F00 0%, #FF0 16.66%, #0F0 33.33%, #0FF 50%,
+				#00F 66.66%, #F0F 83.33%, #F00 100%);
+	background: -webkit-linear-gradient(left, #F00 0%, #FF0 16.66%, #0F0 33.33%, #0FF 50%,
+				#00F 66.66%, #F0F 83.33%, #F00 100%);
+	float: left;
+}
+
+#colorpicker .alpha {
+	width: 200px;
+	height: 30px;
+	margin: 5px;
+	border: 1px solid #CCC;
+	float: left;
+	background: url("https://mdn.mozillademos.org/files/5705/alpha.png");
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+#colorpicker #alpha {
+	width: 100%;
+	height: 100%;
+	background: url("https://mdn.mozillademos.org/files/5703/alpha_mask.png");
+	background: -moz-linear-gradient(left, rgba(255, 0, 0, 0) 0%, rgba(255, 0, 0, 1) 100%);
+}
+
+#colorpicker #gradient_picker {
+	width: 0.5em;
+	height: 0.5em;
+	border-radius: 0.4em;
+	border: 2px solid #CCC;
+	position: relative;
+	top: 20%;
+	left: 20%;
+}
+
+#colorpicker #hue_selector,
+#colorpicker #alpha_selector {
+	width: 3px;
+	height: 100%;
+	border: 1px solid #777;
+	background-color: #FFF;
+	position: relative;
+	top: -1px;
+	left: 0%;
+}
+
+/* input HSV and RGB */
+#colorpicker .info {
+	width: 200px;
+	margin: 5px;
+	float: left;
+}
+
+#colorpicker .info * {
+	float: left;
+}
+
+#colorpicker .info input {
+	margin: 0;
+	text-align: center;
+	width: 30px;
+	-moz-user-select: text;
+	-webkit-user-select: text;
+	-ms-user-select: text;
+}
+
+#colorpicker .info span {
+	height: 20px;
+	width: 30px;
+	text-align: center;
+	line-height: 20px;
+	display: block;
+}
+
+/* Preview color */
+#colorpicker .block {
+	width: 95px;
+	height: 54px;
+	float: left;
+	position: relative;
+}
+
+#colorpicker .preview {
+	margin: 5px;
+	border: 1px solid #CCC;
+	background-image: url("https://mdn.mozillademos.org/files/5705/alpha.png");
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+#colorpicker .preview:before {
+	height: 100%;
+	width: 50%;
+	left: 50%;
+	content: "";
+	background: #FFF;
+	position: absolute;
+	z-index: 1;
+}
+
+#colorpicker .preview > * {
+	width: 50%;
+	height: 100%;
+}
+
+#colorpicker #output_color {
+	width: 100%;
+	height: 100%;
+	position: absolute;
+	z-index: 2;
+}
+
+#colorpicker .block .input {
+	float: right;
+}
+
+#colorpicker [data-topic="a"] > span {
+	width: 50px;
+}
+
+#colorpicker [data-topic="hexa"] {
+	float: right;
+	margin: 10px 0 0 0;
+}
+
+#colorpicker [data-topic="hexa"] > span {
+	display: none;
+}
+
+#colorpicker [data-topic="hexa"] > input {
+	width: 85px;
+	padding: 2px 0;
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+
+/*
+ * UI Components
+ */
+
+/* Property */
+
+.property {
+	height: 20px;
+	margin: 10px 0;
+}
+
+.property * {
+	float: left;
+	height: 100%;
+	line-height: 100%;
+}
+
+/* Slider */
+
+#controls .ui-slider-name {
+	margin: 0 10px 0 0;
+}
+
+/*
+ * Output code styling
+ */
+
+#output {
+	position: relative;
+}
+
+#output .menu {
+	max-width: 70%;
+	height: 20px;
+	position: absolute;
+	top: 2px;
+}
+
+#output .button {
+	width: 90px;
+	height: 22px;
+	margin: 0 5px 0 0;
+	text-align: center;
+	line-height: 20px;
+	font-size: 14px;
+	color: #FFF;
+	background-color: #999;
+	border-top-left-radius: 3px;
+	border-top-right-radius: 3px;
+	bottom: -5px;
+	float:left;
+}
+
+#output .button:hover {
+	color: #FFF;
+	background-color: #666;
+	cursor: pointer;
+}
+
+#output .menu [data-active="true"] {
+	color: #777;
+	background-color: #FFF;
+	border: 1px solid #CCC;
+	border-bottom: none;
+}
+
+#output .menu [data-topic="before"] {
+	left: 100px;
+}
+
+#output .menu [data-topic="after"] {
+	left: 200px;
+}
+
+#output .output {
+	width: 480px;
+	margin: 10px;
+	padding: 10px;
+	overflow: hidden;
+	color: #555;
+	font-size: 14px;
+	border: 1px dashed #CCC;
+	border-radius: 3px;
+	display: none;
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+
+	-moz-user-select: text;
+	-webkit-user-select: text;
+	-ms-user-select: text;
+}
+
+#output .css-property {
+	width: 100%;
+	float: left;
+	white-space: pre;
+}
+
+#output .name {
+	width: 35%;
+	float: left;
+}
+
+#output .value {
+	width: 65%;
+	float: left;
+}
+
+
+ +

JavaScript Content

+ +

+
+'use strict';
+
+/**
+ * UI-SlidersManager
+ */
+
+var SliderManager = (function SliderManager() {
+
+	var subscribers = {};
+	var sliders = [];
+
+	var Slider = function(node) {
+		var min = node.getAttribute('data-min') | 0;
+		var max = node.getAttribute('data-max') | 0;
+		var step = node.getAttribute('data-step') | 0;
+		var value = node.getAttribute('data-value') | 0;
+		var snap = node.getAttribute('data-snap');
+		var topic = node.getAttribute('data-topic');
+
+		this.min = min;
+		this.max = max > 0 ? max : 100;
+		this.step = step === 0 ? 1 : step;
+		this.value = value <= max && value >= min ? value : (min + max) / 2 | 0;
+		this.snap = snap === "true" ? true : false;
+		this.topic = topic;
+		this.node = node;
+
+		var pointer = document.createElement('div');
+		pointer.className = 'ui-slider-pointer';
+		node.appendChild(pointer);
+		this.pointer = pointer;
+
+		setMouseTracking(node, updateSlider.bind(this));
+
+		sliders[topic] = this;
+		setValue(topic, this.value);
+	}
+
+	var setButtonComponent = function setButtonComponent(node) {
+		var type = node.getAttribute('data-type');
+		var topic = node.getAttribute('data-topic');
+		if (type === "sub") {
+			node.textContent = '-';
+			node.addEventListener("click", function() {
+				decrement(topic);
+			});
+		}
+		if (type === "add") {
+			node.textContent = '+';
+			node.addEventListener("click", function() {
+				increment(topic);
+			});
+		}
+	}
+
+	var setInputComponent = function setInputComponent(node) {
+		var topic		= node.getAttribute('data-topic');
+		var unit_type	= node.getAttribute('data-unit');
+
+		var input = document.createElement('input');
+		var unit = document.createElement('span');
+		unit.textContent = unit_type;
+
+		input.setAttribute('type', 'text');
+		node.appendChild(input);
+		node.appendChild(unit);
+
+		input.addEventListener('click', function(e) {
+			this.select();
+		});
+
+		input.addEventListener('change', function(e) {
+			setValue(topic, e.target.value | 0);
+		});
+
+		subscribe(topic, function(value) {
+			node.children[0].value = value;
+		});
+	}
+
+	var increment = function increment(topic) {
+		var slider = sliders[topic];
+		if (slider === null || slider === undefined)
+			return;
+
+		if (slider.value + slider.step <= slider.max) {
+			slider.value += slider.step;
+			setValue(slider.topic, slider.value)
+			notify.call(slider);
+		}
+	};
+
+	var decrement = function decrement(topic) {
+		var slider = sliders[topic];
+		if (slider === null || slider === undefined)
+			return;
+
+		if (slider.value - slider.step >= slider.min) {
+			slider.value -= slider.step;
+			setValue(topic, slider.value)
+			notify.call(slider);
+		}
+	}
+
+	// this = Slider object
+	var updateSlider = function updateSlider(e) {
+		var node = this.node;
+		var pos = e.pageX - node.offsetLeft;
+		var width = node.clientWidth;
+		var delta = this.max - this.min;
+		var offset = this.pointer.clientWidth + 4; // border width * 2
+
+		if (pos < 0) pos = 0;
+		if (pos > width) pos = width;
+
+		var value = pos * delta / width | 0;
+		var precision = value % this.step;
+		value = value - precision + this.min;
+		if (precision > this.step / 2)
+			value = value + this.step;
+
+		if (this.snap)
+			pos =  (value - this.min) * width / delta;
+
+		this.pointer.style.left = pos - offset/2 + "px";
+		this.value = value;
+		node.setAttribute('data-value', value);
+		notify.call(this);
+	}
+
+	var setValue = function setValue(topic, value) {
+		var slider = sliders[topic];
+
+		if (value > slider.max || value < slider.min)
+			return;
+
+		var delta = slider.max - slider.min;
+		var width = slider.node.clientWidth;
+		var offset = slider.pointer.clientWidth;
+		var pos =  (value - slider.min) * width / delta;
+		slider.value = value;
+		slider.pointer.style.left = pos - offset / 2 + "px";
+		slider.node.setAttribute('data-value', value);
+		notify.call(slider);
+	}
+
+	var setMouseTracking = function setMouseTracking(elem, callback) {
+		elem.addEventListener("mousedown", function(e) {
+			callback(e);
+			document.addEventListener("mousemove", callback);
+		});
+
+		document.addEventListener("mouseup", function(e) {
+			document.removeEventListener("mousemove", callback);
+		});
+	}
+
+	var subscribe = function subscribe(topic, callback) {
+		if (subscribers[topic] === undefined)
+			subscribers[topic] = [];
+		subscribers[topic].push(callback);
+	}
+
+	var unsubscribe = function unsubscribe(topic, callback) {
+		subscribers[topic].indexOf(callback);
+		subscribers[topic].splice(index, 1);
+	}
+
+	var notify = function notify() {
+		if (subscribers[this.topic] === undefined)
+			return;
+
+		for (var i in subscribers[this.topic]) {
+			subscribers[this.topic][i](this.value);
+		}
+	}
+
+	var init = function init() {
+		var elem, size;
+
+		elem = document.querySelectorAll('.ui-slider-btn-set');
+		size = elem.length;
+		for (var i = 0; i < size; i++)
+			setButtonComponent(elem[i]);
+
+		elem = document.querySelectorAll('.ui-slider-input');
+		size = elem.length;
+		for (var i = 0; i < size; i++)
+			setInputComponent(elem[i]);
+
+		elem = document.querySelectorAll('.ui-slider');
+		size = elem.length;
+		for (var i = 0; i < size; i++)
+			new Slider(elem[i]);
+	}
+
+	return {
+		init : init,
+		setValue : setValue,
+		subscribe : subscribe,
+		unsubscribe : unsubscribe
+	}
+
+})();
+
+/**
+ * UI-ButtonManager
+ */
+
+var ButtonManager = (function CheckBoxManager() {
+
+	var subscribers = [];
+	var buttons = [];
+
+	var CheckBox = function CheckBox(node) {
+		var topic = node.getAttribute('data-topic');
+		var state = node.getAttribute('data-state');
+		var name = node.getAttribute('data-label');
+		var align = node.getAttribute('data-text-on');
+
+		state = (state === "true");
+
+		var checkbox = document.createElement("input");
+		var label = document.createElement("label");
+
+		var id = 'checkbox-' + topic;
+		checkbox.id = id;
+		checkbox.setAttribute('type', 'checkbox');
+		checkbox.checked = state;
+
+		label.setAttribute('for', id);
+		if (name) {
+			label.className = 'text';
+			if (align)
+				label.className += ' ' + align;
+			label.textContent = name;
+		}
+
+		node.appendChild(checkbox);
+		node.appendChild(label);
+
+		this.node = node;
+		this.topic = topic;
+		this.checkbox = checkbox;
+
+		checkbox.addEventListener('change', function(e) {
+			notify.call(this);
+		}.bind(this));
+
+		buttons[topic] = this;
+	}
+
+	var getNode =  function getNode(topic) {
+		return buttons[topic].node;
+	}
+
+	var setValue = function setValue(topic, value) {
+		try {
+			buttons[topic].checkbox.checked = value;
+			notify.call(buttons[topic]);
+		}
+		catch(error) {
+			console.log(error, topic, value);
+		}
+	}
+
+	var subscribe = function subscribe(topic, callback) {
+		if (subscribers[topic] === undefined)
+			subscribers[topic] = [];
+
+		subscribers[topic].push(callback);
+	}
+
+	var unsubscribe = function unsubscribe(topic, callback) {
+		subscribers[topic].indexOf(callback);
+		subscribers[topic].splice(index, 1);
+	}
+
+	var notify = function notify() {
+		if (subscribers[this.topic] === undefined)
+			return;
+		for (var i = 0; i < subscribers[this.topic].length; i++)
+			subscribers[this.topic][i](this.checkbox.checked);
+	}
+
+	var init = function init() {
+		var elem = document.querySelectorAll('.ui-checkbox');
+		var size = elem.length;
+		for (var i = 0; i < size; i++)
+			new CheckBox(elem[i]);
+	}
+
+	return {
+		init : init,
+		setValue : setValue,
+		subscribe : subscribe,
+		unsubscribe : unsubscribe
+	}
+
+})();
+
+
+window.addEventListener("load", function(){
+	BoxShadow.init();
+});
+
+var BoxShadow = (function BoxShadow() {
+
+	function getElemById(id) {
+		return document.getElementById(id);
+	}
+
+	/**
+	 * RGBA Color class
+	 */
+
+	function Color() {
+		this.r = 0;
+		this.g = 0;
+		this.b = 0;
+		this.a = 1;
+		this.hue = 0;
+		this.saturation = 0;
+		this.value = 0;
+	}
+
+	Color.prototype.copy = function copy(obj) {
+		if(obj instanceof Color !== true) {
+			console.log("Typeof instance not Color");
+			return;
+		}
+
+		this.r = obj.r;
+		this.g = obj.g;
+		this.b = obj.b;
+		this.a = obj.a;
+		this.hue = obj.hue;
+		this.saturation = obj.saturation;
+		this.value = obj.value;
+	}
+
+	Color.prototype.setRGBA = function setRGBA(red, green, blue, alpha) {
+		if (red != undefined)
+			this.r = red | 0;
+		if (green != undefined)
+			this.g = green | 0;
+		if (blue != undefined)
+			this.b = blue | 0;
+		if (alpha != undefined)
+			this.a = alpha | 0;
+	}
+
+	/**
+	 * HSV/HSB (hue, saturation, value / brightness)
+	 * @param hue			0-360
+	 * @param saturation	0-100
+	 * @param value 		0-100
+	 */
+	Color.prototype.setHSV = function setHSV(hue, saturation, value) {
+		this.hue = hue;
+		this.saturation = saturation;
+		this.value = value;
+		this.updateRGB();
+	}
+
+	Color.prototype.updateRGB = function updateRGB() {
+		var sat = this.saturation / 100;
+		var value = this.value / 100;
+		var C = sat * value;
+		var H = this.hue / 60;
+		var X = C * (1 - Math.abs(H % 2 - 1));
+		var m = value - C;
+		var precision = 255;
+
+		C = (C + m) * precision;
+		X = (X + m) * precision;
+		m = m * precision;
+
+		if (H >= 0 && H < 1) {	this.setRGBA(C, X, m);	return; }
+		if (H >= 1 && H < 2) {	this.setRGBA(X, C, m);	return; }
+		if (H >= 2 && H < 3) {	this.setRGBA(m, C, X);	return; }
+		if (H >= 3 && H < 4) {	this.setRGBA(m, X, C);	return; }
+		if (H >= 4 && H < 5) {	this.setRGBA(X, m, C);	return; }
+		if (H >= 5 && H < 6) {	this.setRGBA(C, m, X);	return; }
+	}
+
+	Color.prototype.updateHSV = function updateHSV() {
+		var red		= this.r / 255;
+		var green	= this.g / 255;
+		var blue	= this.b / 255;
+
+		var cmax = Math.max(red, green, blue);
+		var cmin = Math.min(red, green, blue);
+		var delta = cmax - cmin;
+		var hue = 0;
+		var saturation = 0;
+
+		if (delta) {
+			if (cmax === red ) { hue = ((green - blue) / delta); }
+			if (cmax === green ) { hue = 2 + (blue - red) / delta; }
+			if (cmax === blue ) { hue = 4 + (red - green) / delta; }
+			if (cmax) saturation = delta / cmax;
+		}
+
+		this.hue = 60 * hue | 0;
+		if (this.hue < 0) this.hue += 360;
+		this.saturation = (saturation * 100) | 0;
+		this.value = (cmax * 100) | 0;
+	}
+
+	Color.prototype.setHexa = function setHexa(value) {
+		var valid  = /(^#{0,1}[0-9A-F]{6}$)|(^#{0,1}[0-9A-F]{3}$)/i.test(value)
+		if (valid !== true)
+			return;
+
+		if (value[0] === '#')
+			value = value.slice(1, value.length);
+
+		if (value.length === 3)
+			value = value.replace(/([0-9A-F])([0-9A-F])([0-9A-F])/i,"$1$1$2$2$3$3");
+
+		this.r = parseInt(value.substr(0, 2), 16);
+		this.g = parseInt(value.substr(2, 2), 16);
+		this.b = parseInt(value.substr(4, 2), 16);
+
+		this.alpha	= 1;
+	}
+
+	Color.prototype.getHexa = function getHexa() {
+		var r = this.r.toString(16);
+		var g = this.g.toString(16);
+		var b = this.b.toString(16);
+		if (this.r < 16) r = '0' + r;
+		if (this.g < 16) g = '0' + g;
+		if (this.b < 16) b = '0' + b;
+		var value = '#' + r + g + b;
+		return value.toUpperCase();
+	}
+
+	Color.prototype.getRGBA = function getRGBA() {
+
+		var rgb = "(" + this.r + ", " + this.g + ", " + this.b;
+		var a = '';
+		var v = '';
+		if (this.a !== 1) {
+			a = 'a';
+			v = ', ' + this.a;
+		}
+
+		var value = "rgb" + a + rgb + v + ")";
+		return value;
+	}
+
+	Color.prototype.getColor = function getColor() {
+		if (this.a | 0 === 1)
+			return this.getHexa();
+		return this.getRGBA();
+	}
+
+	/**
+	 * Shadow Object
+	 */
+	function Shadow() {
+		this.inset  = false;
+		this.posX   = 5;
+		this.posY   = -5;
+		this.blur   = 5;
+		this.spread = 0;
+		this.color  = new Color();
+
+		var hue			= (Math.random() * 360) | 0;
+		var saturation	= (Math.random() * 75) | 0;
+		var value 		= (Math.random() * 50 + 50) | 0;
+		this.color.setHSV(hue, saturation, value, 1);
+	}
+
+	Shadow.prototype.computeCSS = function computeCSS() {
+		var value = "";
+		if (this.inset === true)
+			value += "inset ";
+		value += this.posX + "px ";
+		value += this.posY + "px ";
+		value += this.blur + "px ";
+		value += this.spread + "px ";
+		value += this.color.getColor();
+
+		return value;
+	}
+
+	Shadow.prototype.toggleInset = function toggleInset(value) {
+		if (value !== undefined || typeof value === "boolean")
+			this.inset = value;
+		else
+			this.inset = this.inset === true ? false : true;
+	}
+
+	Shadow.prototype.copy = function copy(obj) {
+		if(obj instanceof Shadow !== true) {
+			console.log("Typeof instance not Shadow");
+			return;
+		}
+
+		this.inset  = obj.inset;
+		this.posX   = obj.posX;
+		this.posY   = obj.posY;
+		this.blur   = obj.blur;
+		this.spread = obj.spread;
+		this.color.copy(obj.color);
+	}
+
+	/**
+	 * Color Picker
+	 */
+	var ColoPicker = (function ColoPicker() {
+
+		var colorpicker;
+		var hue_area;
+		var gradient_area;
+		var alpha_area;
+		var gradient_picker;
+		var hue_selector;
+		var alpha_selector;
+		var pick_object;
+		var info_rgb;
+		var info_hsv;
+		var info_hexa;
+		var output_color;
+		var color = new Color();
+		var subscribers = [];
+
+		var updateColor = function updateColor(e) {
+			var x = e.pageX - gradient_area.offsetLeft;
+			var y = e.pageY - gradient_area.offsetTop;
+
+			// width and height should be the same
+			var size = gradient_area.clientWidth;
+
+			if (x > size)
+				x = size;
+			if (y > size)
+				y = size;
+
+			if (x < 0) x = 0;
+			if (y < 0) y = 0;
+
+			var value = 100 - (y * 100 / size) | 0;
+			var saturation = x * 100 / size | 0;
+
+			color.setHSV(color.hue, saturation, value);
+			// should update just
+			// color pointer location
+			updateUI();
+			notify("color", color);
+		}
+
+		var updateHue = function updateHue(e) {
+			var x = e.pageX - hue_area.offsetLeft;
+			var width = hue_area.clientWidth;
+
+			if (x < 0) x = 0;
+			if (x > width) x = width;
+
+			var hue = ((360 * x) / width) | 0;
+			if (hue === 360) hue = 359;
+
+			color.setHSV(hue, color.saturation, color.value);
+
+			// should update just
+			// hue pointer location
+			// picker area background
+			// alpha area background
+			updateUI();
+			notify("color", color);
+		}
+
+		var updateAlpha = function updateAlpha(e) {
+			var x = e.pageX - alpha_area.offsetLeft;
+			var width = alpha_area.clientWidth;
+
+			if (x < 0) x = 0;
+			if (x > width) x = width;
+
+			color.a = (x / width).toFixed(2);
+
+			// should update just
+			// alpha pointer location
+			updateUI();
+			notify("color", color);
+		}
+
+		var setHueGfx = function setHueGfx(hue) {
+			var sat = color.saturation;
+			var val = color.value;
+			var alpha = color.a;
+
+			color.setHSV(hue, 100, 100);
+			gradient_area.style.backgroundColor = color.getHexa();
+
+			color.a = 0;
+			var start = color.getRGBA();
+			color.a = 1;
+			var end = color.getRGBA();
+			color.a = alpha;
+
+			var gradient = '-moz-linear-gradient(left, ' +	start + '0%, ' + end + ' 100%)';
+			alpha_area.style.background = gradient;
+		}
+
+		var updateUI = function updateUI() {
+			var x, y;		// coordinates
+			var size;		// size of the area
+			var offset;		// pointer graphic selector offset
+
+			// Set color pointer location
+			size = gradient_area.clientWidth;
+			offset = gradient_picker.clientWidth / 2 + 2;
+
+			x = (color.saturation * size / 100) | 0;
+			y = size - (color.value * size / 100) | 0;
+
+			gradient_picker.style.left = x - offset + "px";
+			gradient_picker.style.top = y - offset + "px";
+
+			// Set hue pointer location
+			size = hue_area.clientWidth;
+			offset = hue_selector.clientWidth/2;
+			x = (color.hue * size / 360 ) | 0;
+			hue_selector.style.left = x - offset + "px";
+
+			// Set alpha pointer location
+			size = alpha_area.clientWidth;
+			offset = alpha_selector.clientWidth/2;
+			x = (color.a * size) | 0;
+			alpha_selector.style.left = x - offset + "px";
+
+			// Set picker area background
+			var nc = new Color();
+			nc.copy(color);
+			if (nc.hue === 360) nc.hue = 0;
+			nc.setHSV(nc.hue, 100, 100);
+			gradient_area.style.backgroundColor = nc.getHexa();
+
+			// Set alpha area background
+			nc.copy(color);
+			nc.a = 0;
+			var start = nc.getRGBA();
+			nc.a = 1;
+			var end = nc.getRGBA();
+			var gradient = '-moz-linear-gradient(left, ' +	start + '0%, ' + end + ' 100%)';
+			alpha_area.style.background = gradient;
+
+			// Update color info
+			notify("color", color);
+			notify("hue", color.hue);
+			notify("saturation", color.saturation);
+			notify("value", color.value);
+			notify("r", color.r);
+			notify("g", color.g);
+			notify("b", color.b);
+			notify("a", color.a);
+			notify("hexa", color.getHexa());
+			output_color.style.backgroundColor = color.getRGBA();
+		}
+
+		var setInputComponent = function setInputComponent(node) {
+			var topic = node.getAttribute('data-topic');
+			var title = node.getAttribute('data-title');
+			var action = node.getAttribute('data-action');
+			title = title === null ? '' : title;
+
+			var input = document.createElement('input');
+			var info = document.createElement('span');
+			info.textContent = title;
+
+			input.setAttribute('type', 'text');
+			input.setAttribute('data-action', 'set-' + action + '-' + topic);
+			node.appendChild(info);
+			node.appendChild(input);
+
+			input.addEventListener('click', function(e) {
+				this.select();
+			});
+
+			input.addEventListener('change', function(e) {
+				if (action === 'HSV')
+					inputChangeHSV(topic);
+				if (action === 'RGB')
+					inputChangeRGB(topic);
+				if (action === 'alpha')
+					inputChangeAlpha(topic);
+				if (action === 'hexa')
+					inputChangeHexa(topic);
+			});
+
+			subscribe(topic, function(value) {
+				node.children[1].value = value;
+			});
+		}
+
+		var inputChangeHSV = function actionHSV(topic) {
+			var selector = "[data-action='set-HSV-" + topic + "']";
+			var node = document.querySelector("#colorpicker " + selector);
+			var value = parseInt(node.value);
+
+			if (typeof value === 'number' && isNaN(value) === false &&
+				value >= 0 && value < 360)
+				color[topic] = value;
+
+			color.updateRGB();
+			updateUI();
+		}
+
+		var inputChangeRGB = function inputChangeRGB(topic) {
+			var selector = "[data-action='set-RGB-" + topic + "']";
+			var node = document.querySelector("#colorpicker " + selector);
+			var value = parseInt(node.value);
+
+			if (typeof value === 'number' && isNaN(value) === false &&
+				value >= 0 && value <= 255)
+				color[topic] = value;
+
+			color.updateHSV();
+			updateUI();
+		}
+
+		var inputChangeAlpha = function inputChangeAlpha(topic) {
+			var selector = "[data-action='set-alpha-" + topic + "']";
+			var node = document.querySelector("#colorpicker " + selector);
+			var value = parseFloat(node.value);
+
+			if (typeof value === 'number' && isNaN(value) === false &&
+				value >= 0 && value <= 1)
+				color.a = value.toFixed(2);
+
+			updateUI();
+		}
+
+		var inputChangeHexa = function inputChangeHexa(topic) {
+			var selector = "[data-action='set-hexa-" + topic + "']";
+			var node = document.querySelector("#colorpicker " + selector);
+			var value = node.value;
+			color.setHexa(value);
+			color.updateHSV();
+			updateUI();
+		}
+
+		var setMouseTracking = function setMouseTracking(elem, callback) {
+
+			elem.addEventListener("mousedown", function(e) {
+				callback(e);
+				document.addEventListener("mousemove", callback);
+			});
+
+			document.addEventListener("mouseup", function(e) {
+				document.removeEventListener("mousemove", callback);
+			});
+		}
+
+		/*
+		 * Observer
+		 */
+		var setColor = function setColor(obj) {
+			if(obj instanceof Color !== true) {
+				console.log("Typeof instance not Color");
+				return;
+			}
+			color.copy(obj);
+			updateUI();
+		}
+
+		var subscribe = function subscribe(topic, callback) {
+			if (subscribers[topic] === undefined)
+				subscribers[topic] = [];
+
+			subscribers[topic].push(callback);
+		}
+
+		var unsubscribe = function unsubscribe(callback) {
+			subscribers.indexOf(callback);
+			subscribers.splice(index, 1);
+		}
+
+		var notify = function notify(topic, value) {
+			for (var i in subscribers[topic])
+				subscribers[topic][i](value);
+		}
+
+		var init = function init() {
+			colorpicker		= getElemById("colorpicker");
+			hue_area		= getElemById("hue");
+			gradient_area	= getElemById("gradient");
+			alpha_area		= getElemById("alpha");
+			gradient_picker	= getElemById("gradient_picker");
+			hue_selector	= getElemById("hue_selector");
+			alpha_selector	= getElemById("alpha_selector");
+			output_color	= getElemById("output_color");
+
+			var elem = document.querySelectorAll('#colorpicker .input');
+			var size = elem.length;
+			for (var i = 0; i < size; i++)
+				setInputComponent(elem[i]);
+
+			setMouseTracking(gradient_area, updateColor);
+			setMouseTracking(hue_area, updateHue);
+			setMouseTracking(alpha_area, updateAlpha);
+
+		}
+
+		return {
+			init : init,
+			setColor : setColor,
+			subscribe : subscribe,
+			unsubscribe : unsubscribe
+		}
+
+	})();
+
+	/**
+	 * Shadow dragging
+	 */
+	var PreviewMouseTracking = (function Drag() {
+		var active = false;
+		var lastX = 0;
+		var lastY = 0;
+		var subscribers = [];
+
+		var init = function init(id) {
+			var elem = getElemById(id);
+			elem.addEventListener('mousedown', dragStart, false);
+			document.addEventListener('mouseup', dragEnd, false);
+		}
+
+		var dragStart = function dragStart(e) {
+			if (e.button !== 0)
+				return;
+
+			active = true;
+			lastX = e.clientX;
+			lastY = e.clientY;
+			document.addEventListener('mousemove', mouseDrag, false);
+		}
+
+		var dragEnd = function dragEnd(e) {
+			if (e.button !== 0)
+				return;
+
+			if (active === true) {
+				active = false;
+				document.removeEventListener('mousemove', mouseDrag, false);
+			}
+		}
+
+		var mouseDrag = function mouseDrag(e) {
+			notify(e.clientX - lastX, e.clientY - lastY);
+			lastX = e.clientX;
+			lastY = e.clientY;
+		}
+
+		var subscribe = function subscribe(callback) {
+			subscribers.push(callback);
+		}
+
+		var unsubscribe = function unsubscribe(callback) {
+			var index = subscribers.indexOf(callback);
+			subscribers.splice(index, 1);
+		}
+
+		var notify = function notify(deltaX, deltaY) {
+			for (var i in subscribers)
+				subscribers[i](deltaX, deltaY);
+		}
+
+		return {
+			init : init,
+			subscribe : subscribe,
+			unsubscribe : unsubscribe
+		}
+
+	})();
+
+	/*
+	 * Element Class
+	 */
+	var CssClass = function CssClass(id) {
+		this.left = 0;
+		this.top = 0;
+		this.rotate = 0;
+		this.width = 300;
+		this.height = 100;
+		this.display = true;
+		this.border = true;
+		this.zIndex = -1;
+		this.bgcolor = new Color();
+		this.id = id;
+		this.node = getElemById('obj-' + id);
+		this.object = getElemById(id);
+		this.shadowID = null;
+		this.shadows = []
+		this.render = [];
+		this.init();
+	}
+
+	CssClass.prototype.init = function init() {
+		this.left = ((this.node.parentNode.clientWidth - this.node.clientWidth) / 2) | 0;
+		this.top = ((this.node.parentNode.clientHeight - this.node.clientHeight) / 2) | 0;
+
+		this.setTop(this.top);
+		this.setLeft(this.left);
+		this.setHeight(this.height);
+		this.setWidth(this.width);
+		this.bgcolor.setHSV(0, 0, 100);
+		this.updateBgColor(this.bgcolor);
+	}
+
+	CssClass.prototype.updatePos = function updatePos(deltaX, deltaY) {
+		this.left += deltaX;
+		this.top += deltaY;
+		this.node.style.top = this.top + "px";
+		this.node.style.left = this.left + "px";
+		SliderManager.setValue("left", this.left);
+		SliderManager.setValue("top", this.top);
+	}
+
+	CssClass.prototype.setLeft = function setLeft(value) {
+		this.left = value;
+		this.node.style.left = this.left + "px";
+		OutputManager.updateProperty(this.id, 'left', this.left + 'px');
+	}
+
+	CssClass.prototype.setTop = function setTop(value) {
+		this.top = value;
+		this.node.style.top = this.top + 'px';
+		OutputManager.updateProperty(this.id, 'top', this.top + 'px');
+	}
+
+	CssClass.prototype.setWidth = function setWidth(value) {
+		this.width = value;
+		this.node.style.width = this.width + 'px';
+		OutputManager.updateProperty(this.id, 'width', this.width + 'px');
+	}
+
+	CssClass.prototype.setHeight = function setHeight(value) {
+		this.height = value;
+		this.node.style.height = this.height + 'px';
+		OutputManager.updateProperty(this.id, 'height', this.height + 'px');
+	}
+
+	// Browser support
+	CssClass.prototype.setRotate = function setRotate(value) {
+		var cssvalue = 'rotate(' + value +'deg)';
+
+		this.node.style.transform = cssvalue;
+		this.node.style.webkitTransform = cssvalue;
+		this.node.style.msTransform = cssvalue;
+
+		if (value !== 0) {
+			if (this.rotate === 0) {
+				OutputManager.toggleProperty(this.id, 'transform', true);
+				OutputManager.toggleProperty(this.id, '-webkit-transform', true);
+				OutputManager.toggleProperty(this.id, '-ms-transform', true);
+			}
+		}
+		else {
+			OutputManager.toggleProperty(this.id, 'transform', false);
+			OutputManager.toggleProperty(this.id, '-webkit-transform', false);
+			OutputManager.toggleProperty(this.id, '-ms-transform', false);
+		}
+
+		OutputManager.updateProperty(this.id, 'transform', cssvalue);
+		OutputManager.updateProperty(this.id, '-webkit-transform', cssvalue);
+		OutputManager.updateProperty(this.id, '-ms-transform', cssvalue);
+		this.rotate = value;
+	}
+
+	CssClass.prototype.setzIndex = function setzIndex(value) {
+		this.node.style.zIndex = value;
+		OutputManager.updateProperty(this.id, 'z-index', value);
+		this.zIndex = value;
+	}
+
+	CssClass.prototype.toggleDisplay = function toggleDisplay(value) {
+		if (typeof value !== "boolean" || this.display === value)
+			return;
+
+		this.display = value;
+		var display = this.display === true ? "block" : "none";
+		this.node.style.display = display;
+		this.object.style.display = display;
+	}
+
+	CssClass.prototype.toggleBorder = function toggleBorder(value) {
+		if (typeof value !== "boolean" || this.border === value)
+			return;
+
+		this.border = value;
+		var border = this.border === true ? "1px solid #CCC" : "none";
+		this.node.style.border = border;
+	}
+
+	CssClass.prototype.updateBgColor = function updateBgColor(color) {
+		this.bgcolor.copy(color);
+		this.node.style.backgroundColor = color.getColor();
+		OutputManager.updateProperty(this.id, 'background-color', color.getColor());
+	}
+
+	CssClass.prototype.updateShadows = function updateShadows() {
+		if (this.render.length === 0)
+			OutputManager.toggleProperty(this.id, 'box-shadow', false);
+		if (this.render.length === 1)
+			OutputManager.toggleProperty(this.id, 'box-shadow', true);
+
+		this.node.style.boxShadow = this.render.join(", ");
+		OutputManager.updateProperty(this.id, 'box-shadow', this.render.join(", \n"));
+
+	}
+
+
+	/**
+	 * Tool Manager
+	 */
+	var Tool = (function Tool() {
+
+		var preview;
+		var classes = [];
+		var active = null;
+		var animate = false;
+
+		/*
+		 * Toll actions
+		 */
+		var addCssClass = function addCssClass(id) {
+			classes[id] = new CssClass(id);
+		}
+
+		var setActiveClass = function setActiveClass(id) {
+			active = classes[id];
+			active.shadowID = null;
+			ColoPicker.setColor(classes[id].bgcolor);
+			SliderManager.setValue("top", active.top);
+			SliderManager.setValue("left", active.left);
+			SliderManager.setValue("rotate", active.rotate);
+			SliderManager.setValue("z-index", active.zIndex);
+			SliderManager.setValue("width", active.width);
+			SliderManager.setValue("height", active.height);
+			ButtonManager.setValue("border-state", active.border);
+			active.updateShadows();
+		}
+
+		var disableClass = function disableClass(topic) {
+			classes[topic].toggleDisplay(false);
+			ButtonManager.setValue(topic, false);
+		}
+
+		var addShadow = function addShadow(position) {
+			if (animate === true)
+				return -1;
+
+			active.shadows.splice(position, 0, new Shadow());
+			active.render.splice(position, 0, null);
+		}
+
+		var swapShadow = function swapShadow(id1, id2) {
+			var x = active.shadows[id1];
+			active.shadows[id1] = active.shadows[id2];
+			active.shadows[id2] = x;
+			updateShadowCSS(id1);
+			updateShadowCSS(id2);
+		}
+
+		var deleteShadow = function deleteShadow(position) {
+			active.shadows.splice(position, 1);
+			active.render.splice(position, 1);
+			active.updateShadows();
+		}
+
+		var setActiveShadow = function setActiveShadow(id, glow) {
+			active.shadowID = id;
+			ColoPicker.setColor(active.shadows[id].color);
+			ButtonManager.setValue("inset", active.shadows[id].inset);
+			SliderManager.setValue("blur", active.shadows[id].blur);
+			SliderManager.setValue("spread", active.shadows[id].spread);
+			SliderManager.setValue("posX", active.shadows[id].posX);
+			SliderManager.setValue("posY", active.shadows[id].posY);
+			if (glow === true)
+				addGlowEffect(id);
+		}
+
+		var addGlowEffect = function addGlowEffect(id) {
+			if (animate === true)
+				return;
+
+			animate = true;
+			var store = new Shadow();
+			var shadow = active.shadows[id];
+
+			store.copy(shadow);
+			shadow.color.setRGBA(40, 125, 200, 1);
+			shadow.blur = 10;
+			shadow.spread = 10;
+
+			active.node.style.transition = "box-shadow 0.2s";
+			updateShadowCSS(id);
+
+			setTimeout(function() {
+				shadow.copy(store);
+				updateShadowCSS(id);
+				setTimeout(function() {
+					active.node.style.removeProperty("transition");
+					animate = false;
+				}, 100);
+			}, 200);
+		}
+
+		var updateActivePos = function updateActivePos(deltaX, deltaY) {
+			if (active.shadowID === null)
+				active.updatePos(deltaX, deltaY);
+			else
+				updateShadowPos(deltaX, deltaY);
+		}
+
+		/*
+		 * Shadow properties
+		 */
+		var updateShadowCSS = function updateShadowCSS(id) {
+			active.render[id] = active.shadows[id].computeCSS();
+			active.updateShadows();
+		}
+
+		var toggleShadowInset = function toggleShadowInset(value) {
+			if (active.shadowID === null)
+				return;
+			active.shadows[active.shadowID].toggleInset(value);
+			updateShadowCSS(active.shadowID);
+		}
+
+		var updateShadowPos = function updateShadowPos(deltaX, deltaY) {
+			var shadow = active.shadows[active.shadowID];
+			shadow.posX += deltaX;
+			shadow.posY += deltaY;
+			SliderManager.setValue("posX", shadow.posX);
+			SliderManager.setValue("posY", shadow.posY);
+			updateShadowCSS(active.shadowID);
+		}
+
+		var setShadowPosX = function setShadowPosX(value) {
+			if (active.shadowID === null)
+				return;
+			active.shadows[active.shadowID].posX = value;
+			updateShadowCSS(active.shadowID);
+		}
+
+		var setShadowPosY = function setShadowPosY(value) {
+			if (active.shadowID === null)
+				return;
+			active.shadows[active.shadowID].posY = value;
+			updateShadowCSS(active.shadowID);
+		}
+
+		var setShadowBlur = function setShadowBlur(value) {
+			if (active.shadowID === null)
+				return;
+			active.shadows[active.shadowID].blur = value;
+			updateShadowCSS(active.shadowID);
+		}
+
+		var setShadowSpread = function setShadowSpread(value) {
+			if (active.shadowID === null)
+				return;
+			active.shadows[active.shadowID].spread = value;
+			updateShadowCSS(active.shadowID);
+		}
+
+		var updateShadowColor = function updateShadowColor(color) {
+			active.shadows[active.shadowID].color.copy(color);
+			updateShadowCSS(active.shadowID);
+		}
+
+		/*
+		 * Element Properties
+		 */
+		var updateColor = function updateColor(color) {
+			if (active.shadowID === null)
+				active.updateBgColor(color);
+			else
+				updateShadowColor(color);
+		}
+
+		var init = function init() {
+			preview = getElemById("preview");
+
+			ColoPicker.subscribe("color", updateColor);
+			PreviewMouseTracking.subscribe(updateActivePos);
+
+			// Affects shadows
+			ButtonManager.subscribe("inset", toggleShadowInset);
+			SliderManager.subscribe("posX", setShadowPosX);
+			SliderManager.subscribe("posY", setShadowPosY);
+			SliderManager.subscribe("blur", setShadowBlur);
+			SliderManager.subscribe("spread", setShadowSpread);
+
+			// Affects element
+			SliderManager.subscribe("top", function(value){
+				active.setTop(value);
+			});
+			SliderManager.subscribe("left", function(value){
+				active.setLeft(value);
+			});
+			SliderManager.subscribe("rotate", function(value) {
+				if (active == classes["element"])
+					return;
+				active.setRotate(value);
+			});
+
+			SliderManager.subscribe("z-index", function(value) {
+				if (active == classes["element"])
+					return;
+				active.setzIndex(value);
+			});
+
+			SliderManager.subscribe("width", function(value) {
+				active.setWidth(value)
+			});
+
+			SliderManager.subscribe("height", function(value) {
+				active.setHeight(value)
+			});
+
+			// Actions
+			classes['before'].top = -30;
+			classes['before'].left = -30;
+			classes['after'].top = 30;
+			classes['after'].left = 30;
+			classes['before'].toggleDisplay(false);
+			classes['after'].toggleDisplay(false);
+			ButtonManager.setValue('before', false);
+			ButtonManager.setValue('after', false);
+
+			ButtonManager.subscribe("before", classes['before'].toggleDisplay.bind(classes['before']));
+			ButtonManager.subscribe("after", classes['after'].toggleDisplay.bind(classes['after']));
+
+			ButtonManager.subscribe("border-state", function(value) {
+				active.toggleBorder(value);
+			});
+
+		}
+
+		return {
+			init 			: init,
+			addShadow		: addShadow,
+			swapShadow		: swapShadow,
+			addCssClass		: addCssClass,
+			disableClass	: disableClass,
+			deleteShadow	: deleteShadow,
+			setActiveClass	: setActiveClass,
+			setActiveShadow : setActiveShadow
+		}
+
+	})();
+
+	/**
+	 * Layer Manager
+	 */
+	var LayerManager = (function LayerManager() {
+		var stacks = [];
+		var active = {
+			node : null,
+			stack : null
+		}
+		var elements = {};
+
+		var mouseEvents = function mouseEvents(e) {
+			var node = e.target;
+			var type = node.getAttribute('data-type');
+
+			if (type === 'subject')
+				setActiveStack(stacks[node.id]);
+
+			if (type === 'disable') {
+				Tool.disableClass(node.parentNode.id);
+				setActiveStack(stacks['element']);
+			}
+
+			if (type === 'add')
+				active.stack.addLayer();
+
+			if (type === 'layer')
+				active.stack.setActiveLayer(node);
+
+			if (type === 'delete')
+				active.stack.deleteLayer(node.parentNode);
+
+			if (type === 'move-up')
+				active.stack.moveLayer(1);
+
+			if (type === 'move-down')
+				active.stack.moveLayer(-1);
+		}
+
+		var setActiveStack = function setActiveStack(stackObj) {
+			active.stack.hide();
+			active.stack = stackObj;
+			active.stack.show();
+		}
+
+		/*
+		 * Stack object
+		 */
+		var Stack = function Stack(subject) {
+			var S = document.createElement('div');
+			var title = document.createElement('div');
+			var stack = document.createElement('div');
+
+			S.className = 'container';
+			stack.className = 'stack';
+			title.className = 'title';
+			title.textContent = subject.getAttribute('data-title');
+			S.appendChild(title);
+			S.appendChild(stack);
+
+			this.id = subject.id;
+			this.container = S;
+			this.stack = stack;
+			this.subject = subject;
+			this.order = [];
+			this.uid = 0;
+			this.count = 0;
+			this.layer = null;
+			this.layerID = 0;
+		}
+
+		Stack.prototype.addLayer = function addLayer() {
+			if (Tool.addShadow(this.layerID) == -1)
+				return;
+
+			var uid = this.getUID();
+			var layer = this.createLayer(uid);
+
+			if (this.layer === null && this.stack.children.length >= 1)
+				this.layer = this.stack.children[0];
+
+			this.stack.insertBefore(layer, this.layer);
+			this.order.splice(this.layerID, 0, uid);
+			this.count++;
+			this.setActiveLayer(layer);
+		}
+
+		Stack.prototype.createLayer = function createLayer(uid) {
+			var layer = document.createElement('div');
+			var del = document.createElement('span');
+
+			layer.className = 'node';
+			layer.setAttribute('data-shid', uid);
+			layer.setAttribute('data-type', 'layer');
+			layer.textContent = 'тень ' + uid;
+
+			del.className = 'delete';
+			del.setAttribute('data-type', 'delete');
+
+			layer.appendChild(del);
+			return layer;
+		}
+
+		Stack.prototype.getUID = function getUID() {
+			return this.uid++;
+		}
+
+		// SOLVE IE BUG
+		Stack.prototype.moveLayer = function moveLayer(direction) {
+			if (this.count <= 1 || this.layer === null)
+				return;
+			if (direction === -1 && this.layerID === (this.count - 1) )
+				return;
+			if (direction === 1 && this.layerID === 0 )
+				return;
+
+			if (direction === -1) {
+				var before = null;
+				Tool.swapShadow(this.layerID, this.layerID + 1);
+				this.swapOrder(this.layerID, this.layerID + 1);
+				this.layerID += 1;
+
+				if (this.layerID + 1 !== this.count)
+					before = this.stack.children[this.layerID + 1];
+
+				this.stack.insertBefore(this.layer, before);
+				Tool.setActiveShadow(this.layerID, false);
+			}
+
+			if (direction === 1) {
+				Tool.swapShadow(this.layerID, this.layerID - 1);
+				this.swapOrder(this.layerID, this.layerID - 1);
+				this.layerID -= 1;
+				this.stack.insertBefore(this.layer, this.stack.children[this.layerID]);
+				Tool.setActiveShadow(this.layerID, false);
+			}
+		}
+
+		Stack.prototype.swapOrder = function swapOrder(pos1, pos2) {
+			var x = this.order[pos1];
+			this.order[pos1] = this.order[pos2];
+			this.order[pos2] = x;
+		}
+
+		Stack.prototype.deleteLayer = function deleteLayer(node) {
+			var shadowID =  node.getAttribute('data-shid') | 0;
+			var index = this.order.indexOf(shadowID);
+			this.stack.removeChild(this.stack.children[index]);
+			this.order.splice(index, 1);
+			this.count--;
+
+			Tool.deleteShadow(index);
+
+			if (index > this.layerID)
+				return;
+
+			if (index == this.layerID) {
+				if (this.count >= 1) {
+					this.layerID = 0;
+					this.setActiveLayer(this.stack.children[0], true);
+				}
+				else {
+					this.layer = null;
+					this.show();
+				}
+			}
+
+			if (index < this.layerID) {
+				this.layerID--;
+				Tool.setActiveShadow(this.layerID, true);
+			}
+
+		}
+
+		Stack.prototype.setActiveLayer = function setActiveLayer(node) {
+			elements.shadow_properties.style.display = 'block';
+			elements.element_properties.style.display = 'none';
+
+			if (this.layer)
+				this.layer.removeAttribute('data-active');
+
+			this.layer = node;
+			this.layer.setAttribute('data-active', 'layer');
+
+			var shadowID =  node.getAttribute('data-shid') | 0;
+			this.layerID = this.order.indexOf(shadowID);
+			Tool.setActiveShadow(this.layerID, true);
+		}
+
+		Stack.prototype.unsetActiveLayer = function unsetActiveLayer() {
+			if (this.layer)
+				this.layer.removeAttribute('data-active');
+
+			this.layer = null;
+			this.layerID = 0;
+		}
+
+		Stack.prototype.hide = function hide() {
+			this.unsetActiveLayer();
+			this.subject.removeAttribute('data-active');
+			var style = this.container.style;
+			style.left = '100%';
+			style.zIndex = '0';
+		}
+
+		Stack.prototype.show = function show() {
+			elements.shadow_properties.style.display = 'none';
+			elements.element_properties.style.display = 'block';
+
+			if (this.id === 'element') {
+				elements.zIndex.style.display = 'none';
+				elements.transform_rotate.style.display = 'none';
+			}
+			else {
+				elements.zIndex.style.display = 'block';
+				elements.transform_rotate.style.display = 'block';
+			}
+
+			this.subject.setAttribute('data-active', 'subject');
+			var style = this.container.style;
+			style.left = '0';
+			style.zIndex = '10';
+			Tool.setActiveClass(this.id);
+		}
+
+		function init() {
+
+			var elem, size;
+			var layerManager = getElemById("layer_manager");
+			var layerMenu = getElemById("layer_menu");
+			var container = getElemById("stack_container");
+
+			elements.shadow_properties = getElemById('shadow_properties');
+			elements.element_properties = getElemById('element_properties');
+			elements.transform_rotate = getElemById('transform_rotate');
+			elements.zIndex = getElemById('z-index');
+
+			elem = document.querySelectorAll('#layer_menu [data-type="subject"]');
+			size = elem.length;
+
+			for (var i = 0; i < size; i++) {
+				var S = new Stack(elem[i]);
+				stacks[elem[i].id] = S;
+				container.appendChild(S.container);
+				Tool.addCssClass(elem[i].id);
+			}
+
+			active.stack = stacks['element'];
+			stacks['element'].show();
+
+			layerManager.addEventListener("click", mouseEvents);
+			layerMenu.addEventListener("click", mouseEvents);
+
+			ButtonManager.subscribe("before", function(value) {
+				if (value === false && active.stack === stacks['before'])
+					setActiveStack(stacks['element'])
+				if (value === true && active.stack !== stacks['before'])
+					setActiveStack(stacks['before'])
+			});
+
+			ButtonManager.subscribe("after", function(value) {
+				if (value === false && active.stack === stacks['after'])
+					setActiveStack(stacks['element'])
+				if (value === true && active.stack !== stacks['after'])
+					setActiveStack(stacks['after'])
+			});
+		}
+
+		return {
+			init : init
+		}
+	})();
+
+	/*
+	 * OutputManager
+	 */
+	var OutputManager = (function OutputManager() {
+		var classes = [];
+		var buttons = [];
+		var active = null;
+		var menu = null;
+		var button_offset = 0;
+
+		var crateOutputNode = function(topic, property) {
+
+			var prop = document.createElement('div');
+			var name = document.createElement('span');
+			var value = document.createElement('span');
+
+			var pmatch = property.match(/(^([a-z0-9\-]*)=\[([a-z0-9\-\"]*)\])|^([a-z0-9\-]*)/i);
+
+			name.textContent = '\t' + pmatch[4];
+
+			if (pmatch[3] !== undefined) {
+				name.textContent = '\t' + pmatch[2];
+				value.textContent = pmatch[3] + ';';
+			}
+
+			name.textContent += ': ';
+			prop.className = 'css-property';
+			name.className = 'name';
+			value.className = 'value';
+			prop.appendChild(name);
+			prop.appendChild(value);
+
+			classes[topic].node.appendChild(prop);
+			classes[topic].line[property] = prop;
+			classes[topic].prop[property] = value;
+		}
+
+		var OutputClass = function OutputClass(node) {
+			var topic = node.getAttribute('data-topic');
+			var prop = node.getAttribute('data-prop');
+			var name = node.getAttribute('data-name');
+			var properties = prop.split(' ');
+
+			classes[topic] = {};
+			classes[topic].node = node;
+			classes[topic].prop = [];
+			classes[topic].line = [];
+			classes[topic].button = new Button(topic);
+
+			var open_decl = document.createElement('div');
+			var end_decl = document.createElement('div');
+
+			open_decl.textContent = name + ' {';
+			end_decl.textContent = '}';
+			node.appendChild(open_decl);
+
+			for (var i in properties)
+				crateOutputNode(topic, properties[i]);
+
+			node.appendChild(end_decl);
+		}
+
+		var Button = function Button(topic) {
+			var button = document.createElement('div');
+
+			button.className = 'button';
+			button.textContent = topic;
+			button.style.left = button_offset + 'px';
+			button_offset += 100;
+
+			button.addEventListener("click", function() {
+				toggleDisplay(topic);
+			})
+
+			menu.appendChild(button);
+			return button;
+		}
+
+		var toggleDisplay = function toggleDisplay(topic) {
+			active.button.removeAttribute('data-active');
+			active.node.style.display = 'none';
+			active = classes[topic];
+			active.node.style.display = 'block';
+			active.button.setAttribute('data-active', 'true');
+		}
+
+		var toggleButton = function toggleButton(topic, value) {
+			var display = (value === true) ? 'block' : 'none';
+			classes[topic].button.style.display = display;
+
+			if (value === true)
+				toggleDisplay(topic);
+			else
+				toggleDisplay('element');
+		}
+
+		var updateProperty = function updateProperty(topic, property, data) {
+			try {
+				classes[topic].prop[property].textContent = data + ';';
+			}
+			catch(error) {
+				// console.log("ERROR undefined : ", topic, property, data);
+			}
+		}
+
+		var toggleProperty = function toggleProperty(topic, property, value) {
+			var display = (value === true) ? 'block' : 'none';
+			try {
+				classes[topic].line[property].style.display = display;
+			}
+			catch(error) {
+				// console.log("ERROR undefined : ",classes, topic, property, value);
+			}
+		}
+
+		var init = function init() {
+
+			menu = getElemById('menu');
+
+			var elem = document.querySelectorAll('#output .output');
+			var size = elem.length;
+			for (var i = 0; i < size; i++)
+				OutputClass(elem[i]);
+
+			active = classes['element'];
+			toggleDisplay('element');
+
+			ButtonManager.subscribe("before", function(value) {
+				toggleButton('before', value);
+			});
+
+			ButtonManager.subscribe("after", function(value) {
+				toggleButton('after', value);
+			});
+		}
+
+		return {
+			init : init,
+			updateProperty : updateProperty,
+			toggleProperty : toggleProperty
+		}
+
+	})();
+
+
+	/**
+	 * Init Tool
+	 */
+	var init = function init() {
+		ButtonManager.init();
+		OutputManager.init();
+		ColoPicker.init();
+		SliderManager.init();
+		LayerManager.init();
+		PreviewMouseTracking.init("preview");
+		Tool.init();
+	}
+
+	return {
+		init : init
+	}
+
+})();
+
+
+
+
+ +
{{ EmbedLiveSample('box-shadow_generator', '100%', '1100px', '') }}
+ +

Похожий инструмент: Генератор CSS Box Shadow

diff --git a/files/ru/web/css/css_background_and_borders/index.html b/files/ru/web/css/css_background_and_borders/index.html deleted file mode 100644 index 59c2117194..0000000000 --- a/files/ru/web/css/css_background_and_borders/index.html +++ /dev/null @@ -1,155 +0,0 @@ ---- -title: CSS Background and Borders -slug: Web/CSS/CSS_Background_and_Borders -tags: - - CSS - - CSS Backgrounds and Borders - - CSS Reference - - NeedsTranslation - - Overview - - TopicStub -translation_of: Web/CSS/CSS_Backgrounds_and_Borders -translation_of_original: Web/CSS/CSS_Background_and_Borders ---- -

{{CSSRef}}

- -

CSS Background and Borders is a module of CSS that defines how background and borders of elements are described. Borders can be lines or images, boxes can have one or multiple backgrounds, have rounded corners, and shadows.

- -

Reference

- -

CSS Properties

- -
-
    -
  • {{cssxref("background")}}
  • -
  • {{cssxref("background-attachment")}}
  • -
  • {{cssxref("background-clip")}}
  • -
  • {{cssxref("background-color")}}
  • -
  • {{cssxref("background-image")}}
  • -
  • {{cssxref("background-origin")}}
  • -
  • {{cssxref("background-position")}}
  • -
  • {{cssxref("background-repeat")}}
  • -
  • {{cssxref("background-size")}}
  • -
  • {{cssxref("box-shadow")}}
  • -
  • {{cssxref("border")}}
  • -
  • {{cssxref("border-bottom")}}
  • -
  • {{cssxref("border-bottom-color")}}
  • -
  • {{cssxref("border-bottom-left-radius")}}
  • -
  • {{cssxref("border-bottom-right-radius")}}
  • -
  • {{cssxref("border-bottom-style")}}
  • -
  • {{cssxref("border-bottom-width")}}
  • -
  • {{cssxref("border-collapse")}}
  • -
  • {{cssxref("border-color")}}
  • -
  • {{cssxref("border-image")}}
  • -
  • {{cssxref("border-image-outset")}}
  • -
  • {{cssxref("border-image-repeat")}}
  • -
  • {{cssxref("border-image-slice")}}
  • -
  • {{cssxref("border-image-source")}}
  • -
  • {{cssxref("border-image-width")}}
  • -
  • {{cssxref("border-left")}}
  • -
  • {{cssxref("border-left-color")}}
  • -
  • {{cssxref("border-left-style")}}
  • -
  • {{cssxref("border-left-width")}}
  • -
  • {{cssxref("border-radius")}}
  • -
  • {{cssxref("border-right")}}
  • -
  • {{cssxref("border-right-color")}}
  • -
  • {{cssxref("border-right-style")}}
  • -
  • {{cssxref("border-right-width")}}
  • -
  • {{cssxref("border-style")}}
  • -
  • {{cssxref("border-top")}}
  • -
  • {{cssxref("border-top-color")}}
  • -
  • {{cssxref("border-top-left-radius")}}
  • -
  • {{cssxref("border-top-right-radius")}}
  • -
  • {{cssxref("border-top-style")}}
  • -
  • {{cssxref("border-top-width")}}
  • -
  • {{cssxref("border-width")}}
  • -
-
- -

Guides

- -
-
Using CSS multiple backgrounds
-
Explains how to set backgrounds on elements and how they will interact with it.
-
Scaling background images
-
Describes how to change the appearance of the background images, by stretching them or repeating them, to cover the whole background of the element, or not.
-
- -

Specifications

- - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{ SpecName('CSS3 Backgrounds') }}{{ Spec2('CSS3 Backgrounds') }} 
{{SpecName('CSS2.1', 'box.html')}}{{Spec2('CSS2.1')}} 
{{SpecName('CSS1', '#border')}}{{Spec2('CSS1')}} 
- -

Browser compatibility

- -

{{CompatibilityTable()}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support1.0{{CompatGeckoDesktop("1.0")}}4.03.51.0 (85)
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown()}}{{CompatGeckoMobile("1.9.2")}}{{CompatVersionUnknown()}}{{CompatVersionUnknown()}}1.0
-
diff --git "a/files/ru/web/css/css_background_and_borders/\320\274\320\275\320\276\320\266\320\265\321\201\321\202\320\262\320\265\320\275\320\275\321\213\320\265_\321\204\320\276\320\275\321\213/index.html" "b/files/ru/web/css/css_background_and_borders/\320\274\320\275\320\276\320\266\320\265\321\201\321\202\320\262\320\265\320\275\320\275\321\213\320\265_\321\204\320\276\320\275\321\213/index.html" deleted file mode 100644 index 231c794702..0000000000 --- "a/files/ru/web/css/css_background_and_borders/\320\274\320\275\320\276\320\266\320\265\321\201\321\202\320\262\320\265\320\275\320\275\321\213\320\265_\321\204\320\276\320\275\321\213/index.html" +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: Множественные фоны -slug: Web/CSS/CSS_Background_and_Borders/Множественные_фоны -translation_of: Web/CSS/CSS_Backgrounds_and_Borders/Using_multiple_backgrounds -translation_of_original: Web/CSS/CSS_Background_and_Borders/Using_CSS_multiple_backgrounds ---- -

{{CSSRef}}

- -

Краткое описание

- -

С помощью CSS3 вы можете применить несколько фонов к элементам. Они будут располагаться поверх друг друга: фон, заданный первым - в самом верху, последний фон - в самом низу.

- -

Задать множественные фоны легко:

- -
.myclass {
-  background: background1, background 2, ..., backgroundN;
-}
-
- -

Вы можете сделать это сокращенным {{ cssxref("background") }} свойством и отдельными свойствами кроме {{ cssxref("background-color") }}. Таким образом следующие свойства могут быть определены в виде списка по одному на фон: {{ cssxref("background") }}, {{ cssxref("background-attachment") }}, {{ cssxref("background-clip") }}, {{ cssxref("background-image") }}, {{ cssxref("background-origin") }}, {{ cssxref("background-position") }}, {{ cssxref("background-repeat") }}, {{ cssxref("background-size") }}.

- -

Пример

- -

В этом примере три фона: логотип Firefox, линейный градиент и изображение пузырей:

- -

HTML

- -
<div class="multi_bg_example"></div>
- -

CSS

- -
.multi_bg_example {
-  width: 100%;
-  height: 400px;
-  background-image: url(https://mdn.mozillademos.org/files/11305/firefox.png), url(https://mdn.mozillademos.org/files/11307/bubbles.png), linear-gradient(to right, rgba(30, 75, 115, 1), rgba(255, 255, 255, 0));
-  background-repeat: no-repeat, no-repeat, no-repeat;
-  background-position: bottom right, left, right;
-  background: -moz-linear-gradient(to right, rgba(30, 75, 115, 1), rgba(255, 255, 255, 0)), -webkit-gradient(to right, rgba(30, 75, 115, 1), rgba(255, 255, 255, 0)), -ms-linear-gradient(to right, rgba(30, 75, 115, 1), rgba(255, 255, 255, 0)), linear-gradient(to right, rgba(30, 75, 115, 1), rgba(255, 255, 255, 0));
-}
- -

Результат

- -

(If image does not appear in CodePen, click the TIdy button in the CSS section)

- -

{{EmbedLiveSample('Example','100%','400')}}

- -

Как вы можете видеть, логотип Firefox (первый в списке) расположен сверху, далее идет градиент и в самом низу фон с пузырями. Каждое последующее под-свойство ({{ cssxref("background-repeat") }} и {{ cssxref("background-position") }}) применяется к соответствующим фонам. Например первое значение свойства {{ cssxref("background-repeat") }} применяется к первому фону, и т.д.

- -

Смотрите также

- - diff --git a/files/ru/web/css/css_backgrounds_and_borders/index.html b/files/ru/web/css/css_backgrounds_and_borders/index.html new file mode 100644 index 0000000000..59c2117194 --- /dev/null +++ b/files/ru/web/css/css_backgrounds_and_borders/index.html @@ -0,0 +1,155 @@ +--- +title: CSS Background and Borders +slug: Web/CSS/CSS_Background_and_Borders +tags: + - CSS + - CSS Backgrounds and Borders + - CSS Reference + - NeedsTranslation + - Overview + - TopicStub +translation_of: Web/CSS/CSS_Backgrounds_and_Borders +translation_of_original: Web/CSS/CSS_Background_and_Borders +--- +

{{CSSRef}}

+ +

CSS Background and Borders is a module of CSS that defines how background and borders of elements are described. Borders can be lines or images, boxes can have one or multiple backgrounds, have rounded corners, and shadows.

+ +

Reference

+ +

CSS Properties

+ +
+
    +
  • {{cssxref("background")}}
  • +
  • {{cssxref("background-attachment")}}
  • +
  • {{cssxref("background-clip")}}
  • +
  • {{cssxref("background-color")}}
  • +
  • {{cssxref("background-image")}}
  • +
  • {{cssxref("background-origin")}}
  • +
  • {{cssxref("background-position")}}
  • +
  • {{cssxref("background-repeat")}}
  • +
  • {{cssxref("background-size")}}
  • +
  • {{cssxref("box-shadow")}}
  • +
  • {{cssxref("border")}}
  • +
  • {{cssxref("border-bottom")}}
  • +
  • {{cssxref("border-bottom-color")}}
  • +
  • {{cssxref("border-bottom-left-radius")}}
  • +
  • {{cssxref("border-bottom-right-radius")}}
  • +
  • {{cssxref("border-bottom-style")}}
  • +
  • {{cssxref("border-bottom-width")}}
  • +
  • {{cssxref("border-collapse")}}
  • +
  • {{cssxref("border-color")}}
  • +
  • {{cssxref("border-image")}}
  • +
  • {{cssxref("border-image-outset")}}
  • +
  • {{cssxref("border-image-repeat")}}
  • +
  • {{cssxref("border-image-slice")}}
  • +
  • {{cssxref("border-image-source")}}
  • +
  • {{cssxref("border-image-width")}}
  • +
  • {{cssxref("border-left")}}
  • +
  • {{cssxref("border-left-color")}}
  • +
  • {{cssxref("border-left-style")}}
  • +
  • {{cssxref("border-left-width")}}
  • +
  • {{cssxref("border-radius")}}
  • +
  • {{cssxref("border-right")}}
  • +
  • {{cssxref("border-right-color")}}
  • +
  • {{cssxref("border-right-style")}}
  • +
  • {{cssxref("border-right-width")}}
  • +
  • {{cssxref("border-style")}}
  • +
  • {{cssxref("border-top")}}
  • +
  • {{cssxref("border-top-color")}}
  • +
  • {{cssxref("border-top-left-radius")}}
  • +
  • {{cssxref("border-top-right-radius")}}
  • +
  • {{cssxref("border-top-style")}}
  • +
  • {{cssxref("border-top-width")}}
  • +
  • {{cssxref("border-width")}}
  • +
+
+ +

Guides

+ +
+
Using CSS multiple backgrounds
+
Explains how to set backgrounds on elements and how they will interact with it.
+
Scaling background images
+
Describes how to change the appearance of the background images, by stretching them or repeating them, to cover the whole background of the element, or not.
+
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{ SpecName('CSS3 Backgrounds') }}{{ Spec2('CSS3 Backgrounds') }} 
{{SpecName('CSS2.1', 'box.html')}}{{Spec2('CSS2.1')}} 
{{SpecName('CSS1', '#border')}}{{Spec2('CSS1')}} 
+ +

Browser compatibility

+ +

{{CompatibilityTable()}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support1.0{{CompatGeckoDesktop("1.0")}}4.03.51.0 (85)
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown()}}{{CompatGeckoMobile("1.9.2")}}{{CompatVersionUnknown()}}{{CompatVersionUnknown()}}1.0
+
diff --git a/files/ru/web/css/css_backgrounds_and_borders/using_multiple_backgrounds/index.html b/files/ru/web/css/css_backgrounds_and_borders/using_multiple_backgrounds/index.html new file mode 100644 index 0000000000..231c794702 --- /dev/null +++ b/files/ru/web/css/css_backgrounds_and_borders/using_multiple_backgrounds/index.html @@ -0,0 +1,53 @@ +--- +title: Множественные фоны +slug: Web/CSS/CSS_Background_and_Borders/Множественные_фоны +translation_of: Web/CSS/CSS_Backgrounds_and_Borders/Using_multiple_backgrounds +translation_of_original: Web/CSS/CSS_Background_and_Borders/Using_CSS_multiple_backgrounds +--- +

{{CSSRef}}

+ +

Краткое описание

+ +

С помощью CSS3 вы можете применить несколько фонов к элементам. Они будут располагаться поверх друг друга: фон, заданный первым - в самом верху, последний фон - в самом низу.

+ +

Задать множественные фоны легко:

+ +
.myclass {
+  background: background1, background 2, ..., backgroundN;
+}
+
+ +

Вы можете сделать это сокращенным {{ cssxref("background") }} свойством и отдельными свойствами кроме {{ cssxref("background-color") }}. Таким образом следующие свойства могут быть определены в виде списка по одному на фон: {{ cssxref("background") }}, {{ cssxref("background-attachment") }}, {{ cssxref("background-clip") }}, {{ cssxref("background-image") }}, {{ cssxref("background-origin") }}, {{ cssxref("background-position") }}, {{ cssxref("background-repeat") }}, {{ cssxref("background-size") }}.

+ +

Пример

+ +

В этом примере три фона: логотип Firefox, линейный градиент и изображение пузырей:

+ +

HTML

+ +
<div class="multi_bg_example"></div>
+ +

CSS

+ +
.multi_bg_example {
+  width: 100%;
+  height: 400px;
+  background-image: url(https://mdn.mozillademos.org/files/11305/firefox.png), url(https://mdn.mozillademos.org/files/11307/bubbles.png), linear-gradient(to right, rgba(30, 75, 115, 1), rgba(255, 255, 255, 0));
+  background-repeat: no-repeat, no-repeat, no-repeat;
+  background-position: bottom right, left, right;
+  background: -moz-linear-gradient(to right, rgba(30, 75, 115, 1), rgba(255, 255, 255, 0)), -webkit-gradient(to right, rgba(30, 75, 115, 1), rgba(255, 255, 255, 0)), -ms-linear-gradient(to right, rgba(30, 75, 115, 1), rgba(255, 255, 255, 0)), linear-gradient(to right, rgba(30, 75, 115, 1), rgba(255, 255, 255, 0));
+}
+ +

Результат

+ +

(If image does not appear in CodePen, click the TIdy button in the CSS section)

+ +

{{EmbedLiveSample('Example','100%','400')}}

+ +

Как вы можете видеть, логотип Firefox (первый в списке) расположен сверху, далее идет градиент и в самом низу фон с пузырями. Каждое последующее под-свойство ({{ cssxref("background-repeat") }} и {{ cssxref("background-position") }}) применяется к соответствующим фонам. Например первое значение свойства {{ cssxref("background-repeat") }} применяется к первому фону, и т.д.

+ +

Смотрите также

+ + diff --git a/files/ru/web/css/css_basic_user_interface/using_url_values_for_the_cursor_property/index.html b/files/ru/web/css/css_basic_user_interface/using_url_values_for_the_cursor_property/index.html new file mode 100644 index 0000000000..c629b7bffd --- /dev/null +++ b/files/ru/web/css/css_basic_user_interface/using_url_values_for_the_cursor_property/index.html @@ -0,0 +1,120 @@ +--- +title: Использование URL значений для свойства cursor +slug: >- + Web/CSS/CSS_Basic_User_Interface/Использование_URL_значений_для_свойства_cursor +tags: + - CSS + - Gecko + - Справка + - справочник +translation_of: Web/CSS/CSS_Basic_User_Interface/Using_URL_values_for_the_cursor_property +--- +
{{cssref}}
+ +

Gecko 1.8 (Firefox 1.5, SeaMonkey 1.0) поддерживает URL-значения для CSS свойства {{cssxref("cursor")}} в Windows и Linux. Поддержка Mac была добавлена в Gecko 2 (Firefox 4). Это позволяет устанавливать произвольные изображения в качестве курсора мыши — может быть использовать любой формат изображений, поддерживаемый Gecko.

+ +

Синтаксис

+ +

Базовый (CSS 2.1) синтаксис для этого свойства:

+ +
cursor:  [<url>,]* ключевое_слово
+ +

Это означает, что устанавливать можно любое количество URL'ов (отделенных запятой), которые должны сопровождаться одним из ключевых слов, определеннымы спецификацией CSS, таких как auto или pointer.

+ +

Например, такая последовательность значений допустима:

+ +
cursor:  url(foo.cur), url(http://www.example.com/bar.gif), auto;
+ +

В первую очередь браузер пытается загрузить foo.cur. Если такой файл отсутствует или его форма не допустим по каким-то другим причинам, то дальше загружается bar.gif. И если он также не может быть использован, будет использовано значение auto.

+ +

Поддержка CSS 3 синтаксиса для указания курсора была добавлена в Gecko 1.8 (Firefox 1.5):

+ +
cursor:  [<uri> [<x> <y>]?,]* ключевое_слово
+ +

Это позволяет устанавливать координаты смещения курсора, которые буду зафиксированы на границах курсора. Если координаты не указаны, то они считываются непосредственно из файла (для CUR и XBM файлов) или же устанавливаются в левый верхний угол изображения.

+ +

Пример CSS 3 синтаксиса:

+ +
.foo  {
+  cursor:  auto;
+  cursor:  url(cursor1.png) 4 12, auto;
+}
+
+.bar  {
+  cursor:  pointer;
+  cursor:  url(cursor2.png) 2 2, pointer;
+}
+
+/* откатываются на 'auto' и 'pointer' в IE, но должны быть установлены отдельны */
+
+ +

Первое число определяет координату по оси x, а вторая - по оси y. Данный пример сместит изображение на точку (4,12) относительно левого верхнего угла (0,0).

+ +

Ограничения

+ +

Могут быть использованы любые форматы, поддерживаемые Gecko. Это означает, что вы можете использовать PNG, GIF, JPG, BMP, CUR и т.д. ANI не поддерживается. Анимированные PNG и GIF не добавят анимацию курсору.

+ +
+

Примечание: Начиная с Gecko 2.0 {{geckoRelease("2.0")}}, Gecko также поддерживает формат SVG в качестве изображения курсора. Тем не менее, SVG изображение должно содержать значения (кроме процентных значений) высоты и ширины на корневом SVG узле. JavaScript, CSS анимация и декларативный SMIL внутри SVG изображения игнорируются; например, вы не можете использовать SVG, чтобы создать анимированный курсор.

+
+ +

В Gecko (Firefox) максимальный размер курсора - 128×128 пикселей. Изображения большего размера игнорируются. Однако, вам следую ограничиться рамером курсора в 32×32 пикселя для максимальной совместимости с операционными системами и платформами.

+ +

(В следствие бага Gecko 1.9.2-1.9.2.6, Firefox 3.6-3.6.6 в Windows ограничивает размер в 32x32 пикселя. Это исправляется в более новых версиях.)

+ +

Прозрачные курсоры не поддерживаются в версиях Windows ниже XP. Это ограничение для операционной системы. Прозрачность работает на любых платформах.

+ +

URL в качестве курсора поддерживаются в Windows, OS/2, и Linux (с использованием GTK+ 2.4 или выше) версиях Mozilla. Поддержка Mac OS X была добавлена в Gecko 2 (Firefox 4).

+ +

Совместимость с другими браузерами

+ +

Microsoft Internet Explorer 6.0 также поддерживает URI значения для свойства cursor. Тем не менее:

+ +
    +
  • IE поддерживает только CUR и ANI форматы.
  • +
  • IE не поддерживает CSS 3 синтаксис с x- и y-координатами. Изображение курсора и дальнейшее свойство игнорируются.
  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
БраузерРанняя версияФорматыx-y-координаты
Internet Explorer6.0.cur | .ani---
Firefox (Gecko), Windows и Linux1.5 (1.8).cur | .png | .gif | .jpg1.5 (1.8)
Firefox (Gecko)4.0 (2.0).cur | .png | .gif | .jpg | .svg(Gecko 2.0)
Opera---------
Safari (Webkit)3.0 (522-523).cur | .png | .gif | .jpg3.0 (522-523)
Начиная с OS X 10.5, Safari (Mac) поддерживает  .cur файлы
diff --git "a/files/ru/web/css/css_basic_user_interface/\320\270\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265_url_\320\267\320\275\320\260\321\207\320\265\320\275\320\270\320\271_\320\264\320\273\321\217_\321\201\320\262\320\276\320\271\321\201\321\202\320\262\320\260_cursor/index.html" "b/files/ru/web/css/css_basic_user_interface/\320\270\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265_url_\320\267\320\275\320\260\321\207\320\265\320\275\320\270\320\271_\320\264\320\273\321\217_\321\201\320\262\320\276\320\271\321\201\321\202\320\262\320\260_cursor/index.html" deleted file mode 100644 index c629b7bffd..0000000000 --- "a/files/ru/web/css/css_basic_user_interface/\320\270\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265_url_\320\267\320\275\320\260\321\207\320\265\320\275\320\270\320\271_\320\264\320\273\321\217_\321\201\320\262\320\276\320\271\321\201\321\202\320\262\320\260_cursor/index.html" +++ /dev/null @@ -1,120 +0,0 @@ ---- -title: Использование URL значений для свойства cursor -slug: >- - Web/CSS/CSS_Basic_User_Interface/Использование_URL_значений_для_свойства_cursor -tags: - - CSS - - Gecko - - Справка - - справочник -translation_of: Web/CSS/CSS_Basic_User_Interface/Using_URL_values_for_the_cursor_property ---- -
{{cssref}}
- -

Gecko 1.8 (Firefox 1.5, SeaMonkey 1.0) поддерживает URL-значения для CSS свойства {{cssxref("cursor")}} в Windows и Linux. Поддержка Mac была добавлена в Gecko 2 (Firefox 4). Это позволяет устанавливать произвольные изображения в качестве курсора мыши — может быть использовать любой формат изображений, поддерживаемый Gecko.

- -

Синтаксис

- -

Базовый (CSS 2.1) синтаксис для этого свойства:

- -
cursor:  [<url>,]* ключевое_слово
- -

Это означает, что устанавливать можно любое количество URL'ов (отделенных запятой), которые должны сопровождаться одним из ключевых слов, определеннымы спецификацией CSS, таких как auto или pointer.

- -

Например, такая последовательность значений допустима:

- -
cursor:  url(foo.cur), url(http://www.example.com/bar.gif), auto;
- -

В первую очередь браузер пытается загрузить foo.cur. Если такой файл отсутствует или его форма не допустим по каким-то другим причинам, то дальше загружается bar.gif. И если он также не может быть использован, будет использовано значение auto.

- -

Поддержка CSS 3 синтаксиса для указания курсора была добавлена в Gecko 1.8 (Firefox 1.5):

- -
cursor:  [<uri> [<x> <y>]?,]* ключевое_слово
- -

Это позволяет устанавливать координаты смещения курсора, которые буду зафиксированы на границах курсора. Если координаты не указаны, то они считываются непосредственно из файла (для CUR и XBM файлов) или же устанавливаются в левый верхний угол изображения.

- -

Пример CSS 3 синтаксиса:

- -
.foo  {
-  cursor:  auto;
-  cursor:  url(cursor1.png) 4 12, auto;
-}
-
-.bar  {
-  cursor:  pointer;
-  cursor:  url(cursor2.png) 2 2, pointer;
-}
-
-/* откатываются на 'auto' и 'pointer' в IE, но должны быть установлены отдельны */
-
- -

Первое число определяет координату по оси x, а вторая - по оси y. Данный пример сместит изображение на точку (4,12) относительно левого верхнего угла (0,0).

- -

Ограничения

- -

Могут быть использованы любые форматы, поддерживаемые Gecko. Это означает, что вы можете использовать PNG, GIF, JPG, BMP, CUR и т.д. ANI не поддерживается. Анимированные PNG и GIF не добавят анимацию курсору.

- -
-

Примечание: Начиная с Gecko 2.0 {{geckoRelease("2.0")}}, Gecko также поддерживает формат SVG в качестве изображения курсора. Тем не менее, SVG изображение должно содержать значения (кроме процентных значений) высоты и ширины на корневом SVG узле. JavaScript, CSS анимация и декларативный SMIL внутри SVG изображения игнорируются; например, вы не можете использовать SVG, чтобы создать анимированный курсор.

-
- -

В Gecko (Firefox) максимальный размер курсора - 128×128 пикселей. Изображения большего размера игнорируются. Однако, вам следую ограничиться рамером курсора в 32×32 пикселя для максимальной совместимости с операционными системами и платформами.

- -

(В следствие бага Gecko 1.9.2-1.9.2.6, Firefox 3.6-3.6.6 в Windows ограничивает размер в 32x32 пикселя. Это исправляется в более новых версиях.)

- -

Прозрачные курсоры не поддерживаются в версиях Windows ниже XP. Это ограничение для операционной системы. Прозрачность работает на любых платформах.

- -

URL в качестве курсора поддерживаются в Windows, OS/2, и Linux (с использованием GTK+ 2.4 или выше) версиях Mozilla. Поддержка Mac OS X была добавлена в Gecko 2 (Firefox 4).

- -

Совместимость с другими браузерами

- -

Microsoft Internet Explorer 6.0 также поддерживает URI значения для свойства cursor. Тем не менее:

- -
    -
  • IE поддерживает только CUR и ANI форматы.
  • -
  • IE не поддерживает CSS 3 синтаксис с x- и y-координатами. Изображение курсора и дальнейшее свойство игнорируются.
  • -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
БраузерРанняя версияФорматыx-y-координаты
Internet Explorer6.0.cur | .ani---
Firefox (Gecko), Windows и Linux1.5 (1.8).cur | .png | .gif | .jpg1.5 (1.8)
Firefox (Gecko)4.0 (2.0).cur | .png | .gif | .jpg | .svg(Gecko 2.0)
Opera---------
Safari (Webkit)3.0 (522-523).cur | .png | .gif | .jpg3.0 (522-523)
Начиная с OS X 10.5, Safari (Mac) поддерживает  .cur файлы
diff --git a/files/ru/web/css/css_box_model/box-shadow_generator/index.html b/files/ru/web/css/css_box_model/box-shadow_generator/index.html deleted file mode 100644 index 3f46cf53ba..0000000000 --- a/files/ru/web/css/css_box_model/box-shadow_generator/index.html +++ /dev/null @@ -1,2884 +0,0 @@ ---- -title: Генератор теней -slug: Web/CSS/CSS_Box_Model/Box-shadow_generator -tags: - - CSS3 - - Тень - - инструменты -translation_of: Web/CSS/CSS_Background_and_Borders/Box-shadow_generator ---- -

Этот инструмент позволяет вам создавать CSS {{cssxref("box-shadow")}} эффекты, добавлять тени вашим элементам.

- -
-

Генератор box-shadow generator

- -

HTML Content

- -
<div id="container">
-    <div class="group section">
-        <div id="layer_manager">
-            <div class="group section">
-                <div class="button" data-type="add"> </div>
-                <div class="button" data-type="move-up"> </div>
-                <div class="button" data-type="move-down"> </div>
-            </div>
-            <div id="stack_container"></div>
-        </div>
-
-        <div id="preview_zone">
-            <div id="layer_menu" class="col span_12">
-                <div class="button" id="element" data-type="subject" data-title="element"> элементы </div>
-                <div class="button" id="before" data-type="subject" data-title=":before">
-                    :before
-                    <span class="delete" data-type="disable"></span>
-                </div>
-                <div class="button" id="after" data-type="subject" data-title=":after">
-                    :after
-                    <span class="delete" data-type="disable"></span>
-                </div>
-                <div class="ui-checkbox" data-topic='before' data-label=":before"></div>
-                <div class="ui-checkbox" data-topic='after' data-label=":after"></div>
-            </div>
-
-            <div id="preview">
-                <div id="obj-element">
-                    <div class="content"> </div>
-                    <div id="obj-before"> </div>
-                    <div id="obj-after"> </div>
-                </div>
-            </div>
-        </div>
-    </div>
-
-    <div id="controls" class="group section">
-        <div class="wrap-left">
-            <div class="colorpicker category">
-                <div class="title"> </div>
-                <div id="colorpicker" class="group">
-                    <div id="gradient" class="gradient">
-                        <div id="gradient_picker"> </div>
-                    </div>
-                    <div id="hue" data-topic="hue" class="hue">
-                        <div id="hue_selector"> </div>
-                    </div>
-                    <div class="info">
-                        <div class="input" data-topic="hue" data-title='H:' data-action="HSV"></div>
-                        <div class="input" data-topic="saturation" data-title='S:' data-action="HSV"></div>
-                        <div class="input" data-topic="value" data-title='V:' data-action="HSV"></div>
-                    </div>
-                    <div class="alpha">
-                        <div id="alpha" data-topic="alpha">
-                            <div id="alpha_selector"> </div>
-                        </div>
-                    </div>
-                    <div class="info">
-                        <div class="input" data-topic="r" data-title='R:' data-action="RGB"></div>
-                        <div class="input" data-topic="g" data-title='G:' data-action="RGB"></div>
-                        <div class="input" data-topic="b" data-title='B:' data-action="RGB"></div>
-                    </div>
-                    <div class="preview block">
-                        <div id="output_color"> </div>
-                    </div>
-                    <div class="block info">
-                        <div class="input" data-topic="a" data-title='alpha:' data-action="alpha"></div>
-                        <div class="input" data-topic="hexa" data-title='' data-action="hexa"></div>
-                    </div>
-                </div>
-            </div>
-        </div>
-
-        <div class="wrap-right">
-
-            <div id="shadow_properties" class="category">
-                <div class="title"> Shadow properties </div>
-                <div class="group">
-                    <div class="group property">
-                        <div class="ui-slider-name"> inset </div>
-                        <div class="ui-checkbox" data-topic='inset'></div>
-                    </div>
-                    <div class="slidergroup">
-                        <div class="ui-slider-name"> Position x </div>
-                        <div class="ui-slider-btn-set" data-topic="posX" data-type="sub"></div>
-                        <div class="ui-slider" data-topic="posX"
-                            data-min="-500" data-max="500" data-step="1"> </div>
-                        <div class="ui-slider-btn-set" data-topic="posX" data-type="add"></div>
-                        <div class="ui-slider-input" data-topic="posX" data-unit="px"></div>
-                    </div>
-                    <div class="slidergroup">
-                        <div class="ui-slider-name"> Position y </div>
-                        <div class="ui-slider-btn-set" data-topic="posY" data-type="sub"></div>
-                        <div class="ui-slider" data-topic="posY"
-                            data-min="-500" data-max="500" data-step="1"> </div>
-                        <div class="ui-slider-btn-set" data-topic="posY" data-type="add"></div>
-                        <div class="ui-slider-input" data-topic="posY" data-unit="px"></div>
-                    </div>
-                    <div class="slidergroup">
-                        <div class="ui-slider-name"> Blur </div>
-                        <div class="ui-slider-btn-set" data-topic="blur" data-type="sub"></div>
-                        <div class="ui-slider" data-topic="blur"
-                            data-min="0" data-max="200" data-step="1"> </div>
-                        <div class="ui-slider-btn-set" data-topic="blur" data-type="add"></div>
-                        <div class="ui-slider-input" data-topic="blur" data-unit="px"></div>
-                    </div>
-                    <div class="slidergroup">
-                        <div class="ui-slider-name"> Spread </div>
-                        <div class="ui-slider-btn-set" data-topic="spread" data-type="sub"></div>
-                        <div class="ui-slider" data-topic="spread"
-                            data-min="-100"    data-max="100" data-step="1" data-value="50">
-                        </div>
-                        <div class="ui-slider-btn-set" data-topic="spread" data-type="add"></div>
-                        <div class="ui-slider-input" data-topic="spread" data-unit="px"></div>
-                    </div>
-                </div>
-            </div>
-
-            <div id="element_properties" class="category">
-                <div class="title"> Параметры элемента</div>
-                <div class="group">
-                    <div class="group property">
-                        <div class="ui-slider-name"> border </div>
-                        <div class="ui-checkbox" data-topic='border-state' data-state="true"></div>
-                    </div>
-                    <div id="z-index" class="slidergroup">
-                        <div class="ui-slider-name"> z-index </div>
-                        <div class="ui-slider-btn-set" data-topic="z-index" data-type="sub"></div>
-                        <div class="ui-slider" data-topic="z-index"
-                            data-min="-10" data-max="10" data-step="1"></div>
-                        <div class="ui-slider-btn-set" data-topic="z-index" data-type="add"></div>
-                        <div class="ui-slider-input" data-topic="z-index"></div>
-                    </div>
-                    <div class="slidergroup">
-                        <div class="ui-slider-name"> top </div>
-                        <div class="ui-slider-btn-set" data-topic="top" data-type="sub"></div>
-                        <div class="ui-slider" data-topic="top"
-                            data-min="-500" data-max="500" data-step="1"> </div>
-                        <div class="ui-slider-btn-set" data-topic="top" data-type="add"></div>
-                        <div class="ui-slider-input" data-topic="top" data-unit="px"></div>
-                    </div>
-                    <div class="slidergroup">
-                        <div class="ui-slider-name"> left </div>
-                        <div class="ui-slider-btn-set" data-topic="left" data-type="sub"></div>
-                        <div class="ui-slider" data-topic="left"
-                            data-min="-300" data-max="700" data-step="1"> </div>
-                        <div class="ui-slider-btn-set" data-topic="left" data-type="add"></div>
-                        <div class="ui-slider-input" data-topic="left" data-unit="px"></div>
-                    </div>
-                    <div id="transform_rotate" class="slidergroup">
-                        <div class="ui-slider-name"> Rotate </div>
-                        <div class="ui-slider-btn-set" data-topic="rotate" data-type="sub"></div>
-                        <div class="ui-slider" data-topic="rotate"
-                            data-min="-360" data-max="360" data-step="1" data-value="0">
-                        </div>
-                        <div class="ui-slider-btn-set" data-topic="rotate" data-type="add"></div>
-                        <div class="ui-slider-input" data-topic="rotate" data-unit="deg"></div>
-                    </div>
-                    <div class="slidergroup">
-                        <div class="ui-slider-name"> Width </div>
-                        <div class="ui-slider-btn-set" data-topic="width" data-type="sub"></div>
-                        <div class="ui-slider" data-topic="width"
-                            data-min="0" data-max="1000" data-step="1" data-value="200">
-                        </div>
-                        <div class="ui-slider-btn-set" data-topic="width" data-type="add"></div>
-                        <div class="ui-slider-input" data-topic="width"  data-unit="px"></div>
-                    </div>
-                    <div class="slidergroup">
-                        <div class="ui-slider-name"> Height </div>
-                        <div class="ui-slider-btn-set" data-topic="height" data-type="sub"></div>
-                        <div class="ui-slider" data-topic="height"
-                            data-min="0" data-max="400" data-step="1" data-value="200">
-                        </div>
-                        <div class="ui-slider-btn-set" data-topic="height" data-type="add"></div>
-                        <div class="ui-slider-input" data-topic="height" data-unit="px"></div>
-                    </div>
-                </div>
-            </div>
-
-            <div id="output" class="category">
-                <div id="menu" class="menu"></div>
-                <div class="title">    CSS-код </div>
-                <div class="group" style="border-top-left-radius: 0;">
-                    <div class="output" data-topic="element" data-name="element"
-                        data-prop="width height background-color position=[relative] box-shadow">
-                    </div>
-                    <div class="output" data-topic="before" data-name="element:before"
-                        data-prop="content=[&quot;&quot;] position=[absolute] width height top left z-index background-color box-shadow transform -webkit-transform -ms-transform">
-                    </div>
-                    <div class="output" data-topic="after" data-name="element:after"
-                        data-prop="content=[&quot;&quot;] position=[absolute] width height top left z-index background-color box-shadow transform -webkit-transform -ms-transform">
-                    </div>
-                </div>
-            </div>
-        </div>
-    </div>
-</div>
-
- -

CSS Content

- -
/*  GRID OF TWELVE
- * ========================================================================== */
-
-.span_12 {
-	width: 100%;
-}
-
-.span_11 {
-	width: 91.46%;
-}
-
-.span_10 {
-	width: 83%;
-}
-
-.span_9 {
-	width: 74.54%;
-}
-
-.span_8 {
-	width: 66.08%;
-}
-
-.span_7 {
-	width: 57.62%;
-}
-
-.span_6 {
-	width: 49.16%;
-}
-
-.span_5 {
-	width: 40.7%;
-}
-
-.span_4 {
-	width: 32.24%;
-}
-
-.span_3 {
-	width: 23.78%;
-}
-
-.span_2 {
-	width: 15.32%;
-}
-
-.span_1 {
-	width: 6.86%;
-}
-
-
-/*  SECTIONS
- * ========================================================================== */
-
-.section {
-	clear: both;
-	padding: 0px;
-	margin: 0px;
-}
-
-/*  GROUPING
- * ========================================================================== */
-
-
-.group:before, .group:after {
-    content: "";
-    display: table;
-}
-
-.group:after {
-    clear:both;
-}
-
-.group {
-    zoom: 1; /* For IE 6/7 (trigger hasLayout) */
-}
-
-/*  GRID COLUMN SETUP
- * ========================================================================== */
-
-.col {
-	display: block;
-	float:left;
-	margin: 1% 0 1% 1.6%;
-}
-
-.col:first-child {
-	margin-left: 0;
-} /* all browsers except IE6 and lower */
-
-/*
- * UI Slider
- */
-
-.slidergroup {
-	height: 20px;
-	margin: 10px 0;
-	font-family: "Segoe UI", Arial, Helvetica, sans-serif;
-	-moz-user-select: none;
-	user-select: none;
-}
-
-.slidergroup * {
-	float: left;
-	height: 100%;
-	line-height: 100%;
-}
-
-/* Slider */
-
-.ui-slider {
-	height: 10px;
-	width: 200px;
-	margin: 4px 10px;
-	display: block;
-	border: 1px solid #999;
-	border-radius: 3px;
-	background: #EEE;
-}
-
-.ui-slider:hover {
-	cursor: pointer;
-}
-
-.ui-slider-name {
-	width: 90px;
-	padding: 0 10px 0 0;
-	text-align: right;
-	text-transform: lowercase;
-}
-
-.ui-slider-pointer {
-	width: 13px;
-	height: 13px;
-	background-color: #EEE;
-	border: 1px solid #2C9FC9;
-	border-radius: 3px;
-	position: relative;
-	top: -3px;
-	left: 0%;
-}
-
-.ui-slider-btn-set {
-	width: 25px;
-	background-color: #2C9FC9;
-	border-radius: 3px;
-	color: #FFF;
-	font-weight: bold;
-	text-align: center;
-}
-
-.ui-slider-btn-set:hover {
-	background-color: #379B4A;
-	cursor: pointer;
-}
-
-.ui-slider-input > input {
-	margin: 0 10px;
-	padding: 0;
-	width: 50px;
-	text-align: center;
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-}
-
-/*
- * UI Button
- */
-
-/* Checkbox */
-
-.ui-checkbox {
-	text-align: center;
-	font-size: 16px;
-	font-family: "Segoe UI", Arial, Helvetica, sans-serif;
-	line-height: 1.5em;
-	color: #FFF;
-
-	-moz-user-select: none;
-	-webkit-user-select: none;
-	-ms-user-select: none;
-	user-select: none;
-}
-
-.ui-checkbox > input {
- 	display: none;
-}
-
-.ui-checkbox > label {
-	font-size: 12px;
-	padding: 0.333em 1.666em 0.5em;
-	height: 1em;
-	line-height: 1em;
-
-	background-color: #888;
-	background-image: url("https://mdn.mozillademos.org/files/5683/disabled.png");
-	background-position: center center;
-	background-repeat: no-repeat;
-
-	color: #FFF;
-	border-radius: 3px;
-	font-weight: bold;
-	float: left;
-}
-
-.ui-checkbox .text {
-	padding-left: 34px;
-	background-position: center left 10px;
-}
-
-.ui-checkbox .left {
-	padding-right: 34px;
-	padding-left: 1.666em;
-	background-position: center right 10px;
-}
-
-.ui-checkbox > label:hover {
-	cursor: pointer;
-}
-
-.ui-checkbox > input:checked + label {
-	background-image: url("https://mdn.mozillademos.org/files/5681/checked.png");
-	background-color: #379B4A;
-}
-
-/*
- * BOX SHADOW GENERATOR TOOL
- */
-
-body {
-	max-width: 1000px;
-	height: 800px;
-	margin: 20px auto 0;
-
-	font-family: "Segoe UI", Arial, Helvetica, sans-serif;
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-
-	-moz-user-select: none;
-	-webkit-user-select: none;
-	-ms-user-select: none;
-}
-
-#container {
-	width: 100%;
-	padding: 2px;
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-}
-
-
-/* container with shadows stacks */
-#stack_container {
-	height: 400px;
-	overflow: hidden;
-	position: relative;
-	border: 1px solid #CCC;
-	border-radius: 3px;
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-}
-
-#stack_container .container {
-	height: 100%;
-	width: 100%;
-	position: absolute;
-	left: 100%;
-	transition-property: left;
-	transition-duration: 0.5s;
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-}
-
-
-#stack_container .title {
-	text-align: center;
-	font-weight: bold;
-	line-height: 2em;
-	border-bottom: 1px solid #43A6E1;
-	color: #666;
-}
-
-
-/*
- * Stack of Layers for shadow
- */
-
-#layer_manager {
-	width: 17%;
-	background-color: #FEFEFE;
-	margin: 0 1% 0 0;
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-	float: left;
-}
-
-
-#layer_manager .button {
-	width: 30%;
-	height: 25px;
-	margin:0 0 10px;
-	color: #333;
-	background-color: #EEE;
-	text-align: center;
-	font-size: 0.75em;
-	line-height: 1.5em;
-	border: 1px solid #CCC;
-	border-radius: 3px;
-
-	display: block;
-	background-position: center center;
-	background-repeat: no-repeat;
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-	float: left;
-}
-
-#layer_manager .button:hover {
-	background-color: #3380C4;
-	border: 1px solid #3380C4;
-	cursor: pointer;
-}
-
-#layer_manager [data-type='add'] {
-	background-image: url("https://mdn.mozillademos.org/files/5685/add-black.png");
-}
-
-#layer_manager [data-type='add']:hover {
-	background-image: url("https://mdn.mozillademos.org/files/5687/add-white.png");
-}
-
-#layer_manager [data-type='move-up'] {
-	background-image: url("https://mdn.mozillademos.org/files/5697/up-black.png");
-	margin-left: 5%;
-	margin-right: 5%;
-}
-
-#layer_manager [data-type='move-up']:hover {
-	background-image: url("https://mdn.mozillademos.org/files/5709/up-white.png");
-}
-
-#layer_manager [data-type='move-down'] {
-	background-image: url("https://mdn.mozillademos.org/files/5693/down-black.png");
-}
-
-#layer_manager [data-type='move-down']:hover {
-	background-image: url("https://mdn.mozillademos.org/files/5695/down-white.png");
-}
-
-/* shadows classes */
-
-#layer_manager .node {
-	width: 100%;
-	margin: 5px 0;
-	padding: 5px;
-	text-align: center;
-	background-color: #EEE;
-	border: 1px solid #DDD;
-	font-size: 0.75em;
-	line-height: 1.5em;
-	color: #333;
-	border-radius: 3px;
-
-	position: relative;
-	display: block;
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-}
-
-#layer_manager .node:hover {
-	color: #FFF;
-	background-color: #3380C4;
-	cursor: pointer;
-}
-
-/* active element styling */
-
-#layer_manager [data-active='layer'] {
-	color: #FFF;
-	border: none;
-	background-color: #379B4A;
-}
-
-#layer_manager [data-active='subject'] {
-	color: #FFF;
-	background-color: #467FC9;
-}
-
-/* delete button */
-
-#layer_manager .delete {
-	width: 1.5em;
-	height: 100%;
-	float: right;
-	border-radius: 3px;
-	background-image: url("https://mdn.mozillademos.org/files/5689/delete-white.png");
-	background-position: center center;
-	background-repeat: no-repeat;
-	position: absolute;
-	top: 0;
-	right: 10px;
-	display: none;
-}
-
-#layer_manager .delete:hover {
-	background-image: url("https://mdn.mozillademos.org/files/5691/delete-yellow.png");
-}
-
-#layer_manager .node:hover .delete {
-	display: block;
-}
-
-
-#layer_manager .stack {
-	padding: 0 5px;
-	max-height: 90%;
-	overflow: auto;
-	overflow-x: hidden;
-}
-
-
-/*
- * Layer Menu
- */
-
-#layer_menu {
-	margin: 0 0 10px 0;
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-}
-
-#layer_menu .button {
-	width: 100px;
-	margin: 0 5px 0 0;
-	padding: 2.5px;
-	color: #333;
-	background-color: #EEE;
-	border: 1px solid #CCC;
-	border-radius: 3px;
-	text-align: center;
-	font-size: 0.75em;
-	line-height: 1.5em;
-
-	position: relative;
-	display: block;
-	float: left;
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-}
-
-#layer_menu .button:hover {
-	color: #FFF;
-	background-color: #3380C4;
-	border: 1px solid #3380C4;
-	cursor: pointer;
-}
-
-#layer_menu .delete {
-	width: 1.5em;
-	height: 100%;
-	float: right;
-	border-radius: 3px;
-	background-image: url("https://mdn.mozillademos.org/files/5689/delete-white.png");
-	background-position: center center;
-	background-repeat: no-repeat;
-	position: absolute;
-	top: 0;
-	right: 5px;
-	display: none;
-}
-
-#layer_menu .delete:hover {
-	background-image: url("https://mdn.mozillademos.org/files/5691/delete-yellow.png");
-}
-
-#layer_menu .button:hover .delete {
-	display: block;
-}
-
-
-/*
- * active element styling
- */
-
-#layer_menu [data-active='subject'] {
-	color: #FFF;
-	background-color: #379B4A;
-	border: 1px solid #379B4A;
-}
-
-
-/* Checkbox */
-
-#layer_menu .ui-checkbox > label {
-	height: 15px;
-	line-height: 17px;
-	font-weight: normal;
-	width: 46px;
-	margin: 0 5px 0 0;
-}
-
-#layer_menu .ui-checkbox > input:checked + label {
-	display: none;
-}
-
-
-/******************************************************************************/
-/******************************************************************************/
-/*
- * Preview Area
- */
-
-#preview_zone {
-	width: 82%;
-	float: left;
-
-}
-
-
-#preview {
-	width: 100%;
-	height: 400px;
-	border: 1px solid #CCC;
-	border-radius: 3px;
-	text-align: center;
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-	cursor: move;
-	float: left;
-}
-
-#preview .content {
-	width: 100%;
-	height: 100%;
-	display: block;
-}
-
-#obj-element {
-	width: 300px;
-	height: 100px;
-	border: 1px solid #CCC;
-	background: #FFF;
-	position: relative;
-}
-
-
-#obj-before {
-	height: 100%;
-	width: 100%;
-	background: #999;
-	border: 1px solid #CCC;
-	text-align: left;
-	display : block;
-	position: absolute;
-	z-index: -1;
-}
-
-#obj-after {
-	height: 100%;
-	width: 100%;
-	background: #DDD;
-	border: 1px solid #CCC;
-	text-align: right;
-	display : block;
-	position: absolute;
-	z-index: -1;
-}
-
-
-/******************************************************************************/
-/******************************************************************************/
-
-/**
- * Controls
- */
-
-.wrap-left {
-	float: left;
-	overflow: hidden;
-}
-
-.wrap-right {
-	float: right;
-	overflow: hidden;
-}
-
-.wrap-left > * {
-	float: left;
-}
-
-.wrap-right > * {
-	float: right;
-}
-
-@media (min-width: 960px) {
-
-	.wrap-left {
-		width: 45%;
-	}
-
-	.wrap-right {
-		width: 55%;
-	}
-}
-
-
-@media (max-width: 959px) {
-
-	.wrap-left {
-		width: 30%;
-	}
-
-	.wrap-right {
-		width: 70%;
-	}
-}
-
-
-#controls {
-	color: #444;
-	margin: 10px 0 0 0;
-}
-
-
-#controls .category {
-	width: 500px;
-	margin: 0 auto 20px;
-	padding: 0;
-
-}
-
-#controls .category .title {
-	width: 100%;
-	height: 1.5em;
-	line-height: 1.5em;
-	color: #AAA;
-	text-align: right;
-}
-
-#controls .category > .group {
-	border: 1px solid #CCC;
-	border-radius: 3px;
-}
-
-
-/**
- * 	Color Picker
- */
-
-@media (min-width: 960px) {
-	#controls .colorpicker {
-		width: 420px;
-	}
-}
-
-@media (max-width: 959px) {
-	#controls .colorpicker {
-		width: 210px;
-	}
-}
-
-#colorpicker {
-	width: 100%;
-	margin: 0 auto;
-}
-
-#colorpicker .gradient {
-	width: 200px;
-	height: 200px;
-	margin: 5px;
-	background: url("https://mdn.mozillademos.org/files/5707/picker_mask_200.png");
-	background: -moz-linear-gradient(bottom, #000 0%, rgba(0, 0, 0, 0) 100%),
-				-moz-linear-gradient(left, #FFF 0%, rgba(255, 255, 255, 0) 100%);
-	background: -webkit-linear-gradient(bottom, #000 0%, rgba(0, 0, 0, 0) 100%),
-				-webkit-linear-gradient(left, #FFF 0%, rgba(255, 255, 255, 0) 100%);
-	background-color: #F00;
-	float: left;
-}
-
-#colorpicker .hue {
-	width: 200px;
-	height: 30px;
-	margin: 5px;
-	background: url("https://mdn.mozillademos.org/files/5701/hue.png");
-	background: -moz-linear-gradient(left, #F00 0%, #FF0 16.66%, #0F0 33.33%, #0FF 50%,
-				#00F 66.66%, #F0F 83.33%, #F00 100%);
-	background: -webkit-linear-gradient(left, #F00 0%, #FF0 16.66%, #0F0 33.33%, #0FF 50%,
-				#00F 66.66%, #F0F 83.33%, #F00 100%);
-	float: left;
-}
-
-#colorpicker .alpha {
-	width: 200px;
-	height: 30px;
-	margin: 5px;
-	border: 1px solid #CCC;
-	float: left;
-	background: url("https://mdn.mozillademos.org/files/5705/alpha.png");
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-}
-
-#colorpicker #alpha {
-	width: 100%;
-	height: 100%;
-	background: url("https://mdn.mozillademos.org/files/5703/alpha_mask.png");
-	background: -moz-linear-gradient(left, rgba(255, 0, 0, 0) 0%, rgba(255, 0, 0, 1) 100%);
-}
-
-#colorpicker #gradient_picker {
-	width: 0.5em;
-	height: 0.5em;
-	border-radius: 0.4em;
-	border: 2px solid #CCC;
-	position: relative;
-	top: 20%;
-	left: 20%;
-}
-
-#colorpicker #hue_selector,
-#colorpicker #alpha_selector {
-	width: 3px;
-	height: 100%;
-	border: 1px solid #777;
-	background-color: #FFF;
-	position: relative;
-	top: -1px;
-	left: 0%;
-}
-
-/* input HSV and RGB */
-#colorpicker .info {
-	width: 200px;
-	margin: 5px;
-	float: left;
-}
-
-#colorpicker .info * {
-	float: left;
-}
-
-#colorpicker .info input {
-	margin: 0;
-	text-align: center;
-	width: 30px;
-	-moz-user-select: text;
-	-webkit-user-select: text;
-	-ms-user-select: text;
-}
-
-#colorpicker .info span {
-	height: 20px;
-	width: 30px;
-	text-align: center;
-	line-height: 20px;
-	display: block;
-}
-
-/* Preview color */
-#colorpicker .block {
-	width: 95px;
-	height: 54px;
-	float: left;
-	position: relative;
-}
-
-#colorpicker .preview {
-	margin: 5px;
-	border: 1px solid #CCC;
-	background-image: url("https://mdn.mozillademos.org/files/5705/alpha.png");
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-}
-
-#colorpicker .preview:before {
-	height: 100%;
-	width: 50%;
-	left: 50%;
-	content: "";
-	background: #FFF;
-	position: absolute;
-	z-index: 1;
-}
-
-#colorpicker .preview > * {
-	width: 50%;
-	height: 100%;
-}
-
-#colorpicker #output_color {
-	width: 100%;
-	height: 100%;
-	position: absolute;
-	z-index: 2;
-}
-
-#colorpicker .block .input {
-	float: right;
-}
-
-#colorpicker [data-topic="a"] > span {
-	width: 50px;
-}
-
-#colorpicker [data-topic="hexa"] {
-	float: right;
-	margin: 10px 0 0 0;
-}
-
-#colorpicker [data-topic="hexa"] > span {
-	display: none;
-}
-
-#colorpicker [data-topic="hexa"] > input {
-	width: 85px;
-	padding: 2px 0;
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-}
-
-
-/*
- * UI Components
- */
-
-/* Property */
-
-.property {
-	height: 20px;
-	margin: 10px 0;
-}
-
-.property * {
-	float: left;
-	height: 100%;
-	line-height: 100%;
-}
-
-/* Slider */
-
-#controls .ui-slider-name {
-	margin: 0 10px 0 0;
-}
-
-/*
- * Output code styling
- */
-
-#output {
-	position: relative;
-}
-
-#output .menu {
-	max-width: 70%;
-	height: 20px;
-	position: absolute;
-	top: 2px;
-}
-
-#output .button {
-	width: 90px;
-	height: 22px;
-	margin: 0 5px 0 0;
-	text-align: center;
-	line-height: 20px;
-	font-size: 14px;
-	color: #FFF;
-	background-color: #999;
-	border-top-left-radius: 3px;
-	border-top-right-radius: 3px;
-	bottom: -5px;
-	float:left;
-}
-
-#output .button:hover {
-	color: #FFF;
-	background-color: #666;
-	cursor: pointer;
-}
-
-#output .menu [data-active="true"] {
-	color: #777;
-	background-color: #FFF;
-	border: 1px solid #CCC;
-	border-bottom: none;
-}
-
-#output .menu [data-topic="before"] {
-	left: 100px;
-}
-
-#output .menu [data-topic="after"] {
-	left: 200px;
-}
-
-#output .output {
-	width: 480px;
-	margin: 10px;
-	padding: 10px;
-	overflow: hidden;
-	color: #555;
-	font-size: 14px;
-	border: 1px dashed #CCC;
-	border-radius: 3px;
-	display: none;
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-
-	-moz-user-select: text;
-	-webkit-user-select: text;
-	-ms-user-select: text;
-}
-
-#output .css-property {
-	width: 100%;
-	float: left;
-	white-space: pre;
-}
-
-#output .name {
-	width: 35%;
-	float: left;
-}
-
-#output .value {
-	width: 65%;
-	float: left;
-}
-
-
- -

JavaScript Content

- -

-
-'use strict';
-
-/**
- * UI-SlidersManager
- */
-
-var SliderManager = (function SliderManager() {
-
-	var subscribers = {};
-	var sliders = [];
-
-	var Slider = function(node) {
-		var min = node.getAttribute('data-min') | 0;
-		var max = node.getAttribute('data-max') | 0;
-		var step = node.getAttribute('data-step') | 0;
-		var value = node.getAttribute('data-value') | 0;
-		var snap = node.getAttribute('data-snap');
-		var topic = node.getAttribute('data-topic');
-
-		this.min = min;
-		this.max = max > 0 ? max : 100;
-		this.step = step === 0 ? 1 : step;
-		this.value = value <= max && value >= min ? value : (min + max) / 2 | 0;
-		this.snap = snap === "true" ? true : false;
-		this.topic = topic;
-		this.node = node;
-
-		var pointer = document.createElement('div');
-		pointer.className = 'ui-slider-pointer';
-		node.appendChild(pointer);
-		this.pointer = pointer;
-
-		setMouseTracking(node, updateSlider.bind(this));
-
-		sliders[topic] = this;
-		setValue(topic, this.value);
-	}
-
-	var setButtonComponent = function setButtonComponent(node) {
-		var type = node.getAttribute('data-type');
-		var topic = node.getAttribute('data-topic');
-		if (type === "sub") {
-			node.textContent = '-';
-			node.addEventListener("click", function() {
-				decrement(topic);
-			});
-		}
-		if (type === "add") {
-			node.textContent = '+';
-			node.addEventListener("click", function() {
-				increment(topic);
-			});
-		}
-	}
-
-	var setInputComponent = function setInputComponent(node) {
-		var topic		= node.getAttribute('data-topic');
-		var unit_type	= node.getAttribute('data-unit');
-
-		var input = document.createElement('input');
-		var unit = document.createElement('span');
-		unit.textContent = unit_type;
-
-		input.setAttribute('type', 'text');
-		node.appendChild(input);
-		node.appendChild(unit);
-
-		input.addEventListener('click', function(e) {
-			this.select();
-		});
-
-		input.addEventListener('change', function(e) {
-			setValue(topic, e.target.value | 0);
-		});
-
-		subscribe(topic, function(value) {
-			node.children[0].value = value;
-		});
-	}
-
-	var increment = function increment(topic) {
-		var slider = sliders[topic];
-		if (slider === null || slider === undefined)
-			return;
-
-		if (slider.value + slider.step <= slider.max) {
-			slider.value += slider.step;
-			setValue(slider.topic, slider.value)
-			notify.call(slider);
-		}
-	};
-
-	var decrement = function decrement(topic) {
-		var slider = sliders[topic];
-		if (slider === null || slider === undefined)
-			return;
-
-		if (slider.value - slider.step >= slider.min) {
-			slider.value -= slider.step;
-			setValue(topic, slider.value)
-			notify.call(slider);
-		}
-	}
-
-	// this = Slider object
-	var updateSlider = function updateSlider(e) {
-		var node = this.node;
-		var pos = e.pageX - node.offsetLeft;
-		var width = node.clientWidth;
-		var delta = this.max - this.min;
-		var offset = this.pointer.clientWidth + 4; // border width * 2
-
-		if (pos < 0) pos = 0;
-		if (pos > width) pos = width;
-
-		var value = pos * delta / width | 0;
-		var precision = value % this.step;
-		value = value - precision + this.min;
-		if (precision > this.step / 2)
-			value = value + this.step;
-
-		if (this.snap)
-			pos =  (value - this.min) * width / delta;
-
-		this.pointer.style.left = pos - offset/2 + "px";
-		this.value = value;
-		node.setAttribute('data-value', value);
-		notify.call(this);
-	}
-
-	var setValue = function setValue(topic, value) {
-		var slider = sliders[topic];
-
-		if (value > slider.max || value < slider.min)
-			return;
-
-		var delta = slider.max - slider.min;
-		var width = slider.node.clientWidth;
-		var offset = slider.pointer.clientWidth;
-		var pos =  (value - slider.min) * width / delta;
-		slider.value = value;
-		slider.pointer.style.left = pos - offset / 2 + "px";
-		slider.node.setAttribute('data-value', value);
-		notify.call(slider);
-	}
-
-	var setMouseTracking = function setMouseTracking(elem, callback) {
-		elem.addEventListener("mousedown", function(e) {
-			callback(e);
-			document.addEventListener("mousemove", callback);
-		});
-
-		document.addEventListener("mouseup", function(e) {
-			document.removeEventListener("mousemove", callback);
-		});
-	}
-
-	var subscribe = function subscribe(topic, callback) {
-		if (subscribers[topic] === undefined)
-			subscribers[topic] = [];
-		subscribers[topic].push(callback);
-	}
-
-	var unsubscribe = function unsubscribe(topic, callback) {
-		subscribers[topic].indexOf(callback);
-		subscribers[topic].splice(index, 1);
-	}
-
-	var notify = function notify() {
-		if (subscribers[this.topic] === undefined)
-			return;
-
-		for (var i in subscribers[this.topic]) {
-			subscribers[this.topic][i](this.value);
-		}
-	}
-
-	var init = function init() {
-		var elem, size;
-
-		elem = document.querySelectorAll('.ui-slider-btn-set');
-		size = elem.length;
-		for (var i = 0; i < size; i++)
-			setButtonComponent(elem[i]);
-
-		elem = document.querySelectorAll('.ui-slider-input');
-		size = elem.length;
-		for (var i = 0; i < size; i++)
-			setInputComponent(elem[i]);
-
-		elem = document.querySelectorAll('.ui-slider');
-		size = elem.length;
-		for (var i = 0; i < size; i++)
-			new Slider(elem[i]);
-	}
-
-	return {
-		init : init,
-		setValue : setValue,
-		subscribe : subscribe,
-		unsubscribe : unsubscribe
-	}
-
-})();
-
-/**
- * UI-ButtonManager
- */
-
-var ButtonManager = (function CheckBoxManager() {
-
-	var subscribers = [];
-	var buttons = [];
-
-	var CheckBox = function CheckBox(node) {
-		var topic = node.getAttribute('data-topic');
-		var state = node.getAttribute('data-state');
-		var name = node.getAttribute('data-label');
-		var align = node.getAttribute('data-text-on');
-
-		state = (state === "true");
-
-		var checkbox = document.createElement("input");
-		var label = document.createElement("label");
-
-		var id = 'checkbox-' + topic;
-		checkbox.id = id;
-		checkbox.setAttribute('type', 'checkbox');
-		checkbox.checked = state;
-
-		label.setAttribute('for', id);
-		if (name) {
-			label.className = 'text';
-			if (align)
-				label.className += ' ' + align;
-			label.textContent = name;
-		}
-
-		node.appendChild(checkbox);
-		node.appendChild(label);
-
-		this.node = node;
-		this.topic = topic;
-		this.checkbox = checkbox;
-
-		checkbox.addEventListener('change', function(e) {
-			notify.call(this);
-		}.bind(this));
-
-		buttons[topic] = this;
-	}
-
-	var getNode =  function getNode(topic) {
-		return buttons[topic].node;
-	}
-
-	var setValue = function setValue(topic, value) {
-		try {
-			buttons[topic].checkbox.checked = value;
-			notify.call(buttons[topic]);
-		}
-		catch(error) {
-			console.log(error, topic, value);
-		}
-	}
-
-	var subscribe = function subscribe(topic, callback) {
-		if (subscribers[topic] === undefined)
-			subscribers[topic] = [];
-
-		subscribers[topic].push(callback);
-	}
-
-	var unsubscribe = function unsubscribe(topic, callback) {
-		subscribers[topic].indexOf(callback);
-		subscribers[topic].splice(index, 1);
-	}
-
-	var notify = function notify() {
-		if (subscribers[this.topic] === undefined)
-			return;
-		for (var i = 0; i < subscribers[this.topic].length; i++)
-			subscribers[this.topic][i](this.checkbox.checked);
-	}
-
-	var init = function init() {
-		var elem = document.querySelectorAll('.ui-checkbox');
-		var size = elem.length;
-		for (var i = 0; i < size; i++)
-			new CheckBox(elem[i]);
-	}
-
-	return {
-		init : init,
-		setValue : setValue,
-		subscribe : subscribe,
-		unsubscribe : unsubscribe
-	}
-
-})();
-
-
-window.addEventListener("load", function(){
-	BoxShadow.init();
-});
-
-var BoxShadow = (function BoxShadow() {
-
-	function getElemById(id) {
-		return document.getElementById(id);
-	}
-
-	/**
-	 * RGBA Color class
-	 */
-
-	function Color() {
-		this.r = 0;
-		this.g = 0;
-		this.b = 0;
-		this.a = 1;
-		this.hue = 0;
-		this.saturation = 0;
-		this.value = 0;
-	}
-
-	Color.prototype.copy = function copy(obj) {
-		if(obj instanceof Color !== true) {
-			console.log("Typeof instance not Color");
-			return;
-		}
-
-		this.r = obj.r;
-		this.g = obj.g;
-		this.b = obj.b;
-		this.a = obj.a;
-		this.hue = obj.hue;
-		this.saturation = obj.saturation;
-		this.value = obj.value;
-	}
-
-	Color.prototype.setRGBA = function setRGBA(red, green, blue, alpha) {
-		if (red != undefined)
-			this.r = red | 0;
-		if (green != undefined)
-			this.g = green | 0;
-		if (blue != undefined)
-			this.b = blue | 0;
-		if (alpha != undefined)
-			this.a = alpha | 0;
-	}
-
-	/**
-	 * HSV/HSB (hue, saturation, value / brightness)
-	 * @param hue			0-360
-	 * @param saturation	0-100
-	 * @param value 		0-100
-	 */
-	Color.prototype.setHSV = function setHSV(hue, saturation, value) {
-		this.hue = hue;
-		this.saturation = saturation;
-		this.value = value;
-		this.updateRGB();
-	}
-
-	Color.prototype.updateRGB = function updateRGB() {
-		var sat = this.saturation / 100;
-		var value = this.value / 100;
-		var C = sat * value;
-		var H = this.hue / 60;
-		var X = C * (1 - Math.abs(H % 2 - 1));
-		var m = value - C;
-		var precision = 255;
-
-		C = (C + m) * precision;
-		X = (X + m) * precision;
-		m = m * precision;
-
-		if (H >= 0 && H < 1) {	this.setRGBA(C, X, m);	return; }
-		if (H >= 1 && H < 2) {	this.setRGBA(X, C, m);	return; }
-		if (H >= 2 && H < 3) {	this.setRGBA(m, C, X);	return; }
-		if (H >= 3 && H < 4) {	this.setRGBA(m, X, C);	return; }
-		if (H >= 4 && H < 5) {	this.setRGBA(X, m, C);	return; }
-		if (H >= 5 && H < 6) {	this.setRGBA(C, m, X);	return; }
-	}
-
-	Color.prototype.updateHSV = function updateHSV() {
-		var red		= this.r / 255;
-		var green	= this.g / 255;
-		var blue	= this.b / 255;
-
-		var cmax = Math.max(red, green, blue);
-		var cmin = Math.min(red, green, blue);
-		var delta = cmax - cmin;
-		var hue = 0;
-		var saturation = 0;
-
-		if (delta) {
-			if (cmax === red ) { hue = ((green - blue) / delta); }
-			if (cmax === green ) { hue = 2 + (blue - red) / delta; }
-			if (cmax === blue ) { hue = 4 + (red - green) / delta; }
-			if (cmax) saturation = delta / cmax;
-		}
-
-		this.hue = 60 * hue | 0;
-		if (this.hue < 0) this.hue += 360;
-		this.saturation = (saturation * 100) | 0;
-		this.value = (cmax * 100) | 0;
-	}
-
-	Color.prototype.setHexa = function setHexa(value) {
-		var valid  = /(^#{0,1}[0-9A-F]{6}$)|(^#{0,1}[0-9A-F]{3}$)/i.test(value)
-		if (valid !== true)
-			return;
-
-		if (value[0] === '#')
-			value = value.slice(1, value.length);
-
-		if (value.length === 3)
-			value = value.replace(/([0-9A-F])([0-9A-F])([0-9A-F])/i,"$1$1$2$2$3$3");
-
-		this.r = parseInt(value.substr(0, 2), 16);
-		this.g = parseInt(value.substr(2, 2), 16);
-		this.b = parseInt(value.substr(4, 2), 16);
-
-		this.alpha	= 1;
-	}
-
-	Color.prototype.getHexa = function getHexa() {
-		var r = this.r.toString(16);
-		var g = this.g.toString(16);
-		var b = this.b.toString(16);
-		if (this.r < 16) r = '0' + r;
-		if (this.g < 16) g = '0' + g;
-		if (this.b < 16) b = '0' + b;
-		var value = '#' + r + g + b;
-		return value.toUpperCase();
-	}
-
-	Color.prototype.getRGBA = function getRGBA() {
-
-		var rgb = "(" + this.r + ", " + this.g + ", " + this.b;
-		var a = '';
-		var v = '';
-		if (this.a !== 1) {
-			a = 'a';
-			v = ', ' + this.a;
-		}
-
-		var value = "rgb" + a + rgb + v + ")";
-		return value;
-	}
-
-	Color.prototype.getColor = function getColor() {
-		if (this.a | 0 === 1)
-			return this.getHexa();
-		return this.getRGBA();
-	}
-
-	/**
-	 * Shadow Object
-	 */
-	function Shadow() {
-		this.inset  = false;
-		this.posX   = 5;
-		this.posY   = -5;
-		this.blur   = 5;
-		this.spread = 0;
-		this.color  = new Color();
-
-		var hue			= (Math.random() * 360) | 0;
-		var saturation	= (Math.random() * 75) | 0;
-		var value 		= (Math.random() * 50 + 50) | 0;
-		this.color.setHSV(hue, saturation, value, 1);
-	}
-
-	Shadow.prototype.computeCSS = function computeCSS() {
-		var value = "";
-		if (this.inset === true)
-			value += "inset ";
-		value += this.posX + "px ";
-		value += this.posY + "px ";
-		value += this.blur + "px ";
-		value += this.spread + "px ";
-		value += this.color.getColor();
-
-		return value;
-	}
-
-	Shadow.prototype.toggleInset = function toggleInset(value) {
-		if (value !== undefined || typeof value === "boolean")
-			this.inset = value;
-		else
-			this.inset = this.inset === true ? false : true;
-	}
-
-	Shadow.prototype.copy = function copy(obj) {
-		if(obj instanceof Shadow !== true) {
-			console.log("Typeof instance not Shadow");
-			return;
-		}
-
-		this.inset  = obj.inset;
-		this.posX   = obj.posX;
-		this.posY   = obj.posY;
-		this.blur   = obj.blur;
-		this.spread = obj.spread;
-		this.color.copy(obj.color);
-	}
-
-	/**
-	 * Color Picker
-	 */
-	var ColoPicker = (function ColoPicker() {
-
-		var colorpicker;
-		var hue_area;
-		var gradient_area;
-		var alpha_area;
-		var gradient_picker;
-		var hue_selector;
-		var alpha_selector;
-		var pick_object;
-		var info_rgb;
-		var info_hsv;
-		var info_hexa;
-		var output_color;
-		var color = new Color();
-		var subscribers = [];
-
-		var updateColor = function updateColor(e) {
-			var x = e.pageX - gradient_area.offsetLeft;
-			var y = e.pageY - gradient_area.offsetTop;
-
-			// width and height should be the same
-			var size = gradient_area.clientWidth;
-
-			if (x > size)
-				x = size;
-			if (y > size)
-				y = size;
-
-			if (x < 0) x = 0;
-			if (y < 0) y = 0;
-
-			var value = 100 - (y * 100 / size) | 0;
-			var saturation = x * 100 / size | 0;
-
-			color.setHSV(color.hue, saturation, value);
-			// should update just
-			// color pointer location
-			updateUI();
-			notify("color", color);
-		}
-
-		var updateHue = function updateHue(e) {
-			var x = e.pageX - hue_area.offsetLeft;
-			var width = hue_area.clientWidth;
-
-			if (x < 0) x = 0;
-			if (x > width) x = width;
-
-			var hue = ((360 * x) / width) | 0;
-			if (hue === 360) hue = 359;
-
-			color.setHSV(hue, color.saturation, color.value);
-
-			// should update just
-			// hue pointer location
-			// picker area background
-			// alpha area background
-			updateUI();
-			notify("color", color);
-		}
-
-		var updateAlpha = function updateAlpha(e) {
-			var x = e.pageX - alpha_area.offsetLeft;
-			var width = alpha_area.clientWidth;
-
-			if (x < 0) x = 0;
-			if (x > width) x = width;
-
-			color.a = (x / width).toFixed(2);
-
-			// should update just
-			// alpha pointer location
-			updateUI();
-			notify("color", color);
-		}
-
-		var setHueGfx = function setHueGfx(hue) {
-			var sat = color.saturation;
-			var val = color.value;
-			var alpha = color.a;
-
-			color.setHSV(hue, 100, 100);
-			gradient_area.style.backgroundColor = color.getHexa();
-
-			color.a = 0;
-			var start = color.getRGBA();
-			color.a = 1;
-			var end = color.getRGBA();
-			color.a = alpha;
-
-			var gradient = '-moz-linear-gradient(left, ' +	start + '0%, ' + end + ' 100%)';
-			alpha_area.style.background = gradient;
-		}
-
-		var updateUI = function updateUI() {
-			var x, y;		// coordinates
-			var size;		// size of the area
-			var offset;		// pointer graphic selector offset
-
-			// Set color pointer location
-			size = gradient_area.clientWidth;
-			offset = gradient_picker.clientWidth / 2 + 2;
-
-			x = (color.saturation * size / 100) | 0;
-			y = size - (color.value * size / 100) | 0;
-
-			gradient_picker.style.left = x - offset + "px";
-			gradient_picker.style.top = y - offset + "px";
-
-			// Set hue pointer location
-			size = hue_area.clientWidth;
-			offset = hue_selector.clientWidth/2;
-			x = (color.hue * size / 360 ) | 0;
-			hue_selector.style.left = x - offset + "px";
-
-			// Set alpha pointer location
-			size = alpha_area.clientWidth;
-			offset = alpha_selector.clientWidth/2;
-			x = (color.a * size) | 0;
-			alpha_selector.style.left = x - offset + "px";
-
-			// Set picker area background
-			var nc = new Color();
-			nc.copy(color);
-			if (nc.hue === 360) nc.hue = 0;
-			nc.setHSV(nc.hue, 100, 100);
-			gradient_area.style.backgroundColor = nc.getHexa();
-
-			// Set alpha area background
-			nc.copy(color);
-			nc.a = 0;
-			var start = nc.getRGBA();
-			nc.a = 1;
-			var end = nc.getRGBA();
-			var gradient = '-moz-linear-gradient(left, ' +	start + '0%, ' + end + ' 100%)';
-			alpha_area.style.background = gradient;
-
-			// Update color info
-			notify("color", color);
-			notify("hue", color.hue);
-			notify("saturation", color.saturation);
-			notify("value", color.value);
-			notify("r", color.r);
-			notify("g", color.g);
-			notify("b", color.b);
-			notify("a", color.a);
-			notify("hexa", color.getHexa());
-			output_color.style.backgroundColor = color.getRGBA();
-		}
-
-		var setInputComponent = function setInputComponent(node) {
-			var topic = node.getAttribute('data-topic');
-			var title = node.getAttribute('data-title');
-			var action = node.getAttribute('data-action');
-			title = title === null ? '' : title;
-
-			var input = document.createElement('input');
-			var info = document.createElement('span');
-			info.textContent = title;
-
-			input.setAttribute('type', 'text');
-			input.setAttribute('data-action', 'set-' + action + '-' + topic);
-			node.appendChild(info);
-			node.appendChild(input);
-
-			input.addEventListener('click', function(e) {
-				this.select();
-			});
-
-			input.addEventListener('change', function(e) {
-				if (action === 'HSV')
-					inputChangeHSV(topic);
-				if (action === 'RGB')
-					inputChangeRGB(topic);
-				if (action === 'alpha')
-					inputChangeAlpha(topic);
-				if (action === 'hexa')
-					inputChangeHexa(topic);
-			});
-
-			subscribe(topic, function(value) {
-				node.children[1].value = value;
-			});
-		}
-
-		var inputChangeHSV = function actionHSV(topic) {
-			var selector = "[data-action='set-HSV-" + topic + "']";
-			var node = document.querySelector("#colorpicker " + selector);
-			var value = parseInt(node.value);
-
-			if (typeof value === 'number' && isNaN(value) === false &&
-				value >= 0 && value < 360)
-				color[topic] = value;
-
-			color.updateRGB();
-			updateUI();
-		}
-
-		var inputChangeRGB = function inputChangeRGB(topic) {
-			var selector = "[data-action='set-RGB-" + topic + "']";
-			var node = document.querySelector("#colorpicker " + selector);
-			var value = parseInt(node.value);
-
-			if (typeof value === 'number' && isNaN(value) === false &&
-				value >= 0 && value <= 255)
-				color[topic] = value;
-
-			color.updateHSV();
-			updateUI();
-		}
-
-		var inputChangeAlpha = function inputChangeAlpha(topic) {
-			var selector = "[data-action='set-alpha-" + topic + "']";
-			var node = document.querySelector("#colorpicker " + selector);
-			var value = parseFloat(node.value);
-
-			if (typeof value === 'number' && isNaN(value) === false &&
-				value >= 0 && value <= 1)
-				color.a = value.toFixed(2);
-
-			updateUI();
-		}
-
-		var inputChangeHexa = function inputChangeHexa(topic) {
-			var selector = "[data-action='set-hexa-" + topic + "']";
-			var node = document.querySelector("#colorpicker " + selector);
-			var value = node.value;
-			color.setHexa(value);
-			color.updateHSV();
-			updateUI();
-		}
-
-		var setMouseTracking = function setMouseTracking(elem, callback) {
-
-			elem.addEventListener("mousedown", function(e) {
-				callback(e);
-				document.addEventListener("mousemove", callback);
-			});
-
-			document.addEventListener("mouseup", function(e) {
-				document.removeEventListener("mousemove", callback);
-			});
-		}
-
-		/*
-		 * Observer
-		 */
-		var setColor = function setColor(obj) {
-			if(obj instanceof Color !== true) {
-				console.log("Typeof instance not Color");
-				return;
-			}
-			color.copy(obj);
-			updateUI();
-		}
-
-		var subscribe = function subscribe(topic, callback) {
-			if (subscribers[topic] === undefined)
-				subscribers[topic] = [];
-
-			subscribers[topic].push(callback);
-		}
-
-		var unsubscribe = function unsubscribe(callback) {
-			subscribers.indexOf(callback);
-			subscribers.splice(index, 1);
-		}
-
-		var notify = function notify(topic, value) {
-			for (var i in subscribers[topic])
-				subscribers[topic][i](value);
-		}
-
-		var init = function init() {
-			colorpicker		= getElemById("colorpicker");
-			hue_area		= getElemById("hue");
-			gradient_area	= getElemById("gradient");
-			alpha_area		= getElemById("alpha");
-			gradient_picker	= getElemById("gradient_picker");
-			hue_selector	= getElemById("hue_selector");
-			alpha_selector	= getElemById("alpha_selector");
-			output_color	= getElemById("output_color");
-
-			var elem = document.querySelectorAll('#colorpicker .input');
-			var size = elem.length;
-			for (var i = 0; i < size; i++)
-				setInputComponent(elem[i]);
-
-			setMouseTracking(gradient_area, updateColor);
-			setMouseTracking(hue_area, updateHue);
-			setMouseTracking(alpha_area, updateAlpha);
-
-		}
-
-		return {
-			init : init,
-			setColor : setColor,
-			subscribe : subscribe,
-			unsubscribe : unsubscribe
-		}
-
-	})();
-
-	/**
-	 * Shadow dragging
-	 */
-	var PreviewMouseTracking = (function Drag() {
-		var active = false;
-		var lastX = 0;
-		var lastY = 0;
-		var subscribers = [];
-
-		var init = function init(id) {
-			var elem = getElemById(id);
-			elem.addEventListener('mousedown', dragStart, false);
-			document.addEventListener('mouseup', dragEnd, false);
-		}
-
-		var dragStart = function dragStart(e) {
-			if (e.button !== 0)
-				return;
-
-			active = true;
-			lastX = e.clientX;
-			lastY = e.clientY;
-			document.addEventListener('mousemove', mouseDrag, false);
-		}
-
-		var dragEnd = function dragEnd(e) {
-			if (e.button !== 0)
-				return;
-
-			if (active === true) {
-				active = false;
-				document.removeEventListener('mousemove', mouseDrag, false);
-			}
-		}
-
-		var mouseDrag = function mouseDrag(e) {
-			notify(e.clientX - lastX, e.clientY - lastY);
-			lastX = e.clientX;
-			lastY = e.clientY;
-		}
-
-		var subscribe = function subscribe(callback) {
-			subscribers.push(callback);
-		}
-
-		var unsubscribe = function unsubscribe(callback) {
-			var index = subscribers.indexOf(callback);
-			subscribers.splice(index, 1);
-		}
-
-		var notify = function notify(deltaX, deltaY) {
-			for (var i in subscribers)
-				subscribers[i](deltaX, deltaY);
-		}
-
-		return {
-			init : init,
-			subscribe : subscribe,
-			unsubscribe : unsubscribe
-		}
-
-	})();
-
-	/*
-	 * Element Class
-	 */
-	var CssClass = function CssClass(id) {
-		this.left = 0;
-		this.top = 0;
-		this.rotate = 0;
-		this.width = 300;
-		this.height = 100;
-		this.display = true;
-		this.border = true;
-		this.zIndex = -1;
-		this.bgcolor = new Color();
-		this.id = id;
-		this.node = getElemById('obj-' + id);
-		this.object = getElemById(id);
-		this.shadowID = null;
-		this.shadows = []
-		this.render = [];
-		this.init();
-	}
-
-	CssClass.prototype.init = function init() {
-		this.left = ((this.node.parentNode.clientWidth - this.node.clientWidth) / 2) | 0;
-		this.top = ((this.node.parentNode.clientHeight - this.node.clientHeight) / 2) | 0;
-
-		this.setTop(this.top);
-		this.setLeft(this.left);
-		this.setHeight(this.height);
-		this.setWidth(this.width);
-		this.bgcolor.setHSV(0, 0, 100);
-		this.updateBgColor(this.bgcolor);
-	}
-
-	CssClass.prototype.updatePos = function updatePos(deltaX, deltaY) {
-		this.left += deltaX;
-		this.top += deltaY;
-		this.node.style.top = this.top + "px";
-		this.node.style.left = this.left + "px";
-		SliderManager.setValue("left", this.left);
-		SliderManager.setValue("top", this.top);
-	}
-
-	CssClass.prototype.setLeft = function setLeft(value) {
-		this.left = value;
-		this.node.style.left = this.left + "px";
-		OutputManager.updateProperty(this.id, 'left', this.left + 'px');
-	}
-
-	CssClass.prototype.setTop = function setTop(value) {
-		this.top = value;
-		this.node.style.top = this.top + 'px';
-		OutputManager.updateProperty(this.id, 'top', this.top + 'px');
-	}
-
-	CssClass.prototype.setWidth = function setWidth(value) {
-		this.width = value;
-		this.node.style.width = this.width + 'px';
-		OutputManager.updateProperty(this.id, 'width', this.width + 'px');
-	}
-
-	CssClass.prototype.setHeight = function setHeight(value) {
-		this.height = value;
-		this.node.style.height = this.height + 'px';
-		OutputManager.updateProperty(this.id, 'height', this.height + 'px');
-	}
-
-	// Browser support
-	CssClass.prototype.setRotate = function setRotate(value) {
-		var cssvalue = 'rotate(' + value +'deg)';
-
-		this.node.style.transform = cssvalue;
-		this.node.style.webkitTransform = cssvalue;
-		this.node.style.msTransform = cssvalue;
-
-		if (value !== 0) {
-			if (this.rotate === 0) {
-				OutputManager.toggleProperty(this.id, 'transform', true);
-				OutputManager.toggleProperty(this.id, '-webkit-transform', true);
-				OutputManager.toggleProperty(this.id, '-ms-transform', true);
-			}
-		}
-		else {
-			OutputManager.toggleProperty(this.id, 'transform', false);
-			OutputManager.toggleProperty(this.id, '-webkit-transform', false);
-			OutputManager.toggleProperty(this.id, '-ms-transform', false);
-		}
-
-		OutputManager.updateProperty(this.id, 'transform', cssvalue);
-		OutputManager.updateProperty(this.id, '-webkit-transform', cssvalue);
-		OutputManager.updateProperty(this.id, '-ms-transform', cssvalue);
-		this.rotate = value;
-	}
-
-	CssClass.prototype.setzIndex = function setzIndex(value) {
-		this.node.style.zIndex = value;
-		OutputManager.updateProperty(this.id, 'z-index', value);
-		this.zIndex = value;
-	}
-
-	CssClass.prototype.toggleDisplay = function toggleDisplay(value) {
-		if (typeof value !== "boolean" || this.display === value)
-			return;
-
-		this.display = value;
-		var display = this.display === true ? "block" : "none";
-		this.node.style.display = display;
-		this.object.style.display = display;
-	}
-
-	CssClass.prototype.toggleBorder = function toggleBorder(value) {
-		if (typeof value !== "boolean" || this.border === value)
-			return;
-
-		this.border = value;
-		var border = this.border === true ? "1px solid #CCC" : "none";
-		this.node.style.border = border;
-	}
-
-	CssClass.prototype.updateBgColor = function updateBgColor(color) {
-		this.bgcolor.copy(color);
-		this.node.style.backgroundColor = color.getColor();
-		OutputManager.updateProperty(this.id, 'background-color', color.getColor());
-	}
-
-	CssClass.prototype.updateShadows = function updateShadows() {
-		if (this.render.length === 0)
-			OutputManager.toggleProperty(this.id, 'box-shadow', false);
-		if (this.render.length === 1)
-			OutputManager.toggleProperty(this.id, 'box-shadow', true);
-
-		this.node.style.boxShadow = this.render.join(", ");
-		OutputManager.updateProperty(this.id, 'box-shadow', this.render.join(", \n"));
-
-	}
-
-
-	/**
-	 * Tool Manager
-	 */
-	var Tool = (function Tool() {
-
-		var preview;
-		var classes = [];
-		var active = null;
-		var animate = false;
-
-		/*
-		 * Toll actions
-		 */
-		var addCssClass = function addCssClass(id) {
-			classes[id] = new CssClass(id);
-		}
-
-		var setActiveClass = function setActiveClass(id) {
-			active = classes[id];
-			active.shadowID = null;
-			ColoPicker.setColor(classes[id].bgcolor);
-			SliderManager.setValue("top", active.top);
-			SliderManager.setValue("left", active.left);
-			SliderManager.setValue("rotate", active.rotate);
-			SliderManager.setValue("z-index", active.zIndex);
-			SliderManager.setValue("width", active.width);
-			SliderManager.setValue("height", active.height);
-			ButtonManager.setValue("border-state", active.border);
-			active.updateShadows();
-		}
-
-		var disableClass = function disableClass(topic) {
-			classes[topic].toggleDisplay(false);
-			ButtonManager.setValue(topic, false);
-		}
-
-		var addShadow = function addShadow(position) {
-			if (animate === true)
-				return -1;
-
-			active.shadows.splice(position, 0, new Shadow());
-			active.render.splice(position, 0, null);
-		}
-
-		var swapShadow = function swapShadow(id1, id2) {
-			var x = active.shadows[id1];
-			active.shadows[id1] = active.shadows[id2];
-			active.shadows[id2] = x;
-			updateShadowCSS(id1);
-			updateShadowCSS(id2);
-		}
-
-		var deleteShadow = function deleteShadow(position) {
-			active.shadows.splice(position, 1);
-			active.render.splice(position, 1);
-			active.updateShadows();
-		}
-
-		var setActiveShadow = function setActiveShadow(id, glow) {
-			active.shadowID = id;
-			ColoPicker.setColor(active.shadows[id].color);
-			ButtonManager.setValue("inset", active.shadows[id].inset);
-			SliderManager.setValue("blur", active.shadows[id].blur);
-			SliderManager.setValue("spread", active.shadows[id].spread);
-			SliderManager.setValue("posX", active.shadows[id].posX);
-			SliderManager.setValue("posY", active.shadows[id].posY);
-			if (glow === true)
-				addGlowEffect(id);
-		}
-
-		var addGlowEffect = function addGlowEffect(id) {
-			if (animate === true)
-				return;
-
-			animate = true;
-			var store = new Shadow();
-			var shadow = active.shadows[id];
-
-			store.copy(shadow);
-			shadow.color.setRGBA(40, 125, 200, 1);
-			shadow.blur = 10;
-			shadow.spread = 10;
-
-			active.node.style.transition = "box-shadow 0.2s";
-			updateShadowCSS(id);
-
-			setTimeout(function() {
-				shadow.copy(store);
-				updateShadowCSS(id);
-				setTimeout(function() {
-					active.node.style.removeProperty("transition");
-					animate = false;
-				}, 100);
-			}, 200);
-		}
-
-		var updateActivePos = function updateActivePos(deltaX, deltaY) {
-			if (active.shadowID === null)
-				active.updatePos(deltaX, deltaY);
-			else
-				updateShadowPos(deltaX, deltaY);
-		}
-
-		/*
-		 * Shadow properties
-		 */
-		var updateShadowCSS = function updateShadowCSS(id) {
-			active.render[id] = active.shadows[id].computeCSS();
-			active.updateShadows();
-		}
-
-		var toggleShadowInset = function toggleShadowInset(value) {
-			if (active.shadowID === null)
-				return;
-			active.shadows[active.shadowID].toggleInset(value);
-			updateShadowCSS(active.shadowID);
-		}
-
-		var updateShadowPos = function updateShadowPos(deltaX, deltaY) {
-			var shadow = active.shadows[active.shadowID];
-			shadow.posX += deltaX;
-			shadow.posY += deltaY;
-			SliderManager.setValue("posX", shadow.posX);
-			SliderManager.setValue("posY", shadow.posY);
-			updateShadowCSS(active.shadowID);
-		}
-
-		var setShadowPosX = function setShadowPosX(value) {
-			if (active.shadowID === null)
-				return;
-			active.shadows[active.shadowID].posX = value;
-			updateShadowCSS(active.shadowID);
-		}
-
-		var setShadowPosY = function setShadowPosY(value) {
-			if (active.shadowID === null)
-				return;
-			active.shadows[active.shadowID].posY = value;
-			updateShadowCSS(active.shadowID);
-		}
-
-		var setShadowBlur = function setShadowBlur(value) {
-			if (active.shadowID === null)
-				return;
-			active.shadows[active.shadowID].blur = value;
-			updateShadowCSS(active.shadowID);
-		}
-
-		var setShadowSpread = function setShadowSpread(value) {
-			if (active.shadowID === null)
-				return;
-			active.shadows[active.shadowID].spread = value;
-			updateShadowCSS(active.shadowID);
-		}
-
-		var updateShadowColor = function updateShadowColor(color) {
-			active.shadows[active.shadowID].color.copy(color);
-			updateShadowCSS(active.shadowID);
-		}
-
-		/*
-		 * Element Properties
-		 */
-		var updateColor = function updateColor(color) {
-			if (active.shadowID === null)
-				active.updateBgColor(color);
-			else
-				updateShadowColor(color);
-		}
-
-		var init = function init() {
-			preview = getElemById("preview");
-
-			ColoPicker.subscribe("color", updateColor);
-			PreviewMouseTracking.subscribe(updateActivePos);
-
-			// Affects shadows
-			ButtonManager.subscribe("inset", toggleShadowInset);
-			SliderManager.subscribe("posX", setShadowPosX);
-			SliderManager.subscribe("posY", setShadowPosY);
-			SliderManager.subscribe("blur", setShadowBlur);
-			SliderManager.subscribe("spread", setShadowSpread);
-
-			// Affects element
-			SliderManager.subscribe("top", function(value){
-				active.setTop(value);
-			});
-			SliderManager.subscribe("left", function(value){
-				active.setLeft(value);
-			});
-			SliderManager.subscribe("rotate", function(value) {
-				if (active == classes["element"])
-					return;
-				active.setRotate(value);
-			});
-
-			SliderManager.subscribe("z-index", function(value) {
-				if (active == classes["element"])
-					return;
-				active.setzIndex(value);
-			});
-
-			SliderManager.subscribe("width", function(value) {
-				active.setWidth(value)
-			});
-
-			SliderManager.subscribe("height", function(value) {
-				active.setHeight(value)
-			});
-
-			// Actions
-			classes['before'].top = -30;
-			classes['before'].left = -30;
-			classes['after'].top = 30;
-			classes['after'].left = 30;
-			classes['before'].toggleDisplay(false);
-			classes['after'].toggleDisplay(false);
-			ButtonManager.setValue('before', false);
-			ButtonManager.setValue('after', false);
-
-			ButtonManager.subscribe("before", classes['before'].toggleDisplay.bind(classes['before']));
-			ButtonManager.subscribe("after", classes['after'].toggleDisplay.bind(classes['after']));
-
-			ButtonManager.subscribe("border-state", function(value) {
-				active.toggleBorder(value);
-			});
-
-		}
-
-		return {
-			init 			: init,
-			addShadow		: addShadow,
-			swapShadow		: swapShadow,
-			addCssClass		: addCssClass,
-			disableClass	: disableClass,
-			deleteShadow	: deleteShadow,
-			setActiveClass	: setActiveClass,
-			setActiveShadow : setActiveShadow
-		}
-
-	})();
-
-	/**
-	 * Layer Manager
-	 */
-	var LayerManager = (function LayerManager() {
-		var stacks = [];
-		var active = {
-			node : null,
-			stack : null
-		}
-		var elements = {};
-
-		var mouseEvents = function mouseEvents(e) {
-			var node = e.target;
-			var type = node.getAttribute('data-type');
-
-			if (type === 'subject')
-				setActiveStack(stacks[node.id]);
-
-			if (type === 'disable') {
-				Tool.disableClass(node.parentNode.id);
-				setActiveStack(stacks['element']);
-			}
-
-			if (type === 'add')
-				active.stack.addLayer();
-
-			if (type === 'layer')
-				active.stack.setActiveLayer(node);
-
-			if (type === 'delete')
-				active.stack.deleteLayer(node.parentNode);
-
-			if (type === 'move-up')
-				active.stack.moveLayer(1);
-
-			if (type === 'move-down')
-				active.stack.moveLayer(-1);
-		}
-
-		var setActiveStack = function setActiveStack(stackObj) {
-			active.stack.hide();
-			active.stack = stackObj;
-			active.stack.show();
-		}
-
-		/*
-		 * Stack object
-		 */
-		var Stack = function Stack(subject) {
-			var S = document.createElement('div');
-			var title = document.createElement('div');
-			var stack = document.createElement('div');
-
-			S.className = 'container';
-			stack.className = 'stack';
-			title.className = 'title';
-			title.textContent = subject.getAttribute('data-title');
-			S.appendChild(title);
-			S.appendChild(stack);
-
-			this.id = subject.id;
-			this.container = S;
-			this.stack = stack;
-			this.subject = subject;
-			this.order = [];
-			this.uid = 0;
-			this.count = 0;
-			this.layer = null;
-			this.layerID = 0;
-		}
-
-		Stack.prototype.addLayer = function addLayer() {
-			if (Tool.addShadow(this.layerID) == -1)
-				return;
-
-			var uid = this.getUID();
-			var layer = this.createLayer(uid);
-
-			if (this.layer === null && this.stack.children.length >= 1)
-				this.layer = this.stack.children[0];
-
-			this.stack.insertBefore(layer, this.layer);
-			this.order.splice(this.layerID, 0, uid);
-			this.count++;
-			this.setActiveLayer(layer);
-		}
-
-		Stack.prototype.createLayer = function createLayer(uid) {
-			var layer = document.createElement('div');
-			var del = document.createElement('span');
-
-			layer.className = 'node';
-			layer.setAttribute('data-shid', uid);
-			layer.setAttribute('data-type', 'layer');
-			layer.textContent = 'тень ' + uid;
-
-			del.className = 'delete';
-			del.setAttribute('data-type', 'delete');
-
-			layer.appendChild(del);
-			return layer;
-		}
-
-		Stack.prototype.getUID = function getUID() {
-			return this.uid++;
-		}
-
-		// SOLVE IE BUG
-		Stack.prototype.moveLayer = function moveLayer(direction) {
-			if (this.count <= 1 || this.layer === null)
-				return;
-			if (direction === -1 && this.layerID === (this.count - 1) )
-				return;
-			if (direction === 1 && this.layerID === 0 )
-				return;
-
-			if (direction === -1) {
-				var before = null;
-				Tool.swapShadow(this.layerID, this.layerID + 1);
-				this.swapOrder(this.layerID, this.layerID + 1);
-				this.layerID += 1;
-
-				if (this.layerID + 1 !== this.count)
-					before = this.stack.children[this.layerID + 1];
-
-				this.stack.insertBefore(this.layer, before);
-				Tool.setActiveShadow(this.layerID, false);
-			}
-
-			if (direction === 1) {
-				Tool.swapShadow(this.layerID, this.layerID - 1);
-				this.swapOrder(this.layerID, this.layerID - 1);
-				this.layerID -= 1;
-				this.stack.insertBefore(this.layer, this.stack.children[this.layerID]);
-				Tool.setActiveShadow(this.layerID, false);
-			}
-		}
-
-		Stack.prototype.swapOrder = function swapOrder(pos1, pos2) {
-			var x = this.order[pos1];
-			this.order[pos1] = this.order[pos2];
-			this.order[pos2] = x;
-		}
-
-		Stack.prototype.deleteLayer = function deleteLayer(node) {
-			var shadowID =  node.getAttribute('data-shid') | 0;
-			var index = this.order.indexOf(shadowID);
-			this.stack.removeChild(this.stack.children[index]);
-			this.order.splice(index, 1);
-			this.count--;
-
-			Tool.deleteShadow(index);
-
-			if (index > this.layerID)
-				return;
-
-			if (index == this.layerID) {
-				if (this.count >= 1) {
-					this.layerID = 0;
-					this.setActiveLayer(this.stack.children[0], true);
-				}
-				else {
-					this.layer = null;
-					this.show();
-				}
-			}
-
-			if (index < this.layerID) {
-				this.layerID--;
-				Tool.setActiveShadow(this.layerID, true);
-			}
-
-		}
-
-		Stack.prototype.setActiveLayer = function setActiveLayer(node) {
-			elements.shadow_properties.style.display = 'block';
-			elements.element_properties.style.display = 'none';
-
-			if (this.layer)
-				this.layer.removeAttribute('data-active');
-
-			this.layer = node;
-			this.layer.setAttribute('data-active', 'layer');
-
-			var shadowID =  node.getAttribute('data-shid') | 0;
-			this.layerID = this.order.indexOf(shadowID);
-			Tool.setActiveShadow(this.layerID, true);
-		}
-
-		Stack.prototype.unsetActiveLayer = function unsetActiveLayer() {
-			if (this.layer)
-				this.layer.removeAttribute('data-active');
-
-			this.layer = null;
-			this.layerID = 0;
-		}
-
-		Stack.prototype.hide = function hide() {
-			this.unsetActiveLayer();
-			this.subject.removeAttribute('data-active');
-			var style = this.container.style;
-			style.left = '100%';
-			style.zIndex = '0';
-		}
-
-		Stack.prototype.show = function show() {
-			elements.shadow_properties.style.display = 'none';
-			elements.element_properties.style.display = 'block';
-
-			if (this.id === 'element') {
-				elements.zIndex.style.display = 'none';
-				elements.transform_rotate.style.display = 'none';
-			}
-			else {
-				elements.zIndex.style.display = 'block';
-				elements.transform_rotate.style.display = 'block';
-			}
-
-			this.subject.setAttribute('data-active', 'subject');
-			var style = this.container.style;
-			style.left = '0';
-			style.zIndex = '10';
-			Tool.setActiveClass(this.id);
-		}
-
-		function init() {
-
-			var elem, size;
-			var layerManager = getElemById("layer_manager");
-			var layerMenu = getElemById("layer_menu");
-			var container = getElemById("stack_container");
-
-			elements.shadow_properties = getElemById('shadow_properties');
-			elements.element_properties = getElemById('element_properties');
-			elements.transform_rotate = getElemById('transform_rotate');
-			elements.zIndex = getElemById('z-index');
-
-			elem = document.querySelectorAll('#layer_menu [data-type="subject"]');
-			size = elem.length;
-
-			for (var i = 0; i < size; i++) {
-				var S = new Stack(elem[i]);
-				stacks[elem[i].id] = S;
-				container.appendChild(S.container);
-				Tool.addCssClass(elem[i].id);
-			}
-
-			active.stack = stacks['element'];
-			stacks['element'].show();
-
-			layerManager.addEventListener("click", mouseEvents);
-			layerMenu.addEventListener("click", mouseEvents);
-
-			ButtonManager.subscribe("before", function(value) {
-				if (value === false && active.stack === stacks['before'])
-					setActiveStack(stacks['element'])
-				if (value === true && active.stack !== stacks['before'])
-					setActiveStack(stacks['before'])
-			});
-
-			ButtonManager.subscribe("after", function(value) {
-				if (value === false && active.stack === stacks['after'])
-					setActiveStack(stacks['element'])
-				if (value === true && active.stack !== stacks['after'])
-					setActiveStack(stacks['after'])
-			});
-		}
-
-		return {
-			init : init
-		}
-	})();
-
-	/*
-	 * OutputManager
-	 */
-	var OutputManager = (function OutputManager() {
-		var classes = [];
-		var buttons = [];
-		var active = null;
-		var menu = null;
-		var button_offset = 0;
-
-		var crateOutputNode = function(topic, property) {
-
-			var prop = document.createElement('div');
-			var name = document.createElement('span');
-			var value = document.createElement('span');
-
-			var pmatch = property.match(/(^([a-z0-9\-]*)=\[([a-z0-9\-\"]*)\])|^([a-z0-9\-]*)/i);
-
-			name.textContent = '\t' + pmatch[4];
-
-			if (pmatch[3] !== undefined) {
-				name.textContent = '\t' + pmatch[2];
-				value.textContent = pmatch[3] + ';';
-			}
-
-			name.textContent += ': ';
-			prop.className = 'css-property';
-			name.className = 'name';
-			value.className = 'value';
-			prop.appendChild(name);
-			prop.appendChild(value);
-
-			classes[topic].node.appendChild(prop);
-			classes[topic].line[property] = prop;
-			classes[topic].prop[property] = value;
-		}
-
-		var OutputClass = function OutputClass(node) {
-			var topic = node.getAttribute('data-topic');
-			var prop = node.getAttribute('data-prop');
-			var name = node.getAttribute('data-name');
-			var properties = prop.split(' ');
-
-			classes[topic] = {};
-			classes[topic].node = node;
-			classes[topic].prop = [];
-			classes[topic].line = [];
-			classes[topic].button = new Button(topic);
-
-			var open_decl = document.createElement('div');
-			var end_decl = document.createElement('div');
-
-			open_decl.textContent = name + ' {';
-			end_decl.textContent = '}';
-			node.appendChild(open_decl);
-
-			for (var i in properties)
-				crateOutputNode(topic, properties[i]);
-
-			node.appendChild(end_decl);
-		}
-
-		var Button = function Button(topic) {
-			var button = document.createElement('div');
-
-			button.className = 'button';
-			button.textContent = topic;
-			button.style.left = button_offset + 'px';
-			button_offset += 100;
-
-			button.addEventListener("click", function() {
-				toggleDisplay(topic);
-			})
-
-			menu.appendChild(button);
-			return button;
-		}
-
-		var toggleDisplay = function toggleDisplay(topic) {
-			active.button.removeAttribute('data-active');
-			active.node.style.display = 'none';
-			active = classes[topic];
-			active.node.style.display = 'block';
-			active.button.setAttribute('data-active', 'true');
-		}
-
-		var toggleButton = function toggleButton(topic, value) {
-			var display = (value === true) ? 'block' : 'none';
-			classes[topic].button.style.display = display;
-
-			if (value === true)
-				toggleDisplay(topic);
-			else
-				toggleDisplay('element');
-		}
-
-		var updateProperty = function updateProperty(topic, property, data) {
-			try {
-				classes[topic].prop[property].textContent = data + ';';
-			}
-			catch(error) {
-				// console.log("ERROR undefined : ", topic, property, data);
-			}
-		}
-
-		var toggleProperty = function toggleProperty(topic, property, value) {
-			var display = (value === true) ? 'block' : 'none';
-			try {
-				classes[topic].line[property].style.display = display;
-			}
-			catch(error) {
-				// console.log("ERROR undefined : ",classes, topic, property, value);
-			}
-		}
-
-		var init = function init() {
-
-			menu = getElemById('menu');
-
-			var elem = document.querySelectorAll('#output .output');
-			var size = elem.length;
-			for (var i = 0; i < size; i++)
-				OutputClass(elem[i]);
-
-			active = classes['element'];
-			toggleDisplay('element');
-
-			ButtonManager.subscribe("before", function(value) {
-				toggleButton('before', value);
-			});
-
-			ButtonManager.subscribe("after", function(value) {
-				toggleButton('after', value);
-			});
-		}
-
-		return {
-			init : init,
-			updateProperty : updateProperty,
-			toggleProperty : toggleProperty
-		}
-
-	})();
-
-
-	/**
-	 * Init Tool
-	 */
-	var init = function init() {
-		ButtonManager.init();
-		OutputManager.init();
-		ColoPicker.init();
-		SliderManager.init();
-		LayerManager.init();
-		PreviewMouseTracking.init("preview");
-		Tool.init();
-	}
-
-	return {
-		init : init
-	}
-
-})();
-
-
-
-
- -
{{ EmbedLiveSample('box-shadow_generator', '100%', '1100px', '') }}
- -

Похожий инструмент: Генератор CSS Box Shadow

diff --git a/files/ru/web/css/css_box_model/introduction_to_the_css_box_model/index.html b/files/ru/web/css/css_box_model/introduction_to_the_css_box_model/index.html new file mode 100644 index 0000000000..6868871c5a --- /dev/null +++ b/files/ru/web/css/css_box_model/introduction_to_the_css_box_model/index.html @@ -0,0 +1,66 @@ +--- +title: 'Блоковая модель (боксовая модель, box model)' +slug: Web/CSS/box_model +tags: + - CSS + - Guide + - Веб +translation_of: Web/CSS/CSS_Box_Model/Introduction_to_the_CSS_box_model +--- +

Описание

+ +

В HTML-документе каждому элементу на странице соответствует прямоугольная область (бокс или блок). Движок рендеринга в браузере определяет размеры и положение боксов на странице, а также их свойства вроде цвета, фоновой картинки для того, чтобы отобразить их на экране.

+ +

В языке CSS есть специальная боксовая модель (также блоковая модель или блочная модель, англ. box model), которая описывает, из чего состоит бокс и какие свойства влияют на его размеры. В ней у каждого бокса есть 4 области: margin (внешние отступы), border (рамка), padding (внутренние поля), и content (контент или содержимое).

+ +

CSS Box model

+ +

Внутренняя область элемента (content area) содержит текст и другие элементы, расположенные внутри (контент или содержимое). У неё часто бывает фон, цвет или изображение (в таком порядке: фоновый цвет скрывается под непрозрачным изображением), и она находится внутри content edge; её размеры называются ширина контента (content width или content-box width), и высота контента (content height или content-box height). Иногда еще говорят «внутренняя ширина/высота элемента»

+ +

По умолчанию, если CSS-свойство {{ cssxref("box-sizing") }} не задано, размер внутренней области с содержимым задается свойствами {{ cssxref("width") }}, {{ cssxref("min-width") }}, {{ cssxref("max-width") }}, {{ cssxref("height") }}, {{ cssxref("min-height") }} and {{ cssxref("max-height") }}. Если же свойство  {{ cssxref("box-sizing") }} задано, то оно определяет, для какой области указаны размеры.

+ +

Поля элемента (padding area) — это пустая область, окружающая контент. Она может быть залита каким-то цветом, покрыта фоновый картинкой, а её границы называются края полей (padding edge).

+ +

Размеры полей задаются по отдельности с разных сторон свойствами {{ cssxref("padding-top") }}, {{ cssxref("padding-right") }}, {{ cssxref("padding-bottom") }}, {{ cssxref("padding-left") }} или общим свойством {{ cssxref("padding") }}.

+ +

Область рамки (border area) окружает поля элемента, а ее граница называется края рамки (border edge). Ширина рамки задается отдельным свойством  {{ cssxref("border-width") }} или в составе свойства {{ cssxref("border") }}. Размеры элемента с учетом полей и рамки иногда называют внешней шириной/высотой элемента.

+ +

Отступы (margin area) добавляют пустое пространство вокруг элемента и определяют расстояние до соседних элементов.

+ +

Величина отступов задается по отдельности в разных направлениях свойствами {{ cssxref("margin-top") }}, {{ cssxref("margin-right") }}, {{ cssxref("margin-bottom") }}, {{ cssxref("margin-left") }} или общим свойством {{ cssxref("margin") }}.

+ +

Отступы двух соседних элементов, расположенных друг над другом или вложенных друг в друга, могут накладываться. Это называется схлопывание границ (margin collapsing). Схлопываются только вертикальные отступы.

+ +

Для элементов с {{ cssxref("display") }}: inline (или inline-block, inline-table) на занимаемое по высоте место также влияет значение свойства {{ cssxref('line-height') }}.

+ +

Стандарты

+ + + + + + + + + + + + + + + + + + + + + +
СтандартСтатусПримечание
CSS Level 2 (revision 1){{ Spec2('CSS2.1') }}Though more precisely worded, there is no practical change
CSS Level 1{{ Spec2('CSS1') }} 
+ +

Смотрите также

+ +
    +
  • Справочник по CSS
  • +
  • {{ CSS_key_concepts() }}
  • +
  • Связанные свойства: {{ cssxref("box-sizing") }}, {{ cssxref("background-clip") }}, {{ cssxref("height") }}, {{ cssxref("max-height") }}, {{ cssxref("min-height") }}, {{ cssxref("width") }}, {{ cssxref("max-height") }}, {{ cssxref("min-height") }}, {{ cssxref("padding") }}, {{ cssxref("padding-top") }}, {{ cssxref("padding-right") }}, {{ cssxref("padding-bottom") }}, {{ cssxref("padding-left") }}, {{ cssxref("border") }}, {{ cssxref("border-top") }}, {{ cssxref("border-right") }}, {{ cssxref("border-bottom") }}, {{ cssxref("border-left") }}, {{ cssxref("border-width") }}, {{ cssxref("border-top-width") }}, {{ cssxref("border-right-width") }}, {{ cssxref("border-bottom-width") }}, {{ cssxref("border-left-width") }}, {{ cssxref("margin") }}, {{ cssxref("margin-top") }}, {{ cssxref("margin-right") }}, {{ cssxref("margin-bottom") }}, {{ cssxref("margin-left") }}
  • +
diff --git a/files/ru/web/css/css_color/index.html b/files/ru/web/css/css_color/index.html new file mode 100644 index 0000000000..c6225aec39 --- /dev/null +++ b/files/ru/web/css/css_color/index.html @@ -0,0 +1,117 @@ +--- +title: CSS Colors +slug: Web/CSS/CSS_Colors +tags: + - CSS + - Цвета + - Цвета в CSS +translation_of: Web/CSS/CSS_Color +translation_of_original: Web/CSS/CSS_Colors +--- +
{{CSSRef}}
+ +

CSS Colors - модуль в CSS, который работает с цветами, типами цветов и прозрачностью.

+ +

Руководство

+ +

Свойства

+ +
+
    +
  • {{cssxref("color")}}
  • +
  • {{cssxref("opacity")}}
  • +
+
+ +

Типы данных в CSS

+ +

{{cssxref("<color>")}}

+ +

Руководства

+ +

Нет.

+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('CSS3 Colors')}}{{Spec2('CSS3 Colors')}} 
{{SpecName('CSS2.1', 'colors.html')}}{{Spec2('CSS2.1')}} 
{{SpecName('CSS1')}}{{Spec2('CSS1')}}Изначальное определение
+ +

Поддержка браузерами

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
ВозможностьChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка1.0{{CompatGeckoDesktop("1")}}3.03.51.0
+
+ +
+ + + + + + + + + + + + + + + + + + + +
ВозможностьAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Базовая поддержка1.0{{CompatGeckoMobile("1")}}6.06.01.0
+
+ +

Смотрите также

+ + diff --git a/files/ru/web/css/css_colors/index.html b/files/ru/web/css/css_colors/index.html deleted file mode 100644 index c6225aec39..0000000000 --- a/files/ru/web/css/css_colors/index.html +++ /dev/null @@ -1,117 +0,0 @@ ---- -title: CSS Colors -slug: Web/CSS/CSS_Colors -tags: - - CSS - - Цвета - - Цвета в CSS -translation_of: Web/CSS/CSS_Color -translation_of_original: Web/CSS/CSS_Colors ---- -
{{CSSRef}}
- -

CSS Colors - модуль в CSS, который работает с цветами, типами цветов и прозрачностью.

- -

Руководство

- -

Свойства

- -
-
    -
  • {{cssxref("color")}}
  • -
  • {{cssxref("opacity")}}
  • -
-
- -

Типы данных в CSS

- -

{{cssxref("<color>")}}

- -

Руководства

- -

Нет.

- -

Спецификации

- - - - - - - - - - - - - - - - - - - - - - - - - - -
СпецификацияСтатусКомментарий
{{SpecName('CSS3 Colors')}}{{Spec2('CSS3 Colors')}} 
{{SpecName('CSS2.1', 'colors.html')}}{{Spec2('CSS2.1')}} 
{{SpecName('CSS1')}}{{Spec2('CSS1')}}Изначальное определение
- -

Поддержка браузерами

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
ВозможностьChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка1.0{{CompatGeckoDesktop("1")}}3.03.51.0
-
- -
- - - - - - - - - - - - - - - - - - - -
ВозможностьAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Базовая поддержка1.0{{CompatGeckoMobile("1")}}6.06.01.0
-
- -

Смотрите также

- - diff --git a/files/ru/web/css/css_columns/using_multi-column_layouts/index.html b/files/ru/web/css/css_columns/using_multi-column_layouts/index.html new file mode 100644 index 0000000000..65e96fcdcf --- /dev/null +++ b/files/ru/web/css/css_columns/using_multi-column_layouts/index.html @@ -0,0 +1,124 @@ +--- +title: Использование CSS разметки для многих колонок +slug: Web/Guide/CSS/Using_multi-column_layouts +translation_of: Web/CSS/CSS_Columns/Using_multi-column_layouts +--- +

{{CSSRef("CSS Multi-columns")}}

+ +

CSS разметка для многих колонок расширяет способ блочной разметки, чтобы позволить легкое описание нескольких колонок текста. Людям сложно читать текст, если строки слишком длинные; это занимает слишком много времени для глаз, чтобы перемещать взгляд с конца одной на начало следующей строки, и они забывают на какой строке находились. Поэтому, чтобы использовать большие дисплеи по максимуму, авторам следует ограничить ширину колонок текст расположенных бок о бок, как в газетах.

+ +

К несчастью, это невозможно сделать с CSS и HTML без принудительного разбиения колонки в фиксированных позициях, или строго ограничить допустимую разметку в тексте, или использовать экстраординарный скрипт. Это ограничение снимается с помощью добавления новых CSS свойств, чтобы расширить традиционный блочный способ разметки.

+ +

Использование колонок

+ +

Количество колонок и ширина

+ +

Два свойства CSS контролируют появятся ли колонки и как много их будет: {{ Cssxref("column-count") }} and {{ Cssxref("column-width") }}.

+ +

Свойство column-count устанавливает количество колонок определённым числом. Пример,

+ +
<div style="column-count:2;">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
+sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
+Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
+nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa
+qui officia deserunt mollit anim id est laborum</div>
+
+ +

отобразит содержимое в двух колонках (если вы используете многоколоночно совместимый браузер):

+ +

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

+ +

Свойство column-width устанавливает минимальную желаемую ширину колонки. Если column-count также не установлено, тогда браузер автоматически сделает столько колонок, сколько нужно, чтобы заполнить  доступную ширину.

+ +
<div style="column-width:20em;">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
+sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
+Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
+nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa
+qui officia deserunt mollit anim id est laborum</div>
+
+ +

становится:

+ +

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

+ +

Подробные детали описаны в CSS3 спецификации.

+ +

В многоколончатом блоке, содержимое автоматически перетекает из одной колонки в следующую, как это необходимо. Вся HTML, CSS и DOM функциональность поддерживается внутри колонок, как например редактирование и печать.

+ +

Краткая запись columns

+ +

В большинстве случаев веб-разработчики используют одно из двух свойств CSS: {{ cssxref("column-count") }} или {{ cssxref("column-width") }}. Так как значения для этих свойств не пересекаются, то часто удобно использовать короткую запись {{ cssxref("columns") }}. Пример:

+ +

CSS объявление  column-width:12em может быть заменено:

+ +
<div style="columns:12em">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
+sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
+Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
+nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa
+qui officia deserunt mollit anim id est laborum</div>
+
+ +

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

+ +

CSS объявление column-count:4 может быть заменено:

+ +
<div style="columns:4">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
+sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
+Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
+nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa
+qui officia deserunt mollit anim id est laborum</div>
+
+ +

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

+ +

Два CSS объявления column-width:8em и column-count:12 могут быть заменены:

+ +
<div style="columns:12 8em">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
+sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
+Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
+nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa
+qui officia deserunt mollit anim id est laborum</div>
+
+ +

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

+ +

Выравнивание высоты

+ +

CSS3-спецификация колонок требует, чтобы высота колонки была выровнена, т.е. браузер автоматически устанавливает максимальную высоту колонки, для того, чтобы высота содержимого в каждой из них была приблизительно одинаковая. Firefox так и делает.

+ +

Однако, в некоторых ситуациях полезно установить максимальную высоту колонок явно, тогда расположение содержимого, начиная с первой колонки и последующих созданных, как необходимо, возможно, перекроют правую границу. Поэтому, если высота ограничена, с помощью CSS {{ cssxref("height") }} или {{ cssxref("max-height") }} свойств на многоколончатом блоке, каждой колонке разрешено расти до этой высоты, но не более, пока не добавится новая колонка. Этот режим также более эффективен для разметки.

+ +

Промежутки между колонками

+ +

Существует промежуток между колонками. По умолчанию рекомендовано значение 1em. Это значение можно изменить, применяя свойство {{ Cssxref("column-gap") }} на многоколончатом блоке:

+ +
<div style="column-width:20em; column-gap:2em;">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
+sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
+Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
+nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa
+qui officia deserunt mollit anim id est laborum</div>
+
+ +

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

+ +

Постепенное ухудшение

+ +

Свойства колонки будут просто проигнорированы браузерами, которые не поддерживают многоколончатый режим. Поэтому соответственно легче создать разметку, которая отобразит содержимое в одной колонке и будет использовать несколько колонок в тех браузерах, которые поддерживают многоколончатый режим.

+ +

Обратите внимание, что не все браузеры поддерживают эти свойства без префикса. Чтобы использовать эти свойства в большинстве современных браузеров, каждое свойство должно быть написано трижды: одно с префиксом {{ property_prefix("-moz") }} , одно с префиксом {{ property_prefix("-webkit") }} и третье без префикса.

+ +

Заключение

+ +

CSS3 колонки - примитивная разметка, которая поможет Веб-разработчикам лучше воспользоваться реальным участком экрана. Разработчики с воображением могут найти много способов для их использования, особенно с автоматическим выравниванием высоты.

+ +

Смотрите также

+ + diff --git a/files/ru/web/css/css_flexible_box_layout/aligning_items_in_a_flex_container/index.html b/files/ru/web/css/css_flexible_box_layout/aligning_items_in_a_flex_container/index.html new file mode 100644 index 0000000000..9fe0b2932f --- /dev/null +++ b/files/ru/web/css/css_flexible_box_layout/aligning_items_in_a_flex_container/index.html @@ -0,0 +1,213 @@ +--- +title: Выравнивание элементов во Flex контейнере +slug: Web/CSS/CSS_Flexible_Box_Layout/Выравнивание_элементов_в_Flex_контейнере +translation_of: Web/CSS/CSS_Flexible_Box_Layout/Aligning_Items_in_a_Flex_Container +--- +

{{CSSRef}}

+ +

Одной из причин быстрого роста популярности flexbox среди веб-разработчиков было то, что впервые были предоставлены адекватные возможности выравнивания. Он предоставил адекватное вертикальное выравнивание, и стало возможным, наконец, легко поместить элемент в центр по вертикали. В этом руководстве детально рассматривается, как выравнивание и распределение работают во Flexbox.

+ +

Для центрирования элемента по перекрёстной оси (в данном случае - вертикальной) используется свойство align-items. Для центрирования элемента по главной оси (в данном случае - горизонтально), используется свойство justify-content.

+ +

A containing element with another box centered inside it.

+ + + +

На примере ниже можно изменить размер контейнера или вложенного элемента, но элемент всегда останется по центру.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/alignment/intro.html", '100%', 700)}}

+ +

Свойства управления выравниванием

+ +

В этом руководстве рассматриваются следующие свойства:

+ +
    +
  • {{cssxref("justify-content")}} — управляет выравниванием элементов по главной оси.
  • +
  • {{cssxref("align-items")}} — управляет выравниванием элементов по перекрёстной оси.
  • +
  • {{cssxref("align-self")}} — управляет выравниванием конкретного flex элемента по перекрёстной оси.
  • +
  • {{cssxref("align-content")}} — описывается в спецификации как “упаковка flex строк”; управляет промежутками между flex строками по перекрёстной оси.
  • +
+ +

Также будет рассмотрены авто-отступы для выравнивания элементов во flexbox.

+ +
+

Замечание: Свойства выравнивания во Flexbox помещены в отдельную спецификацию — CSS Box Alignment Level 3. Ожидается, что данная спецификация в конце концов заменит свойства, определённые во Flexbox Level One.

+
+ +

Перекрёстная ось

+ +

Свойства align-items и align-self управляют выравниванием flex элементов по перекрёстной оси: вертикальной для flex-direction установленным в row, и горизонтальной для flex-direction установленным в column.

+ +

Рассмотрим выравнивание по перекрёстной оси на простейшем примере. Если установить display: flex у контейнера, все дочерние элементы становятся flex элементами, выстроенными в ряд. Все они по вертикали примут размер самого высокого элемента, который станет определяющим вертикального размера. Если у flex контейнера задана высота, то все элементы растянутся до высоты контейнера, независимо от размера содержимого.

+ +

Three items, one with additional text causing it to be taller than the others.

+ +

Three items stretched to 200 pixels tall

+ +

Все элементы становятся одной высоты, т.к. по умолчанию свойство align-items имеет значение stretch.

+ +

Другие возможные значения свойства:

+ +
    +
  • align-items: flex-start
  • +
  • align-items: flex-end
  • +
  • align-items: center
  • +
  • align-items: stretch
  • +
  • align-items: baseline
  • +
+ +

В примере ниже значение свойств align-items установлено в stretch. Попробуйте другие значения для понимания их действия.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/alignment/align-items.html", '100%', 520)}} 

+ +

Выравнивание одного элемента при помощи align-self

+ +

Свойство align-items устанавливает align-self для всех flex элементов как для группы. Это означает, что можно явно указать значение align-self для конкретного элемента. Свойство align-self может принимать все те же значения, что и свойство align-items, а так же значение auto, которое сбросит значение, установленное в flex контейнере.

+ +

В следующем примере, у flex контейнера установлено align-items: flex-start, означающее, что все элементы будут выравнены по началу перекрёстной оси. У первого элемента с помощью first-child селектора установлено align-items: stretch; у следующего элемента с классом selected установлено align-self: center. Можно изменять значение align-items на контейнере или align-self на элементе для изучения их работы.8н

+ +

{{EmbedGHLiveSample("css-examples/flexbox/alignment/align-self.html", '100%', 650)}} 

+ +

Изменение основной оси

+ +

До сего момента мы изучали поведение при flex-direction установленном в row, в языке, использующем написание сверху вниз. Это означает, что основная ось идёт горизонтально, а выравнивание по перекрёстной оси сдвигает элементы вверх или вниз.

+ +

Three items, the first aligned to flex-start, second to center, third to flex-end. Aligning on the vertical axis.

+ +

Если изменить flex-direction на column, align-items и align-self будут сдвигать элементы влево или вправо.

+ +

Three items, the first aligned to flex-start, second to center, third to flex-end. Aligning on the horizontal axis.

+ +

Можно попробовать пример ниже, где установлено flex-direction: column.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/alignment/align-self-column.html", '100%', 730)}} 

+ +

Выравнивание содержимого по перекрёстной оси — свойство align-content

+ +

До сих пор мы выравнивали элементы внутри flex-контейнера. Если содержимое вашего flex контейнера переносится на несколько строк, используйте свойство align-content для управления свободным пространством между строками. В спецификации это описано как упаковка flex-строк.

+ +

Чтобы свойство align-content работало, необходимо, чтобы в flex-контейнере было больше места, что требуется для отображения всего содержимого. Оно применяется ко всем элементам как группе, и управляет распределением свободного места и положением всей группы элементов внутри контейнера.

+ +

Свойство align-content принимает следующие значения:

+ +
    +
  • align-content: flex-start
  • +
  • align-content: flex-end
  • +
  • align-content: center
  • +
  • align-content: space-between
  • +
  • align-content: space-around
  • +
  • align-content: stretch
  • +
  • align-content: space-evenly (не описано в спецификации Flexbox)
  • +
+ +

В примере ниже flex контейнер имеет высоту 400 пикселей - больше, чем необходимо для отображения всех элементов. Значение align-content установлено в space-between, означающее, что свободное пространство разделено между строками, расположенными вплотную к началу и концу контейнера по перекрёстной оси.

+ +

Попробуйте другие значения align-content для понимания принципа их работы.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/alignment/align-content.html", '100%', 850)}} 

+ +

Также можно сменить значение flex-direction на column и увидеть, как наше свойство работает в режиме колонок. Как и ранее, что увидеть работу свойства, у контейнера должно быть больше свободного места, чем требуется содержимому.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/alignment/align-content-column.html", '100%', 860)}} 

+ +
+

Замечание: значение space-evenly не определено в спецификации flexbox и добавлено позже в спецификацию Box Alignment. Поддержка браузерами этого значение не так широка, как значений определённым в спецификации flexbox.

+
+ +

В документации по justify-content на MDN приведено больше деталей о всех значениях и поддержке браузерами.

+ +

Выравнивание содержимого по главной оси

+ +

Теперь, когда мы увидели, как работает выравнивание по перекрёстной оси, можно посмотреть на главную ось. Здесь нам доступно только одно свойство — justify-content. Это обсуловлено тем, что с элементами на  главной оси мы работаем только как с группой. Используя свойство justify-content, мы контролируем, что происходит со свободным пространством на главной оси, и требуется ли нам больше пространства, чем нужно для отображения наших элементов.

+ +

В нашем первом примере с использованием свойства display: flex, примененным к контейнеру, элементы отображаются как строка и выстраиваются в начале блока. Это обусловлено тем, что свойство justify-content имеет начальное значение flex-start. Все свободное место располагается в конце контейнера.

+ +

Three items, each 100 pixels wide in a 500 pixel container. The available space is at the end of the items.

+ +

Свойство justify-content может принимать те же самые значения, что и align-content.

+ +
    +
  • justify-content: flex-start
  • +
  • justify-content: flex-end
  • +
  • justify-content: center
  • +
  • justify-content: space-between
  • +
  • justify-content: space-around
  • +
  • justify-content: stretch
  • +
  • justify-content: space-evenly (не определено в спецификации Flexbox)
  • +
+ +

В примере ниже, свойству justify-content задано значение space-between. Все доступное пространство распределяется между элементами после их позиционирования в контейнере. Первый и последний элементы занимают положения в начале и в конце контейнера соответственно.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/alignment/justify-content.html", '100%', 480)}}

+ +

Если свойство flex-direction имеет значение column, то свойство justify-content распределит доступное пространство в контейнере между элементами.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/alignment/justify-content-column.html", '100%', 880)}} 

+ +

Выравнивание и режим записи

+ +

Необходимо помнить, что при использовании свойств flex-start иflex-end элементы позиционируются в режиме записи. Если свойству justify-content задано значение start и стоит режим записи left-to-right (слева-направо), как в английском, то элементы выравниваются, начиная с левой стороны контейнера.

+ +

Three items lined up on the left

+ +

Однако, если задан режим записи right-to-left (справа-налево), как в арабском языке, то элементы будут выстраиваться с правой стороны контейнера.

+ +

Three items lined up from the right

+ +

В примере ниже свойству property задано значение rtl, которое изменяет порядок наших элементов. Вы можете удалить это свойство или изменить значение свойства justify-content, чтобы увидеть, как работает flexbox, когда отображение элементов начинается справа.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/alignment/justify-content-writing-mode.html", '100%', 440)}} 

+ +

Выравнивание и гибкое-направление

+ +

Начальное положение элементов поменяется, если вы измените значение свойства flex-direction — например установите row-reverse вместо row.

+ +

В следующем примере заданы следующие свойства: flex-direction: row-reverse и justify-content: flex-end. В языках с параметром записи ltr все элементы будут отображаться с левой стороны. Попробуйте изменить свойство flex-direction: row-reverse на flex-direction: row. Вы увидите, что теперь элементы отображаются реверсивно.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/alignment/justify-content-reverse.html", '100%', 440)}} 

+ +

Может показаться немного запутанным, но главное правило, которое необходимо запомить – до тех пор, пока вы не измените свойство flex-direction, элементы контейнера выстраиваются в режиме записи вашего языка (ltr или rtl). 

+ +

Diagram showing start on the left and end on the right.

+ +

Вы можете сделать отображение элементов контейнера блочным, задав свойству flex-direction значение  column. Свойство flex-start будет отображать элементы в столбец сверху вниз. Таким образом, первый элемент будет первым параграфом.

+ +

Diagram showing start at the top and end at the bottom.

+ +

Если вы зададите свойству flex-direction реверсивное значение, то элементы будут позиционироваться в обратном порядке. Так, свойство flex-start будет брать начало в конце контейнера. Первый элемент будет находится в конце строки, если задано строчное отображение элементов или в конце параграфа, если задано блочное отображение.   

+ +

Diagram showing start on the right and end on the left.

+ +

Diagram showing end at the top and start at the bottom

+ +

Использование авто отступов для выравнивания по главной оси

+ +

Так как элементы, расположенные на главной оси, обрабатываются как группа, свойства justify-items или justify-self становятся недоступными. Тем не менее, существует способ отделить конкретный элемент или группу элементов от остальных, используя внешний отступ margin со значением auto

+ +

Распространённый пример — панель навигации, в которой отдельные важные элементы выровнены по правому краю, а основная группа элементов — по левому.

+ +

На первый взгляд может показаться, что это юзкейс для свойства justify-self. Однако, рассмотрим следующий ниже пример. Имеется три элемента с одной стороны и два — с другой. Если бы мы могли использовать justify-self на элементе d, это также изменило бы выравнивание следующего элемента — e, что может противоречить первоначальному замыслу.

+ +

Five items, in two groups. Three on the left and two on the right.

+ +

Вместо этого мы можем выбрать четвёртый элемент (d) и отделить его от первых трёх, задав ему значение auto для margin-left. Авто-margin заполнит всё доступное свободное место по своей оси. Тем же образом cработает margin-right. Оба свойства со значениями auto отцентрируют блок, так как каждый из отступов будет пытаться занять максимум пространства.

+ +

В интерактивном примере ниже у нас имеется простой ряд из флекс-элементов и класс push с заданным margin-left: auto. Вы можете, например, попробовать удалить это значение или добавить класс другому элементу, чтобы увидеть, как работает этот метод. 

+ +

{{EmbedGHLiveSample("css-examples/flexbox/alignment/auto-margins.html", '100%', 470)}} 

+ +

Будущие функции выравнивания для Flexbox

+ +

В начале этой статьи объясняется, что свойства выравнивания, которые в настоящее время содержатся в спецификации Flexbox Level 1, также включены в спецификацию Box Alignment Level 3, которая в дальнейшем может расширить эти свойства и значения. Мы уже видели, как это произошло с введением значения space-evenly для свойств align-content и justify-content.

+ +

Выравнивание во Flexbox также включает в себя другие методы создания пространства между элементами, такие как column-gap and row-gap, как показано в макете CSS Grid Layout. Включение этих свойств в Box Alignment означает, что в будущем мы также сможем использовать column-gap и row-gap во Flexbox разметке. Это означает, что вам не нужно будет использовать отступы, чтобы создать пространство между элементами.

+ +

Мое предложение заключается в том, чтобы при изучении выравнивания во Flexbox, делать это параллельно с выравниванием в Grid Layout. В обеих спецификациях используются свойства выравнивания, подобные Flexbox. Вы можете видеть, как эти свойства ведут себя при работе с сеткой в статье Box Alignment in Grid Layout, а также рассмотреть как выравнивание работает в этих спецификациях в статье Box Alignment Cheatsheet.

+ +

Смотрите Также

+ +
    +
  • Выравнивание Коробки
  • +
  • Выравнивание Коробки в Flexbox (Гибкая Коробка)
  • +
  • Выравнивание Коробки в Grid Layout (Макет Сетки)
  • +
diff --git a/files/ru/web/css/css_flexible_box_layout/controlling_ratios_of_flex_items_along_the_main_ax/index.html b/files/ru/web/css/css_flexible_box_layout/controlling_ratios_of_flex_items_along_the_main_ax/index.html new file mode 100644 index 0000000000..97e521c2e1 --- /dev/null +++ b/files/ru/web/css/css_flexible_box_layout/controlling_ratios_of_flex_items_along_the_main_ax/index.html @@ -0,0 +1,194 @@ +--- +title: Управление соотношением элементов вдоль главной оси +slug: >- + Web/CSS/CSS_Flexible_Box_Layout/Контролирование_соотношения_элементов_вдоль_главной_оси +translation_of: >- + Web/CSS/CSS_Flexible_Box_Layout/Controlling_Ratios_of_Flex_Items_Along_the_Main_Ax +--- +
{{CSSRef}}
+ +
+ +
В данном руководстве, мы исследуем три свойства  применяемые к flex элементам, которые позволяют нам контролировать размер и  гибкость flex элементов по основной(main) оси. Полное понимание, как эти свойства работают,  при увеличение и уменьшение элементов, есть ключ к мастерству flexbox.
+ +

A first look

+ +

Our three properties control the following aspects of a flex item's flexibility:

+ +
    +
  • flex-grow: How much of the positive free space does this item get?
  • +
  • flex-shrink: How much negative free space can be removed from this item?
  • +
  • flex-basis: What is the size of the item before growing and shrinking happens?
  • +
+ +

The properties are usually expressed as the shorthand {{CSSxRef("flex")}} property. The following code would set the flex-grow property to 2, flex-shrink to 1 and flex-basis to auto.

+ +
.item {
+  flex: 2 1 auto;
+}
+ +

If you have read the article Basic Concepts of Flexbox, then you will have already had an introduction to the properties. Here we will explore them in depth in order that you can fully understand what the browser is doing when you use them.

+ +

Important concepts when working on the main axis

+ +

There are a few concepts worth digging into before looking at how the flex properties work to control ratios along the main axis. These relate to the natural size of flex items before any growing or shrinking takes place, and to the concept of free space.

+ +

Flex item sizing

+ +

In order to work out how much space there is available to lay out flex items, the browser needs to know how big the item is to start with. How is this worked out for items that don’t have a width or a height applied using an absolute length unit?

+ +

There is a concept in CSS of {{CSSxRef('width','min-content','#min-content')}} and {{CSSxRef('width','max-content','#max-content')}} — these keywords are defined in the CSS Intrinsic and Extrinsic Sizing Specification, and can be used in place of a length unit.

+ +

In the live example below for instance I have two paragraph elements that contain a string of text. The first paragraph has a width of min-content. In a browser that supports this keyword you should be able to see that the text has taken all of the soft wrapping opportunities available to it, becoming as small as it can be without overflowing. This then, is the min-content size of that string. Essentially, the longest word in the string is dictating the size.

+ +

The second paragraph has a value of max-content and so it does the opposite. It gets as big as it possibly can be, taking no soft-wrapping opportunities. It would overflow the box it is in if that container was too narrow.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/ratios/min-max-content.html", '100%', 750)}}

+ +

If your browser does not yet support these keywords both paragraphs will be rendered as normal paragraphs in block flow; the below screenshots show the expected rendering.

+ +

The first paragraph is wrapped to the longest word, the second stretched out so as to cause overflow.

+ +

Remember this behaviour and what effects min-content and max-content have as we explore flex-grow and flex-shrink later in this article.

+ +

Positive and negative free space

+ +

To talk about these properties we need to understand the concept of positive and negative free space. When a flex container has positive free space, it has more space than is required to display the flex items inside the container. For example, if I have a 500 pixel-wide container, {{CSSxRef("flex-direction")}} is row, and I have three flex items each 100 pixels wide, then I have 200 pixels of positive free space, which could be distributed between the items if I wanted them to fill the container.

+ +

Image showing space left over after items have been displayed.

+ +

We have negative free space when the natural size of the items adds up to larger than the available space in the flex container. If I have a 500 pixel-wide container like the one above, but the three flex items are each 200 pixels wide, the total space I need will be 600 pixels, so I have 100 pixels of negative free space. This could be removed from the items in order to make them fit the container.

+ +

The items overflow the container

+ +

It is this distribution of positive free space and removal of negative free space that we need to understand in order to understand the flex properties.

+ +

In the following examples I am working with {{CSSxRef("flex-direction")}} set to row, therefore the size of items will always come from their width. We will be calculating the positive and negative free space created by comparing the total width of all the items with the container width. You could equally try out each example with flex-direction: column. The main axis would then be the column, and you would then need to compare the height of the items and that of the container they are in to work out the positive and negative free space.

+ +

The flex-basis property

+ +

The {{CSSxRef("flex-basis")}} property specifies the initial size of the flex item before any space distribution happens. The initial value for this property is auto. If flex-basis is set to auto then to work out the initial size of the item the browser first checks if the main size of the item has an absolute size set. This would be the case if you had given your item a width of 200 pixels. In that case 200px would be the flex-basis for this item.

+ +

If your item is instead auto-sized, then auto resolves to the size of its content. At this point your knowledge of min- and max-content sizing becomes useful, as flexbox will take the max-content size of the item as the flex-basis. The following live example can help to demonstrate this.

+ +

In this example I have created a series of inflexible boxes, with both flex-grow and flex-shrink set to 0. Here we can see how the first item — which has an explicit width of 150 pixels set as the main size — takes a flex-basis of 150px, whereas the other two items have no width and so are sized according to their content width.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/ratios/flex-basis.html", '100%', 500)}}

+ +

In addition to the auto keyword, you can use the content keyword as the flex-basis. This will result in the flex-basis being taken from the content size even if there is a width set on the item. This is a newer keyword and has less browser support, however you can always get the same effect by using auto as the flex-basis and ensuring that your item does not have a width set, in order that it will be auto-sized.

+ +

If you want flexbox to completely ignore the size of the item when doing space distribution then set flex-basis to 0. This essentially tells flexbox that all the space is up for grabs, and to share it out in proportion. We will see examples of this as we move on to look at flex-grow.

+ +

The flex-grow property

+ +

The {{CSSxRef("flex-grow")}} property specifies the flex grow factor, which determines how much the flex item will grow relative to the rest of the flex items in the flex container when the positive free space is distributed.

+ +

If all of your items have the same flex-grow factor then space will be distributed evenly between all of them. If this is the situation that you want then typically you would use 1 as the value, however you could give them all a flex-grow of 88, or 100, or 1.2 if you like — it is a ratio. If the factor is the same for all, and there is positive free space in the flex container then it will be distributed equally to all.

+ +

Combining flex-grow and flex-basis

+ +

Things can get confusing in terms of how flex-grow and flex-basis interact. Let's consider the case of three flex items of differing content lengths and the following flex rules applied to them:

+ +

flex: 1 1 auto;

+ +

In this case the flex-basis value is auto and the items don’t have a width set, and so are auto-sized. This means that flexbox is looking at the max-content size of the items. After laying the items out we have some positive free space in the flex container, shown in this image as the hatched area:

+ +

Images shows the positive free space as a hatched area

+ +

We are working with a flex-basis equal to the content size so the available space to distribute is subtracted from the total available space (the width of the flex container), and the leftover space is then shared out equally among each item. Our bigger item ends up bigger because it started from a bigger size, even though it has the same amount of spare space assigned to it as the others:

+ +

The positive space is distributed between items

+ +

If what you actually want is three equally-sized items, even if they start out at different sizes, you should use this:

+ +

flex: 1 1 0;

+ +

Here we are saying that the size of the item for the purposes of our space distribution calculation is 0 — all the space is up for grabs and as all of the items have the same flex-grow factor, they each get an equal amount of space distributed. The end result is three equal width, flexible items.

+ +

Try changing the flex-grow factor from 1 to 0 in this live example to see the different behavior:

+ +

{{EmbedGHLiveSample("css-examples/flexbox/ratios/flex-grow.html", '100%', 520)}}

+ +

Giving items different flex-grow factors

+ +

Our understanding of how flex-grow works with flex-basis allows us to have further control over our individual item sizes by assigning items different flex-grow factors. If we keep our flex-basis at 0 so all of the space can be distributed, we could assign each of the three flex items a different flex-grow factor. In the example below I am using the following values:

+ +
    +
  • 1 for the first item.
  • +
  • 1 for the second item.
  • +
  • 2 for the third item.
  • +
+ +

Working from a flex-basis of 0 this means that the available space is distributed as follows. We need to add up the flex grow factors, then divide the total amount of positive free space in the flex container by that number, which in this case is 4. We then share out the space according to the individual values — the first item gets one part, the second one part, the third two parts. This means that the third item is twice the size of the first and second items.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/ratios/flex-grow-ratios.html", '100%', 520)}}

+ +

Remember that you can use any positive value here. It is the ratio between one item and the others that matters. You can use large numbers, or decimals — it is up to you. To test that out change the values assigned in the above example to .25, .25, and .50 — you should see the same result.

+ +

The flex-shrink property

+ +

The {{CSSxRef("flex-shrink")}} property specifies the flex shrink factor, which determines how much the flex item will shrink relative to the rest of the flex items in the flex container when negative free space is distributed.

+ +

This property deals with situations where the browser calculates the flex-basis values of the flex items, and finds that they are too large to fit into the flex container. As long as flex-shrink has a positive value the items will shrink in order that they do not overflow the container.

+ +

So where flex-grow deals with adding available space, flex-shrink manages taking away space to make boxes fit into their container without overflowing.

+ +

In the next live example I have three items in a flex container; I’ve given each a width of 200 pixels, and the container is 500 pixels wide. With flex-shrink set to 0 the items are not allowed to shrink and so they overflow the box.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/ratios/flex-shrink.html", '100%', 500)}}

+ +

Change the flex-shrink value to 1 and you will see each item shrink by the same amount, in order that all of the items now fit in the box. They have become smaller than their initial width in order to do so.

+ +

Combining flex-shrink and flex-basis

+ +

You could say that flex-shrink works in pretty much the same way as flex-grow. However there are two reasons why it isn’t quite the same.

+ +

While it is usually subtle, defined in the specification is one reason why flex-shrink isn’t quite the same for negative space as flex-grow is for positive space:

+ +
+

“Note: The flex shrink factor is multiplied by the flex base size when distributing negative space. This distributes negative space in proportion to how much the item is able to shrink, so that e.g. a small item won’t shrink to zero before a larger item has been noticeably reduced.”

+
+ +

The second reason is that flexbox prevents small items from shrinking to zero size during this removal of negative free space. The items will be floored at their min-content size — the size that they become if they take advantage of any soft wrapping opportunities available to them.

+ +

You can see this min-content flooring happen in the below example, where the flex-basis is resolving to the size of the content. If you change the width on the flex container — increasing it to 700px for example — and then reduce the flex item width, you can see that the first two items will wrap, however they will never become smaller than that min-content size. As the box gets smaller space is then just removed from the third item.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/ratios/flex-shrink-min-content.html", '100%', 500)}}

+ +

In practice the shrinking behaviour does tend to give you reasonable results. You don’t usually want your content to disappear completely or for boxes to get smaller than their minimum content, so the above rules make sense in terms of sensible behaviour for content that needs to be shrunk in order to fit into a container.

+ +

Giving items different flex-shrink factors

+ +

In the same way as flex-grow, you can give flex-items different flex-shrink factors. This can help change the default behaviour if, for example, you want an item to shrink more or less rapidly than its siblings or not shrink at all.

+ +

In the following live example the first item has a flex-shrink factor of 1, the second 0 (so it won’t shrink at all), and the third 4. The third item therefore shrinks more rapidly than the first. Play around with the different values — as for flex-grow you can use decimals or larger numbers here. Choose whatever makes most sense to you.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/ratios/flex-shrink-ratios.html", '100%', 570)}}

+ +

Mastering sizing of flex items

+ +

The key to really understanding how flex item sizing works is in understanding the number of things that come into play. Consider the following aspects, which we have already discussed in these guides:

+ +

What sets the base size of the item?

+ +
    +
  1. Is flex-basis set to auto, and does the item have a width set? If so, the size will be based on that width.
  2. +
  3. Is flex-basis set to auto or content (in a supporting browser)? If so, the size is based on the item size.
  4. +
  5. Is flex-basis a length unit, but not zero? If so this is the size of the item.
  6. +
  7. Is flex-basis set to 0? if so then the item size is not taken into consideration for the space-sharing calculation.
  8. +
+ +

Do we have available space?

+ +

Items can’t grow with no positive free space, and they won’t shrink unless there is negative free space.

+ +
    +
  1. If we took all of the items and added up their widths (or heights if working in a column), is that total less than the total width (or height) of the container? If so, then you have positive free space and flex-grow comes into play.
  2. +
  3. If we took all of the items and added up their widths (or heights if working in a column), is that total more than the total width (or height) of the container? If so, you have negative free space and flex-shrink comes into play.
  4. +
+ +

Other ways to distribute space

+ +

If you do not want space added to the items, remember that you can deal with free space between or around items using the alignment properties described in the guide to aligning items in a flex container. The {{CSSxRef("justify-content")}} property will enable the distribution of free space between or around items. You can also use auto margins on flex items to absorb space and create gaps between items.

+ +

With all the flex tools at your disposal you will find that most tasks can be achieved, although it might take a little bit of experimentation at first.

diff --git a/files/ru/web/css/css_flexible_box_layout/using_css_flexible_boxes/index.html b/files/ru/web/css/css_flexible_box_layout/using_css_flexible_boxes/index.html deleted file mode 100644 index 3f0b229d20..0000000000 --- a/files/ru/web/css/css_flexible_box_layout/using_css_flexible_boxes/index.html +++ /dev/null @@ -1,379 +0,0 @@ ---- -title: Используем CSS Flexible Boxes -slug: Web/CSS/CSS_Flexible_Box_Layout/Using_CSS_flexible_boxes -translation_of: Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox -translation_of_original: Web/CSS/CSS_Flexible_Box_Layout/Using_CSS_flexible_boxes ---- -
Эта статья устарела и удалена из английской версии. Вместо неё идёт перенаправление на статью: -

Основные понятия Flexbox

- - - -

У меня не поднялась рука удалить эту статью окончательно, но я рекомендую Вам вместо неё, всё-таки, прочитать ту.

-
- -
{{CSSRef}}
- -

CSS3 Flexible Box, или просто flexbox — это режим разметки, созданный для упорядочения элементов на странице таким образом, чтобы они вели себя предсказуемо в случаях, когда разметка страницы адаптирована под различные размеры экрана и устройства. Во многих случаях флексбоксы лучше блочной модели разметки, поскольку не использует обтекания (floats) и не выполняет схлопывание отступлений flex-контейнера и его содержимого (margin collapse).

- -

Для многих дизайнеров модель использования флексбоксов будет более простой для применения. Дочерние элементы внутри флексбокса могут размещаться в любом направлении и могут менять размер, чтобы адаптироваться к различным размерам дисплея. Позиционирование элементов в таком случае является простым и комплексная разметка достигается значительно легче и с более чистым кодом, поскольку порядок отображения элементов не связан с их порядком в коде. Эта независимость умышленно касается только визуального рендеринга, оставляя порядок интерпретации и навигацию зависимыми от порядка в исходниках.

- -
Внимание: некоторые браузеры все еще могут частично или полностью не поддерживать флексбоксы. Ознакомьтесь с таблицей совместимости.
- -

Концепция Flexbox

- -

Главной концепцией Flexbox есть возможность изменения высоты и/или ширины его элементов, чтобы лучше заполнять пространство любого дисплея. Flex-контейнер увеличивает элементы, чтобы заполнить доступное пространство или уменьшает чтобы предотвратить перекрытие.

- -

Алгоритм разметки флексбоксами агностичено направлен в противовес блочной разметке, которая ориентирована строго вертикально, или горизонтально-ориентированной инлайн-разметке. Несмотря на то что разметка блоками хорошо подходит для страницы, ей не хватает объективного механизма для поддержки компонентов, которые должны менять ориентацию, размеры а также растягиваться или сжиматься при изменениях размера экрана, изменении ориентации с вертикальной на горизонтальную и так далее. Разметка флексбоксами наиболее желательна для компонентов приложения и шаблонов, которые мало масштабируются, тогда как grid-разметка создана для больших шаблонов. Обе технологии являются частью разработки CSS Working Group которая должна способствовать совместимости web-приложений с различными браузерами, режимами а также большей гибкости.

- -

Терминология

- -

Поскольку описание флексбоксов не включает таких словосочетаний, как горизонтальная / inline и вертикальная / block оси, объяснение модели предусматривает новую терминологию. Используйте следующую диаграмму при просмотре словаря терминов. Она изображает flex-контейнер, имеющий flex-направление ряда, что означает, что каждый flex item расположен горизонтально, друг за другом по главной оси (main axis) в соответствии с установленным направлением написания текста элемента. Слева направо в данном случае.

- -

flex_terms.png

- -
-
Flex-контейнер
-
Родительский элемент, в котором содержатся flex-элементы. Flex-контейнер определяется установкой свойства {{Cssxref("display")}} в flex или inline-flex.
-
Flex-элемент, flex item
-
-

Каждый дочерний элемент flex-контейнера становится flex-элементом. Текст, который напрямую содержится в flex-контейнере, оборачивается анонимным flex-элементом.

-
-
Оси
-
-

Каждый flexible-бокс шаблон строится по двум осям. Главная ось (main axis) — это ось, вдоль которой flex-элементы следуют один за другим, а перекрёстная ось (cross axis) перпендикулярна ей.

- -
    -
  • Свойство {{Cssxref("flex-direction")}} устанавливает главную ось.
  • -
  • Свойство {{Cssxref("justify-content")}} определяет расположение элементов вдоль главной оси в текущем ряду.
  • -
  • Свойство align-items расположение элементов вдоль перекрёстной оси в текущем ряду.
  • -
  • Свойство align-self устанавливает, как отдельный flex-элемент выровнен по перекрёстной оси, переопределяя значения, установленные с помощью align-items.
  • -
-
-
Направления
-
-

Главное начало и конец (main) и перекрёстное начало и конец (cross start/end) — это стороны контейнера, определяющие начало и окончание потока flex-элемментов. Они следуют по главной и перекрестной осями flex-контейнера в векторе, установленном режимом написания ({{Cssxref("writing-mode")}}) (слева направо, справа налево и т. д.).

- -
    -
  • Свойство {{Cssxref("order")}} присваивает элементы порядковым группам и определяет, в каком порядке их показывать.
  • -
  • Свойство {{Cssxref("flex-flow")}} — это короткая форма, состоящая из свойств {{Cssxref("flex-direction")}} и {{Cssxref("flex-wrap")}}, определяющих расплолжение элементов.
  • -
-
-
Линии
-
-

Flex-элементы могут размещаться на одной или нескольких линиях в зависимости от значения свойства {{Cssxref("flex-wrap")}}, которое контролирует направление перекрестных линий и направление в котором складываются новые линии.

-
-
Размеры
-
-

Флекс элементы агностически эквивалентны высоте и ширине главного размера и поперечного размера, которые равны, соответственно,  главной оси (main axis) и поперечной оси (cross axis) флекс-контейнера.

- - -
-
- -

Делаем элемент флексбоксом

- -

Чтобы сделать элемент flexible-боксом, укажите значение {{cssxref("display")}} следующим образом:

- -
display: flex
- -

или

- -
display: inline-flex
- -

Таким образом мы определяем элемент как флексбокс, а его дочерниие элементы — как flex-элементы. Значение flex делает контейнер блочным элементом, а inline-flex значение превращает его в инлайн-элемент.

- -
Внимание: для указания префикса вендора, добавьте строку в значение атрибута, а не к самому атрибуту. Например, display: -webkit-flex.
- -

Рассмотрим flex-элементы

- -

Текст, который содержится непосредственно внутри flex-контейнера, автоматически оборачивается анонимным flex-элементом. Однако, анонимный flex-элемент, содержащий только пробелы, не отображается (как будто было указано значение display: none).

- -

Абсолютно позиционированные дочерние элементы flex-контейнера позиционируются так, что их статическое положение определяется относительно главного начального угла содержащего их flex-контейнера.

- -

Отступы (margin) соседних flex-контейнеров не схлопываются. Установка значений margin: auto поглощает дополнительное место в вертикальном или горизонтальном направлении и может быть использовано для выравнивания или для разделения соседних flex-элементов. См. Выравнивание при помощи 'автоматических' отступов в разделе "Модель расположения при помощи flex-контейнеров" спецификации W3C.

- -

Свойства выравнивания flexbox выполняют "истинное" центрирование в отличие от других способов центрирования в CSS. Это означает, что flex-элементы будут оставаться отцентрированными даже если они переполняют flex-контейнер. Впрочем, это может иногда быть проблематичным, если они вылезают за верхний или левый край страницы (в языках с написанием слева направо; в языках с написанием справа налево, таких как арабский, возникает проблема с правой границей), так как вы не можете прокрутить страницу в данную область даже если там есть содержимое! В будущем релизе свойства выравнивания будут также дополнены "безопасной" опцией. На данный момент, если это проблема, вы можете использовать отступы (margin) для достижения центрирования, так как они сработают "безопасно" и центрирование будет прекращено при переполнении. Вместо использования свойства align- просто установите автоматические отступы (margin: auto) для flex-элементов, которые вы хотите отцентрировать. Вместо свойств justify- установите margin: auto на внешние края первого и последнего элемента в flex-контейнере. Автоматические отступы будут "подстраиваться" и занимать оставшееся место, центрируя flex-элементы при наличии свободного места и используя стандартное выравнивание при его отсутствии. Тем не менее, если вы пытаетесь заменить justify-content центрированием, основанным на отступах (margin-based) в многострочном flexbox, вам, видимо, не повезло, так как вам необходимо установить отступы для первого и последнего элемента на каждой строке. Если вы не можете предугадать заранее на какой строке окажется каждый элемент, вы не сможете надежно использовать центрирование, основанное на отступах, на основной оси для замены свойства justify-content.

- -

Помните, что, несмотря на то, что порядок отображения элементов не зависит от их положения в исходном коде, эта независимость затрагивает только визуальное отображение, оставляя навигацию и голосовую помощь в исходном порядке. Даже свойство {{cssxref("order")}} не влияет на очередность голосовой помощи и навигации. Таким образом, разработчики должны уделять внимание правильному порядку элементов в исходном коде, чтобы не навредить доступности документа.

- -

Свойства Flexbox

- -

Свойства, не влияющие на Flexbox

- -

Так как flexbox используют другой алгоритм расположения, некоторые свойства не имеют смысла для flex-контейнера:

- -
    -
  • свойства column-* модуля с множественными столбцами не влияет на flex-элементы.
  • -
  • {{cssxref("clear")}} не действует на flex-элементах.
  • -
  • {{cssxref("float")}} заставляет свойство элемента display считаться как block.
  • -
  • {{cssxref("vertical-align")}} не оказывает эффекта на выравнивание flex-элементов.
  • -
- -

Пример

- -

Типичный пример flex

- -

Типичный пример показывает как применять "flex-эффект" к элементам и как соседние элементы ведут себя в состоянии flex.

- -
​<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <style>
-    .flex {
-        /* basic styling */
-        width: 350px;
-        height: 200px;
-        border: 1px solid #555;
-        font: 14px Arial;
-
-        /* flexbox setup */
-        display: flex;
-        flex-direction: row;
-    }
-
-    .flex > div {
-        flex: 1 1 auto;
-        width: 30px; /* To make the transition work nicely. (Transitions to/from
-                        "width:auto" are buggy in Gecko and Webkit, at least.
-                        See http://bugzil.la/731886 for more info.) */
-        transition: width 0.7s ease-out;
-    }
-
-    /* colors */
-    .flex > div:nth-child(1){ background: #009246; }
-    .flex > div:nth-child(2){ background: #F1F2F1; }
-    .flex > div:nth-child(3){ background: #CE2B37; }
-
-    .flex > div:hover {
-        width: 200px;
-    }
-
-    </style>
-  </head>
-  <body>
-    <p>Flexbox nuovo</p>
-    <div class="flex">
-      <div>uno</div>
-      <div>due</div>
-      <div>tre</div>
-    </div>
-  </body>
-</html>
- -

Пример расположения "Священный Грааль"

- -

Данный пример показывает как flexbox предоставляет возможность динамически изменять расположение для различных разрешений экрана. Следующая схема иллюстрирует преобразование.

- -

HolyGrailLayout.png

- -

Здесь изображен случай, когда расположение, подходящее для окна браузера должно быть оптимизировано для экрана смартфона. Не только элементы должны уменьшиться в размере, но и порядок, в котором они отображаются, должен измениться. Flexbox сильно упрощает это.

- -
​<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <style>
-    body {
-        font: 24px Helvetica;
-        background: #999999;
-    }
-
-    #main {
-        min-height: 800px;
-        margin: 0px;
-        padding: 0px;
-        display: flex;
-        flex-flow: row;
-    }
-
-    #main > article {
-        margin: 4px;
-        padding: 5px;
-        border: 1px solid #cccc33;
-        border-radius: 7pt;
-        background: #dddd88;
-        flex: 3 1 60%;
-        order: 2;
-    }
-
-    #main > nav {
-        margin: 4px;
-        padding: 5px;
-        border: 1px solid #8888bb;
-        border-radius: 7pt;
-        background: #ccccff;
-        flex: 1 6 20%;
-        order: 1;
-    }
-
-    #main > aside {
-        margin: 4px;
-        padding: 5px;
-        border: 1px solid #8888bb;
-        border-radius: 7pt;
-        background: #ccccff;
-        flex: 1 6 20%;
-        order: 3;
-    }
-
-    header, footer {
-        display: block;
-        margin: 4px;
-        padding: 5px;
-        min-height: 100px;
-        border: 1px solid #eebb55;
-        border-radius: 7pt;
-        background: #ffeebb;
-    }
-
-    /* Too narrow to support three columns */
-    @media all and (max-width: 640px) {
-        #main, #page {
-            flex-direction: column;
-        }
-
-        #main > article, #main > nav, #main > aside {
-        /* Return them to document order */
-            order: 0;
-        }
-
-        #main > nav, #main > aside, header, footer {
-            min-height: 50px;
-            max-height: 50px;
-        }
-    }
-    </style>
-  </head>
-  <body>
-    <header>header</header>
-    <div id='main'>
-      <article>article</article>
-      <nav>nav</nav>
-      <aside>aside</aside>
-    </div>
-    <footer>footer</footer>
-  </body>
-</html>
- -

Песочница

- -

Существует несколько песочниц с flexbox, доступных онлайн для экспериментов:

- - - -

О чем нужно помнить

- -

Алгоритм, описывающий как flex-элементы располагаются, иногда может быть довольно запутанным. Вот несколько правильных решений, которые позволят избежать неприятных сюрпризов при верстке с использованием flexbox.

- -

Flexbox располагаются в соответствие с направлением письма, что означает, что главное начало и главный конец располагаются в зависимости от положения начала и конца (строки - прим.).

- -

Перекрестное начало и перекрестный конец полагаются на определение позиции начала и конца, которое зависит от значения свойства {{cssxref("direction")}}.

- -

Разрывы страницы допустимы в расположении flex-контейнеров, когда это позволяет свойство break-. Свойства CSS3 break-after, break-before и break-inside, а также свойства CSS 2.1 page-break-before, page-break-after и page-break-inside работают на flex-контейнере, flex-элементах, а также внутри flex-элементов.

- -

Совместимость с браузерами

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureFirefox (Gecko)ChromeInternet ExplorerOperaSafari
Basic support (single-line flexbox){{CompatGeckoDesktop("18.0")}}[6]{{property_prefix("-moz")}}[2]
- {{CompatGeckoDesktop("22.0")}}
21.0{{property_prefix("-webkit")}}
- 29.0
11[3]12.10{{property_prefix("-webkit")}}[5]6.1{{property_prefix("-webkit")}}[1]
Multi-line flexbox{{CompatGeckoDesktop("28.0")}}21.0{{property_prefix("-webkit")}}
- 29.0
11[3]12.10[5]
- 15 {{property_prefix("-webkit")}}
6.1{{property_prefix("-webkit")}}[1]
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureFirefox Mobile (Gecko)Firefox OSAndroidIE PhoneOpera MobileSafari Mobile
Basic support (single-line flexbox){{CompatGeckoMobile("18.0")}}{{property_prefix("-moz")}}[2]
- {{CompatGeckoMobile("22.0")}}
-

1.0{{property_prefix("-moz")}}[2]
- 1.1

-
2.1{{property_prefix("-webkit")}}[4]
- 4.4
1112.10[5]
- 15{{property_prefix("-webkit")}}
7{{property_prefix("-webkit")}}[1]
Multi-line flexbox{{CompatGeckoMobile("28.0")}}1.32.1{{property_prefix("-webkit")}}[4]
- 4.4
1112.10[5]
- 15{{property_prefix("-webkit")}}
7{{property_prefix("-webkit")}}[1]
-
- -

[1] Safari до версии 6.0 (iOS.1) поддерживал старую несовместимую черновую версию спецификации. Safari 6.1 (и Safari на iOS 7) был обновлен для поддержки финальной версии.

- -

[2] До Firefox 22, чтобы активировать поддержку flexbox, пользователь должен установить параметр about:config layout.css.flexbox.enabled в значение true. Начиная с Firefox 22 по Firefox 27, параметр установлен в true по умолчанию, и полностью исключен в Firefox 28.

- -

[3] Internet Explorer 10 поддерживает старую несовместимую черновую версию спецификации; Internet Explorer 11 был обновлен для поддержки финальной версии.

- -

[4] Android browser до версии 4.3 поддерживал старую несовместимую черновую версию спецификации. Android 4.4 был обновлен для поддержки финальной версии.

- -

[5] Хотя изначальная реализация в Opera 12.10 flexbox была без приставки, она получила приставку {{property_prefix("-webkit")}} в версиях с 15 по 16 Opera и с 15 по 19 Opera Mobile. Приставка была снова убрана в Opera 17 и Opera Mobile 24.

- -

[6] До Firefox 29, установка visibility: collapse для flex-элемента заставляет его обрабатываться как display: none вместо предполагаемого поведения, обрабатывающего его как visibility: hidden. Предложенное решение - использовать visibility:hidden для flex-элементов, которые должны вести себя как при установленном visibility:collapse. Для большей информации, см {{bug(783470)}}.

- -

См. также

- -
    -
  • Проект Flexbugs для информации о багах в браузерных реализациях flexbox.
  • -
diff --git "a/files/ru/web/css/css_flexible_box_layout/\320\262\321\213\321\200\320\260\320\262\320\275\320\270\320\262\320\260\320\275\320\270\320\265_\321\215\320\273\320\265\320\274\320\265\320\275\321\202\320\276\320\262_\320\262_flex_\320\272\320\276\320\275\321\202\320\265\320\271\320\275\320\265\321\200\320\265/index.html" "b/files/ru/web/css/css_flexible_box_layout/\320\262\321\213\321\200\320\260\320\262\320\275\320\270\320\262\320\260\320\275\320\270\320\265_\321\215\320\273\320\265\320\274\320\265\320\275\321\202\320\276\320\262_\320\262_flex_\320\272\320\276\320\275\321\202\320\265\320\271\320\275\320\265\321\200\320\265/index.html" deleted file mode 100644 index 9fe0b2932f..0000000000 --- "a/files/ru/web/css/css_flexible_box_layout/\320\262\321\213\321\200\320\260\320\262\320\275\320\270\320\262\320\260\320\275\320\270\320\265_\321\215\320\273\320\265\320\274\320\265\320\275\321\202\320\276\320\262_\320\262_flex_\320\272\320\276\320\275\321\202\320\265\320\271\320\275\320\265\321\200\320\265/index.html" +++ /dev/null @@ -1,213 +0,0 @@ ---- -title: Выравнивание элементов во Flex контейнере -slug: Web/CSS/CSS_Flexible_Box_Layout/Выравнивание_элементов_в_Flex_контейнере -translation_of: Web/CSS/CSS_Flexible_Box_Layout/Aligning_Items_in_a_Flex_Container ---- -

{{CSSRef}}

- -

Одной из причин быстрого роста популярности flexbox среди веб-разработчиков было то, что впервые были предоставлены адекватные возможности выравнивания. Он предоставил адекватное вертикальное выравнивание, и стало возможным, наконец, легко поместить элемент в центр по вертикали. В этом руководстве детально рассматривается, как выравнивание и распределение работают во Flexbox.

- -

Для центрирования элемента по перекрёстной оси (в данном случае - вертикальной) используется свойство align-items. Для центрирования элемента по главной оси (в данном случае - горизонтально), используется свойство justify-content.

- -

A containing element with another box centered inside it.

- - - -

На примере ниже можно изменить размер контейнера или вложенного элемента, но элемент всегда останется по центру.

- -

{{EmbedGHLiveSample("css-examples/flexbox/alignment/intro.html", '100%', 700)}}

- -

Свойства управления выравниванием

- -

В этом руководстве рассматриваются следующие свойства:

- -
    -
  • {{cssxref("justify-content")}} — управляет выравниванием элементов по главной оси.
  • -
  • {{cssxref("align-items")}} — управляет выравниванием элементов по перекрёстной оси.
  • -
  • {{cssxref("align-self")}} — управляет выравниванием конкретного flex элемента по перекрёстной оси.
  • -
  • {{cssxref("align-content")}} — описывается в спецификации как “упаковка flex строк”; управляет промежутками между flex строками по перекрёстной оси.
  • -
- -

Также будет рассмотрены авто-отступы для выравнивания элементов во flexbox.

- -
-

Замечание: Свойства выравнивания во Flexbox помещены в отдельную спецификацию — CSS Box Alignment Level 3. Ожидается, что данная спецификация в конце концов заменит свойства, определённые во Flexbox Level One.

-
- -

Перекрёстная ось

- -

Свойства align-items и align-self управляют выравниванием flex элементов по перекрёстной оси: вертикальной для flex-direction установленным в row, и горизонтальной для flex-direction установленным в column.

- -

Рассмотрим выравнивание по перекрёстной оси на простейшем примере. Если установить display: flex у контейнера, все дочерние элементы становятся flex элементами, выстроенными в ряд. Все они по вертикали примут размер самого высокого элемента, который станет определяющим вертикального размера. Если у flex контейнера задана высота, то все элементы растянутся до высоты контейнера, независимо от размера содержимого.

- -

Three items, one with additional text causing it to be taller than the others.

- -

Three items stretched to 200 pixels tall

- -

Все элементы становятся одной высоты, т.к. по умолчанию свойство align-items имеет значение stretch.

- -

Другие возможные значения свойства:

- -
    -
  • align-items: flex-start
  • -
  • align-items: flex-end
  • -
  • align-items: center
  • -
  • align-items: stretch
  • -
  • align-items: baseline
  • -
- -

В примере ниже значение свойств align-items установлено в stretch. Попробуйте другие значения для понимания их действия.

- -

{{EmbedGHLiveSample("css-examples/flexbox/alignment/align-items.html", '100%', 520)}} 

- -

Выравнивание одного элемента при помощи align-self

- -

Свойство align-items устанавливает align-self для всех flex элементов как для группы. Это означает, что можно явно указать значение align-self для конкретного элемента. Свойство align-self может принимать все те же значения, что и свойство align-items, а так же значение auto, которое сбросит значение, установленное в flex контейнере.

- -

В следующем примере, у flex контейнера установлено align-items: flex-start, означающее, что все элементы будут выравнены по началу перекрёстной оси. У первого элемента с помощью first-child селектора установлено align-items: stretch; у следующего элемента с классом selected установлено align-self: center. Можно изменять значение align-items на контейнере или align-self на элементе для изучения их работы.8н

- -

{{EmbedGHLiveSample("css-examples/flexbox/alignment/align-self.html", '100%', 650)}} 

- -

Изменение основной оси

- -

До сего момента мы изучали поведение при flex-direction установленном в row, в языке, использующем написание сверху вниз. Это означает, что основная ось идёт горизонтально, а выравнивание по перекрёстной оси сдвигает элементы вверх или вниз.

- -

Three items, the first aligned to flex-start, second to center, third to flex-end. Aligning on the vertical axis.

- -

Если изменить flex-direction на column, align-items и align-self будут сдвигать элементы влево или вправо.

- -

Three items, the first aligned to flex-start, second to center, third to flex-end. Aligning on the horizontal axis.

- -

Можно попробовать пример ниже, где установлено flex-direction: column.

- -

{{EmbedGHLiveSample("css-examples/flexbox/alignment/align-self-column.html", '100%', 730)}} 

- -

Выравнивание содержимого по перекрёстной оси — свойство align-content

- -

До сих пор мы выравнивали элементы внутри flex-контейнера. Если содержимое вашего flex контейнера переносится на несколько строк, используйте свойство align-content для управления свободным пространством между строками. В спецификации это описано как упаковка flex-строк.

- -

Чтобы свойство align-content работало, необходимо, чтобы в flex-контейнере было больше места, что требуется для отображения всего содержимого. Оно применяется ко всем элементам как группе, и управляет распределением свободного места и положением всей группы элементов внутри контейнера.

- -

Свойство align-content принимает следующие значения:

- -
    -
  • align-content: flex-start
  • -
  • align-content: flex-end
  • -
  • align-content: center
  • -
  • align-content: space-between
  • -
  • align-content: space-around
  • -
  • align-content: stretch
  • -
  • align-content: space-evenly (не описано в спецификации Flexbox)
  • -
- -

В примере ниже flex контейнер имеет высоту 400 пикселей - больше, чем необходимо для отображения всех элементов. Значение align-content установлено в space-between, означающее, что свободное пространство разделено между строками, расположенными вплотную к началу и концу контейнера по перекрёстной оси.

- -

Попробуйте другие значения align-content для понимания принципа их работы.

- -

{{EmbedGHLiveSample("css-examples/flexbox/alignment/align-content.html", '100%', 850)}} 

- -

Также можно сменить значение flex-direction на column и увидеть, как наше свойство работает в режиме колонок. Как и ранее, что увидеть работу свойства, у контейнера должно быть больше свободного места, чем требуется содержимому.

- -

{{EmbedGHLiveSample("css-examples/flexbox/alignment/align-content-column.html", '100%', 860)}} 

- -
-

Замечание: значение space-evenly не определено в спецификации flexbox и добавлено позже в спецификацию Box Alignment. Поддержка браузерами этого значение не так широка, как значений определённым в спецификации flexbox.

-
- -

В документации по justify-content на MDN приведено больше деталей о всех значениях и поддержке браузерами.

- -

Выравнивание содержимого по главной оси

- -

Теперь, когда мы увидели, как работает выравнивание по перекрёстной оси, можно посмотреть на главную ось. Здесь нам доступно только одно свойство — justify-content. Это обсуловлено тем, что с элементами на  главной оси мы работаем только как с группой. Используя свойство justify-content, мы контролируем, что происходит со свободным пространством на главной оси, и требуется ли нам больше пространства, чем нужно для отображения наших элементов.

- -

В нашем первом примере с использованием свойства display: flex, примененным к контейнеру, элементы отображаются как строка и выстраиваются в начале блока. Это обусловлено тем, что свойство justify-content имеет начальное значение flex-start. Все свободное место располагается в конце контейнера.

- -

Three items, each 100 pixels wide in a 500 pixel container. The available space is at the end of the items.

- -

Свойство justify-content может принимать те же самые значения, что и align-content.

- -
    -
  • justify-content: flex-start
  • -
  • justify-content: flex-end
  • -
  • justify-content: center
  • -
  • justify-content: space-between
  • -
  • justify-content: space-around
  • -
  • justify-content: stretch
  • -
  • justify-content: space-evenly (не определено в спецификации Flexbox)
  • -
- -

В примере ниже, свойству justify-content задано значение space-between. Все доступное пространство распределяется между элементами после их позиционирования в контейнере. Первый и последний элементы занимают положения в начале и в конце контейнера соответственно.

- -

{{EmbedGHLiveSample("css-examples/flexbox/alignment/justify-content.html", '100%', 480)}}

- -

Если свойство flex-direction имеет значение column, то свойство justify-content распределит доступное пространство в контейнере между элементами.

- -

{{EmbedGHLiveSample("css-examples/flexbox/alignment/justify-content-column.html", '100%', 880)}} 

- -

Выравнивание и режим записи

- -

Необходимо помнить, что при использовании свойств flex-start иflex-end элементы позиционируются в режиме записи. Если свойству justify-content задано значение start и стоит режим записи left-to-right (слева-направо), как в английском, то элементы выравниваются, начиная с левой стороны контейнера.

- -

Three items lined up on the left

- -

Однако, если задан режим записи right-to-left (справа-налево), как в арабском языке, то элементы будут выстраиваться с правой стороны контейнера.

- -

Three items lined up from the right

- -

В примере ниже свойству property задано значение rtl, которое изменяет порядок наших элементов. Вы можете удалить это свойство или изменить значение свойства justify-content, чтобы увидеть, как работает flexbox, когда отображение элементов начинается справа.

- -

{{EmbedGHLiveSample("css-examples/flexbox/alignment/justify-content-writing-mode.html", '100%', 440)}} 

- -

Выравнивание и гибкое-направление

- -

Начальное положение элементов поменяется, если вы измените значение свойства flex-direction — например установите row-reverse вместо row.

- -

В следующем примере заданы следующие свойства: flex-direction: row-reverse и justify-content: flex-end. В языках с параметром записи ltr все элементы будут отображаться с левой стороны. Попробуйте изменить свойство flex-direction: row-reverse на flex-direction: row. Вы увидите, что теперь элементы отображаются реверсивно.

- -

{{EmbedGHLiveSample("css-examples/flexbox/alignment/justify-content-reverse.html", '100%', 440)}} 

- -

Может показаться немного запутанным, но главное правило, которое необходимо запомить – до тех пор, пока вы не измените свойство flex-direction, элементы контейнера выстраиваются в режиме записи вашего языка (ltr или rtl). 

- -

Diagram showing start on the left and end on the right.

- -

Вы можете сделать отображение элементов контейнера блочным, задав свойству flex-direction значение  column. Свойство flex-start будет отображать элементы в столбец сверху вниз. Таким образом, первый элемент будет первым параграфом.

- -

Diagram showing start at the top and end at the bottom.

- -

Если вы зададите свойству flex-direction реверсивное значение, то элементы будут позиционироваться в обратном порядке. Так, свойство flex-start будет брать начало в конце контейнера. Первый элемент будет находится в конце строки, если задано строчное отображение элементов или в конце параграфа, если задано блочное отображение.   

- -

Diagram showing start on the right and end on the left.

- -

Diagram showing end at the top and start at the bottom

- -

Использование авто отступов для выравнивания по главной оси

- -

Так как элементы, расположенные на главной оси, обрабатываются как группа, свойства justify-items или justify-self становятся недоступными. Тем не менее, существует способ отделить конкретный элемент или группу элементов от остальных, используя внешний отступ margin со значением auto

- -

Распространённый пример — панель навигации, в которой отдельные важные элементы выровнены по правому краю, а основная группа элементов — по левому.

- -

На первый взгляд может показаться, что это юзкейс для свойства justify-self. Однако, рассмотрим следующий ниже пример. Имеется три элемента с одной стороны и два — с другой. Если бы мы могли использовать justify-self на элементе d, это также изменило бы выравнивание следующего элемента — e, что может противоречить первоначальному замыслу.

- -

Five items, in two groups. Three on the left and two on the right.

- -

Вместо этого мы можем выбрать четвёртый элемент (d) и отделить его от первых трёх, задав ему значение auto для margin-left. Авто-margin заполнит всё доступное свободное место по своей оси. Тем же образом cработает margin-right. Оба свойства со значениями auto отцентрируют блок, так как каждый из отступов будет пытаться занять максимум пространства.

- -

В интерактивном примере ниже у нас имеется простой ряд из флекс-элементов и класс push с заданным margin-left: auto. Вы можете, например, попробовать удалить это значение или добавить класс другому элементу, чтобы увидеть, как работает этот метод. 

- -

{{EmbedGHLiveSample("css-examples/flexbox/alignment/auto-margins.html", '100%', 470)}} 

- -

Будущие функции выравнивания для Flexbox

- -

В начале этой статьи объясняется, что свойства выравнивания, которые в настоящее время содержатся в спецификации Flexbox Level 1, также включены в спецификацию Box Alignment Level 3, которая в дальнейшем может расширить эти свойства и значения. Мы уже видели, как это произошло с введением значения space-evenly для свойств align-content и justify-content.

- -

Выравнивание во Flexbox также включает в себя другие методы создания пространства между элементами, такие как column-gap and row-gap, как показано в макете CSS Grid Layout. Включение этих свойств в Box Alignment означает, что в будущем мы также сможем использовать column-gap и row-gap во Flexbox разметке. Это означает, что вам не нужно будет использовать отступы, чтобы создать пространство между элементами.

- -

Мое предложение заключается в том, чтобы при изучении выравнивания во Flexbox, делать это параллельно с выравниванием в Grid Layout. В обеих спецификациях используются свойства выравнивания, подобные Flexbox. Вы можете видеть, как эти свойства ведут себя при работе с сеткой в статье Box Alignment in Grid Layout, а также рассмотреть как выравнивание работает в этих спецификациях в статье Box Alignment Cheatsheet.

- -

Смотрите Также

- -
    -
  • Выравнивание Коробки
  • -
  • Выравнивание Коробки в Flexbox (Гибкая Коробка)
  • -
  • Выравнивание Коробки в Grid Layout (Макет Сетки)
  • -
diff --git "a/files/ru/web/css/css_flexible_box_layout/\320\272\320\276\320\275\321\202\321\200\320\276\320\273\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265_\321\201\320\276\320\276\321\202\320\275\320\276\321\210\320\265\320\275\320\270\321\217_\321\215\320\273\320\265\320\274\320\265\320\275\321\202\320\276\320\262_\320\262\320\264\320\276\320\273\321\214_\320\263\320\273\320\260\320\262\320\275\320\276\320\271_\320\276\321\201\320\270/index.html" "b/files/ru/web/css/css_flexible_box_layout/\320\272\320\276\320\275\321\202\321\200\320\276\320\273\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265_\321\201\320\276\320\276\321\202\320\275\320\276\321\210\320\265\320\275\320\270\321\217_\321\215\320\273\320\265\320\274\320\265\320\275\321\202\320\276\320\262_\320\262\320\264\320\276\320\273\321\214_\320\263\320\273\320\260\320\262\320\275\320\276\320\271_\320\276\321\201\320\270/index.html" deleted file mode 100644 index 97e521c2e1..0000000000 --- "a/files/ru/web/css/css_flexible_box_layout/\320\272\320\276\320\275\321\202\321\200\320\276\320\273\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265_\321\201\320\276\320\276\321\202\320\275\320\276\321\210\320\265\320\275\320\270\321\217_\321\215\320\273\320\265\320\274\320\265\320\275\321\202\320\276\320\262_\320\262\320\264\320\276\320\273\321\214_\320\263\320\273\320\260\320\262\320\275\320\276\320\271_\320\276\321\201\320\270/index.html" +++ /dev/null @@ -1,194 +0,0 @@ ---- -title: Управление соотношением элементов вдоль главной оси -slug: >- - Web/CSS/CSS_Flexible_Box_Layout/Контролирование_соотношения_элементов_вдоль_главной_оси -translation_of: >- - Web/CSS/CSS_Flexible_Box_Layout/Controlling_Ratios_of_Flex_Items_Along_the_Main_Ax ---- -
{{CSSRef}}
- -
- -
В данном руководстве, мы исследуем три свойства  применяемые к flex элементам, которые позволяют нам контролировать размер и  гибкость flex элементов по основной(main) оси. Полное понимание, как эти свойства работают,  при увеличение и уменьшение элементов, есть ключ к мастерству flexbox.
- -

A first look

- -

Our three properties control the following aspects of a flex item's flexibility:

- -
    -
  • flex-grow: How much of the positive free space does this item get?
  • -
  • flex-shrink: How much negative free space can be removed from this item?
  • -
  • flex-basis: What is the size of the item before growing and shrinking happens?
  • -
- -

The properties are usually expressed as the shorthand {{CSSxRef("flex")}} property. The following code would set the flex-grow property to 2, flex-shrink to 1 and flex-basis to auto.

- -
.item {
-  flex: 2 1 auto;
-}
- -

If you have read the article Basic Concepts of Flexbox, then you will have already had an introduction to the properties. Here we will explore them in depth in order that you can fully understand what the browser is doing when you use them.

- -

Important concepts when working on the main axis

- -

There are a few concepts worth digging into before looking at how the flex properties work to control ratios along the main axis. These relate to the natural size of flex items before any growing or shrinking takes place, and to the concept of free space.

- -

Flex item sizing

- -

In order to work out how much space there is available to lay out flex items, the browser needs to know how big the item is to start with. How is this worked out for items that don’t have a width or a height applied using an absolute length unit?

- -

There is a concept in CSS of {{CSSxRef('width','min-content','#min-content')}} and {{CSSxRef('width','max-content','#max-content')}} — these keywords are defined in the CSS Intrinsic and Extrinsic Sizing Specification, and can be used in place of a length unit.

- -

In the live example below for instance I have two paragraph elements that contain a string of text. The first paragraph has a width of min-content. In a browser that supports this keyword you should be able to see that the text has taken all of the soft wrapping opportunities available to it, becoming as small as it can be without overflowing. This then, is the min-content size of that string. Essentially, the longest word in the string is dictating the size.

- -

The second paragraph has a value of max-content and so it does the opposite. It gets as big as it possibly can be, taking no soft-wrapping opportunities. It would overflow the box it is in if that container was too narrow.

- -

{{EmbedGHLiveSample("css-examples/flexbox/ratios/min-max-content.html", '100%', 750)}}

- -

If your browser does not yet support these keywords both paragraphs will be rendered as normal paragraphs in block flow; the below screenshots show the expected rendering.

- -

The first paragraph is wrapped to the longest word, the second stretched out so as to cause overflow.

- -

Remember this behaviour and what effects min-content and max-content have as we explore flex-grow and flex-shrink later in this article.

- -

Positive and negative free space

- -

To talk about these properties we need to understand the concept of positive and negative free space. When a flex container has positive free space, it has more space than is required to display the flex items inside the container. For example, if I have a 500 pixel-wide container, {{CSSxRef("flex-direction")}} is row, and I have three flex items each 100 pixels wide, then I have 200 pixels of positive free space, which could be distributed between the items if I wanted them to fill the container.

- -

Image showing space left over after items have been displayed.

- -

We have negative free space when the natural size of the items adds up to larger than the available space in the flex container. If I have a 500 pixel-wide container like the one above, but the three flex items are each 200 pixels wide, the total space I need will be 600 pixels, so I have 100 pixels of negative free space. This could be removed from the items in order to make them fit the container.

- -

The items overflow the container

- -

It is this distribution of positive free space and removal of negative free space that we need to understand in order to understand the flex properties.

- -

In the following examples I am working with {{CSSxRef("flex-direction")}} set to row, therefore the size of items will always come from their width. We will be calculating the positive and negative free space created by comparing the total width of all the items with the container width. You could equally try out each example with flex-direction: column. The main axis would then be the column, and you would then need to compare the height of the items and that of the container they are in to work out the positive and negative free space.

- -

The flex-basis property

- -

The {{CSSxRef("flex-basis")}} property specifies the initial size of the flex item before any space distribution happens. The initial value for this property is auto. If flex-basis is set to auto then to work out the initial size of the item the browser first checks if the main size of the item has an absolute size set. This would be the case if you had given your item a width of 200 pixels. In that case 200px would be the flex-basis for this item.

- -

If your item is instead auto-sized, then auto resolves to the size of its content. At this point your knowledge of min- and max-content sizing becomes useful, as flexbox will take the max-content size of the item as the flex-basis. The following live example can help to demonstrate this.

- -

In this example I have created a series of inflexible boxes, with both flex-grow and flex-shrink set to 0. Here we can see how the first item — which has an explicit width of 150 pixels set as the main size — takes a flex-basis of 150px, whereas the other two items have no width and so are sized according to their content width.

- -

{{EmbedGHLiveSample("css-examples/flexbox/ratios/flex-basis.html", '100%', 500)}}

- -

In addition to the auto keyword, you can use the content keyword as the flex-basis. This will result in the flex-basis being taken from the content size even if there is a width set on the item. This is a newer keyword and has less browser support, however you can always get the same effect by using auto as the flex-basis and ensuring that your item does not have a width set, in order that it will be auto-sized.

- -

If you want flexbox to completely ignore the size of the item when doing space distribution then set flex-basis to 0. This essentially tells flexbox that all the space is up for grabs, and to share it out in proportion. We will see examples of this as we move on to look at flex-grow.

- -

The flex-grow property

- -

The {{CSSxRef("flex-grow")}} property specifies the flex grow factor, which determines how much the flex item will grow relative to the rest of the flex items in the flex container when the positive free space is distributed.

- -

If all of your items have the same flex-grow factor then space will be distributed evenly between all of them. If this is the situation that you want then typically you would use 1 as the value, however you could give them all a flex-grow of 88, or 100, or 1.2 if you like — it is a ratio. If the factor is the same for all, and there is positive free space in the flex container then it will be distributed equally to all.

- -

Combining flex-grow and flex-basis

- -

Things can get confusing in terms of how flex-grow and flex-basis interact. Let's consider the case of three flex items of differing content lengths and the following flex rules applied to them:

- -

flex: 1 1 auto;

- -

In this case the flex-basis value is auto and the items don’t have a width set, and so are auto-sized. This means that flexbox is looking at the max-content size of the items. After laying the items out we have some positive free space in the flex container, shown in this image as the hatched area:

- -

Images shows the positive free space as a hatched area

- -

We are working with a flex-basis equal to the content size so the available space to distribute is subtracted from the total available space (the width of the flex container), and the leftover space is then shared out equally among each item. Our bigger item ends up bigger because it started from a bigger size, even though it has the same amount of spare space assigned to it as the others:

- -

The positive space is distributed between items

- -

If what you actually want is three equally-sized items, even if they start out at different sizes, you should use this:

- -

flex: 1 1 0;

- -

Here we are saying that the size of the item for the purposes of our space distribution calculation is 0 — all the space is up for grabs and as all of the items have the same flex-grow factor, they each get an equal amount of space distributed. The end result is three equal width, flexible items.

- -

Try changing the flex-grow factor from 1 to 0 in this live example to see the different behavior:

- -

{{EmbedGHLiveSample("css-examples/flexbox/ratios/flex-grow.html", '100%', 520)}}

- -

Giving items different flex-grow factors

- -

Our understanding of how flex-grow works with flex-basis allows us to have further control over our individual item sizes by assigning items different flex-grow factors. If we keep our flex-basis at 0 so all of the space can be distributed, we could assign each of the three flex items a different flex-grow factor. In the example below I am using the following values:

- -
    -
  • 1 for the first item.
  • -
  • 1 for the second item.
  • -
  • 2 for the third item.
  • -
- -

Working from a flex-basis of 0 this means that the available space is distributed as follows. We need to add up the flex grow factors, then divide the total amount of positive free space in the flex container by that number, which in this case is 4. We then share out the space according to the individual values — the first item gets one part, the second one part, the third two parts. This means that the third item is twice the size of the first and second items.

- -

{{EmbedGHLiveSample("css-examples/flexbox/ratios/flex-grow-ratios.html", '100%', 520)}}

- -

Remember that you can use any positive value here. It is the ratio between one item and the others that matters. You can use large numbers, or decimals — it is up to you. To test that out change the values assigned in the above example to .25, .25, and .50 — you should see the same result.

- -

The flex-shrink property

- -

The {{CSSxRef("flex-shrink")}} property specifies the flex shrink factor, which determines how much the flex item will shrink relative to the rest of the flex items in the flex container when negative free space is distributed.

- -

This property deals with situations where the browser calculates the flex-basis values of the flex items, and finds that they are too large to fit into the flex container. As long as flex-shrink has a positive value the items will shrink in order that they do not overflow the container.

- -

So where flex-grow deals with adding available space, flex-shrink manages taking away space to make boxes fit into their container without overflowing.

- -

In the next live example I have three items in a flex container; I’ve given each a width of 200 pixels, and the container is 500 pixels wide. With flex-shrink set to 0 the items are not allowed to shrink and so they overflow the box.

- -

{{EmbedGHLiveSample("css-examples/flexbox/ratios/flex-shrink.html", '100%', 500)}}

- -

Change the flex-shrink value to 1 and you will see each item shrink by the same amount, in order that all of the items now fit in the box. They have become smaller than their initial width in order to do so.

- -

Combining flex-shrink and flex-basis

- -

You could say that flex-shrink works in pretty much the same way as flex-grow. However there are two reasons why it isn’t quite the same.

- -

While it is usually subtle, defined in the specification is one reason why flex-shrink isn’t quite the same for negative space as flex-grow is for positive space:

- -
-

“Note: The flex shrink factor is multiplied by the flex base size when distributing negative space. This distributes negative space in proportion to how much the item is able to shrink, so that e.g. a small item won’t shrink to zero before a larger item has been noticeably reduced.”

-
- -

The second reason is that flexbox prevents small items from shrinking to zero size during this removal of negative free space. The items will be floored at their min-content size — the size that they become if they take advantage of any soft wrapping opportunities available to them.

- -

You can see this min-content flooring happen in the below example, where the flex-basis is resolving to the size of the content. If you change the width on the flex container — increasing it to 700px for example — and then reduce the flex item width, you can see that the first two items will wrap, however they will never become smaller than that min-content size. As the box gets smaller space is then just removed from the third item.

- -

{{EmbedGHLiveSample("css-examples/flexbox/ratios/flex-shrink-min-content.html", '100%', 500)}}

- -

In practice the shrinking behaviour does tend to give you reasonable results. You don’t usually want your content to disappear completely or for boxes to get smaller than their minimum content, so the above rules make sense in terms of sensible behaviour for content that needs to be shrunk in order to fit into a container.

- -

Giving items different flex-shrink factors

- -

In the same way as flex-grow, you can give flex-items different flex-shrink factors. This can help change the default behaviour if, for example, you want an item to shrink more or less rapidly than its siblings or not shrink at all.

- -

In the following live example the first item has a flex-shrink factor of 1, the second 0 (so it won’t shrink at all), and the third 4. The third item therefore shrinks more rapidly than the first. Play around with the different values — as for flex-grow you can use decimals or larger numbers here. Choose whatever makes most sense to you.

- -

{{EmbedGHLiveSample("css-examples/flexbox/ratios/flex-shrink-ratios.html", '100%', 570)}}

- -

Mastering sizing of flex items

- -

The key to really understanding how flex item sizing works is in understanding the number of things that come into play. Consider the following aspects, which we have already discussed in these guides:

- -

What sets the base size of the item?

- -
    -
  1. Is flex-basis set to auto, and does the item have a width set? If so, the size will be based on that width.
  2. -
  3. Is flex-basis set to auto or content (in a supporting browser)? If so, the size is based on the item size.
  4. -
  5. Is flex-basis a length unit, but not zero? If so this is the size of the item.
  6. -
  7. Is flex-basis set to 0? if so then the item size is not taken into consideration for the space-sharing calculation.
  8. -
- -

Do we have available space?

- -

Items can’t grow with no positive free space, and they won’t shrink unless there is negative free space.

- -
    -
  1. If we took all of the items and added up their widths (or heights if working in a column), is that total less than the total width (or height) of the container? If so, then you have positive free space and flex-grow comes into play.
  2. -
  3. If we took all of the items and added up their widths (or heights if working in a column), is that total more than the total width (or height) of the container? If so, you have negative free space and flex-shrink comes into play.
  4. -
- -

Other ways to distribute space

- -

If you do not want space added to the items, remember that you can deal with free space between or around items using the alignment properties described in the guide to aligning items in a flex container. The {{CSSxRef("justify-content")}} property will enable the distribution of free space between or around items. You can also use auto margins on flex items to absorb space and create gaps between items.

- -

With all the flex tools at your disposal you will find that most tasks can be achieved, although it might take a little bit of experimentation at first.

diff --git a/files/ru/web/css/css_flow_layout/block_and_inline_layout_in_normal_flow/index.html b/files/ru/web/css/css_flow_layout/block_and_inline_layout_in_normal_flow/index.html new file mode 100644 index 0000000000..86879d343e --- /dev/null +++ b/files/ru/web/css/css_flow_layout/block_and_inline_layout_in_normal_flow/index.html @@ -0,0 +1,123 @@ +--- +title: Блочное и строчное расположение в нормальном потоке +slug: Web/CSS/CSS_Flow_Layout/Блочное_и_строчное_размещение_в_нормальном_потоке +tags: + - CSS + - Макет + - Макет потока CSS + - Отступы + - Руководство + - Средний уровень + - поток +translation_of: Web/CSS/CSS_Flow_Layout/Block_and_Inline_Layout_in_Normal_Flow +--- +
{{CSSRef}}
+ +

В этом руководстве мы исследуем основы поведения блочных и строчных элементов - участников нормального потока.

+ +

Normal Flow is defined in the CSS 2.1 specification, which explains that any boxes in normal flow will be part of a formatting context. They can be either block or inline, but not both at once. We describe block-level boxes as participating in a block formatting context, and inline-level boxes as participating in an inline formatting context.

+ +

The behaviour of elements which have a block or inline formatting context is also defined in this specification. For elements with a block formatting context, the spec says:

+ +
+

“In a block formatting context, boxes are laid out one after the other, vertically, beginning at the top of a containing block. The vertical distance between two sibling boxes is determined by the 'margin' properties. Vertical margins between adjacent block-level boxes in a block formatting context collapse.
+
+ In a block formatting context, each box's left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch).” - 9.4.1

+
+ +

For elements with an inline formatting context:

+ +
+

“In an inline formatting context, boxes are laid out horizontally, one after the other, beginning at the top of a containing block. Horizontal margins, borders, and padding are respected between these boxes. The boxes may be aligned vertically in different ways: their bottoms or tops may be aligned, or the baselines of text within them may be aligned. The rectangular area that contains the boxes that form a line is called a line box.” - 9.4.2

+
+ +

Note that the CSS 2.1 specification describes documents as being in a horizontal, top to bottom writing mode. For example, by describing vertical distance between block boxes. The behavior on block and inline elements is the same when working in a vertical writing mode, and we will explore this in a future guide on Flow Layout and Writing Modes.

+ +

Elements participating in a block formatting context

+ +

Block elements in a horizontal writing mode such as English, layout vertically, one below the other.

+ +

+ +

In a vertical writing mode then would lay out horizontally.

+ +

+ +

In this guide, we will be working in English and therefore a horizontal writing mode. However, everything described should work in the same way if your document is in a vertical writing mode.

+ +

As defined in the specification, the margins between two block boxes are what creates separation between the elements. We see this with a very simple layout of two paragraphs, to which I have added a border. The default browser stylesheet adds spacing between the paragraphs by way of adding a margin to the top and bottom.

+ +

{{EmbedGHLiveSample("css-examples/flow/block-inline/normal-flow.html", '100%', 700)}}

+ +

If we set margins on the paragraph element to 0 then the borders will touch.

+ +

{{EmbedGHLiveSample("css-examples/flow/block-inline/normal-flow-margin-zero.html", '100%', 700)}}

+ +

By default block elements will consume all of the space in the inline direction, so our paragraphs spread out and get as big as they can inside their containing block. If we give them a width, they will continue to lay out one below the other - even if there would be space for them to be side by side. Each will start against the start edge of the containing block, so the place at which sentences would begin in that writing mode.

+ +

{{EmbedGHLiveSample("css-examples/flow/block-inline/normal-flow-width.html", '100%', 700)}}

+ +

Margin collapsing

+ +

The spec explains that margins between block elements collapse. This means that if you have an element with a top margin immediately after an element with a bottom margin, rather than the total space being the sum of these two margins, the margin collapses, and so will essentially become as large as the larger of the two margins.

+ +

In the example below, the paragraphs have a top margin of 20px and a bottom margin of 40px. The size of the margin between the paragraphs is 40px as the smaller top margin on the second paragraph has collapsed with the larger bottom margin of the first.

+ +

{{EmbedGHLiveSample("css-examples/flow/block-inline/normal-flow-collapsing.html", '100%', 500)}}

+ +

You can read more about margin collapsing in our article Mastering Margin Collapsing.

+ +
+

Note: if you are not sure whether margins are collapsing, check the Box Model values in your browser DevTools. This will give you the actual size of the margin which can help you to identify what is happening.

+ +

+
+ +

Elements participating in an inline formatting context

+ +

Inline elements display one after the other in the direction that sentences run in that particular writing mode. While we don’t tend to think of inline elements as having a box, as with everything in CSS they do. These inline boxes are arranged one after the other. If there is not enough space in the containing block for all of the boxes a box can break onto a new line. The lines created are known as line boxes.

+ +

In the following example, we have three inline boxes created by a paragraph with a {{HTMLElement("strong")}} element inside it.

+ +

{{EmbedGHLiveSample("css-examples/flow/block-inline/inline.html", '100%', 500)}}

+ +

The boxes around the words before the <strong> element and after the <strong> element are referred to as anonymous boxes, boxes introduced to ensure that everything is wrapped in a box, but ones that we cannot target directly.

+ +

The line box size in the block direction (so the height when working in English) is defined by the tallest box inside it. In the next example, I have made the <strong> element 300%; that content now defines the height of the line box on that line.

+ +

{{EmbedGHLiveSample("css-examples/flow/block-inline/line-box.html", '100%', 500)}}

+ +

Find out more about how Block and Inline Boxes behave in our Guide to the Visual Formatting Model.

+ +

The display property and flow layout

+ +

In addition to the rules existing in CSS2.1, new levels of CSS further describe the behaviour of block and inline boxes. The {{cssxref("display")}} property defines how a box and any boxes inside it behave. In the CSS Display Model Level 3, we can learn more about how the display property changes the behaviour of boxes and the boxes they generate.

+ +

The display type of an element defines the outer display type; this dictates how the box displays alongside other elements in the same formatting context. It also defines the inner display type, which dictates how boxes inside this element behave. We can see this very clearly when considering a flex layout. In the example below I have a {{HTMLElement("div")}}, which I have given display: flex. The flex container behaves like a block element: it displays on a new line and takes up all of the space it can in the inline direction. This is the outer display type of block.

+ +

The flex items however are participating in a flex formatting context, because their parent is the element with display: flex, which has an inner display type of flex, establishing the flex formatting context for the direct children.

+ +

{{EmbedGHLiveSample("css-examples/flow/block-inline/flex.html", '100%', 500)}}

+ +

Therefore you can think of every box in CSS working in this way. The box itself has an outer display type, so it knows how to behave alongside other boxes. It then has an inner display type which changes the way its children behave. Those children then have an outer and inner display type too. The flex items in the previous example become flex level boxes, so their outer display type is dictated by way of them being part of the flex formatting context. They have an inner display type of flow however, meaning that their children participate in normal flow. Items nested inside our flex item lay themselves out as block and inline elements unless something changes their display type.

+ +

This concept of the outer and inner display type is important as this tells us that a container using a layout method such as Flexbox (display: flex) and Grid Layout (display: grid) is still participating in block and inline layout, due to the outer display type of those methods being block.

+ +

Changing the Formatting Context an element participates in

+ +

Browsers display items as part of a block or inline formatting context in terms of what normally makes sense for that element. For example, a {{HTMLElement("strong")}} element is used to highlight a word and displays bold in browsers. It would not generally make sense for that <strong> element to be displayed as a block level element, breaking onto a new line. If you did want all <strong> elements to display as block elements, you could do so by setting display: block on <strong>. This means that you can always use most of the semantic HTML elements to markup your content, and then change the way it displays using CSS.

+ +

{{EmbedGHLiveSample("css-examples/flow/block-inline/change-formatting.html", '100%', 500)}}

+ +

Summary

+ +

In this guide, we have looked at how elements display in normal flow, as block and inline elements. Due to the default behaviour of these elements, an HTML document with no CSS styling at all, will display in a readable way. By understanding how normal flow works you will find layout easier, as you understand the starting point for making changes to how elements are displayed.

+ +

See Also

+ + diff --git a/files/ru/web/css/css_flow_layout/intro_to_formatting_contexts/index.html b/files/ru/web/css/css_flow_layout/intro_to_formatting_contexts/index.html new file mode 100644 index 0000000000..c027e8eb3b --- /dev/null +++ b/files/ru/web/css/css_flow_layout/intro_to_formatting_contexts/index.html @@ -0,0 +1,85 @@ +--- +title: Введение в контексты форматирования +slug: Web/CSS/CSS_Flow_Layout/Введение_в_контексты_форматирования +translation_of: Web/CSS/CSS_Flow_Layout/Intro_to_formatting_contexts +--- +
{{CSSRef}}
+ +

В этой статье представлена концепция контекстов форматирования (formatting context). Существует несколько типов контекстов форматирования, например, блочный контекст форматирования (block formatting context, BFC), строчный контекст форматирования (inline formatting context), флексовый контекст форматирования (flex formatting context). В статье даны основы того, как они себя ведут, и как вы можете использовать это поведение.

+ +

Всё на странице является частью контекста форматирования (formatting context), который представляет собой область, в которой происходит раскладка контента по определенным правилам. Блочный контекст форматирования (block formatting context, BFC) делает раскладку своих дочерних элементов в соответствии с правилами блочной раскладки, флексовый контекст форматирования (flex formatting context) раскладывает свои дочерние элементы как {{Glossary("flex item", "флекс-элементы")}} и т.д. Каждый контекст форматирования использует свои правила раскладки.

+ +

Блочные контексты форматирования

+ +

Самый внешний элемент в документе, который использует правила блочной раскладки, устанавливает первый или начальный блочный контекст форматирования (initial block formatting context). Это означает, что все элементы внутри элемента <html> раскладываются в соответствии с нормальным потоком, следуя правилам блочной и строчной раскладки. Элементы, участвующие в БКФ, используют правила, описанные в модели бокса (CSS Box Model), которая определяет, как поля (margins), границы (borders) и отступы (paddings) элемента взаимодействуют с другими блоками в том же контексте.

+ +

Создание нового блочного контекста форматирования

+ +

Элемент {{HTMLElement("html")}} не единственный, кто может создавать блочный контекст форматирования. Любой элемент, который по умолчанию представляет собой блок, также создает блочный контекст форматирования для своих потомков. Кроме того, существуют свойства CSS, которые могут заставить элемент создавать БКФ, даже если он не делает этого по умолчанию. Это может быть полезным поскольку новый БКФ будет вести себя во многом как внешний документа, в том смысле, что он создает новую мини-раскладку в основной раскладке. БКФ содержит все внутри себя, {{cssxref("float")}} and {{cssxref("clear")}} применяются только к элементам, которые находится в том же контексте форматирования, также как и поля (margings) схлопываются только между элементами одного и того же контекста форматирования.

+ +

Кроме корневого элемента ({{HTMLElement("html")}}) новый БКФ создается в следующих случаях:

+ +
    +
  • плавающие элементы ({{cssxref("float", "float: left", "#left")}} или {{cssxref("float", "float: right", "#right")}});
  • +
  • абсолютно позиционированные элементы ({{cssxref("position", "position: absolute", "#absolute")}}, {{cssxref("position", "position: fixed", "#fixed")}} или {{cssxref("position", "position: sticky", "#sticky")}});
  • +
  • элементы с {{cssxref("display", "display: inline-block", "#inline-block")}};
  • +
  • ячейки табицы или элементы с display: table-cell, включая анонимные ячейки таблицы, которые создаются, когда используются свойства display: table-*;
  • +
  • заголовки таблицы или элементы с display: table-caption;
  • +
  • блочные элементы, когда значение свойства overflow отлично от visible;
  • +
  • элементы с display: flow-root или display: flow-root list-item;
  • +
  • элементы с {{cssxref("contain", "contain: layout", "#layout")}}, content, или strict
  • +
  • {{Glossary("flex item", "флекс-элементы")}};
  • +
  • грид-элементы;
  • +
  • контейнеры мультиколонок;
  • +
  • элементы с {{cssxref("column-span")}} в значении all.
  • +
+ + + +

Let's have a look at a couple of these in order to see the effect creating a new BFC.

+ +

In the example below, we have a floated element inside a <div> with a border applied. The content of that div has floated alongside the floated element. As the content of the float is taller than the content alongside it, the border of the div now runs through the float. As explained in the guide to in-flow and out of flow elements, the float has been taken out of flow so the background and border of the div only contain the content and not the float.

+ +

{{EmbedGHLiveSample("css-examples/flow/formatting-contexts/float.html", '100%', 720)}}

+ +

Creating a new BFC would contain the float. A typical way to do this in the past has been to set overflow: auto or set other values than the initial value of overflow: visible.

+ +

{{EmbedGHLiveSample("css-examples/flow/formatting-contexts/bfc-overflow.html", '100%', 720)}}

+ +

Setting  overflow: auto created a new BFC containing the float. Our div now becomes a mini-layout inside our layout. Any child element will be contained inside it.

+ +

The problem with using overflow to create a new BFC is that the overflow property is meant for telling the browser how you wish to deal with overflowing content. There are some occasions in which you will find you get unwanted scrollbars or clipped shadows when you use this property purely to create a BFC. In addition, it is potentially not very readable for a future developer, as it may not be obvious why you used overflow for this purpose. If you do this, it would be a good idea to comment the code to explain.

+ +

Explicitly creating a BFC using display: flow-root

+ +

Using display: flow-root (or display: flow-root list-item) on the containing block will create a new BFC without any other potentially problematic side-effects.

+ +

{{EmbedGHLiveSample("css-examples/flow/formatting-contexts/bfc-flow-root.html", '100%', 720)}}

+ +

With display: flow-root on the {{HTMLElement("div")}}, everything inside that container participates in the block formatting context of that container, and floats will not poke out of the bottom of the element.

+ +

The name of the flow-root keyword refers to the fact that you're creating something that serves, in essence, like a new root element (like {{HTMLElement("html")}} does), given how the new context is created and its flow layout functions.

+ +

Inline formatting contexts

+ +

Inline formatting contexts exist inside other formatting contexts and can be thought of as the context of a paragraph. The paragraph creates an inline formatting context inside which such things as {{HTMLElement("strong")}}, {{HTMLElement("a")}}, or {{HTMLElement("span")}} elements are used on text.

+ +

The box model does not fully apply to items participating in an inline formatting context. In a horizontal writing mode line, horizontal padding, borders and margin will be applied to the element and push the text away left and right. However, margins above and below the element will not be applied. Vertical padding and borders will be applied but may  overlap content above and below as, in the inline formatting context, the line boxes will not be pushed apart by padding and borders.

+ +

{{EmbedGHLiveSample("css-examples/flow/formatting-contexts/inline.html", '100%', 720)}}

+ +

Other formatting contexts

+ +

This guide covers flow layout and is therefore not referring to other possible formatting contexts. As such, it is useful to understand that creating any kind of formatting context will change the way elements inside that formatting context behave. This behavior is always described in the specification and also here on MDN.

+ +

Summary

+ +

In this guide, we have looked in more detail at the block and Inline formatting contexts and the important subject of creating a block formatting context (BFC). In the next guide, we will find out how normal flow interacts with different writing modes.

+ +

See also

+ + diff --git "a/files/ru/web/css/css_flow_layout/\320\261\320\273\320\276\321\207\320\275\320\276\320\265_\320\270_\321\201\321\202\321\200\320\276\321\207\320\275\320\276\320\265_\321\200\320\260\320\267\320\274\320\265\321\211\320\265\320\275\320\270\320\265_\320\262_\320\275\320\276\321\200\320\274\320\260\320\273\321\214\320\275\320\276\320\274_\320\277\320\276\321\202\320\276\320\272\320\265/index.html" "b/files/ru/web/css/css_flow_layout/\320\261\320\273\320\276\321\207\320\275\320\276\320\265_\320\270_\321\201\321\202\321\200\320\276\321\207\320\275\320\276\320\265_\321\200\320\260\320\267\320\274\320\265\321\211\320\265\320\275\320\270\320\265_\320\262_\320\275\320\276\321\200\320\274\320\260\320\273\321\214\320\275\320\276\320\274_\320\277\320\276\321\202\320\276\320\272\320\265/index.html" deleted file mode 100644 index 86879d343e..0000000000 --- "a/files/ru/web/css/css_flow_layout/\320\261\320\273\320\276\321\207\320\275\320\276\320\265_\320\270_\321\201\321\202\321\200\320\276\321\207\320\275\320\276\320\265_\321\200\320\260\320\267\320\274\320\265\321\211\320\265\320\275\320\270\320\265_\320\262_\320\275\320\276\321\200\320\274\320\260\320\273\321\214\320\275\320\276\320\274_\320\277\320\276\321\202\320\276\320\272\320\265/index.html" +++ /dev/null @@ -1,123 +0,0 @@ ---- -title: Блочное и строчное расположение в нормальном потоке -slug: Web/CSS/CSS_Flow_Layout/Блочное_и_строчное_размещение_в_нормальном_потоке -tags: - - CSS - - Макет - - Макет потока CSS - - Отступы - - Руководство - - Средний уровень - - поток -translation_of: Web/CSS/CSS_Flow_Layout/Block_and_Inline_Layout_in_Normal_Flow ---- -
{{CSSRef}}
- -

В этом руководстве мы исследуем основы поведения блочных и строчных элементов - участников нормального потока.

- -

Normal Flow is defined in the CSS 2.1 specification, which explains that any boxes in normal flow will be part of a formatting context. They can be either block or inline, but not both at once. We describe block-level boxes as participating in a block formatting context, and inline-level boxes as participating in an inline formatting context.

- -

The behaviour of elements which have a block or inline formatting context is also defined in this specification. For elements with a block formatting context, the spec says:

- -
-

“In a block formatting context, boxes are laid out one after the other, vertically, beginning at the top of a containing block. The vertical distance between two sibling boxes is determined by the 'margin' properties. Vertical margins between adjacent block-level boxes in a block formatting context collapse.
-
- In a block formatting context, each box's left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch).” - 9.4.1

-
- -

For elements with an inline formatting context:

- -
-

“In an inline formatting context, boxes are laid out horizontally, one after the other, beginning at the top of a containing block. Horizontal margins, borders, and padding are respected between these boxes. The boxes may be aligned vertically in different ways: their bottoms or tops may be aligned, or the baselines of text within them may be aligned. The rectangular area that contains the boxes that form a line is called a line box.” - 9.4.2

-
- -

Note that the CSS 2.1 specification describes documents as being in a horizontal, top to bottom writing mode. For example, by describing vertical distance between block boxes. The behavior on block and inline elements is the same when working in a vertical writing mode, and we will explore this in a future guide on Flow Layout and Writing Modes.

- -

Elements participating in a block formatting context

- -

Block elements in a horizontal writing mode such as English, layout vertically, one below the other.

- -

- -

In a vertical writing mode then would lay out horizontally.

- -

- -

In this guide, we will be working in English and therefore a horizontal writing mode. However, everything described should work in the same way if your document is in a vertical writing mode.

- -

As defined in the specification, the margins between two block boxes are what creates separation between the elements. We see this with a very simple layout of two paragraphs, to which I have added a border. The default browser stylesheet adds spacing between the paragraphs by way of adding a margin to the top and bottom.

- -

{{EmbedGHLiveSample("css-examples/flow/block-inline/normal-flow.html", '100%', 700)}}

- -

If we set margins on the paragraph element to 0 then the borders will touch.

- -

{{EmbedGHLiveSample("css-examples/flow/block-inline/normal-flow-margin-zero.html", '100%', 700)}}

- -

By default block elements will consume all of the space in the inline direction, so our paragraphs spread out and get as big as they can inside their containing block. If we give them a width, they will continue to lay out one below the other - even if there would be space for them to be side by side. Each will start against the start edge of the containing block, so the place at which sentences would begin in that writing mode.

- -

{{EmbedGHLiveSample("css-examples/flow/block-inline/normal-flow-width.html", '100%', 700)}}

- -

Margin collapsing

- -

The spec explains that margins between block elements collapse. This means that if you have an element with a top margin immediately after an element with a bottom margin, rather than the total space being the sum of these two margins, the margin collapses, and so will essentially become as large as the larger of the two margins.

- -

In the example below, the paragraphs have a top margin of 20px and a bottom margin of 40px. The size of the margin between the paragraphs is 40px as the smaller top margin on the second paragraph has collapsed with the larger bottom margin of the first.

- -

{{EmbedGHLiveSample("css-examples/flow/block-inline/normal-flow-collapsing.html", '100%', 500)}}

- -

You can read more about margin collapsing in our article Mastering Margin Collapsing.

- -
-

Note: if you are not sure whether margins are collapsing, check the Box Model values in your browser DevTools. This will give you the actual size of the margin which can help you to identify what is happening.

- -

-
- -

Elements participating in an inline formatting context

- -

Inline elements display one after the other in the direction that sentences run in that particular writing mode. While we don’t tend to think of inline elements as having a box, as with everything in CSS they do. These inline boxes are arranged one after the other. If there is not enough space in the containing block for all of the boxes a box can break onto a new line. The lines created are known as line boxes.

- -

In the following example, we have three inline boxes created by a paragraph with a {{HTMLElement("strong")}} element inside it.

- -

{{EmbedGHLiveSample("css-examples/flow/block-inline/inline.html", '100%', 500)}}

- -

The boxes around the words before the <strong> element and after the <strong> element are referred to as anonymous boxes, boxes introduced to ensure that everything is wrapped in a box, but ones that we cannot target directly.

- -

The line box size in the block direction (so the height when working in English) is defined by the tallest box inside it. In the next example, I have made the <strong> element 300%; that content now defines the height of the line box on that line.

- -

{{EmbedGHLiveSample("css-examples/flow/block-inline/line-box.html", '100%', 500)}}

- -

Find out more about how Block and Inline Boxes behave in our Guide to the Visual Formatting Model.

- -

The display property and flow layout

- -

In addition to the rules existing in CSS2.1, new levels of CSS further describe the behaviour of block and inline boxes. The {{cssxref("display")}} property defines how a box and any boxes inside it behave. In the CSS Display Model Level 3, we can learn more about how the display property changes the behaviour of boxes and the boxes they generate.

- -

The display type of an element defines the outer display type; this dictates how the box displays alongside other elements in the same formatting context. It also defines the inner display type, which dictates how boxes inside this element behave. We can see this very clearly when considering a flex layout. In the example below I have a {{HTMLElement("div")}}, which I have given display: flex. The flex container behaves like a block element: it displays on a new line and takes up all of the space it can in the inline direction. This is the outer display type of block.

- -

The flex items however are participating in a flex formatting context, because their parent is the element with display: flex, which has an inner display type of flex, establishing the flex formatting context for the direct children.

- -

{{EmbedGHLiveSample("css-examples/flow/block-inline/flex.html", '100%', 500)}}

- -

Therefore you can think of every box in CSS working in this way. The box itself has an outer display type, so it knows how to behave alongside other boxes. It then has an inner display type which changes the way its children behave. Those children then have an outer and inner display type too. The flex items in the previous example become flex level boxes, so their outer display type is dictated by way of them being part of the flex formatting context. They have an inner display type of flow however, meaning that their children participate in normal flow. Items nested inside our flex item lay themselves out as block and inline elements unless something changes their display type.

- -

This concept of the outer and inner display type is important as this tells us that a container using a layout method such as Flexbox (display: flex) and Grid Layout (display: grid) is still participating in block and inline layout, due to the outer display type of those methods being block.

- -

Changing the Formatting Context an element participates in

- -

Browsers display items as part of a block or inline formatting context in terms of what normally makes sense for that element. For example, a {{HTMLElement("strong")}} element is used to highlight a word and displays bold in browsers. It would not generally make sense for that <strong> element to be displayed as a block level element, breaking onto a new line. If you did want all <strong> elements to display as block elements, you could do so by setting display: block on <strong>. This means that you can always use most of the semantic HTML elements to markup your content, and then change the way it displays using CSS.

- -

{{EmbedGHLiveSample("css-examples/flow/block-inline/change-formatting.html", '100%', 500)}}

- -

Summary

- -

In this guide, we have looked at how elements display in normal flow, as block and inline elements. Due to the default behaviour of these elements, an HTML document with no CSS styling at all, will display in a readable way. By understanding how normal flow works you will find layout easier, as you understand the starting point for making changes to how elements are displayed.

- -

See Also

- - diff --git "a/files/ru/web/css/css_flow_layout/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_\320\272\320\276\320\275\321\202\320\265\320\272\321\201\321\202\321\213_\321\204\320\276\321\200\320\274\320\260\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\321\217/index.html" "b/files/ru/web/css/css_flow_layout/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_\320\272\320\276\320\275\321\202\320\265\320\272\321\201\321\202\321\213_\321\204\320\276\321\200\320\274\320\260\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\321\217/index.html" deleted file mode 100644 index c027e8eb3b..0000000000 --- "a/files/ru/web/css/css_flow_layout/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_\320\272\320\276\320\275\321\202\320\265\320\272\321\201\321\202\321\213_\321\204\320\276\321\200\320\274\320\260\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\321\217/index.html" +++ /dev/null @@ -1,85 +0,0 @@ ---- -title: Введение в контексты форматирования -slug: Web/CSS/CSS_Flow_Layout/Введение_в_контексты_форматирования -translation_of: Web/CSS/CSS_Flow_Layout/Intro_to_formatting_contexts ---- -
{{CSSRef}}
- -

В этой статье представлена концепция контекстов форматирования (formatting context). Существует несколько типов контекстов форматирования, например, блочный контекст форматирования (block formatting context, BFC), строчный контекст форматирования (inline formatting context), флексовый контекст форматирования (flex formatting context). В статье даны основы того, как они себя ведут, и как вы можете использовать это поведение.

- -

Всё на странице является частью контекста форматирования (formatting context), который представляет собой область, в которой происходит раскладка контента по определенным правилам. Блочный контекст форматирования (block formatting context, BFC) делает раскладку своих дочерних элементов в соответствии с правилами блочной раскладки, флексовый контекст форматирования (flex formatting context) раскладывает свои дочерние элементы как {{Glossary("flex item", "флекс-элементы")}} и т.д. Каждый контекст форматирования использует свои правила раскладки.

- -

Блочные контексты форматирования

- -

Самый внешний элемент в документе, который использует правила блочной раскладки, устанавливает первый или начальный блочный контекст форматирования (initial block formatting context). Это означает, что все элементы внутри элемента <html> раскладываются в соответствии с нормальным потоком, следуя правилам блочной и строчной раскладки. Элементы, участвующие в БКФ, используют правила, описанные в модели бокса (CSS Box Model), которая определяет, как поля (margins), границы (borders) и отступы (paddings) элемента взаимодействуют с другими блоками в том же контексте.

- -

Создание нового блочного контекста форматирования

- -

Элемент {{HTMLElement("html")}} не единственный, кто может создавать блочный контекст форматирования. Любой элемент, который по умолчанию представляет собой блок, также создает блочный контекст форматирования для своих потомков. Кроме того, существуют свойства CSS, которые могут заставить элемент создавать БКФ, даже если он не делает этого по умолчанию. Это может быть полезным поскольку новый БКФ будет вести себя во многом как внешний документа, в том смысле, что он создает новую мини-раскладку в основной раскладке. БКФ содержит все внутри себя, {{cssxref("float")}} and {{cssxref("clear")}} применяются только к элементам, которые находится в том же контексте форматирования, также как и поля (margings) схлопываются только между элементами одного и того же контекста форматирования.

- -

Кроме корневого элемента ({{HTMLElement("html")}}) новый БКФ создается в следующих случаях:

- -
    -
  • плавающие элементы ({{cssxref("float", "float: left", "#left")}} или {{cssxref("float", "float: right", "#right")}});
  • -
  • абсолютно позиционированные элементы ({{cssxref("position", "position: absolute", "#absolute")}}, {{cssxref("position", "position: fixed", "#fixed")}} или {{cssxref("position", "position: sticky", "#sticky")}});
  • -
  • элементы с {{cssxref("display", "display: inline-block", "#inline-block")}};
  • -
  • ячейки табицы или элементы с display: table-cell, включая анонимные ячейки таблицы, которые создаются, когда используются свойства display: table-*;
  • -
  • заголовки таблицы или элементы с display: table-caption;
  • -
  • блочные элементы, когда значение свойства overflow отлично от visible;
  • -
  • элементы с display: flow-root или display: flow-root list-item;
  • -
  • элементы с {{cssxref("contain", "contain: layout", "#layout")}}, content, или strict
  • -
  • {{Glossary("flex item", "флекс-элементы")}};
  • -
  • грид-элементы;
  • -
  • контейнеры мультиколонок;
  • -
  • элементы с {{cssxref("column-span")}} в значении all.
  • -
- - - -

Let's have a look at a couple of these in order to see the effect creating a new BFC.

- -

In the example below, we have a floated element inside a <div> with a border applied. The content of that div has floated alongside the floated element. As the content of the float is taller than the content alongside it, the border of the div now runs through the float. As explained in the guide to in-flow and out of flow elements, the float has been taken out of flow so the background and border of the div only contain the content and not the float.

- -

{{EmbedGHLiveSample("css-examples/flow/formatting-contexts/float.html", '100%', 720)}}

- -

Creating a new BFC would contain the float. A typical way to do this in the past has been to set overflow: auto or set other values than the initial value of overflow: visible.

- -

{{EmbedGHLiveSample("css-examples/flow/formatting-contexts/bfc-overflow.html", '100%', 720)}}

- -

Setting  overflow: auto created a new BFC containing the float. Our div now becomes a mini-layout inside our layout. Any child element will be contained inside it.

- -

The problem with using overflow to create a new BFC is that the overflow property is meant for telling the browser how you wish to deal with overflowing content. There are some occasions in which you will find you get unwanted scrollbars or clipped shadows when you use this property purely to create a BFC. In addition, it is potentially not very readable for a future developer, as it may not be obvious why you used overflow for this purpose. If you do this, it would be a good idea to comment the code to explain.

- -

Explicitly creating a BFC using display: flow-root

- -

Using display: flow-root (or display: flow-root list-item) on the containing block will create a new BFC without any other potentially problematic side-effects.

- -

{{EmbedGHLiveSample("css-examples/flow/formatting-contexts/bfc-flow-root.html", '100%', 720)}}

- -

With display: flow-root on the {{HTMLElement("div")}}, everything inside that container participates in the block formatting context of that container, and floats will not poke out of the bottom of the element.

- -

The name of the flow-root keyword refers to the fact that you're creating something that serves, in essence, like a new root element (like {{HTMLElement("html")}} does), given how the new context is created and its flow layout functions.

- -

Inline formatting contexts

- -

Inline formatting contexts exist inside other formatting contexts and can be thought of as the context of a paragraph. The paragraph creates an inline formatting context inside which such things as {{HTMLElement("strong")}}, {{HTMLElement("a")}}, or {{HTMLElement("span")}} elements are used on text.

- -

The box model does not fully apply to items participating in an inline formatting context. In a horizontal writing mode line, horizontal padding, borders and margin will be applied to the element and push the text away left and right. However, margins above and below the element will not be applied. Vertical padding and borders will be applied but may  overlap content above and below as, in the inline formatting context, the line boxes will not be pushed apart by padding and borders.

- -

{{EmbedGHLiveSample("css-examples/flow/formatting-contexts/inline.html", '100%', 720)}}

- -

Other formatting contexts

- -

This guide covers flow layout and is therefore not referring to other possible formatting contexts. As such, it is useful to understand that creating any kind of formatting context will change the way elements inside that formatting context behave. This behavior is always described in the specification and also here on MDN.

- -

Summary

- -

In this guide, we have looked in more detail at the block and Inline formatting contexts and the important subject of creating a block formatting context (BFC). In the next guide, we will find out how normal flow interacts with different writing modes.

- -

See also

- - diff --git a/files/ru/web/css/css_grid_layout/css_grid,_logical_values_and_writing_modes/index.html b/files/ru/web/css/css_grid_layout/css_grid,_logical_values_and_writing_modes/index.html deleted file mode 100644 index 48eec35abe..0000000000 --- a/files/ru/web/css/css_grid_layout/css_grid,_logical_values_and_writing_modes/index.html +++ /dev/null @@ -1,498 +0,0 @@ ---- -title: 'CSS grids, logical values and writing modes' -slug: 'Web/CSS/CSS_Grid_Layout/CSS_Grid,_Logical_Values_and_Writing_Modes' -translation_of: 'Web/CSS/CSS_Grid_Layout/CSS_Grid,_Logical_Values_and_Writing_Modes' ---- -

В этих руководствах я уже затронул важную особенность grid layout: поддержка различных режимов записи, встроенных в спецификацию. В этом руководстве мы рассмотрим эту особенность grid и других современных методов компоновки, немного узнав о режимах записи и логических и физических свойствах, когда мы это делаем.

- -

Логические и физические свойства и ценности

- -

CSS полон физических слов позиционирования - слева и справа, сверху и снизу. Если мы позиционируем элемент с использованием абсолютного позиционирования, мы используем эти физические ключевые слова в качестве значений смещения, чтобы обжимать элемент вокруг. В нижеприведенном фрагменте кода элемент помещается в 20 пикселей сверху и 30 пикселей слева от контейнера:

- -
.container {
-  position: relative;
-}
-.item {
-  position: absolute;
-  top: 20px;
-  left: 30px;
-}
-
- -
<div class="container">
-  <div class="item">Item</div>
-</div>
-
- -

Еще одно место, где вы можете увидеть используемые физические ключевые слова, - это использовать text-align: right выравнивать текст вправо. В CSS есть также физические свойства. Мы добавляем поля, дополнения и границы, используя эти физические свойства {{cssxref ("margin-left")}}, {{cssxref ("padding-left")}} и т. д.

- -

Мы называем эти ключевые слова и свойства физическими, потому что они относятся к экрану, на который вы смотрите. Слева всегда слева, независимо от того, в каком направлении работает ваш текст.

- -

Это может стать проблемой при разработке сайта, который должен работать на нескольких языках, включая языки с текстом, начинающимся справа, а не слева. Браузеры хорошо справляются с направлением текста и вам даже не нужно работать на языке {{glossary ("rtl")}}, чтобы посмотреть. В приведенном ниже примере у меня есть два абзаца. У одного не установлено {{cssxref ("text-align")}}, второе имеет выравнивание текста (text-align) влево. Я добавил dir = "rtl" в элемент html, который переключает режим записи по умолчанию для документа на английском языке ltr. Вы можете видеть, что первый абзац остается слева направо, из-за оставленного значения выравнивания текста. Второе, однако, переключает направление и текст пробегает справа налево.

- -

A simple example of text direction.

- -

Это очень простой пример проблемы с физическими значениями и свойствами, которые используются в CSS. Они не позволяют браузеру выполнять работу по переключению режима записи, поскольку они делают предположение, что текст течет слева направо и сверху вниз.

- -

Логические свойства и значения

- -

Логические свойства и значения не делают предположения о направлении текста. Именно поэтому в Grid Layout мы используем ключевое слово start при выравнивании чего-либо с началом контейнера. Для меня, работая на английском языке, start может быть слева, но это не обязательно и слово start не имеет физического местоположения.

- -

Block и Inline

- -

Как только мы начнем заниматься логическими, а не физическими свойствами, мы перестаем видеть мир как слева направо, так и сверху вниз. Нам нужна новая контрольная точка и именно здесь понимание использования блока и встроенных осей, которые мы встретили ранее в руководстве по выравниванию, становится очень полезным. Если вы можете начать видеть макет с точки зрения блочного и встроенного, то, как все работает в сетке, становится намного больше смысла.

- -

An image showing the default direction of the Block and Inline Axes.

- -

Режимы записи CSS

- -

Я собираюсь представить здесь еще одну спецификацию, которую я буду использовать в своих примерах: спецификация CSS Writing Modes. Эта спецификация подробно описывает, как мы можем использовать эти разные режимы записи в CSS, а не только для поддержки языков, которые имеют другой режим записи на английском языке, но также и для творческих целей. Я буду использовать свойство {{cssxref ("write-mode")}}, чтобы внести изменения в режим записи, применяемый к нашей сетке, чтобы продемонстрировать, как работают логические значения. Однако, если вы хотите, чтобы вы меняли в режиме записи, я бы рекомендовал вам прочитать Jen Simmons отличную статью о CSS Writing Modes. Это более подробно описано в этой спецификации, чем мы коснемся здесь.

- -

writing-mode

- -

Режимы записи - это больше, чем текст слева направо и справа налево, а свойство writing-mode помогает отображать текст в других направлениях. Свойство {{cssxref ("write-mode")}} может иметь значения:

- -
    -
  • horizontal-tb
  • -
  • vertical-rl
  • -
  • vertical-lr
  • -
  • sideways-rl
  • -
  • sideways-lr
  • -
- -

Значение horizontal-tb является значением по умолчанию для текста в Интернете. Это направление, в котором вы читаете это руководство. Другие свойства изменят способ передачи текста в нашем документе, соответствующий различным режимам записи, найденным по всему миру. Опять же, для получения полной информации об этом см. Jen’s article. В качестве простого примера у меня есть два параграфа ниже. Первый использует по умолчанию horizontal-tb, а второй использует vertical-rl. В тексте режима все еще выполняется влево-вправо, однако направление текста вертикально - встроенный текст теперь проходит вниз по странице, сверху вниз.

- -
- - -
<div class="wrapper">
-   <p style="writing-mode: horizontal-tb">I have writing mode set to the default <code>horizontal-tb</code></p>
-  <p style="writing-mode: vertical-rl">I have writing mode set to <code>vertical-rl</code></p>
-</div>
-
- -

{{ EmbedLiveSample('writing_1', '500', '420') }}

-
- -

Writing modes в grid layouts

- -

Если мы сейчас рассмотрим пример компоновки сетки, мы увидим, как изменение режима записи означает изменение нашей идеи о том, где находятся Block и Inline Axis.

- -

В моем следующем примере сетка имеет три столбца и две строки. Это означает, что на оси блока есть три дорожки. В режиме записи по умолчанию сетка автоматически помещает элементы, начинающиеся в верхнем левом углу, перемещаясь вправо, заполняя три ячейки на встроенной оси. Затем он переходит на следующую строку, создавая новый дорожку Row и заполняя больше элементов:

- -
- - -
.wrapper {
-  display: grid;
-  grid-template-columns: repeat(3, 100px);
-  grid-template-rows: repeat(2, 100px);
-  grid-gap: 10px;
-}
-
- -
<div class="wrapper">
-  <div class="item1">Item 1</div>
-  <div class="item2">Item 2</div>
-  <div class="item3">Item 3</div>
-  <div class="item4">Item 4</div>
-  <div class="item5">Item 5</div>
-</div>
-
- -

{{ EmbedLiveSample('writing_2', '500', '330') }}

-
- -

Если мы добавим writing-mode: vertical-lr в контейнер сетки, мы увидим, что блок и встроенная ось теперь работают в другом направлении. Ось блока или столбца теперь проходит через страницу слева направо, Inline запускается вниз по странице, создавая строки сверху вниз.

- -
- - -
.wrapper {
-  writing-mode: vertical-lr;
-  display: grid;
-  grid-template-columns: repeat(3, 100px);
-  grid-template-rows: repeat(2, 100px);
-  grid-gap: 10px;
-}
-
- -
<div class="wrapper">
-  <div class="item1">Item 1</div>
-  <div class="item2">Item 2</div>
-  <div class="item3">Item 3</div>
-  <div class="item4">Item 4</div>
-  <div class="item5">Item 5</div>
-</div>
-
- -

{{ EmbedLiveSample('writing_3', '500', '330') }}

-
- -

A image showing the direction of Block and Inline when writing-mode is vertical-lr

- -

Логические значения для выравнивания

- -

Когда блок и встроенная ось могут изменять направление, логические значения свойств выравнивания начинают иметь больше смысла.

- -

В следующем примере я использую выравнивание для выравнивания элементов внутри сетки, которая настроена на writing-mode: vertical-lr. start и end свойства работают точно так же, как в режиме записи по умолчанию, и остаются логичными в том смысле, что использование левого и правого, верхнего и нижнего уровней для выравнивания элементов не будет выполнено. Это происходит, когда мы перевернули сетку сбоку, например:

- -
- - -
.wrapper {
-  writing-mode: vertical-lr;
-  display: grid;
-  grid-template-columns: repeat(3, 1fr);
-  grid-template-rows: repeat(3, 100px);
-  grid-gap: 10px;
-}
-
-.item1 {
-    grid-column: 1 / 4;
-    align-self: start;
-}
-
-.item2 {
-    grid-column: 1 / 3;
-    grid-row: 2 / 4;
-    align-self: start;
-}
-
-.item3 {
-    grid-column: 3;
-    grid-row: 2 / 4;
-    align-self: end;
-    justify-self: end;
-}
-
- -
<div class="wrapper">
-  <div class="item1">Item 1</div>
-  <div class="item2">Item 2</div>
-  <div class="item3">Item 3</div>
-</div>
-
- -

{{ EmbedLiveSample('writing_4', '500', '330') }}

-
- -

Если вы хотите посмотреть, как они работают, как справа, так и сверху вниз, переключите vertical-lr на vertical-rl, который является вертикальным режимом записи, работающим справа налево.

- -

Auto-placement and Writing Modes

- -

В примере, который уже показан, вы можете видеть, как режим записи меняет направление, в котором элементы помещаются в сетку. Элементы по умолчанию помещают себя вдоль оси Inline, а затем переходят в новую строку. Однако эта линейная ось может не всегда выполняться слева направо.

- -

Линейное размещение и режимы записи

- -

Главное, что следует помнить при размещении элементов по номеру строки, является то, что строка 1 является стартовой линией, независимо от того, в каком режиме записи вы находитесь. Строка -1 - это конечная строка, независимо от того, в каком режиме записи вы находитесь.

- -

В следующем примере у меня есть сетка, которая находится в направлении по умолчанию ltr. Я разместил три элемента, используя линейное размещение.

- -
    -
  • Item 1 starts at column line 1, охватывающей один трек.
  • -
  • Item 2 starts at column line -1, охватывая -3.
  • -
  • Item 3 starts at column line 1, охватывая строку столбца 3.
  • -
- -
- - -
.wrapper {
-  display: grid;
-  grid-template-columns: repeat(3, 1fr);
-  grid-template-rows: repeat(2, 100px);
-  grid-gap: 10px;
-}
-.item1 {
-    grid-column: 1 ;
-}
-.item2 {
-    grid-column: -1 / -3;
-}
-.item3 {
-    grid-column: 1 / 3;
-    grid-row: 2;
-}
-
- -
<div class="wrapper">
-        <div class="item1">Item 1</div>
-        <div class="item2">Item 2</div>
-        <div class="item3">Item 3</div>
-    </div>
-
- -

{{ EmbedLiveSample('writing_5', '500', '330') }}

-
- -

Если теперь добавить свойство {{cssxref ("direction")}} со значением rtl в контейнер сетки, строка 1 станет правой частью сетки, а строка -1 - слева.

- -
- - -
.wrapper {
-  direction: rtl;
-  display: grid;
-  grid-template-columns: repeat(3, 1fr);
-  grid-template-rows: repeat(2, 100px);
-  grid-gap: 10px;
-}
-.item1 {
-    grid-column: 1 ;
-}
-.item2 {
-    grid-column: -1 / -3;
-}
-.item3 {
-    grid-column: 1 / 3;
-    grid-row: 2;
-}
-
- -
<div class="wrapper">
-        <div class="item1">Item 1</div>
-        <div class="item2">Item 2</div>
-        <div class="item3">Item 3</div>
-    </div>
-
- -

{{ EmbedLiveSample('writing_6', '500', '330') }}

-
- -

То, что это демонстрирует, заключается в том, что если вы переключаете направление текста на целые страницы или на части страниц и используете строки: вы можете назвать свои строки, если вы не хотите, чтобы макет полностью переключал направление , для некоторых вещей, например, когда сетка содержит текстовое содержимое, это переключение может быть именно тем, что вы хотите. Для других целей это не так.

- -

Странный порядок значений в свойстве grid-area

- -

Вы можете использовать свойство {{cssxref ("grid-area")}}, чтобы указать все четыре строки области сетки как одно значение. Когда люди впервые сталкиваются с этим, они часто удивляются тому, что значения не следуют тому же порядку, что и сокращенное поле, которое работает по часовой стрелке: сверху, справа, внизу, слева.

- -

Порядок значений grid-area:

- -
    -
  • grid-row-start
  • -
  • grid-column-start
  • -
  • grid-row-end
  • -
  • grid-column-end
  • -
- -

Что для английского языка, слева направо означает, что заказ:

- -
    -
  • top
  • -
  • left
  • -
  • bottom
  • -
  • right
  • -
- -

Это против часовой стрелки! Итак, обратное тому, что мы делаем для полей и заполнения. Как только вы поймете, что grid-area видит мир как "block и inline", вы можете помнить, что мы устанавливаем два запуска, а затем два конца. Когда вы знаете, это становится намного логичнее!

- -

Смешанные режимы записи и макет сетки

- -

В дополнение к отображению документов, используя правильный режим записи для языка, режимы записи могут быть использованы творчески в документах, которые в противном случае будут ltr. В следующем примере у меня есть макет сетки с набором ссылок вниз с одной стороны. Я использовал режимы записи, чтобы включить их на стороне в треке столбца:

- -
-
.wrapper {
-    display: grid;
-    grid-gap: 20px;
-    grid-template-columns: 1fr auto;
-    font: 1em Helvetica, Arial, sans-serif;
-}
-.wrapper nav {
-    writing-mode: vertical-lr;
-}
-.wrapper ul {
-    list-style: none;
-    margin: 0;
-    padding: 1em;
-    display: flex;
-    justify-content: space-between;
-}
-.wrapper a {
-    text-decoration: none;
-}
-
- -
<div class="wrapper">
-        <div class="content">
-            <p>Turnip greens yarrow ricebean rutabaga endive cauliflower sea lettuce kohlrabi amaranth water spinach avocado daikon napa cabbage asparagus winter purslane kale. Celery potato scallion desert raisin horseradish spinach carrot soko. Lotus root water spinach fennel kombu maize bamboo shoot green bean swiss chard seakale pumpkin onion chickpea gram corn pea. Brussels sprout coriander water chestnut gourd swiss chard wakame kohlrabi beetroot carrot watercress. Corn amaranth salsify bunya nuts nori azuki bean chickweed potato bell pepper artichoke.</p>
-
-<p>Nori grape silver beet broccoli kombu beet greens fava bean potato quandong celery. Bunya nuts black-eyed pea prairie turnip leek lentil turnip greens parsnip. Sea lettuce lettuce water chestnut eggplant winter purslane fennel azuki bean earthnut pea sierra leone bologi leek soko chicory celtuce parsley jícama salsify.</p>
-        </div>
-        <nav>
-            <ul>
-                <li><a href="">Link 1</a></li>
-                <li><a href="">Link 2</a></li>
-                <li><a href="">Link 3</a></li>
-            </ul>
-        </nav>
-    </div>
-
- -

{{ EmbedLiveSample('writing_7', '500', '330') }}

-
- -

Физические значения и grid layout

- -

Мы часто сталкиваемся с физическими свойствами при создании веб-сайтов и в то время как свойства и значения размещения и выравнивания сетки соответствуют режимам записи, есть вещи, которые вы можете сделать с Grid, которые заставляют вас использовать физические свойства и значения. В руководстве по выравниванию ячеек и сеткам я продемонстрировал, как автоматические поля работают в области сетки. Использование автоматической маржи, чтобы оттолкнуть один элемент от других, является общим трюком flexbox, однако это также связывает макет с физическим пространством.

- -

Если вы используете абсолютное позиционирование в области сетки, то вы снова будете использовать физические смещения, чтобы нажимать элемент вокруг области сетки. Главное, что нужно знать, - это напряжение между физическими и логическими свойствами и ценностями. Например, имейте в виду, что вам может потребоваться внести изменения в ваш CSS, чтобы справиться с переходом от ltr до rtl.

- -

Логические свойства для всего!

- -

Наши новые методы компоновки дают нам возможность использовать эти логические значения для размещения элементов, однако, как только мы начнем объединять их с физическими свойствами, используемыми для полей и отступов, нам нужно помнить, что эти физические свойства не изменятся в соответствии с режимом записи.

- -

Спецификация логических свойств CSS имеет целью изменить это и в будущем мы сможем использовать логические эквиваленты для свойств, такие как {{cssxref ("margin-left")}} и {{cssxref ("margin-right") }}, в нашем CSS. Firefox уже реализовал их, поэтому вы можете попробовать их прямо сейчас в Firefox. Я знаю в будущем, как только эти корабли повсюду, ваши знания «Блокировать и встроить» с помощью Grid означают, что вы точно знаете, как их использовать.

- - diff --git a/files/ru/web/css/css_grid_layout/css_grid_logical_values_and_writing_modes/index.html b/files/ru/web/css/css_grid_layout/css_grid_logical_values_and_writing_modes/index.html new file mode 100644 index 0000000000..48eec35abe --- /dev/null +++ b/files/ru/web/css/css_grid_layout/css_grid_logical_values_and_writing_modes/index.html @@ -0,0 +1,498 @@ +--- +title: 'CSS grids, logical values and writing modes' +slug: 'Web/CSS/CSS_Grid_Layout/CSS_Grid,_Logical_Values_and_Writing_Modes' +translation_of: 'Web/CSS/CSS_Grid_Layout/CSS_Grid,_Logical_Values_and_Writing_Modes' +--- +

В этих руководствах я уже затронул важную особенность grid layout: поддержка различных режимов записи, встроенных в спецификацию. В этом руководстве мы рассмотрим эту особенность grid и других современных методов компоновки, немного узнав о режимах записи и логических и физических свойствах, когда мы это делаем.

+ +

Логические и физические свойства и ценности

+ +

CSS полон физических слов позиционирования - слева и справа, сверху и снизу. Если мы позиционируем элемент с использованием абсолютного позиционирования, мы используем эти физические ключевые слова в качестве значений смещения, чтобы обжимать элемент вокруг. В нижеприведенном фрагменте кода элемент помещается в 20 пикселей сверху и 30 пикселей слева от контейнера:

+ +
.container {
+  position: relative;
+}
+.item {
+  position: absolute;
+  top: 20px;
+  left: 30px;
+}
+
+ +
<div class="container">
+  <div class="item">Item</div>
+</div>
+
+ +

Еще одно место, где вы можете увидеть используемые физические ключевые слова, - это использовать text-align: right выравнивать текст вправо. В CSS есть также физические свойства. Мы добавляем поля, дополнения и границы, используя эти физические свойства {{cssxref ("margin-left")}}, {{cssxref ("padding-left")}} и т. д.

+ +

Мы называем эти ключевые слова и свойства физическими, потому что они относятся к экрану, на который вы смотрите. Слева всегда слева, независимо от того, в каком направлении работает ваш текст.

+ +

Это может стать проблемой при разработке сайта, который должен работать на нескольких языках, включая языки с текстом, начинающимся справа, а не слева. Браузеры хорошо справляются с направлением текста и вам даже не нужно работать на языке {{glossary ("rtl")}}, чтобы посмотреть. В приведенном ниже примере у меня есть два абзаца. У одного не установлено {{cssxref ("text-align")}}, второе имеет выравнивание текста (text-align) влево. Я добавил dir = "rtl" в элемент html, который переключает режим записи по умолчанию для документа на английском языке ltr. Вы можете видеть, что первый абзац остается слева направо, из-за оставленного значения выравнивания текста. Второе, однако, переключает направление и текст пробегает справа налево.

+ +

A simple example of text direction.

+ +

Это очень простой пример проблемы с физическими значениями и свойствами, которые используются в CSS. Они не позволяют браузеру выполнять работу по переключению режима записи, поскольку они делают предположение, что текст течет слева направо и сверху вниз.

+ +

Логические свойства и значения

+ +

Логические свойства и значения не делают предположения о направлении текста. Именно поэтому в Grid Layout мы используем ключевое слово start при выравнивании чего-либо с началом контейнера. Для меня, работая на английском языке, start может быть слева, но это не обязательно и слово start не имеет физического местоположения.

+ +

Block и Inline

+ +

Как только мы начнем заниматься логическими, а не физическими свойствами, мы перестаем видеть мир как слева направо, так и сверху вниз. Нам нужна новая контрольная точка и именно здесь понимание использования блока и встроенных осей, которые мы встретили ранее в руководстве по выравниванию, становится очень полезным. Если вы можете начать видеть макет с точки зрения блочного и встроенного, то, как все работает в сетке, становится намного больше смысла.

+ +

An image showing the default direction of the Block and Inline Axes.

+ +

Режимы записи CSS

+ +

Я собираюсь представить здесь еще одну спецификацию, которую я буду использовать в своих примерах: спецификация CSS Writing Modes. Эта спецификация подробно описывает, как мы можем использовать эти разные режимы записи в CSS, а не только для поддержки языков, которые имеют другой режим записи на английском языке, но также и для творческих целей. Я буду использовать свойство {{cssxref ("write-mode")}}, чтобы внести изменения в режим записи, применяемый к нашей сетке, чтобы продемонстрировать, как работают логические значения. Однако, если вы хотите, чтобы вы меняли в режиме записи, я бы рекомендовал вам прочитать Jen Simmons отличную статью о CSS Writing Modes. Это более подробно описано в этой спецификации, чем мы коснемся здесь.

+ +

writing-mode

+ +

Режимы записи - это больше, чем текст слева направо и справа налево, а свойство writing-mode помогает отображать текст в других направлениях. Свойство {{cssxref ("write-mode")}} может иметь значения:

+ +
    +
  • horizontal-tb
  • +
  • vertical-rl
  • +
  • vertical-lr
  • +
  • sideways-rl
  • +
  • sideways-lr
  • +
+ +

Значение horizontal-tb является значением по умолчанию для текста в Интернете. Это направление, в котором вы читаете это руководство. Другие свойства изменят способ передачи текста в нашем документе, соответствующий различным режимам записи, найденным по всему миру. Опять же, для получения полной информации об этом см. Jen’s article. В качестве простого примера у меня есть два параграфа ниже. Первый использует по умолчанию horizontal-tb, а второй использует vertical-rl. В тексте режима все еще выполняется влево-вправо, однако направление текста вертикально - встроенный текст теперь проходит вниз по странице, сверху вниз.

+ +
+ + +
<div class="wrapper">
+   <p style="writing-mode: horizontal-tb">I have writing mode set to the default <code>horizontal-tb</code></p>
+  <p style="writing-mode: vertical-rl">I have writing mode set to <code>vertical-rl</code></p>
+</div>
+
+ +

{{ EmbedLiveSample('writing_1', '500', '420') }}

+
+ +

Writing modes в grid layouts

+ +

Если мы сейчас рассмотрим пример компоновки сетки, мы увидим, как изменение режима записи означает изменение нашей идеи о том, где находятся Block и Inline Axis.

+ +

В моем следующем примере сетка имеет три столбца и две строки. Это означает, что на оси блока есть три дорожки. В режиме записи по умолчанию сетка автоматически помещает элементы, начинающиеся в верхнем левом углу, перемещаясь вправо, заполняя три ячейки на встроенной оси. Затем он переходит на следующую строку, создавая новый дорожку Row и заполняя больше элементов:

+ +
+ + +
.wrapper {
+  display: grid;
+  grid-template-columns: repeat(3, 100px);
+  grid-template-rows: repeat(2, 100px);
+  grid-gap: 10px;
+}
+
+ +
<div class="wrapper">
+  <div class="item1">Item 1</div>
+  <div class="item2">Item 2</div>
+  <div class="item3">Item 3</div>
+  <div class="item4">Item 4</div>
+  <div class="item5">Item 5</div>
+</div>
+
+ +

{{ EmbedLiveSample('writing_2', '500', '330') }}

+
+ +

Если мы добавим writing-mode: vertical-lr в контейнер сетки, мы увидим, что блок и встроенная ось теперь работают в другом направлении. Ось блока или столбца теперь проходит через страницу слева направо, Inline запускается вниз по странице, создавая строки сверху вниз.

+ +
+ + +
.wrapper {
+  writing-mode: vertical-lr;
+  display: grid;
+  grid-template-columns: repeat(3, 100px);
+  grid-template-rows: repeat(2, 100px);
+  grid-gap: 10px;
+}
+
+ +
<div class="wrapper">
+  <div class="item1">Item 1</div>
+  <div class="item2">Item 2</div>
+  <div class="item3">Item 3</div>
+  <div class="item4">Item 4</div>
+  <div class="item5">Item 5</div>
+</div>
+
+ +

{{ EmbedLiveSample('writing_3', '500', '330') }}

+
+ +

A image showing the direction of Block and Inline when writing-mode is vertical-lr

+ +

Логические значения для выравнивания

+ +

Когда блок и встроенная ось могут изменять направление, логические значения свойств выравнивания начинают иметь больше смысла.

+ +

В следующем примере я использую выравнивание для выравнивания элементов внутри сетки, которая настроена на writing-mode: vertical-lr. start и end свойства работают точно так же, как в режиме записи по умолчанию, и остаются логичными в том смысле, что использование левого и правого, верхнего и нижнего уровней для выравнивания элементов не будет выполнено. Это происходит, когда мы перевернули сетку сбоку, например:

+ +
+ + +
.wrapper {
+  writing-mode: vertical-lr;
+  display: grid;
+  grid-template-columns: repeat(3, 1fr);
+  grid-template-rows: repeat(3, 100px);
+  grid-gap: 10px;
+}
+
+.item1 {
+    grid-column: 1 / 4;
+    align-self: start;
+}
+
+.item2 {
+    grid-column: 1 / 3;
+    grid-row: 2 / 4;
+    align-self: start;
+}
+
+.item3 {
+    grid-column: 3;
+    grid-row: 2 / 4;
+    align-self: end;
+    justify-self: end;
+}
+
+ +
<div class="wrapper">
+  <div class="item1">Item 1</div>
+  <div class="item2">Item 2</div>
+  <div class="item3">Item 3</div>
+</div>
+
+ +

{{ EmbedLiveSample('writing_4', '500', '330') }}

+
+ +

Если вы хотите посмотреть, как они работают, как справа, так и сверху вниз, переключите vertical-lr на vertical-rl, который является вертикальным режимом записи, работающим справа налево.

+ +

Auto-placement and Writing Modes

+ +

В примере, который уже показан, вы можете видеть, как режим записи меняет направление, в котором элементы помещаются в сетку. Элементы по умолчанию помещают себя вдоль оси Inline, а затем переходят в новую строку. Однако эта линейная ось может не всегда выполняться слева направо.

+ +

Линейное размещение и режимы записи

+ +

Главное, что следует помнить при размещении элементов по номеру строки, является то, что строка 1 является стартовой линией, независимо от того, в каком режиме записи вы находитесь. Строка -1 - это конечная строка, независимо от того, в каком режиме записи вы находитесь.

+ +

В следующем примере у меня есть сетка, которая находится в направлении по умолчанию ltr. Я разместил три элемента, используя линейное размещение.

+ +
    +
  • Item 1 starts at column line 1, охватывающей один трек.
  • +
  • Item 2 starts at column line -1, охватывая -3.
  • +
  • Item 3 starts at column line 1, охватывая строку столбца 3.
  • +
+ +
+ + +
.wrapper {
+  display: grid;
+  grid-template-columns: repeat(3, 1fr);
+  grid-template-rows: repeat(2, 100px);
+  grid-gap: 10px;
+}
+.item1 {
+    grid-column: 1 ;
+}
+.item2 {
+    grid-column: -1 / -3;
+}
+.item3 {
+    grid-column: 1 / 3;
+    grid-row: 2;
+}
+
+ +
<div class="wrapper">
+        <div class="item1">Item 1</div>
+        <div class="item2">Item 2</div>
+        <div class="item3">Item 3</div>
+    </div>
+
+ +

{{ EmbedLiveSample('writing_5', '500', '330') }}

+
+ +

Если теперь добавить свойство {{cssxref ("direction")}} со значением rtl в контейнер сетки, строка 1 станет правой частью сетки, а строка -1 - слева.

+ +
+ + +
.wrapper {
+  direction: rtl;
+  display: grid;
+  grid-template-columns: repeat(3, 1fr);
+  grid-template-rows: repeat(2, 100px);
+  grid-gap: 10px;
+}
+.item1 {
+    grid-column: 1 ;
+}
+.item2 {
+    grid-column: -1 / -3;
+}
+.item3 {
+    grid-column: 1 / 3;
+    grid-row: 2;
+}
+
+ +
<div class="wrapper">
+        <div class="item1">Item 1</div>
+        <div class="item2">Item 2</div>
+        <div class="item3">Item 3</div>
+    </div>
+
+ +

{{ EmbedLiveSample('writing_6', '500', '330') }}

+
+ +

То, что это демонстрирует, заключается в том, что если вы переключаете направление текста на целые страницы или на части страниц и используете строки: вы можете назвать свои строки, если вы не хотите, чтобы макет полностью переключал направление , для некоторых вещей, например, когда сетка содержит текстовое содержимое, это переключение может быть именно тем, что вы хотите. Для других целей это не так.

+ +

Странный порядок значений в свойстве grid-area

+ +

Вы можете использовать свойство {{cssxref ("grid-area")}}, чтобы указать все четыре строки области сетки как одно значение. Когда люди впервые сталкиваются с этим, они часто удивляются тому, что значения не следуют тому же порядку, что и сокращенное поле, которое работает по часовой стрелке: сверху, справа, внизу, слева.

+ +

Порядок значений grid-area:

+ +
    +
  • grid-row-start
  • +
  • grid-column-start
  • +
  • grid-row-end
  • +
  • grid-column-end
  • +
+ +

Что для английского языка, слева направо означает, что заказ:

+ +
    +
  • top
  • +
  • left
  • +
  • bottom
  • +
  • right
  • +
+ +

Это против часовой стрелки! Итак, обратное тому, что мы делаем для полей и заполнения. Как только вы поймете, что grid-area видит мир как "block и inline", вы можете помнить, что мы устанавливаем два запуска, а затем два конца. Когда вы знаете, это становится намного логичнее!

+ +

Смешанные режимы записи и макет сетки

+ +

В дополнение к отображению документов, используя правильный режим записи для языка, режимы записи могут быть использованы творчески в документах, которые в противном случае будут ltr. В следующем примере у меня есть макет сетки с набором ссылок вниз с одной стороны. Я использовал режимы записи, чтобы включить их на стороне в треке столбца:

+ +
+
.wrapper {
+    display: grid;
+    grid-gap: 20px;
+    grid-template-columns: 1fr auto;
+    font: 1em Helvetica, Arial, sans-serif;
+}
+.wrapper nav {
+    writing-mode: vertical-lr;
+}
+.wrapper ul {
+    list-style: none;
+    margin: 0;
+    padding: 1em;
+    display: flex;
+    justify-content: space-between;
+}
+.wrapper a {
+    text-decoration: none;
+}
+
+ +
<div class="wrapper">
+        <div class="content">
+            <p>Turnip greens yarrow ricebean rutabaga endive cauliflower sea lettuce kohlrabi amaranth water spinach avocado daikon napa cabbage asparagus winter purslane kale. Celery potato scallion desert raisin horseradish spinach carrot soko. Lotus root water spinach fennel kombu maize bamboo shoot green bean swiss chard seakale pumpkin onion chickpea gram corn pea. Brussels sprout coriander water chestnut gourd swiss chard wakame kohlrabi beetroot carrot watercress. Corn amaranth salsify bunya nuts nori azuki bean chickweed potato bell pepper artichoke.</p>
+
+<p>Nori grape silver beet broccoli kombu beet greens fava bean potato quandong celery. Bunya nuts black-eyed pea prairie turnip leek lentil turnip greens parsnip. Sea lettuce lettuce water chestnut eggplant winter purslane fennel azuki bean earthnut pea sierra leone bologi leek soko chicory celtuce parsley jícama salsify.</p>
+        </div>
+        <nav>
+            <ul>
+                <li><a href="">Link 1</a></li>
+                <li><a href="">Link 2</a></li>
+                <li><a href="">Link 3</a></li>
+            </ul>
+        </nav>
+    </div>
+
+ +

{{ EmbedLiveSample('writing_7', '500', '330') }}

+
+ +

Физические значения и grid layout

+ +

Мы часто сталкиваемся с физическими свойствами при создании веб-сайтов и в то время как свойства и значения размещения и выравнивания сетки соответствуют режимам записи, есть вещи, которые вы можете сделать с Grid, которые заставляют вас использовать физические свойства и значения. В руководстве по выравниванию ячеек и сеткам я продемонстрировал, как автоматические поля работают в области сетки. Использование автоматической маржи, чтобы оттолкнуть один элемент от других, является общим трюком flexbox, однако это также связывает макет с физическим пространством.

+ +

Если вы используете абсолютное позиционирование в области сетки, то вы снова будете использовать физические смещения, чтобы нажимать элемент вокруг области сетки. Главное, что нужно знать, - это напряжение между физическими и логическими свойствами и ценностями. Например, имейте в виду, что вам может потребоваться внести изменения в ваш CSS, чтобы справиться с переходом от ltr до rtl.

+ +

Логические свойства для всего!

+ +

Наши новые методы компоновки дают нам возможность использовать эти логические значения для размещения элементов, однако, как только мы начнем объединять их с физическими свойствами, используемыми для полей и отступов, нам нужно помнить, что эти физические свойства не изменятся в соответствии с режимом записи.

+ +

Спецификация логических свойств CSS имеет целью изменить это и в будущем мы сможем использовать логические эквиваленты для свойств, такие как {{cssxref ("margin-left")}} и {{cssxref ("margin-right") }}, в нашем CSS. Firefox уже реализовал их, поэтому вы можете попробовать их прямо сейчас в Firefox. Я знаю в будущем, как только эти корабли повсюду, ваши знания «Блокировать и встроить» с помощью Grid означают, что вы точно знаете, как их использовать.

+ + diff --git a/files/ru/web/css/css_grid_layout/grid_template_areas/index.html b/files/ru/web/css/css_grid_layout/grid_template_areas/index.html new file mode 100644 index 0000000000..6d2d3b6892 --- /dev/null +++ b/files/ru/web/css/css_grid_layout/grid_template_areas/index.html @@ -0,0 +1,529 @@ +--- +title: Шаблоны грид-областей +slug: Web/CSS/CSS_Grid_Layout/Грид-области +translation_of: Web/CSS/CSS_Grid_Layout/Grid_Template_Areas +--- +

В предыдущем обзоре мы рассмотрели грид-линии и то, как с их помощью размещать элементы в гридах. Когда Вы работаете с CSS Grid Layout, у Вас всегда есть грид-линии, поэтому они - быстрый, прямой и надежный способ расположить элементы. Как бы то ни было, существует альтернативный метод, и этот метод можно использовать как в одиночку, так и в сочетании с расположением элементов по грид-линиям. В этом методе элементы располагаются с помощью именнованных, заранее определенных грид-областей. Давайте рассмотрим, как он работает, и Вы скоро поймете, почему его называют методом ascii-искусства в концепции макетов на гридах!

+ +

Имя для грид-области

+ +

Вы уже знакомы со свойством {{cssxref("grid-area")}}. Это то свойство, которое принимает в качестве значения номера четырех грид-линий, определяющих расположение грид-области.

+ +
.box1 {
+   grid-area: 1 / 1 / 4 / 2;
+}
+
+ +

Что мы делаем, когда задаем все четыре значения? Мы определяем область, ограниченную данными грид-линиями. 

+ +

The Grid Area defined by lines

+ +

Другой способ определить грид-область, - задать ей имя и определить местоположение как значения свойства {{cssxref("grid-template-areas")}}. Вы можете выбрать для грид-области любое имя. Например, если нам нужно создать макет согласно картинке ниже, мы можем назвать четыре основных области следующим образом:

+ +
    +
  • header
  • +
  • footer
  • +
  • sidebar
  • +
  • основное содержимое content
  • +
+ +

An image showing a simple two column layout with header and footer

+ +

С помощью свойства {{cssxref("grid-area")}} мы можем назначить каждой из этих областей свое собственное имя. Именование областей еще не создает никакого макета, однако теперь у нас есть именнованные области, которые мы можем в нем использовать.

+ +
+
.header {
+    grid-area: hd;
+}
+.footer {
+    grid-area: ft;
+}
+.content {
+    grid-area: main;
+}
+.sidebar {
+    grid-area: sd;
+}
+
+ +

Определив имена, мы можем приступить к созданию макета. На этот раз вместо того, чтобы расположить элементы с помощью номеров линий, заданных для самих элементов, мы создаем весь макет в грид-контейнере.

+ +
.wrapper {
+    display: grid;
+    grid-template-columns: repeat(9, 1fr);
+    grid-auto-rows: minmax(100px, auto);
+    grid-template-areas:
+      "hd hd hd hd   hd   hd   hd   hd   hd"
+      "sd sd sd main main main main main main"
+      "ft ft ft ft   ft   ft   ft   ft   ft";
+}
+
+ + + +

 

+ +
<div class="wrapper">
+    <div class="header">Header</div>
+    <div class="sidebar">Sidebar</div>
+    <div class="content">Content</div>
+    <div class="footer">Footer</div>
+</div>
+ +

{{ EmbedLiveSample('Grid_Area_1', '300', '330') }}

+
+ +

Если мы используем этот метод, то нам не нужно задавать что-то отдельно для грид-элементов, все задается для грид-контейнера. Весь макет описывается значением свойства {{cssxref("grid-template-areas")}}.

+ +

Оставляем ячейку пустой

+ +

В данном примере мы полностью заполнили грид областями и не оставили пустого пространства. Однако, наш метод также позволяет оставлять грид-ячейки пустыми. Чтобы сделать это воспользуйтесь символом точки, '.'. Если нам нужно отображать футер только под основным содержимым страницы, значит, мы должны оставить три ячейки под сайдбаром пустыми.

+ +
.header {
+    grid-area: hd;
+}
+.footer {
+    grid-area: ft;
+}
+.content {
+    grid-area: main;
+}
+.sidebar {
+    grid-area: sd;
+}
+
+ + + +
.wrapper {
+    display: grid;
+    grid-template-columns: repeat(9, 1fr);
+    grid-auto-rows: minmax(100px, auto);
+    grid-template-areas:
+      "hd hd hd hd   hd   hd   hd   hd   hd"
+      "sd sd sd main main main main main main"
+      ".  .  .  ft   ft   ft   ft   ft   ft";
+}
+
+ +
<div class="wrapper">
+    <div class="header">Header</div>
+    <div class="sidebar">Sidebar</div>
+    <div class="content">Content</div>
+    <div class="footer">Footer</div>
+</div>
+ +

{{ EmbedLiveSample('Leaving_a_grid_cell_empty', '300', '330') }}

+ +

Чтобы сделать наш макет чище, мы можем использовать множество символов .. Если между точками нет пробелов, то они считаются одной ячейкой. В комплексных макетах подобная возможность помогает аккуратно выравнивать строки и колонки. То есть, Вы прямо в CSS можете видеть, как выглядит Ваш макет.

+ +

Охватываем несколько ячеек

+ +

В нашем примере каждая из областей охватывает несколько грид-ячеек, и получаем мы подобный эффект за счет того, что через пробел повторяем имя этой грид-области несколько раз. Вы можете добавить дополнительные пробелы, чтобы аккуратно выравнять значения в grid-template-areas. В нашем примере мы пробелами подравняли hd и ft , чтобы они коррелировали с  main.

+ +

Область, которую мы создаем подобными цепочками имен, должна быть прямоугольной. На данном этапе нельзя создать L-образную область. В спецификации говорится, что, возможно, в будущем подобная функциональность добавится. А сейчас мы можем охватывать строки так же легко, как и колонки. Например, давайте сделаем так, чтобы наш сайдбар простирался до конца футера. Для этого поменяем . на sd.

+ +
.header {
+    grid-area: hd;
+}
+.footer {
+    grid-area: ft;
+}
+.content {
+    grid-area: main;
+}
+.sidebar {
+    grid-area: sd;
+}
+
+ + + +
.wrapper {
+    display: grid;
+    grid-template-columns: repeat(9, 1fr);
+    grid-auto-rows: minmax(100px, auto);
+    grid-template-areas:
+      "hd hd hd hd   hd   hd   hd   hd   hd"
+      "sd sd sd main main main main main main"
+      "sd sd sd  ft  ft   ft   ft   ft   ft";
+}
+
+ + + +

{{ EmbedLiveSample('Spanning_multiple_cells', '300', '330') }}

+ +

Значение {{cssxref("grid-template-areas")}} должно отображать законченный грид, а иначе оно невалидно (и игнорируется!). Это значит, что у Вас должно быть одинаковое количество ячеек в каждой строке, а если какая-то ячейка должна быть пустой, то вместо имени в ней должна быть точка. Грид будет также невалидным, если области в нем не прямоугольные.

+ +

Переопределение грида с медиа-запросами

+ +

Поскольку наш макет теперь содержится в одной части CSS, вносить изменения для различных контрольных точек (breakpoints) становится крайне легко. Сделать это можно либо переопределив сам грид, либо положение элементов на гриде, либо и то, и другое одновеременно.

+ +

При этом определяйте имена для ваших грид-областей за пределами медиа-запросов. В таком случае, область основного содержимого (content) всегда будет называться main независимо от того, где она находится на сетке.

+ +

Мы можем теперь изменить наш макет для узкой ширины экрана на более простой, где все грид-области будут друг над другом в одном столбце.

+ + + +
.header {
+    grid-area: hd;
+}
+.footer {
+    grid-area: ft;
+}
+.content {
+    grid-area: main;
+}
+.sidebar {
+    grid-area: sd;
+}
+
+.wrapper {
+    display: grid;
+    grid-auto-rows: minmax(100px, auto);
+    grid-template-columns: 1fr;
+    grid-template-areas:
+      "hd"
+      "main"
+      "sd"
+      "ft";
+}
+
+ +

Внутри медиа-запросов, мы переопределяем этот макет на двухколонный, а при увеличении свободного пространства, на трехколонный. Обратите внимание, что для широкого макета я оставляю свою девятиколонную трековую сетку, а с помощью grid-template-areas я указываю куда стоит разместить грид-области. 

+ +
@media (min-width: 500px) {
+    .wrapper {
+        grid-template-columns: repeat(9, 1fr);
+        grid-template-areas:
+          "hd hd hd hd   hd   hd   hd   hd   hd"
+          "sd sd sd main main main main main main"
+          "sd sd sd  ft  ft   ft   ft   ft   ft";
+    }
+}
+@media (min-width: 700px) {
+    .wrapper {
+        grid-template-areas:
+          "hd hd hd   hd   hd   hd   hd   hd hd"
+          "sd sd main main main main main ft ft";
+    }
+}
+
+ + + +

{{ EmbedLiveSample('Redefining_the_grid_using_media_queries', '550', '330') }}

+ +

Использование grid-template-areas для элементов UI

+ +

Многие из примеров grid, которые вы найдете в Интернете, предполагают, что вы будете использовать grid для макета главной страницы, однако grid может быть столь же полезна для небольших элементов. Использование {{cssxref ("grid-template-areas")}} может быть особенно приятным, так как в коде легко видеть, как выглядит ваш элемент.

+ +

В качестве очень простого примера мы можем создать «медиа-объект». Это компонент с пространством для изображения или другого носителя с одной стороны, а контент - с другой. Изображение может отображаться справа или слева от окна.

+ +

Images showing an example media object design

+ +

Наша сетка представляет собой двухколоночную трековую сетку, со столбцом для изображения размером 1fr и текстом 3fr. Если вы хотите область с фиксированной шириной изображения, тогда вы можете установить столбец изображения как ширину пикселя и назначить текстовую область 1fr. Одна колонка трека 1fr затем займет оставшуюся часть пространства.

+ +

Мы предоставляем области изображения имя области сетки img и содержимое текстовой области, затем мы можем выложить их, используя свойство grid-template-areas.

+ +
+
* {box-sizing: border-box;}
+
+.media {
+    border: 2px solid #f76707;
+    border-radius: 5px;
+    background-color: #fff4e6;
+    max-width: 400px;
+}
+.media {
+    display: grid;
+    grid-template-columns: 1fr 3fr;
+    grid-template-areas: "img content";
+    margin-bottom: 1em;
+}
+
+.media .image {
+    grid-area: img;
+    background-color: #ffd8a8;
+}
+
+.media .text {
+    grid-area: content;
+    padding: 10px;
+
+}
+
+ +
<div class="media">
+    <div class="image"></div>
+    <div class="text">This is a media object example.
+      We can use grid-template-areas to switch around the image and text part of the media object.
+    </div>
+</div>
+ +

{{ EmbedLiveSample('Media_1', '300', '200') }}

+
+ +

Отображение изображения с другой стороны окна

+ +

Возможно, нам захочется отобразить нашу коробку с изображением наоборот. Для этого мы переопределим сетку, чтобы поместить последний трек 1fr и просто переверните значения {{cssxref ("grid-template-areas")}}.

+ +
+
* {box-sizing: border-box;}
+
+.media {
+    border: 2px solid #f76707;
+    border-radius: 5px;
+    background-color: #fff4e6;
+    max-width: 400px;
+}
+.media {
+    display: grid;
+    grid-template-columns: 1fr 3fr;
+    grid-template-areas: "img content";
+    margin-bottom: 1em;
+}
+
+.media.flipped {
+    grid-template-columns: 3fr 1fr;
+    grid-template-areas: "content img";
+}
+
+.media .image {
+    grid-area: img;
+    background-color: #ffd8a8;
+}
+
+.media .text {
+    grid-area: content;
+    padding: 10px;
+
+}
+
+ +
<div class="media flipped">
+    <div class="image"></div>
+    <div class="text">This is a media object example.
+      We can use grid-template-areas to switch around the image and text part of the media object.
+    </div>
+</div>
+ +

{{ EmbedLiveSample('Media_2', '300', '200') }}

+
+ +

Сокращения определения сетки

+ +

Рассмотрев различные способы размещения элементов на наших сетках и многие свойства, используемые для определения сетки, самое время взглянуть на пару сокращений, доступных для определения сетки и многое из всего этого в одной строке CSS.

+ +

Они могут быстро стать трудными для чтения для других разработчиков или даже для вашего будущего. Однако они являются частью спецификации и, вероятно, вы столкнетесь с ними в примерах или в использовании другими разработчиками, даже если вы решите не использовать их.

+ +

Прежде чем использовать какиу-либо сокращения (shorthand), стоит помнить, что shorthand не только позволяют устанавливать множество свойств за один раз, но также действуют, чтобы сбросить объекты до их начальных значений, которых вы не используете, или не можете установить в сокращении. Поэтому, если вы используете сокращения, помните, что оно может сбросить все, что вы применили в другом месте.

+ +

Два сокращения (shorthand) для контейнера сетки - это Explicit Grid Shorthand grid-template и Grid Definition Shorthand grid.

+ +

grid-template

+ +

Свойство {{cssxref ("grid-template")}} задает следующие свойства:

+ +
    +
  • {{cssxref("grid-template-rows")}}
  • +
  • {{cssxref("grid-template-columns")}}
  • +
  • {{cssxref("grid-template-areas")}}
  • +
+ +

Свойство называется явным сокращением сетки, потому что оно устанавливает те вещи, которые вы контролируете, когда вы определяете явную сетку, а не те, которые влияют на любые неявные строки или столбцы, которые могут быть созданы.

+ +

Следующий код создает макет, используя {{cssxref ("grid-template")}}, который совпадает с макетом, созданным ранее в этом руководстве.

+ +
.wrapper {
+    display: grid;
+    grid-template:
+      "hd hd hd hd   hd   hd   hd   hd   hd" minmax(100px, auto)
+      "sd sd sd main main main main main main" minmax(100px, auto)
+      "ft ft ft ft   ft   ft   ft   ft   ft" minmax(100px, auto)
+             / 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr ;
+}
+
+ +

Первое значение - это значение нашей grid-template-areas, но мы также объявляем размер строки в конце каждой строки. Это то, что делает minmax (100px, auto).

+ +

Затем после grid-template-areas у нас есть косая черта, после чего явный список треков столбцов.

+ +

grid

+ +

Сокращение {{cssxref ("grid")}} идет еще дальше, а также задает свойства, используемые неявной сеткой. Таким образом, вы будете устанавливать:

+ +
    +
  • {{cssxref("grid-template-rows")}}
  • +
  • {{cssxref("grid-template-columns")}}
  • +
  • {{cssxref("grid-template-areas")}}
  • +
  • {{cssxref("grid-auto-rows")}}
  • +
  • {{cssxref("grid-auto-columns")}}
  • +
  • {{cssxref("grid-auto-flow")}}
  • +
+ +

Свойство также сбрасывает {{cssxref ("grid-gap")}} свойство на 0, однако вы не можете указывать пробелы в этой сокращенности.

+ +

Вы можете использовать этот синтаксис точно так же, как сокращение {{cssxref ("grid-template")}}, просто знайте, что при этом вы сбросите другие значения, установленные этим свойством.

+ +
.wrapper {
+    display: grid;
+    grid: "hd hd hd hd   hd   hd   hd   hd   hd" minmax(100px, auto)
+    "sd sd sd main main main main main main" minmax(100px, auto)
+    "ft ft ft ft   ft   ft   ft   ft   ft" minmax(100px, auto)
+    / 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr ;
+}
+
+ +

Мы снова рассмотрим другие функции, предлагаемые этом сокращением позже в этих руководствах, когда мы рассмотрим автоматическое размещение и свойство grid-auto-flow.

+ +

Если вы проработали эти начальные руководства, теперь вы должны иметь возможность создавать сетки с использованием линейного размещения или названных областей. Потратьте некоторое время на создание некоторых общих шаблонов макетов с использованием сетки, в то время как есть много новых терминов для изучения, синтаксис относительно прост. По мере того, как вы разрабатываете примеры, вы, вероятно, придумаете некоторые вопросы и воспользуетесь случаями, которые мы еще не рассмотрели. В остальных этих руководствах мы рассмотрим некоторые детали, включенные в спецификацию, - чтобы вы могли начать создавать с ним расширенные макеты.

+ + diff --git a/files/ru/web/css/css_grid_layout/line-based_placement_with_css_grid/index.html b/files/ru/web/css/css_grid_layout/line-based_placement_with_css_grid/index.html new file mode 100644 index 0000000000..e470a72ce7 --- /dev/null +++ b/files/ru/web/css/css_grid_layout/line-based_placement_with_css_grid/index.html @@ -0,0 +1,652 @@ +--- +title: Расположение элементов по грид-линиям с помощью CSS Grid +slug: >- + Web/CSS/CSS_Grid_Layout/Расположение_элементов_по_грид-линиям_с_помощью_CSS_Grid +tags: + - CSS + - CSS Grid + - Грид + - Руководство + - Сетка +translation_of: Web/CSS/CSS_Grid_Layout/Line-based_Placement_with_CSS_Grid +--- +

В статье, касавшейся основных понятий позиционирования элементов с помощью гридов, мы кратенько рассмотрели, как располагать элементы в гриде, используя номера линий. Теперь давайте детально исследуем то, как работает эта фундаментальная часть спецификации.

+ +

Собственно, начать квест по гридам со знакомства с пронумерованными линиями - логично, потому что в ситуации, когда Вы работаете с гридами, пронумерованные линии у Вас есть всегда. Линии нумеруются и для колонок, и для строк, отсчет начинается с 1. Нужно заметить, что грид индексируется в соответствии с режимом написания (writing mode) документа. В языках с написанием слева направо, таких как русский, например, линия 1 - самая левая линия грида. Если написание справа налево, то линия 1 будет, соответственно, самой правой линией в гриде. По ходу изучения недр мы детально узнаем, как гриды взаимодействуют с режимами написания, поэтому не исчезайте, впереди много интересного.

+ +

Базовый пример

+ +

В качестве крайне простого примера давайте возьмем грид с тремя треками-колонками и тремя треками-строками. Такой грид дает нам по 4 линии для каждого направления.

+ +

Внутри нашего грид-контейнера у нас есть четыре дочерних элемента. Если мы не размещаем их явным образом, эти элементы будут расположены в гриде в соответствии с правилами авторазмещения, то есть, по одному элементу - в каждой из четырех первых ячеек. Если Вы воспользуетесь Firefox Grid Highlighter , то увидете, как грид инициирует колонки и строки.

+ +

Our Grid highlighted in DevTools

+ + + +
.wrapper {
+   display: grid;
+   grid-template-columns: repeat(3, 1fr);
+   grid-template-rows: repeat(3, 100px);
+}
+
+ +
<div class="wrapper">
+   <div class="box1">One</div>
+   <div class="box2">Two</div>
+   <div class="box3">Three</div>
+   <div class="box4">Four</div>
+</div>
+
+ +

{{ EmbedLiveSample('A_basic_example', '300', '330') }}

+ +

Позиционирование элементов по номерам линий

+ +

Мы можем воспользоваться размещением по линиям (line-based placement), чтобы расположить элементы на гриде. Например, нам нужно, чтобы первый элемент начинался от левого края и занимал один трек-колонку. Пусть он также начинается с первой строчной линии,  то есть, от верхнего края грида, и занимает пространство до четвертой строчной линии.

+ +
+
.box1 {
+   grid-column-start: 1;
+   grid-column-end: 2;
+   grid-row-start: 1;
+   grid-row-end: 4;
+}
+
+ +

Если Вы явно позиционируете одни элементы, другие элементы грида по-прежнему размещаются в соответствии с правилами авторазмещения. Дальше мы детально рассмотрим, как это происходит, а пока Вы и сами могли заметить, что по мере размещения одних элементов, оставшиеся элементы занимают пустые ячейки грида.

+ +

Задавая адреса для каждого элемента по отдельности, мы можем разместить все наши четыре элемента по колонкам и строкам. Заметьте, что при желании можно оставить ячейки пустыми. Одна из самых приятных вещей при работе с Grid Layout - возможность создавать негативное пространство (пустые области в макете) без кувырков через голову и прочих хаков.

+ + + +
<div class="wrapper">
+   <div class="box1">One</div>
+   <div class="box2">Two</div>
+   <div class="box3">Three</div>
+   <div class="box4">Four</div>
+</div>
+
+ +
.box2 {
+   grid-column-start: 3;
+   grid-column-end: 4;
+   grid-row-start: 1;
+   grid-row-end: 3;
+}
+.box3 {
+   grid-column-start: 2;
+   grid-column-end: 3;
+   grid-row-start: 1;
+   grid-row-end: 2;
+}
+.box4 {
+   grid-column-start: 2;
+   grid-column-end: 4;
+   grid-row-start: 3;
+   grid-row-end: 4;
+}
+
+ +

{{ EmbedLiveSample('Line_Number', '300', '330') }}

+
+ +
+

Сокращения grid-column и grid-row

+ +

Мы написали много кода, чтобы разместить каждый элемент. Неудивительно, что существует краткая форма записи свойств. {{cssxref("grid-column-start")}} и {{cssxref("grid-column-end")}} могут быть объединены в одном {{cssxref("grid-column")}}, а {{cssxref("grid-row-start")}} и {{cssxref("grid-row-end")}} - в {{cssxref("grid-row")}}.

+ + + +
<div class="wrapper">
+   <div class="box1">One</div>
+   <div class="box2">Two</div>
+   <div class="box3">Three</div>
+   <div class="box4">Four</div>
+</div>
+
+ +
.box1 {
+   grid-column: 1 / 2;
+   grid-row: 1 / 4;
+}
+.box2 {
+   grid-column: 3 / 4;
+   grid-row: 1 / 3;
+}
+.box3 {
+   grid-column: 2 / 3;
+   grid-row: 1 /  2;
+}
+.box4 {
+   grid-column: 2 / 4;
+   grid-row: 3 / 4;
+}
+
+ +

{{ EmbedLiveSample('Grid_Shorthands', '300', '330') }}

+
+ +

Расположение элемента по умолчанию

+ +

В примерах выше мы задавали конечную линию для строки и колонки, чтобы продемонстрировать работу свойств, однако, если элемент занимает только один трек, Вы можете опустить значение grid-column-end или grid-row-end. Грид по умолчанию размещает элемент таким образом, чтобы он занимал всего один трек. Это значит, что длинная запись свойств в нашем первоначальном примере может выглядеть вот так:

+ +
+ + +
<div class="wrapper">
+   <div class="box1">One</div>
+   <div class="box2">Two</div>
+   <div class="box3">Three</div>
+   <div class="box4">Four</div>
+</div>
+
+ +
.box1 {
+   grid-column-start: 1;
+   grid-row-start: 1;
+   grid-row-end: 4;
+}
+.box2 {
+   grid-column-start: 3;
+   grid-row-start: 1;
+   grid-row-end: 3;
+}
+.box3 {
+   grid-column-start: 2;
+   grid-row-start: 1;
+}
+.box4 {
+   grid-column-start: 2;
+   grid-column-end: 4;
+   grid-row-start: 3;
+}
+
+ +

{{ EmbedLiveSample('End_Lines', '300', '330') }}

+
+ +

Поэтому, если мы хотим, чтобы элементы занимали только один трек, наша сокращенная запись будет выглядеть вот так, без слэша и без второго значения:

+ +
+ + +
<div class="wrapper">
+   <div class="box1">One</div>
+   <div class="box2">Two</div>
+   <div class="box3">Three</div>
+   <div class="box4">Four</div>
+</div>
+
+ +
.box1 {
+   grid-column: 1 ;
+   grid-row: 1 / 4;
+}
+.box2 {
+   grid-column: 3 ;
+   grid-row: 1 / 3;
+}
+.box3 {
+   grid-column: 2 ;
+   grid-row: 1 ;
+}
+.box4 {
+   grid-column: 2 / 4;
+   grid-row: 3 ;
+}
+
+ +

{{ EmbedLiveSample('New_Shorthand', '300', '330') }}

+
+ +

Свойство grid-area

+ +

Мы можем пойти еще дальше и определить целую область с помощью одного единственного свойства – {{cssxref("grid-area")}}. Порядок свойств для грид-области следующий:

+ +
    +
  • grid-row-start
  • +
  • grid-column-start
  • +
  • grid-row-end
  • +
  • grid-column-end
  • +
+ + + +
<div class="wrapper">
+   <div class="box1">One</div>
+   <div class="box2">Two</div>
+   <div class="box3">Three</div>
+   <div class="box4">Four</div>
+</div>
+
+ +
.box1 {
+   grid-area: 1 / 1 / 4 / 2;
+}
+.box2 {
+   grid-area: 1 / 3 / 3 / 4;
+}
+.box3 {
+   grid-area: 1 / 2 / 2 / 3;
+}
+.box4 {
+   grid-area: 3 / 2 / 4 / 4;
+}
+
+ +

{{ EmbedLiveSample('The_grid-area_property', '300', '330') }}

+ +

Порядок значений для grid-area может показаться немного странным, он противоположен тому порядку, в котором мы, например, записываем значения для сокращенных свойств margin и padding. Но сделано это потому, что грид работает с направлениями относительно потока, определенными в спецификации CSS Writing Modes. В дальнейшем мы рассмотрим, как гриды взаимодействуют с режимами написания (writing modes), но пока давайте примем за данность, что мы имеем дело с концепцией четырех направлений относительно потока:

+ +
    +
  • block-start (начало блока)
  • +
  • block-end (конец блока)
  • +
  • inline-start (начало строки)
  • +
  • inline-end (конец строки)
  • +
+ +

Мы работаем с русским, языком с написанием слева направо. Начало нашего блока (block-start) - верхняя строчная линия грид-контейнера, конец блока (block-end) - последняя строчная линия контейнера. Начало строки (inline-start) - самая левая колоночная линия, поскольку начало строки - это всегда точка, с которой начинается написание текста в заданном режиме написания. Конец строки (inline-end) - последняя колоночная линия грида.

+ +

Когда мы задаем нашу грид-область с помощью свойства grid-area , мы сначала определяем обе начальные линии block-start и inline-start, а затем обе конечные линии  block-end и inline-end. Поскольку мы давно работаем с физическими свойствами top, right, bottom и left, поначалу это кажется непривычным, но вполне осмысленно, если осознать, что относительно режима написания вебсайты - многонаправленные структуры.

+ +

Считая с конца

+ +

Мы также можем отсчитывать грид-линии с конца, то есть с последней (для русского языка - самой правой) колоночной и последней (самой нижней) строчной линий. Индекс этих линий будет -1, а линий непосредственно перед ними -2, и так далее. Нужно помнить, что под последней линией понимается последняя линия явного грида (explicit grid), то есть грида, определенного с помощью grid-template-columns иgrid-template-rows. Любые линии строк и колонок, добавленные неявным гридом (implicit grid) не считаются.

+ +

В примере ниже мы "перевернули" определение нашего грида, при размещении элементов задавая линии с конца, то есть, от правого и нижнего краев.

+ + + +
<div class="wrapper">
+   <div class="box1">One</div>
+   <div class="box2">Two</div>
+   <div class="box3">Three</div>
+   <div class="box4">Four</div>
+</div>
+
+ +
.box1 {
+   grid-column-start: -1;
+   grid-column-end: -2;
+   grid-row-start: -1;
+   grid-row-end: -4;
+}
+.box2 {
+   grid-column-start: -3;
+   grid-column-end: -4;
+   grid-row-start: -1;
+   grid-row-end: -3;
+}
+.box3 {
+   grid-column-start: -2;
+   grid-column-end: -3;
+   grid-row-start: -1;
+   grid-row-end: -2;
+}
+.box4 {
+   grid-column-start: -2;
+   grid-column-end: -4;
+   grid-row-start: -3;
+   grid-row-end: -4;
+}
+
+ +

{{ EmbedLiveSample('Counting_backwards', '300', '330') }}

+ +

Как растянуть элемент на длину всего грида?

+ +

Возможность адресовать и первую, и последнюю линии грида становится крайне полезной, если нам нужно растянуть элемент на всю длину грида. Сделать это можно вот так:

+ +
.item {
+  grid-column: 1 / -1;
+}
+
+ +

Зазоры (Gutters) или аллеи (Alleys)

+ +

Спецификация CSS Grid включает возможность добавлять промежутки (зазоры) между треками-колонками и треками-строками с помощью свойств {{cssxref("grid-column-gap")}} и {{cssxref("grid-row-gap")}}. Эти свойства задают промежутки, которые во многом действуют точно так же, как свойство {{cssxref("column-gap")}} в многоколоночных макетах.

+ +

Зазоры появляются только между треками и не добавляют пространство сверху, снизу, справа или слева грид-контейнеру. Мы можем добавить зазоры в предыдущий пример, дописав эти свойства грид-контейнеру.

+ + + +
<div class="wrapper">
+   <div class="box1">One</div>
+   <div class="box2">Two</div>
+   <div class="box3">Three</div>
+   <div class="box4">Four</div>
+</div>
+
+ +
.box1 {
+   grid-column: 1 ;
+   grid-row: 1 / 4;
+}
+.box2 {
+   grid-column: 3 ;
+   grid-row: 1 / 3;
+}
+.box3 {
+   grid-column: 2 ;
+   grid-row: 1 ;
+}
+.box4 {
+   grid-column: 2 / 4;
+   grid-row: 3 ;
+}
+.wrapper {
+     display: grid;
+     grid-template-columns: repeat(3, 1fr);
+     grid-template-rows: repeat(3, 100px);
+     grid-column-gap: 20px;
+     grid-row-gap: 1em;
+}
+
+ +

{{ EmbedLiveSample('Gutters_or_Alleys', '300', '350') }}

+ +

Сокращенная запись для грид-зазоров

+ +

Оба свойства также можно записать с помощью свойства-сокращения {{cssxref("grid-gap")}}. Если задать только одно значение, то оно определит размер зазоров и между колонками, и между строками. Если мы задаем два значения, то первое используется для grid-row-gap , а второе - для grid-column-gap.

+ +
.wrapper {
+     display: grid;
+     grid-template-columns: repeat(3, 1fr);
+     grid-template-rows: repeat(3, 100px);
+     grid-gap: 1em 20px;
+}
+
+ +

В терминах расположения элементов по грид-линиям (line-based positioning) зазоры ведут себя так, как если бы самой линии была добавлена толщина. Все, что должно было начинаться от линии, начинается от нее на расстоянии зазора, и Вы не можете адресовать зазор напрямую или поместить в него что-нибудь. Если Вам нужны зазоры, которые ведут себя, как обыкновенные треки, что же - определите трек, а не зазор.

+ +

Использование ключевого слова span 

+ +

В дополнение к возможности обращаться к начальной и конечной линии по их номерам Вы можете задать номер начальной линии, а после - количество треков, которые должен занять элемент.

+ + + +
<div class="wrapper">
+   <div class="box1">One</div>
+   <div class="box2">Two</div>
+   <div class="box3">Three</div>
+   <div class="box4">Four</div>
+</div>
+
+ +
.box1 {
+  grid-column: 1;
+  grid-row: 1 / span 3;
+}
+.box2 {
+   grid-column: 3;
+   grid-row: 1 / span 2;
+}
+.box3 {
+   grid-column: 2;
+   grid-row: 1;
+}
+.box4 {
+   grid-column: 2 / span 2;
+   grid-row: 3;
+}
+
+ +

{{ EmbedLiveSample('Using_the_span_keyword', '300', '330') }}

+ +

Ключево слово  span также можно использовать в качестве значения grid-row-start/grid-row-end иgrid-column-start/grid-column-end. Два примера ниже создают одну и ту же грид-область. В первом примере мы задаем начальную строчную линию, а после говорим свойству, отвечающему за конечную линию: эй, мы хотим занять под этот элемент три линии. В итоге, грид-область начинается с первой линии и занимает пространство до 4-ой.

+ +
.box1 {
+    grid-column-start: 1;
+    grid-row-start: 1;
+    grid-row-end: span 3;
+}
+
+ +

Во втором примере поступим наоборот: зададим конечную строчную линию, а в значении свойства, отвечающего за начальную линию, напишем span 3. Это значит, что элемент должен занять три трека до заданной конечной линии. Грид-область начинается с линии 4 и занимает три трека до линии 1.

+ +
.box1 {
+    grid-column-start: 1;
+    grid-row-start: span 3;
+    grid-row-end: 4;
+}
+
+ +

Чтобы лучше освоиться с размещением элементов по грид-линиям, попробуйте собрать несколько распространенных макетов, располагая элементы на гридах с различным количеством колонок. Помните, что если вы не размещаете все Ваши элементы, оставшиеся располагаются в соответствии с правилами авторазмещения. В результате может получиться как раз тот макет, который Вам нужен, но не факт, и если что-то пошло не так, проверьте, определили ли Вы позицию для проблемного элемента.

+ +

Также помните, что элементы на гриде могут перекрывать друг друга, если Вы намеренно разместили их так, чтобы они друг друга перекрывали. Подобное поведение позволяет получить интересные эффекты, но, если Вы некорректно задали начальные и конечные линии, результат может неприятно Вас удивить. Firefox Grid Highlighter будет крайне полезен в процессе обучения, особенно, когда Вы строите сложные гриды.

+ + diff --git "a/files/ru/web/css/css_grid_layout/\320\263\321\200\320\270\320\264-\320\276\320\261\320\273\320\260\321\201\321\202\320\270/index.html" "b/files/ru/web/css/css_grid_layout/\320\263\321\200\320\270\320\264-\320\276\320\261\320\273\320\260\321\201\321\202\320\270/index.html" deleted file mode 100644 index 6d2d3b6892..0000000000 --- "a/files/ru/web/css/css_grid_layout/\320\263\321\200\320\270\320\264-\320\276\320\261\320\273\320\260\321\201\321\202\320\270/index.html" +++ /dev/null @@ -1,529 +0,0 @@ ---- -title: Шаблоны грид-областей -slug: Web/CSS/CSS_Grid_Layout/Грид-области -translation_of: Web/CSS/CSS_Grid_Layout/Grid_Template_Areas ---- -

В предыдущем обзоре мы рассмотрели грид-линии и то, как с их помощью размещать элементы в гридах. Когда Вы работаете с CSS Grid Layout, у Вас всегда есть грид-линии, поэтому они - быстрый, прямой и надежный способ расположить элементы. Как бы то ни было, существует альтернативный метод, и этот метод можно использовать как в одиночку, так и в сочетании с расположением элементов по грид-линиям. В этом методе элементы располагаются с помощью именнованных, заранее определенных грид-областей. Давайте рассмотрим, как он работает, и Вы скоро поймете, почему его называют методом ascii-искусства в концепции макетов на гридах!

- -

Имя для грид-области

- -

Вы уже знакомы со свойством {{cssxref("grid-area")}}. Это то свойство, которое принимает в качестве значения номера четырех грид-линий, определяющих расположение грид-области.

- -
.box1 {
-   grid-area: 1 / 1 / 4 / 2;
-}
-
- -

Что мы делаем, когда задаем все четыре значения? Мы определяем область, ограниченную данными грид-линиями. 

- -

The Grid Area defined by lines

- -

Другой способ определить грид-область, - задать ей имя и определить местоположение как значения свойства {{cssxref("grid-template-areas")}}. Вы можете выбрать для грид-области любое имя. Например, если нам нужно создать макет согласно картинке ниже, мы можем назвать четыре основных области следующим образом:

- -
    -
  • header
  • -
  • footer
  • -
  • sidebar
  • -
  • основное содержимое content
  • -
- -

An image showing a simple two column layout with header and footer

- -

С помощью свойства {{cssxref("grid-area")}} мы можем назначить каждой из этих областей свое собственное имя. Именование областей еще не создает никакого макета, однако теперь у нас есть именнованные области, которые мы можем в нем использовать.

- -
-
.header {
-    grid-area: hd;
-}
-.footer {
-    grid-area: ft;
-}
-.content {
-    grid-area: main;
-}
-.sidebar {
-    grid-area: sd;
-}
-
- -

Определив имена, мы можем приступить к созданию макета. На этот раз вместо того, чтобы расположить элементы с помощью номеров линий, заданных для самих элементов, мы создаем весь макет в грид-контейнере.

- -
.wrapper {
-    display: grid;
-    grid-template-columns: repeat(9, 1fr);
-    grid-auto-rows: minmax(100px, auto);
-    grid-template-areas:
-      "hd hd hd hd   hd   hd   hd   hd   hd"
-      "sd sd sd main main main main main main"
-      "ft ft ft ft   ft   ft   ft   ft   ft";
-}
-
- - - -

 

- -
<div class="wrapper">
-    <div class="header">Header</div>
-    <div class="sidebar">Sidebar</div>
-    <div class="content">Content</div>
-    <div class="footer">Footer</div>
-</div>
- -

{{ EmbedLiveSample('Grid_Area_1', '300', '330') }}

-
- -

Если мы используем этот метод, то нам не нужно задавать что-то отдельно для грид-элементов, все задается для грид-контейнера. Весь макет описывается значением свойства {{cssxref("grid-template-areas")}}.

- -

Оставляем ячейку пустой

- -

В данном примере мы полностью заполнили грид областями и не оставили пустого пространства. Однако, наш метод также позволяет оставлять грид-ячейки пустыми. Чтобы сделать это воспользуйтесь символом точки, '.'. Если нам нужно отображать футер только под основным содержимым страницы, значит, мы должны оставить три ячейки под сайдбаром пустыми.

- -
.header {
-    grid-area: hd;
-}
-.footer {
-    grid-area: ft;
-}
-.content {
-    grid-area: main;
-}
-.sidebar {
-    grid-area: sd;
-}
-
- - - -
.wrapper {
-    display: grid;
-    grid-template-columns: repeat(9, 1fr);
-    grid-auto-rows: minmax(100px, auto);
-    grid-template-areas:
-      "hd hd hd hd   hd   hd   hd   hd   hd"
-      "sd sd sd main main main main main main"
-      ".  .  .  ft   ft   ft   ft   ft   ft";
-}
-
- -
<div class="wrapper">
-    <div class="header">Header</div>
-    <div class="sidebar">Sidebar</div>
-    <div class="content">Content</div>
-    <div class="footer">Footer</div>
-</div>
- -

{{ EmbedLiveSample('Leaving_a_grid_cell_empty', '300', '330') }}

- -

Чтобы сделать наш макет чище, мы можем использовать множество символов .. Если между точками нет пробелов, то они считаются одной ячейкой. В комплексных макетах подобная возможность помогает аккуратно выравнивать строки и колонки. То есть, Вы прямо в CSS можете видеть, как выглядит Ваш макет.

- -

Охватываем несколько ячеек

- -

В нашем примере каждая из областей охватывает несколько грид-ячеек, и получаем мы подобный эффект за счет того, что через пробел повторяем имя этой грид-области несколько раз. Вы можете добавить дополнительные пробелы, чтобы аккуратно выравнять значения в grid-template-areas. В нашем примере мы пробелами подравняли hd и ft , чтобы они коррелировали с  main.

- -

Область, которую мы создаем подобными цепочками имен, должна быть прямоугольной. На данном этапе нельзя создать L-образную область. В спецификации говорится, что, возможно, в будущем подобная функциональность добавится. А сейчас мы можем охватывать строки так же легко, как и колонки. Например, давайте сделаем так, чтобы наш сайдбар простирался до конца футера. Для этого поменяем . на sd.

- -
.header {
-    grid-area: hd;
-}
-.footer {
-    grid-area: ft;
-}
-.content {
-    grid-area: main;
-}
-.sidebar {
-    grid-area: sd;
-}
-
- - - -
.wrapper {
-    display: grid;
-    grid-template-columns: repeat(9, 1fr);
-    grid-auto-rows: minmax(100px, auto);
-    grid-template-areas:
-      "hd hd hd hd   hd   hd   hd   hd   hd"
-      "sd sd sd main main main main main main"
-      "sd sd sd  ft  ft   ft   ft   ft   ft";
-}
-
- - - -

{{ EmbedLiveSample('Spanning_multiple_cells', '300', '330') }}

- -

Значение {{cssxref("grid-template-areas")}} должно отображать законченный грид, а иначе оно невалидно (и игнорируется!). Это значит, что у Вас должно быть одинаковое количество ячеек в каждой строке, а если какая-то ячейка должна быть пустой, то вместо имени в ней должна быть точка. Грид будет также невалидным, если области в нем не прямоугольные.

- -

Переопределение грида с медиа-запросами

- -

Поскольку наш макет теперь содержится в одной части CSS, вносить изменения для различных контрольных точек (breakpoints) становится крайне легко. Сделать это можно либо переопределив сам грид, либо положение элементов на гриде, либо и то, и другое одновеременно.

- -

При этом определяйте имена для ваших грид-областей за пределами медиа-запросов. В таком случае, область основного содержимого (content) всегда будет называться main независимо от того, где она находится на сетке.

- -

Мы можем теперь изменить наш макет для узкой ширины экрана на более простой, где все грид-области будут друг над другом в одном столбце.

- - - -
.header {
-    grid-area: hd;
-}
-.footer {
-    grid-area: ft;
-}
-.content {
-    grid-area: main;
-}
-.sidebar {
-    grid-area: sd;
-}
-
-.wrapper {
-    display: grid;
-    grid-auto-rows: minmax(100px, auto);
-    grid-template-columns: 1fr;
-    grid-template-areas:
-      "hd"
-      "main"
-      "sd"
-      "ft";
-}
-
- -

Внутри медиа-запросов, мы переопределяем этот макет на двухколонный, а при увеличении свободного пространства, на трехколонный. Обратите внимание, что для широкого макета я оставляю свою девятиколонную трековую сетку, а с помощью grid-template-areas я указываю куда стоит разместить грид-области. 

- -
@media (min-width: 500px) {
-    .wrapper {
-        grid-template-columns: repeat(9, 1fr);
-        grid-template-areas:
-          "hd hd hd hd   hd   hd   hd   hd   hd"
-          "sd sd sd main main main main main main"
-          "sd sd sd  ft  ft   ft   ft   ft   ft";
-    }
-}
-@media (min-width: 700px) {
-    .wrapper {
-        grid-template-areas:
-          "hd hd hd   hd   hd   hd   hd   hd hd"
-          "sd sd main main main main main ft ft";
-    }
-}
-
- - - -

{{ EmbedLiveSample('Redefining_the_grid_using_media_queries', '550', '330') }}

- -

Использование grid-template-areas для элементов UI

- -

Многие из примеров grid, которые вы найдете в Интернете, предполагают, что вы будете использовать grid для макета главной страницы, однако grid может быть столь же полезна для небольших элементов. Использование {{cssxref ("grid-template-areas")}} может быть особенно приятным, так как в коде легко видеть, как выглядит ваш элемент.

- -

В качестве очень простого примера мы можем создать «медиа-объект». Это компонент с пространством для изображения или другого носителя с одной стороны, а контент - с другой. Изображение может отображаться справа или слева от окна.

- -

Images showing an example media object design

- -

Наша сетка представляет собой двухколоночную трековую сетку, со столбцом для изображения размером 1fr и текстом 3fr. Если вы хотите область с фиксированной шириной изображения, тогда вы можете установить столбец изображения как ширину пикселя и назначить текстовую область 1fr. Одна колонка трека 1fr затем займет оставшуюся часть пространства.

- -

Мы предоставляем области изображения имя области сетки img и содержимое текстовой области, затем мы можем выложить их, используя свойство grid-template-areas.

- -
-
* {box-sizing: border-box;}
-
-.media {
-    border: 2px solid #f76707;
-    border-radius: 5px;
-    background-color: #fff4e6;
-    max-width: 400px;
-}
-.media {
-    display: grid;
-    grid-template-columns: 1fr 3fr;
-    grid-template-areas: "img content";
-    margin-bottom: 1em;
-}
-
-.media .image {
-    grid-area: img;
-    background-color: #ffd8a8;
-}
-
-.media .text {
-    grid-area: content;
-    padding: 10px;
-
-}
-
- -
<div class="media">
-    <div class="image"></div>
-    <div class="text">This is a media object example.
-      We can use grid-template-areas to switch around the image and text part of the media object.
-    </div>
-</div>
- -

{{ EmbedLiveSample('Media_1', '300', '200') }}

-
- -

Отображение изображения с другой стороны окна

- -

Возможно, нам захочется отобразить нашу коробку с изображением наоборот. Для этого мы переопределим сетку, чтобы поместить последний трек 1fr и просто переверните значения {{cssxref ("grid-template-areas")}}.

- -
-
* {box-sizing: border-box;}
-
-.media {
-    border: 2px solid #f76707;
-    border-radius: 5px;
-    background-color: #fff4e6;
-    max-width: 400px;
-}
-.media {
-    display: grid;
-    grid-template-columns: 1fr 3fr;
-    grid-template-areas: "img content";
-    margin-bottom: 1em;
-}
-
-.media.flipped {
-    grid-template-columns: 3fr 1fr;
-    grid-template-areas: "content img";
-}
-
-.media .image {
-    grid-area: img;
-    background-color: #ffd8a8;
-}
-
-.media .text {
-    grid-area: content;
-    padding: 10px;
-
-}
-
- -
<div class="media flipped">
-    <div class="image"></div>
-    <div class="text">This is a media object example.
-      We can use grid-template-areas to switch around the image and text part of the media object.
-    </div>
-</div>
- -

{{ EmbedLiveSample('Media_2', '300', '200') }}

-
- -

Сокращения определения сетки

- -

Рассмотрев различные способы размещения элементов на наших сетках и многие свойства, используемые для определения сетки, самое время взглянуть на пару сокращений, доступных для определения сетки и многое из всего этого в одной строке CSS.

- -

Они могут быстро стать трудными для чтения для других разработчиков или даже для вашего будущего. Однако они являются частью спецификации и, вероятно, вы столкнетесь с ними в примерах или в использовании другими разработчиками, даже если вы решите не использовать их.

- -

Прежде чем использовать какиу-либо сокращения (shorthand), стоит помнить, что shorthand не только позволяют устанавливать множество свойств за один раз, но также действуют, чтобы сбросить объекты до их начальных значений, которых вы не используете, или не можете установить в сокращении. Поэтому, если вы используете сокращения, помните, что оно может сбросить все, что вы применили в другом месте.

- -

Два сокращения (shorthand) для контейнера сетки - это Explicit Grid Shorthand grid-template и Grid Definition Shorthand grid.

- -

grid-template

- -

Свойство {{cssxref ("grid-template")}} задает следующие свойства:

- -
    -
  • {{cssxref("grid-template-rows")}}
  • -
  • {{cssxref("grid-template-columns")}}
  • -
  • {{cssxref("grid-template-areas")}}
  • -
- -

Свойство называется явным сокращением сетки, потому что оно устанавливает те вещи, которые вы контролируете, когда вы определяете явную сетку, а не те, которые влияют на любые неявные строки или столбцы, которые могут быть созданы.

- -

Следующий код создает макет, используя {{cssxref ("grid-template")}}, который совпадает с макетом, созданным ранее в этом руководстве.

- -
.wrapper {
-    display: grid;
-    grid-template:
-      "hd hd hd hd   hd   hd   hd   hd   hd" minmax(100px, auto)
-      "sd sd sd main main main main main main" minmax(100px, auto)
-      "ft ft ft ft   ft   ft   ft   ft   ft" minmax(100px, auto)
-             / 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr ;
-}
-
- -

Первое значение - это значение нашей grid-template-areas, но мы также объявляем размер строки в конце каждой строки. Это то, что делает minmax (100px, auto).

- -

Затем после grid-template-areas у нас есть косая черта, после чего явный список треков столбцов.

- -

grid

- -

Сокращение {{cssxref ("grid")}} идет еще дальше, а также задает свойства, используемые неявной сеткой. Таким образом, вы будете устанавливать:

- -
    -
  • {{cssxref("grid-template-rows")}}
  • -
  • {{cssxref("grid-template-columns")}}
  • -
  • {{cssxref("grid-template-areas")}}
  • -
  • {{cssxref("grid-auto-rows")}}
  • -
  • {{cssxref("grid-auto-columns")}}
  • -
  • {{cssxref("grid-auto-flow")}}
  • -
- -

Свойство также сбрасывает {{cssxref ("grid-gap")}} свойство на 0, однако вы не можете указывать пробелы в этой сокращенности.

- -

Вы можете использовать этот синтаксис точно так же, как сокращение {{cssxref ("grid-template")}}, просто знайте, что при этом вы сбросите другие значения, установленные этим свойством.

- -
.wrapper {
-    display: grid;
-    grid: "hd hd hd hd   hd   hd   hd   hd   hd" minmax(100px, auto)
-    "sd sd sd main main main main main main" minmax(100px, auto)
-    "ft ft ft ft   ft   ft   ft   ft   ft" minmax(100px, auto)
-    / 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr ;
-}
-
- -

Мы снова рассмотрим другие функции, предлагаемые этом сокращением позже в этих руководствах, когда мы рассмотрим автоматическое размещение и свойство grid-auto-flow.

- -

Если вы проработали эти начальные руководства, теперь вы должны иметь возможность создавать сетки с использованием линейного размещения или названных областей. Потратьте некоторое время на создание некоторых общих шаблонов макетов с использованием сетки, в то время как есть много новых терминов для изучения, синтаксис относительно прост. По мере того, как вы разрабатываете примеры, вы, вероятно, придумаете некоторые вопросы и воспользуетесь случаями, которые мы еще не рассмотрели. В остальных этих руководствах мы рассмотрим некоторые детали, включенные в спецификацию, - чтобы вы могли начать создавать с ним расширенные макеты.

- - diff --git "a/files/ru/web/css/css_grid_layout/\321\200\320\260\321\201\320\277\320\276\320\273\320\276\320\266\320\265\320\275\320\270\320\265_\321\215\320\273\320\265\320\274\320\265\320\275\321\202\320\276\320\262_\320\277\320\276_\320\263\321\200\320\270\320\264-\320\273\320\270\320\275\320\270\321\217\320\274_\321\201_\320\277\320\276\320\274\320\276\321\211\321\214\321\216_css_grid/index.html" "b/files/ru/web/css/css_grid_layout/\321\200\320\260\321\201\320\277\320\276\320\273\320\276\320\266\320\265\320\275\320\270\320\265_\321\215\320\273\320\265\320\274\320\265\320\275\321\202\320\276\320\262_\320\277\320\276_\320\263\321\200\320\270\320\264-\320\273\320\270\320\275\320\270\321\217\320\274_\321\201_\320\277\320\276\320\274\320\276\321\211\321\214\321\216_css_grid/index.html" deleted file mode 100644 index e470a72ce7..0000000000 --- "a/files/ru/web/css/css_grid_layout/\321\200\320\260\321\201\320\277\320\276\320\273\320\276\320\266\320\265\320\275\320\270\320\265_\321\215\320\273\320\265\320\274\320\265\320\275\321\202\320\276\320\262_\320\277\320\276_\320\263\321\200\320\270\320\264-\320\273\320\270\320\275\320\270\321\217\320\274_\321\201_\320\277\320\276\320\274\320\276\321\211\321\214\321\216_css_grid/index.html" +++ /dev/null @@ -1,652 +0,0 @@ ---- -title: Расположение элементов по грид-линиям с помощью CSS Grid -slug: >- - Web/CSS/CSS_Grid_Layout/Расположение_элементов_по_грид-линиям_с_помощью_CSS_Grid -tags: - - CSS - - CSS Grid - - Грид - - Руководство - - Сетка -translation_of: Web/CSS/CSS_Grid_Layout/Line-based_Placement_with_CSS_Grid ---- -

В статье, касавшейся основных понятий позиционирования элементов с помощью гридов, мы кратенько рассмотрели, как располагать элементы в гриде, используя номера линий. Теперь давайте детально исследуем то, как работает эта фундаментальная часть спецификации.

- -

Собственно, начать квест по гридам со знакомства с пронумерованными линиями - логично, потому что в ситуации, когда Вы работаете с гридами, пронумерованные линии у Вас есть всегда. Линии нумеруются и для колонок, и для строк, отсчет начинается с 1. Нужно заметить, что грид индексируется в соответствии с режимом написания (writing mode) документа. В языках с написанием слева направо, таких как русский, например, линия 1 - самая левая линия грида. Если написание справа налево, то линия 1 будет, соответственно, самой правой линией в гриде. По ходу изучения недр мы детально узнаем, как гриды взаимодействуют с режимами написания, поэтому не исчезайте, впереди много интересного.

- -

Базовый пример

- -

В качестве крайне простого примера давайте возьмем грид с тремя треками-колонками и тремя треками-строками. Такой грид дает нам по 4 линии для каждого направления.

- -

Внутри нашего грид-контейнера у нас есть четыре дочерних элемента. Если мы не размещаем их явным образом, эти элементы будут расположены в гриде в соответствии с правилами авторазмещения, то есть, по одному элементу - в каждой из четырех первых ячеек. Если Вы воспользуетесь Firefox Grid Highlighter , то увидете, как грид инициирует колонки и строки.

- -

Our Grid highlighted in DevTools

- - - -
.wrapper {
-   display: grid;
-   grid-template-columns: repeat(3, 1fr);
-   grid-template-rows: repeat(3, 100px);
-}
-
- -
<div class="wrapper">
-   <div class="box1">One</div>
-   <div class="box2">Two</div>
-   <div class="box3">Three</div>
-   <div class="box4">Four</div>
-</div>
-
- -

{{ EmbedLiveSample('A_basic_example', '300', '330') }}

- -

Позиционирование элементов по номерам линий

- -

Мы можем воспользоваться размещением по линиям (line-based placement), чтобы расположить элементы на гриде. Например, нам нужно, чтобы первый элемент начинался от левого края и занимал один трек-колонку. Пусть он также начинается с первой строчной линии,  то есть, от верхнего края грида, и занимает пространство до четвертой строчной линии.

- -
-
.box1 {
-   grid-column-start: 1;
-   grid-column-end: 2;
-   grid-row-start: 1;
-   grid-row-end: 4;
-}
-
- -

Если Вы явно позиционируете одни элементы, другие элементы грида по-прежнему размещаются в соответствии с правилами авторазмещения. Дальше мы детально рассмотрим, как это происходит, а пока Вы и сами могли заметить, что по мере размещения одних элементов, оставшиеся элементы занимают пустые ячейки грида.

- -

Задавая адреса для каждого элемента по отдельности, мы можем разместить все наши четыре элемента по колонкам и строкам. Заметьте, что при желании можно оставить ячейки пустыми. Одна из самых приятных вещей при работе с Grid Layout - возможность создавать негативное пространство (пустые области в макете) без кувырков через голову и прочих хаков.

- - - -
<div class="wrapper">
-   <div class="box1">One</div>
-   <div class="box2">Two</div>
-   <div class="box3">Three</div>
-   <div class="box4">Four</div>
-</div>
-
- -
.box2 {
-   grid-column-start: 3;
-   grid-column-end: 4;
-   grid-row-start: 1;
-   grid-row-end: 3;
-}
-.box3 {
-   grid-column-start: 2;
-   grid-column-end: 3;
-   grid-row-start: 1;
-   grid-row-end: 2;
-}
-.box4 {
-   grid-column-start: 2;
-   grid-column-end: 4;
-   grid-row-start: 3;
-   grid-row-end: 4;
-}
-
- -

{{ EmbedLiveSample('Line_Number', '300', '330') }}

-
- -
-

Сокращения grid-column и grid-row

- -

Мы написали много кода, чтобы разместить каждый элемент. Неудивительно, что существует краткая форма записи свойств. {{cssxref("grid-column-start")}} и {{cssxref("grid-column-end")}} могут быть объединены в одном {{cssxref("grid-column")}}, а {{cssxref("grid-row-start")}} и {{cssxref("grid-row-end")}} - в {{cssxref("grid-row")}}.

- - - -
<div class="wrapper">
-   <div class="box1">One</div>
-   <div class="box2">Two</div>
-   <div class="box3">Three</div>
-   <div class="box4">Four</div>
-</div>
-
- -
.box1 {
-   grid-column: 1 / 2;
-   grid-row: 1 / 4;
-}
-.box2 {
-   grid-column: 3 / 4;
-   grid-row: 1 / 3;
-}
-.box3 {
-   grid-column: 2 / 3;
-   grid-row: 1 /  2;
-}
-.box4 {
-   grid-column: 2 / 4;
-   grid-row: 3 / 4;
-}
-
- -

{{ EmbedLiveSample('Grid_Shorthands', '300', '330') }}

-
- -

Расположение элемента по умолчанию

- -

В примерах выше мы задавали конечную линию для строки и колонки, чтобы продемонстрировать работу свойств, однако, если элемент занимает только один трек, Вы можете опустить значение grid-column-end или grid-row-end. Грид по умолчанию размещает элемент таким образом, чтобы он занимал всего один трек. Это значит, что длинная запись свойств в нашем первоначальном примере может выглядеть вот так:

- -
- - -
<div class="wrapper">
-   <div class="box1">One</div>
-   <div class="box2">Two</div>
-   <div class="box3">Three</div>
-   <div class="box4">Four</div>
-</div>
-
- -
.box1 {
-   grid-column-start: 1;
-   grid-row-start: 1;
-   grid-row-end: 4;
-}
-.box2 {
-   grid-column-start: 3;
-   grid-row-start: 1;
-   grid-row-end: 3;
-}
-.box3 {
-   grid-column-start: 2;
-   grid-row-start: 1;
-}
-.box4 {
-   grid-column-start: 2;
-   grid-column-end: 4;
-   grid-row-start: 3;
-}
-
- -

{{ EmbedLiveSample('End_Lines', '300', '330') }}

-
- -

Поэтому, если мы хотим, чтобы элементы занимали только один трек, наша сокращенная запись будет выглядеть вот так, без слэша и без второго значения:

- -
- - -
<div class="wrapper">
-   <div class="box1">One</div>
-   <div class="box2">Two</div>
-   <div class="box3">Three</div>
-   <div class="box4">Four</div>
-</div>
-
- -
.box1 {
-   grid-column: 1 ;
-   grid-row: 1 / 4;
-}
-.box2 {
-   grid-column: 3 ;
-   grid-row: 1 / 3;
-}
-.box3 {
-   grid-column: 2 ;
-   grid-row: 1 ;
-}
-.box4 {
-   grid-column: 2 / 4;
-   grid-row: 3 ;
-}
-
- -

{{ EmbedLiveSample('New_Shorthand', '300', '330') }}

-
- -

Свойство grid-area

- -

Мы можем пойти еще дальше и определить целую область с помощью одного единственного свойства – {{cssxref("grid-area")}}. Порядок свойств для грид-области следующий:

- -
    -
  • grid-row-start
  • -
  • grid-column-start
  • -
  • grid-row-end
  • -
  • grid-column-end
  • -
- - - -
<div class="wrapper">
-   <div class="box1">One</div>
-   <div class="box2">Two</div>
-   <div class="box3">Three</div>
-   <div class="box4">Four</div>
-</div>
-
- -
.box1 {
-   grid-area: 1 / 1 / 4 / 2;
-}
-.box2 {
-   grid-area: 1 / 3 / 3 / 4;
-}
-.box3 {
-   grid-area: 1 / 2 / 2 / 3;
-}
-.box4 {
-   grid-area: 3 / 2 / 4 / 4;
-}
-
- -

{{ EmbedLiveSample('The_grid-area_property', '300', '330') }}

- -

Порядок значений для grid-area может показаться немного странным, он противоположен тому порядку, в котором мы, например, записываем значения для сокращенных свойств margin и padding. Но сделано это потому, что грид работает с направлениями относительно потока, определенными в спецификации CSS Writing Modes. В дальнейшем мы рассмотрим, как гриды взаимодействуют с режимами написания (writing modes), но пока давайте примем за данность, что мы имеем дело с концепцией четырех направлений относительно потока:

- -
    -
  • block-start (начало блока)
  • -
  • block-end (конец блока)
  • -
  • inline-start (начало строки)
  • -
  • inline-end (конец строки)
  • -
- -

Мы работаем с русским, языком с написанием слева направо. Начало нашего блока (block-start) - верхняя строчная линия грид-контейнера, конец блока (block-end) - последняя строчная линия контейнера. Начало строки (inline-start) - самая левая колоночная линия, поскольку начало строки - это всегда точка, с которой начинается написание текста в заданном режиме написания. Конец строки (inline-end) - последняя колоночная линия грида.

- -

Когда мы задаем нашу грид-область с помощью свойства grid-area , мы сначала определяем обе начальные линии block-start и inline-start, а затем обе конечные линии  block-end и inline-end. Поскольку мы давно работаем с физическими свойствами top, right, bottom и left, поначалу это кажется непривычным, но вполне осмысленно, если осознать, что относительно режима написания вебсайты - многонаправленные структуры.

- -

Считая с конца

- -

Мы также можем отсчитывать грид-линии с конца, то есть с последней (для русского языка - самой правой) колоночной и последней (самой нижней) строчной линий. Индекс этих линий будет -1, а линий непосредственно перед ними -2, и так далее. Нужно помнить, что под последней линией понимается последняя линия явного грида (explicit grid), то есть грида, определенного с помощью grid-template-columns иgrid-template-rows. Любые линии строк и колонок, добавленные неявным гридом (implicit grid) не считаются.

- -

В примере ниже мы "перевернули" определение нашего грида, при размещении элементов задавая линии с конца, то есть, от правого и нижнего краев.

- - - -
<div class="wrapper">
-   <div class="box1">One</div>
-   <div class="box2">Two</div>
-   <div class="box3">Three</div>
-   <div class="box4">Four</div>
-</div>
-
- -
.box1 {
-   grid-column-start: -1;
-   grid-column-end: -2;
-   grid-row-start: -1;
-   grid-row-end: -4;
-}
-.box2 {
-   grid-column-start: -3;
-   grid-column-end: -4;
-   grid-row-start: -1;
-   grid-row-end: -3;
-}
-.box3 {
-   grid-column-start: -2;
-   grid-column-end: -3;
-   grid-row-start: -1;
-   grid-row-end: -2;
-}
-.box4 {
-   grid-column-start: -2;
-   grid-column-end: -4;
-   grid-row-start: -3;
-   grid-row-end: -4;
-}
-
- -

{{ EmbedLiveSample('Counting_backwards', '300', '330') }}

- -

Как растянуть элемент на длину всего грида?

- -

Возможность адресовать и первую, и последнюю линии грида становится крайне полезной, если нам нужно растянуть элемент на всю длину грида. Сделать это можно вот так:

- -
.item {
-  grid-column: 1 / -1;
-}
-
- -

Зазоры (Gutters) или аллеи (Alleys)

- -

Спецификация CSS Grid включает возможность добавлять промежутки (зазоры) между треками-колонками и треками-строками с помощью свойств {{cssxref("grid-column-gap")}} и {{cssxref("grid-row-gap")}}. Эти свойства задают промежутки, которые во многом действуют точно так же, как свойство {{cssxref("column-gap")}} в многоколоночных макетах.

- -

Зазоры появляются только между треками и не добавляют пространство сверху, снизу, справа или слева грид-контейнеру. Мы можем добавить зазоры в предыдущий пример, дописав эти свойства грид-контейнеру.

- - - -
<div class="wrapper">
-   <div class="box1">One</div>
-   <div class="box2">Two</div>
-   <div class="box3">Three</div>
-   <div class="box4">Four</div>
-</div>
-
- -
.box1 {
-   grid-column: 1 ;
-   grid-row: 1 / 4;
-}
-.box2 {
-   grid-column: 3 ;
-   grid-row: 1 / 3;
-}
-.box3 {
-   grid-column: 2 ;
-   grid-row: 1 ;
-}
-.box4 {
-   grid-column: 2 / 4;
-   grid-row: 3 ;
-}
-.wrapper {
-     display: grid;
-     grid-template-columns: repeat(3, 1fr);
-     grid-template-rows: repeat(3, 100px);
-     grid-column-gap: 20px;
-     grid-row-gap: 1em;
-}
-
- -

{{ EmbedLiveSample('Gutters_or_Alleys', '300', '350') }}

- -

Сокращенная запись для грид-зазоров

- -

Оба свойства также можно записать с помощью свойства-сокращения {{cssxref("grid-gap")}}. Если задать только одно значение, то оно определит размер зазоров и между колонками, и между строками. Если мы задаем два значения, то первое используется для grid-row-gap , а второе - для grid-column-gap.

- -
.wrapper {
-     display: grid;
-     grid-template-columns: repeat(3, 1fr);
-     grid-template-rows: repeat(3, 100px);
-     grid-gap: 1em 20px;
-}
-
- -

В терминах расположения элементов по грид-линиям (line-based positioning) зазоры ведут себя так, как если бы самой линии была добавлена толщина. Все, что должно было начинаться от линии, начинается от нее на расстоянии зазора, и Вы не можете адресовать зазор напрямую или поместить в него что-нибудь. Если Вам нужны зазоры, которые ведут себя, как обыкновенные треки, что же - определите трек, а не зазор.

- -

Использование ключевого слова span 

- -

В дополнение к возможности обращаться к начальной и конечной линии по их номерам Вы можете задать номер начальной линии, а после - количество треков, которые должен занять элемент.

- - - -
<div class="wrapper">
-   <div class="box1">One</div>
-   <div class="box2">Two</div>
-   <div class="box3">Three</div>
-   <div class="box4">Four</div>
-</div>
-
- -
.box1 {
-  grid-column: 1;
-  grid-row: 1 / span 3;
-}
-.box2 {
-   grid-column: 3;
-   grid-row: 1 / span 2;
-}
-.box3 {
-   grid-column: 2;
-   grid-row: 1;
-}
-.box4 {
-   grid-column: 2 / span 2;
-   grid-row: 3;
-}
-
- -

{{ EmbedLiveSample('Using_the_span_keyword', '300', '330') }}

- -

Ключево слово  span также можно использовать в качестве значения grid-row-start/grid-row-end иgrid-column-start/grid-column-end. Два примера ниже создают одну и ту же грид-область. В первом примере мы задаем начальную строчную линию, а после говорим свойству, отвечающему за конечную линию: эй, мы хотим занять под этот элемент три линии. В итоге, грид-область начинается с первой линии и занимает пространство до 4-ой.

- -
.box1 {
-    grid-column-start: 1;
-    grid-row-start: 1;
-    grid-row-end: span 3;
-}
-
- -

Во втором примере поступим наоборот: зададим конечную строчную линию, а в значении свойства, отвечающего за начальную линию, напишем span 3. Это значит, что элемент должен занять три трека до заданной конечной линии. Грид-область начинается с линии 4 и занимает три трека до линии 1.

- -
.box1 {
-    grid-column-start: 1;
-    grid-row-start: span 3;
-    grid-row-end: 4;
-}
-
- -

Чтобы лучше освоиться с размещением элементов по грид-линиям, попробуйте собрать несколько распространенных макетов, располагая элементы на гридах с различным количеством колонок. Помните, что если вы не размещаете все Ваши элементы, оставшиеся располагаются в соответствии с правилами авторазмещения. В результате может получиться как раз тот макет, который Вам нужен, но не факт, и если что-то пошло не так, проверьте, определили ли Вы позицию для проблемного элемента.

- -

Также помните, что элементы на гриде могут перекрывать друг друга, если Вы намеренно разместили их так, чтобы они друг друга перекрывали. Подобное поведение позволяет получить интересные эффекты, но, если Вы некорректно задали начальные и конечные линии, результат может неприятно Вас удивить. Firefox Grid Highlighter будет крайне полезен в процессе обучения, особенно, когда Вы строите сложные гриды.

- - diff --git a/files/ru/web/css/css_positioning/understanding_z_index/adding_z-index/index.html b/files/ru/web/css/css_positioning/understanding_z_index/adding_z-index/index.html new file mode 100644 index 0000000000..2fff1726d3 --- /dev/null +++ b/files/ru/web/css/css_positioning/understanding_z_index/adding_z-index/index.html @@ -0,0 +1,157 @@ +--- +title: Using z-index +slug: Web/Guide/CSS/Understanding_z_index/Adding_z-index +translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/Adding_z-index +--- +
{{cssref}}
+ +

The first part of this article, Stacking without the z-index property, explains how stacking is arranged by default. If you want to create a custom stacking order, you can use the {{cssxref("z-index")}} property on a positioned element.

+ +

Свойство z-index может иметь значение в целых числах (положительные, ноль, или отрицательные), что представляет собой позицию єлемента вдоль оси z. Если вы не знакомы с осью z, представьте себе страницу как стопку слоев, имеющих собственое порядковое число. Слои представлены в числовом порядке, with larger numbers above smaller numbers.

+ +
    +
  • bottom layer (farthest from the observer)
  • +
  • ...
  • +
  • Layer -3
  • +
  • Layer -2
  • +
  • Layer -1
  • +
  • Layer 0 (default rendering layer)
  • +
  • Layer 1
  • +
  • Layer 2
  • +
  • Layer 3
  • +
  • ...
  • +
  • top layer (closest to the observer)
  • +
+ +
+

Notes:

+ +
    +
  • When no z-index property is specified, elements are rendered on the default rendering layer 0 (zero).
  • +
  • If several elements share the same z-index value (i.e., they are placed on the same layer), stacking rules explained in the section Stacking without z-index apply.
  • +
+
+ +

In the following example, the layers' stacking order is rearranged using z-index. The z-index of element #5 has no effect since it is not a positioned element.

+ +

{{EmbedLiveSample("Source_code_for_the_example", 600, 400)}}

+ +

Source code for the example

+ +

HTML

+ +
<div id="abs1">
+  <b>DIV #1</b>
+  <br />position: absolute;
+  <br />z-index: 5;
+</div>
+
+<div id="rel1">
+  <b>DIV #2</b>
+  <br />position: relative;
+  <br />z-index: 3;
+</div>
+
+<div id="rel2">
+  <b>DIV #3</b>
+  <br />position: relative;
+  <br />z-index: 2;
+</div>
+
+<div id="abs2">
+  <b>DIV #4</b>
+  <br />position: absolute;
+  <br />z-index: 1;
+</div>
+
+<div id="sta1">
+  <b>DIV #5</b>
+  <br />no positioning
+  <br />z-index: 8;
+</div>
+
+ +

CSS

+ +
div {
+  padding: 10px;
+  opacity: 0.7;
+  text-align: center;
+}
+
+b {
+  font-family: sans-serif;
+}
+
+#abs1 {
+  z-index: 5;
+  position: absolute;
+  width: 150px;
+  height: 350px;
+  top: 10px;
+  left: 10px;
+  border: 1px dashed #900;
+  background-color: #fdd;
+}
+
+#rel1 {
+  z-index: 3;
+  height: 100px;
+  position: relative;
+  top: 30px;
+  border: 1px dashed #696;
+  background-color: #cfc;
+  margin: 0px 50px 0px 50px;
+}
+
+#rel2 {
+  z-index: 2;
+  height: 100px;
+  position: relative;
+  top: 15px;
+  left: 20px;
+  border: 1px dashed #696;
+  background-color: #cfc;
+  margin: 0px 50px 0px 50px;
+}
+
+#abs2 {
+  z-index: 1;
+  position: absolute;
+  width: 150px;
+  height: 350px;
+  top: 10px;
+  right: 10px;
+  border: 1px dashed #900;
+  background-color: #fdd;
+}
+
+#sta1 {
+  z-index: 8;
+  height: 70px;
+  border: 1px dashed #996;
+  background-color: #ffc;
+  margin: 0px 50px 0px 50px;
+}
+
+ +

See also

+ + + +
+

Original Document Information

+ + +
diff --git a/files/ru/web/css/css_positioning/understanding_z_index/index.html b/files/ru/web/css/css_positioning/understanding_z_index/index.html new file mode 100644 index 0000000000..0074ff2577 --- /dev/null +++ b/files/ru/web/css/css_positioning/understanding_z_index/index.html @@ -0,0 +1,51 @@ +--- +title: Понимание CSS z-index +slug: Web/Guide/CSS/Understanding_z_index +tags: + - Advanced + - CSS + - Guide + - NeedsTranslation + - TopicStub + - Understanding_CSS_z-index + - Web + - z-index +translation_of: Web/CSS/CSS_Positioning/Understanding_z_index +--- +

Обычно HTML страницы можно считать двухмерными, потому что текст, картинки и другие элементы расположены на странице без перекрытия. Существует единый нормальный поток отрисовки (rendering flow) и элементы избегают пространства, занятого другими.{{cssxref("z-index")}} атрибут позволяет регулировать порядок наложения объектов друг на друга в процессе отрисовки контента (rendering content).

+ +
+

В CSS 2.1, позиция каждого блока была в трех измерениях. В дополнении к их горизонтальной и вертикальной позиции блоки лежали вдоль оси "z" и распологались один поверх другого. Позиция относительно оси "z" особенно актуальна, когда блоки визуально накладываются друг на друга. 

+
+ +

(from CSS 2.1 Section 9.9.1 - Layered presentation)

+ +

Это означает, что правила стиля CSS позволяют вам позиционировать блоки на слоях в дополнение к обычному слою рендеринга (слой 0). Положение Z каждого слоя выражается как целое число, представляющее порядок наложения для рендеринга. Большие числа означают ближе к наблюдателю. Положение Z можно контролировать с помощью свойства CSS z-index.

+ +

Использование z-index кажется чрезвычайно простым: одно свойство, которому присваивается одно целое число, с простым для понимания поведением. Однако, когда z-index применяется к сложным иерархиям элементов HTML, его поведение может быть трудно понять или предсказать. Это обьясняется целым комплексом правил "укладки" элементов. Фактически в спецификации  CSS-2.1 Appendix E (CSS-2.1 Приложение Е) зарезервирован целый раздел, подробно обьясняющий эти правила.

+ +

Данная статья попытается объяснить эти правила, с некоторым упрощением и несколькими примерами.

+ +
    +
  1. Позиционирование без z-индекса : правила по умолчанию
  2. +
  3. Позиционирование и float : как себя поводят float элементы c позиционированием
  4. +
  5. Использование z-index : Using z-index to change default stacking
  6. +
  7. The stacking context : Notes on the stacking context
  8. +
  9. Stacking context example 1 : 2-level HTML hierarchy, z-index on the last level
  10. +
  11. Stacking context example 2 : 2-level HTML hierarchy, z-index on all levels
  12. +
  13. Stacking context example 3 : 3-level HTML hierarchy, z-index on the second level
  14. +
+ +
+

Информация о документе

+ +
    +
  • Автор: Paolo Lombardi
  • +
  • Эта статья - английский перевод статьи, которую я написал на итальянском для YappY. Я даю право делиться всем контентом: Creative Commons: Attribution-Sharealike license
  • +
  • Дата последнего обновления: 9 июля 2005 г.
  • +
+ +

Примечание автора: спасибо Владимиру Паланту и Роду Уайтли за обзор.

+ +
+
diff --git a/files/ru/web/css/css_positioning/understanding_z_index/stacking_without_z-index/index.html b/files/ru/web/css/css_positioning/understanding_z_index/stacking_without_z-index/index.html new file mode 100644 index 0000000000..7f4eb09133 --- /dev/null +++ b/files/ru/web/css/css_positioning/understanding_z_index/stacking_without_z-index/index.html @@ -0,0 +1,140 @@ +--- +title: Stacking without z-index +slug: Web/Guide/CSS/Understanding_z_index/Stacking_without_z-index +tags: + - CSS + - z-index +translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_without_z-index +--- +

« CSS « Понимание CSS z-index

+ +

Наложения без Z-индекса

+ +

Когда элементы не имеют z-индека, они накладываються в таком порядке(снизу вверх):

+ +

1. Фон и границы корневого элемента.

+ +

2. Дочерние блоки в нормальном потоке в порядке размещения(в HTML порядке).

+ +

3. Дочерние позиционированные элементы, в порядке размещения (в HTML порядке).

+ +

В следующем примере, абсолютно и относительно спозиционированным блокам определена величина  и позиция таким образом, чтобы продемонстировать правила наложения.

+ +
+

Заметки:

+ +
    +
  • Given a homogeneous group of elements without any z-index property, such as the positioned blocks (DIV #1 to #4) in the example, the element's stacking order is their order in the HTML hierarchy, regardless of their position.
  • +
  • +

    Standard blocks (DIV #5) in the normal flow, without any positioning property, are always rendered before positioned elements, and appear below them, even if they come later in the HTML hierarchy. 

    +
  • +
+
+ +

understanding_zindex_01.png

+ +

Пример

+ +

HTML

+ +
<div id="absdiv1">
+    <br /><span class="bold">DIV #1</span>
+    <br />position: absolute; </div>
+<div id="reldiv1">
+    <br /><span class="bold">DIV #2</span>
+    <br />position: relative; </div>
+<div id="reldiv2">
+    <br /><span class="bold">DIV #3</span>
+    <br />position: relative; </div>
+<div id="absdiv2">
+    <br /><span class="bold">DIV #4</span>
+    <br />position: absolute; </div>
+<div id="normdiv">
+    <br /><span class="bold">DIV #5</span>
+    <br />no positioning </div>
+
+ +

CSS

+ +
 .bold {
+     font-weight: bold;
+     font: 12px Arial;
+ }
+ #normdiv {
+     height: 70px;
+     border: 1px dashed #999966;
+     background-color: #ffffcc;
+     margin: 0px 50px 0px 50px;
+     text-align: center;
+ }
+ #reldiv1 {
+     opacity: 0.7;
+     height: 100px;
+     position: relative;
+     top: 30px;
+     border: 1px dashed #669966;
+     background-color: #ccffcc;
+     margin: 0px 50px 0px 50px;
+     text-align: center;
+ }
+ #reldiv2 {
+     opacity: 0.7;
+     height: 100px;
+     position: relative;
+     top: 15px;
+     left: 20px;
+     border: 1px dashed #669966;
+     background-color: #ccffcc;
+     margin: 0px 50px 0px 50px;
+     text-align: center;
+ }
+ #absdiv1 {
+     opacity: 0.7;
+     position: absolute;
+     width: 150px;
+     height: 350px;
+     top: 10px;
+     left: 10px;
+     border: 1px dashed #990000;
+     background-color: #ffdddd;
+     text-align: center;
+ }
+ #absdiv2 {
+     opacity: 0.7;
+     position: absolute;
+     width: 150px;
+     height: 350px;
+     top: 10px;
+     right: 10px;
+     border: 1px dashed #990000;
+     background-color: #ffdddd;
+     text-align: center;
+ }
+
+ +

Результат

+ +

(If the image does not display in CodePen, click the Tidy button in the CSS section)

+ +

{{ EmbedLiveSample('Example', '', '', '', 'Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_without_z-index') }}

+ +

Так же посмотрите

+ + + +
+

Original Document Information

+ + +
diff --git a/files/ru/web/css/css_selectors/index.html b/files/ru/web/css/css_selectors/index.html new file mode 100644 index 0000000000..8745681718 --- /dev/null +++ b/files/ru/web/css/css_selectors/index.html @@ -0,0 +1,122 @@ +--- +title: CSS-селекторы +slug: Web/CSS/CSS_Селекторы +tags: + - CSS + - Обзор + - Селекторы +translation_of: Web/CSS/CSS_Selectors +--- +
{{CSSRef}}
+ +

Селектор определяет, к какому элементу применять то или иное CSS-правило.

+ +

Обратите внимание - не существует селекторов, которые бы позволили выбрать родителя (содержащий контейнер) или соседа родителя или потомков соседа родителя.

+ +

Базовые селекторы

+ +
+
Универсальный селектор
+
Выбирает все элементы. По желанию, он может быть ограничен определенным пространством имен или относиться ко всему пространству имён.
+ Синтаксис: * ns|* *|*
+ Пример: * будет соответствовать всем элементам на странице.
+
+ +
+
Селекторы по типу элемента
+
Этот базовый селектор выбирает тип элементов, к которым будет применяться правило.
+ Синтаксис: элемент
+ Пример: селектор input выберет все элементы {{HTMLElement('input')}}.
+
Селекторы по классу
+
Этот базовый селектор выбирает элементы, основываясь на значении их атрибута class.
+ Синтаксис: .имяКласса
+ Пример: селектор .index выберет все элементы с соответствующим классом (который был определен в атрибуте class="index").
+
Селекторы по идентификатору
+
Этот базовый селектор выбирает элементы, основываясь на значении их id атрибута. Не забывайте, что идентификатор должен быть уникальным, т. е. использоваться только для одного элемента в HTML-документе. 
+ Синтаксис: #имяИдентификатора
+ Пример: селектор #toc выберет элемент с идентификатором toc (который был определен в атрибуте id="toc").
+
Селекторы по атрибуту
+
Этот селектор выбирает все элементы, имеющие данный атрибут или атрибут с определённым значением.
+ Синтаксис: [attr] [attr=value] [attr~=value] [attr|=value] [attr^=value] [attr$=value] [attr*=value]
+ Пример: селектор [autoplay] выберет все элементы, у которых есть  атрибут autoplay (независимо от его значения).
+ Ещё пример: a[href$=".jpg"] выберет все ссылки, у которых адрес заканчивается на ".jpg".
+ Ещё пример: a[href^="https"] выберет все ссылки, у которых адрес начинается на "https".
+
+ +

Комбинаторы

+ +
+
Комбинатор запятая
+
Комбинатор , это способ группировки, он выбирает все совпадающие узлы.
+ Синтаксис: A, B
+ Пример: div, span выберет оба элемента - и {{HTMLElement("div")}} и {{HTMLElement("span")}}.
+
Комбинатор потомков
+
Комбинатор ' ' (пробел) выбирает элементы, которые находятся внутри указанного элемента (вне зависимости от уровня вложенности).
+ Синтаксис: A B
+ Пример: селектор div span выберет все элементы {{HTMLElement('span')}}, которые находятся внутри элемента {{HTMLElement('div')}}.
+
Дочерние селекторы
+
Комбинатор '>' в отличие от пробела выбирает только те элементы, которые являются дочерними непосредственно по отношению к указанному элементу.
+ Синтаксис: A > B
+ Пример: селектор ul > li выберет только дочерние элементы {{HTMLElement('li')}}, которые находятся внутри, на первом уровне вложенности по отношению к элементу {{HTMLElement('ul')}}.
+
Комбинатор всех соседних элементов
+
Комбинатор '~' выбирает элементы, которые находятся на этом же уровне вложенности, после указанного элемента, с тем же родителем.
+ Синтаксис: A ~ B
+ Пример: p ~ span выберет все элементы {{HTMLElement('span')}}, которые находятся после элемента {{HTMLElement('p')}} внутри одного родителя.
+
Комбинатор следующего соседнего элемента
+
Комбинатор '+' выбирает элемент, который находится непосредственно после указанного элемента, если у них общий родитель.
+ Синтаксис: A + B
+ Пример: селектор ul + li выберет любой {{HTMLElement('li')}} элемент, который  находится непосредственно после элемента {{HTMLElement('ul')}}.
+
+ +

Псевдо

+ +
+
Псевдоклассы
+
Знак : позволяет выбрать элементы, основываясь на информации, которой нет в дереве элементов.
+ Пример: a:visited соответствует всем элементам {{HTMLElement("a")}} которые имеют статус "посещённые".
+ Ещё пример: div:hover соответствует элементу, над которым проходит указатель мыши.
+ Ещё пример: input:focus соответствует полю ввода, которое получило фокус.
+
Псевдоэлементы
+
Знак :: позволяет выбрать вещи, которых нет в HTML.
+ Пример: p::first-line соответствует первой линии абзаца {{HTMLElement("p")}}.
+
+ +

Версии CSS

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарии
{{SpecName('CSS4 Selectors')}}{{Spec2('CSS4 Selectors')}}Добавление комбинатора колонок || , селекторов структуры сеточной разметки (CSS grid selector), логических комбинаторов, местоположения, временных, состояния ресурсов, лингвистических и UI псевдоклассов, модификаторов для ASCII регистрозависимых и регистронезависимых атрибутов со значениями и без них.
{{SpecName('CSS3 Selectors')}}{{Spec2('CSS3 Selectors')}}Добавлен комбинатор ~ и древовидные структурные псевдоклассы.
+ Сделаны псевдоэлементы, использующие префик :: двойное двоеточие. Селекторы дополнительных атрибутов.
{{SpecName('CSS2.1', 'selector.html')}}{{Spec2('CSS2.1')}}Добавлен комбинатор потомков > и комбинатор следующего соседа + .
+ Добавлен универсальный (*)  комбинатор и селектор атрибутов.
{{SpecName('CSS1')}}{{Spec2('CSS1')}}Первоначальное определение.
+ +

См. также

+ +

CSS специфичность

diff --git a/files/ru/web/css/css_selectors/using_the__colon_target_pseudo-class_in_selectors/index.html b/files/ru/web/css/css_selectors/using_the__colon_target_pseudo-class_in_selectors/index.html new file mode 100644 index 0000000000..f737d2cb6d --- /dev/null +++ b/files/ru/web/css/css_selectors/using_the__colon_target_pseudo-class_in_selectors/index.html @@ -0,0 +1,62 @@ +--- +title: 'Использование псевдокласса :target в селекторах' +slug: 'Web/CSS/CSS_Селекторы/Using_the_:target_pseudo-class_in_selectors' +translation_of: 'Web/CSS/CSS_Selectors/Using_the_:target_pseudo-class_in_selectors' +--- +
{{CSSRef}}
+ +

Иногда пользователям трудно заметить, что URL указывает на определённую часть документа.  Узнайте, как можно использовать простое CSS правило, чтобы привлечь внимание пользователей к цели указания URL и улучшить их впечатления.

+ +

Выбор целевых элементов

+ +

Псевдокласс {{cssxref(":target")}} используется для стилизации целевого элемента URL, содержащего идентификатор фрагмента. Например, URL http://developer.mozilla.org/en/docs/Using_the_:target_selector#example содержит идентификатор фрагмента #example. В HTML, идентификаторы определяются значениями атрибутов  id или name, т.к. эти аттрибуты разделяют одно пространство имён. Таким образом,  в вышеприведённом примере URL указывает на первый элемент "example" в документе.

+ +

Пердположим, вы хотите стилизовать любой элемент h2, который является целью URL, но не хотите, чтобы другие элементы получили стиль цели. Сделать это довольно просто:

+ +
h2:target { font-weight: bold; }
+ +

Также возможно создать стили, специфичные для определённого фрагмента документа. Это достигается использованием такого же идентификационного значения, как в URI. Таким образом, чтобы добавить рамку к фрагменту #example , напишем:

+ +
#example:target { border: 1px solid black; }
+ +

Отметка всех элементов, как целевых

+ +

Если вы намерены создать общий стиль, который будет применяться ко всем целевым элементам, то вам пригодится следующий универсальный селектор:

+ +
:target { color: red; }
+
+ +

Пример

+ +

В данном примере имеются пять ссылок, которые ссылаются на элементы одного и того же документа. Выбор ссылки "First" , например, приведёт к тому, что  <h1 id="one"> станет целевым элементом.  Заметьте, что при прокутке документа целевые элементы располагаются вверху окна браузера, если это возможно.

+ +
+
<h4 id="one">...</h4> <p id="two">...</p>
+<div id="three">...</div> <a id="four">...</a> <em id="five">...</em>
+
+<a href="#one">First</a>
+<a href="#two">Second</a>
+<a href="#three">Third</a>
+<a href="#four">Fourth</a>
+<a href="#five">Fifth</a>
+
+ +

Вывод

+ +

В некоторых случаях, когда идентификатор фрагмента указывает на часть документа, читатели могут запутаться в том, какую именно часть документа они читают. Стилизуя целевой элемент URI, такую путаницу читателей можно уменьшить или убрать вообще.

+ + + +
    +
  • {{cssxref(":target")}}
  • +
+ +
+

Original Document Information

+ +
    +
  • Author(s): Eric Meyer, Standards Evangelist, Netscape Communications
  • +
  • Original Copyright Information: Copyright © 2001-2003 Netscape. All rights reserved.
  • +
  • Note: This reprinted article was originally part of the DevEdge site.
  • +
+
diff --git a/files/ru/web/css/css_user_interface/index.html b/files/ru/web/css/css_user_interface/index.html deleted file mode 100644 index 2a4028644d..0000000000 --- a/files/ru/web/css/css_user_interface/index.html +++ /dev/null @@ -1,119 +0,0 @@ ---- -title: CSS Basic User Interface -slug: Web/CSS/CSS_User_Interface -tags: - - CSS - - CSS Basic User Interface - - NeedsTranslation - - Overview - - Reference - - TopicStub -translation_of: Web/CSS/CSS_Basic_User_Interface -translation_of_original: Web/CSS/CSS_User_Interface ---- -
{{CSSRef}}
- -

CSS User Interface is a CSS module that lets you define the rendering and functionality of features related to the user interface.

- -

Reference

- -

Preferences

- -
-
    -
  • {{cssxref("box-sizing")}}
  • -
  • {{cssxref("cursor")}}
  • -
  • {{cssxref("outline")}}
  • -
  • {{cssxref("outline-width")}}
  • -
  • {{cssxref("outline-style")}}
  • -
  • {{cssxref("outline-color")}}
  • -
  • {{cssxref("outline-offset")}}
  • -
  • {{cssxref("resize")}}
  • -
  • {{cssxref("text-overflow")}}
  • -
  • {{cssxref("nav-down")}}
  • -
  • {{cssxref("nav-left")}}
  • -
  • {{cssxref("nav-right")}}
  • -
  • {{cssxref("nav-up")}}
  • -
-
- -

Guides

- -
-
Using URL values for the cursor property
-
Explains how a URL can be used with the {{cssxref("cursor")}} property to produce custom cursors.
-
- -

Specifications

- - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('CSS3 Basic UI')}}{{Spec2('CSS3 Basic UI')}} 
{{SpecName('CSS2.1', 'ui.html')}}{{Spec2('CSS2.1')}}Initial definition
- -

Browser compatibility

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support1.01.5 (1.8)8.07.01.2 (125)
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support1.0{{CompatGeckoMobile(1.8)}}8.06.03.1
-
diff --git "a/files/ru/web/css/css_\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/index.html" "b/files/ru/web/css/css_\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/index.html" deleted file mode 100644 index 8745681718..0000000000 --- "a/files/ru/web/css/css_\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/index.html" +++ /dev/null @@ -1,122 +0,0 @@ ---- -title: CSS-селекторы -slug: Web/CSS/CSS_Селекторы -tags: - - CSS - - Обзор - - Селекторы -translation_of: Web/CSS/CSS_Selectors ---- -
{{CSSRef}}
- -

Селектор определяет, к какому элементу применять то или иное CSS-правило.

- -

Обратите внимание - не существует селекторов, которые бы позволили выбрать родителя (содержащий контейнер) или соседа родителя или потомков соседа родителя.

- -

Базовые селекторы

- -
-
Универсальный селектор
-
Выбирает все элементы. По желанию, он может быть ограничен определенным пространством имен или относиться ко всему пространству имён.
- Синтаксис: * ns|* *|*
- Пример: * будет соответствовать всем элементам на странице.
-
- -
-
Селекторы по типу элемента
-
Этот базовый селектор выбирает тип элементов, к которым будет применяться правило.
- Синтаксис: элемент
- Пример: селектор input выберет все элементы {{HTMLElement('input')}}.
-
Селекторы по классу
-
Этот базовый селектор выбирает элементы, основываясь на значении их атрибута class.
- Синтаксис: .имяКласса
- Пример: селектор .index выберет все элементы с соответствующим классом (который был определен в атрибуте class="index").
-
Селекторы по идентификатору
-
Этот базовый селектор выбирает элементы, основываясь на значении их id атрибута. Не забывайте, что идентификатор должен быть уникальным, т. е. использоваться только для одного элемента в HTML-документе. 
- Синтаксис: #имяИдентификатора
- Пример: селектор #toc выберет элемент с идентификатором toc (который был определен в атрибуте id="toc").
-
Селекторы по атрибуту
-
Этот селектор выбирает все элементы, имеющие данный атрибут или атрибут с определённым значением.
- Синтаксис: [attr] [attr=value] [attr~=value] [attr|=value] [attr^=value] [attr$=value] [attr*=value]
- Пример: селектор [autoplay] выберет все элементы, у которых есть  атрибут autoplay (независимо от его значения).
- Ещё пример: a[href$=".jpg"] выберет все ссылки, у которых адрес заканчивается на ".jpg".
- Ещё пример: a[href^="https"] выберет все ссылки, у которых адрес начинается на "https".
-
- -

Комбинаторы

- -
-
Комбинатор запятая
-
Комбинатор , это способ группировки, он выбирает все совпадающие узлы.
- Синтаксис: A, B
- Пример: div, span выберет оба элемента - и {{HTMLElement("div")}} и {{HTMLElement("span")}}.
-
Комбинатор потомков
-
Комбинатор ' ' (пробел) выбирает элементы, которые находятся внутри указанного элемента (вне зависимости от уровня вложенности).
- Синтаксис: A B
- Пример: селектор div span выберет все элементы {{HTMLElement('span')}}, которые находятся внутри элемента {{HTMLElement('div')}}.
-
Дочерние селекторы
-
Комбинатор '>' в отличие от пробела выбирает только те элементы, которые являются дочерними непосредственно по отношению к указанному элементу.
- Синтаксис: A > B
- Пример: селектор ul > li выберет только дочерние элементы {{HTMLElement('li')}}, которые находятся внутри, на первом уровне вложенности по отношению к элементу {{HTMLElement('ul')}}.
-
Комбинатор всех соседних элементов
-
Комбинатор '~' выбирает элементы, которые находятся на этом же уровне вложенности, после указанного элемента, с тем же родителем.
- Синтаксис: A ~ B
- Пример: p ~ span выберет все элементы {{HTMLElement('span')}}, которые находятся после элемента {{HTMLElement('p')}} внутри одного родителя.
-
Комбинатор следующего соседнего элемента
-
Комбинатор '+' выбирает элемент, который находится непосредственно после указанного элемента, если у них общий родитель.
- Синтаксис: A + B
- Пример: селектор ul + li выберет любой {{HTMLElement('li')}} элемент, который  находится непосредственно после элемента {{HTMLElement('ul')}}.
-
- -

Псевдо

- -
-
Псевдоклассы
-
Знак : позволяет выбрать элементы, основываясь на информации, которой нет в дереве элементов.
- Пример: a:visited соответствует всем элементам {{HTMLElement("a")}} которые имеют статус "посещённые".
- Ещё пример: div:hover соответствует элементу, над которым проходит указатель мыши.
- Ещё пример: input:focus соответствует полю ввода, которое получило фокус.
-
Псевдоэлементы
-
Знак :: позволяет выбрать вещи, которых нет в HTML.
- Пример: p::first-line соответствует первой линии абзаца {{HTMLElement("p")}}.
-
- -

Версии CSS

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
СпецификацияСтатусКомментарии
{{SpecName('CSS4 Selectors')}}{{Spec2('CSS4 Selectors')}}Добавление комбинатора колонок || , селекторов структуры сеточной разметки (CSS grid selector), логических комбинаторов, местоположения, временных, состояния ресурсов, лингвистических и UI псевдоклассов, модификаторов для ASCII регистрозависимых и регистронезависимых атрибутов со значениями и без них.
{{SpecName('CSS3 Selectors')}}{{Spec2('CSS3 Selectors')}}Добавлен комбинатор ~ и древовидные структурные псевдоклассы.
- Сделаны псевдоэлементы, использующие префик :: двойное двоеточие. Селекторы дополнительных атрибутов.
{{SpecName('CSS2.1', 'selector.html')}}{{Spec2('CSS2.1')}}Добавлен комбинатор потомков > и комбинатор следующего соседа + .
- Добавлен универсальный (*)  комбинатор и селектор атрибутов.
{{SpecName('CSS1')}}{{Spec2('CSS1')}}Первоначальное определение.
- -

См. также

- -

CSS специфичность

diff --git "a/files/ru/web/css/css_\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/using_the__colon_target_pseudo-class_in_selectors/index.html" "b/files/ru/web/css/css_\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/using_the__colon_target_pseudo-class_in_selectors/index.html" deleted file mode 100644 index f737d2cb6d..0000000000 --- "a/files/ru/web/css/css_\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/using_the__colon_target_pseudo-class_in_selectors/index.html" +++ /dev/null @@ -1,62 +0,0 @@ ---- -title: 'Использование псевдокласса :target в селекторах' -slug: 'Web/CSS/CSS_Селекторы/Using_the_:target_pseudo-class_in_selectors' -translation_of: 'Web/CSS/CSS_Selectors/Using_the_:target_pseudo-class_in_selectors' ---- -
{{CSSRef}}
- -

Иногда пользователям трудно заметить, что URL указывает на определённую часть документа.  Узнайте, как можно использовать простое CSS правило, чтобы привлечь внимание пользователей к цели указания URL и улучшить их впечатления.

- -

Выбор целевых элементов

- -

Псевдокласс {{cssxref(":target")}} используется для стилизации целевого элемента URL, содержащего идентификатор фрагмента. Например, URL http://developer.mozilla.org/en/docs/Using_the_:target_selector#example содержит идентификатор фрагмента #example. В HTML, идентификаторы определяются значениями атрибутов  id или name, т.к. эти аттрибуты разделяют одно пространство имён. Таким образом,  в вышеприведённом примере URL указывает на первый элемент "example" в документе.

- -

Пердположим, вы хотите стилизовать любой элемент h2, который является целью URL, но не хотите, чтобы другие элементы получили стиль цели. Сделать это довольно просто:

- -
h2:target { font-weight: bold; }
- -

Также возможно создать стили, специфичные для определённого фрагмента документа. Это достигается использованием такого же идентификационного значения, как в URI. Таким образом, чтобы добавить рамку к фрагменту #example , напишем:

- -
#example:target { border: 1px solid black; }
- -

Отметка всех элементов, как целевых

- -

Если вы намерены создать общий стиль, который будет применяться ко всем целевым элементам, то вам пригодится следующий универсальный селектор:

- -
:target { color: red; }
-
- -

Пример

- -

В данном примере имеются пять ссылок, которые ссылаются на элементы одного и того же документа. Выбор ссылки "First" , например, приведёт к тому, что  <h1 id="one"> станет целевым элементом.  Заметьте, что при прокутке документа целевые элементы располагаются вверху окна браузера, если это возможно.

- -
-
<h4 id="one">...</h4> <p id="two">...</p>
-<div id="three">...</div> <a id="four">...</a> <em id="five">...</em>
-
-<a href="#one">First</a>
-<a href="#two">Second</a>
-<a href="#three">Third</a>
-<a href="#four">Fourth</a>
-<a href="#five">Fifth</a>
-
- -

Вывод

- -

В некоторых случаях, когда идентификатор фрагмента указывает на часть документа, читатели могут запутаться в том, какую именно часть документа они читают. Стилизуя целевой элемент URI, такую путаницу читателей можно уменьшить или убрать вообще.

- - - -
    -
  • {{cssxref(":target")}}
  • -
- -
-

Original Document Information

- -
    -
  • Author(s): Eric Meyer, Standards Evangelist, Netscape Communications
  • -
  • Original Copyright Information: Copyright © 2001-2003 Netscape. All rights reserved.
  • -
  • Note: This reprinted article was originally part of the DevEdge site.
  • -
-
diff --git a/files/ru/web/css/filter-function/url/index.html b/files/ru/web/css/filter-function/url/index.html deleted file mode 100644 index 755d1adfe4..0000000000 --- a/files/ru/web/css/filter-function/url/index.html +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: url() -slug: Web/CSS/filter-function/url -tags: - - CSS - - Начинающий - - Ссылка - - Функция -translation_of: Web/CSS/url() -translation_of_original: Web/CSS/filter-function/url ---- -
{{cssref}}
- -

url() - это CSS функция, использующая SVG filter для измения внешнего вида у выводимого изображения.

- -

Синтаксис

- -
url(расположение)
- -

Параметры

- -
-
расположение
-
В {{cssxref("<URL-адрес>")}} из {{glossary("XML")}} указывается файл, который задает фильтр SVG, а также может включать в себя привязки к конкретному фильтрующему элементу.
-
- -

Пример

- -
url(resources.svg#c1)
- -

Изучите также

- - diff --git a/files/ru/web/css/grid-gap/index.html b/files/ru/web/css/grid-gap/index.html deleted file mode 100644 index 90daa7c0ea..0000000000 --- a/files/ru/web/css/grid-gap/index.html +++ /dev/null @@ -1,194 +0,0 @@ ---- -title: grid-gap -slug: Web/CSS/grid-gap -translation_of: Web/CSS/gap -translation_of_original: Web/CSS/grid-gap ---- -

{{Deprecated_Header}}

- -
-

Примечание. Свойство CSS с разделительной сеткой было переименовано в свойство prefix-less {{cssxref('gap')}}.

-
- -

Свойство CSS grid-gap является сокращенным свойством для {{cssxref("grid-row-gap")}} и {{cssxref("grid-column-gap")}}, определяющего желоба между строками и столбцами сетки.

- -
{{EmbedInteractiveExample("pages/css/grid-gap.html")}}
- - - -

Syntax

- -
/* Одно <length> значение */
-grid-gap: 20px;
-grid-gap: 1em;
-grid-gap: 3vmin;
-grid-gap: 0.5cm;
-
-/* Одно <percentage> значение */
-grid-gap: 16%;
-grid-gap: 100%;
-
-/* Два <length> значения */
-grid-gap: 20px 10px;
-grid-gap: 1em 0.5em;
-grid-gap: 3vmin 2vmax;
-grid-gap: 0.5cm 2mm;
-
-/* Один или два <percentage> значения */
-grid-gap: 16% 100%;
-grid-gap: 21px 82%;
-
-/* calc() значения */
-grid-gap: calc(10% + 20px);
-grid-gap: calc(20px + 10%) calc(10% - 5px);
-
-/* Глобальные значения */
-grid-gap: inherit;
-grid-gap: initial;
-grid-gap: unset;
-
- -

Это свойство указывается как значение для <'grid-row-gap'> , за которым необязательно следует значение для <'grid-column-gap'>. Если <'grid-column-gap'> опущено, для него устанавливается то же значение, что и <'grid-row-gap'>.

- -

Каждое из свойств <'grid-row-gap'> и <'grid-column-gap'> указываются как <length> или <percentage>.

- -

Значения

- -
-
<length>
-
Ширина отступа, разделяющего линии сетки.
-
<percentage>
-
Ширина отступа, разделяющего линии сетки относительно размеров элемента.
-
- -

Формальный синтаксис

- -
{{csssyntax}}
- -

Примеры

- -

HTML Контент

- -
<div id="grid">
-  <div></div>
-  <div></div>
-  <div></div>
-  <div></div>
-  <div></div>
-  <div></div>
-  <div></div>
-  <div></div>
-  <div></div>
-</div>
- -

CSS Контент

- -
#grid {
-  display: grid;
-  height: 200px;
-  grid-template: repeat(3, 1fr) / repeat(3, 1fr);
-  grid-gap: 20px 5px;
-}
-
-#grid > div {
-  background-color: lime;
-}
-
- -

{{EmbedLiveSample("Example", "100%", "200px")}}

- -

Спецификации

- - - - - - - - - - - - - - - - - - - - - -
СпецификацияСтатусКомментарий
{{SpecName("CSS3 Box Alignment", "#propdef-grid-gap", "grid-gap")}}{{Spec2("CSS3 Box Alignment")}}Устарело в пользу gap
{{SpecName("CSS3 Grid", "#gutters", "grid-gap")}}{{Spec2("CSS3 Grid")}}Начальное определение
- -

{{cssinfo}}

- -

Совместимость с браузерами

- - - -

{{Compat("css.properties.grid-gap")}}

- -

Смотрите также

- -
    -
  • Prefixless CSS equivalents: {{cssxref("row-gap")}}, {{cssxref("column-gap")}}, {{cssxref("gap")}}
  • -
  • Related CSS properties: {{cssxref("grid-row-gap")}}, {{cssxref("grid-column-gap")}}
  • -
  • Grid Layout Guide: Basic concepts of grid layout - Gutters
  • -
- - diff --git a/files/ru/web/css/layout_mode/index.html b/files/ru/web/css/layout_mode/index.html new file mode 100644 index 0000000000..dcf1440cb5 --- /dev/null +++ b/files/ru/web/css/layout_mode/index.html @@ -0,0 +1,28 @@ +--- +title: Способ разметки +slug: Web/CSS/Способ_расположения +tags: + - CSS +translation_of: Web/CSS/Layout_mode +--- +

CSS способ разметки (или раскладки, или англ. layout) — это алгоритм определения позиции и размеров блоков, основанный на способе, которым они взаимодействуют с родственными блоками. Существует несколько типов разметки:

+ +
    +
  • Обычная (Normal Flow) — все элементы являются частью обычного потока до тех пор, пока вы не переопределите это каким-либо образом. Обычный layout включает в себя блочную раскладку, созданную для расположения отдельных блоков, таких как параграфы, и линейную, для строчных элементов;
  • +
  • Табличная, спроектированная для расположения таблиц;
  • +
  • Float layout — для возможности обозначить элементы плавающими. Такой элемент начинает позиционироваться слева или справа отностительно содержимого обычного потока, элементы которого начинают обтекать него;
  • +
  • Позиционированная — для позиционирования элементов без особого взаимодействия с другими элементами;
  • +
  • Множественные столбцы — для расположения контента колонками, как в газетах;
  • +
  • Флексбокс (CSS Flexible Box Layout) — для расположения сложных страниц, которые плавно могут изменять свой размер; {{ experimental_inline() }}
  • +
  • Сеточная — для расположения элементов относительно фиксированной сетки. {{ experimental_inline() }}
  • +
+ +
+

Примечание: не все CSS свойства применимы ко всем способам разметки. Большинство из них применяются к одному или двум из них и не действуют, если применяются на элементе, участвующем в другом режиме разметки.

+
+ +

Смотрите также

+ +
    +
  • {{ CSS_key_concepts() }}
  • +
diff --git a/files/ru/web/css/length/index.html b/files/ru/web/css/length/index.html new file mode 100644 index 0000000000..4fd88f8cc2 --- /dev/null +++ b/files/ru/web/css/length/index.html @@ -0,0 +1,153 @@ +--- +title: +slug: Web/CSS/размер +tags: + - CSS + - CSS Тип Данных + - Величина + - Разметка + - длина +translation_of: Web/CSS/length +--- +
{{CSSRef}}
+ +

CSS тип данных <length> представляет единицу длины. Длина может быть использована в таких свойствах CSS как {{Cssxref("width")}}, {{Cssxref("height")}}, {{Cssxref("margin")}}, {{Cssxref("padding")}}, {{Cssxref("border-width")}}, {{Cssxref("font-size")}}, и {{Cssxref("text-shadow")}}.

+ +
+

Обратите внимание: Хоть значения {{cssxref("<percentage>")}} также определяют размеры и могут использоваться в некоторых свойствах, принимающих значения типа <length>, они не являются <length> значениями.

+
+ +

Синтаксис

+ +

Тип данных <length> состоит из {{cssxref("<number>")}}, за которым следует одна из единиц измерения, перечисленных ниже. Как и у любых единиц измерения CSS между числом и единицей нет знака пробела. После числа 0 единица измерения необязательна.

+ +
+

Обратите внимание: Некоторые свойства допускают использование отрицательных значений <length>, а некоторые нет.

+
+ +

Единицы измерения

+ +

Относительные единицы измерения

+ +

Относительные единицы измерения представляют расстояние, определённое какой-либо другой величиной. В зависимости от единицы, это может быть размер определённого символа, высота строки или размер {{glossary("viewport")}}.

+ +
Единицы, зависящие от шрифта
+ +

Единицы, зависящие от шрифта, определяют значение <length>, используя размер какого-либо символа или характеристики шрифта, который применяется к элементу или его родителю.

+ +
+

Обратите внимание: Эти единицы, особенно em и rem, часто используются для создания адаптивных разметок, которые сохраняют вертикальную структуру страницы даже если пользователь изменяет размер шрифта.

+
+ +
+
cap {{experimental_inline}}
+
Представляет высоту заглавных букв в шрифте, применённом к элементу.
+
ch
+
Представляет ширину символа "0" (ноль, символ Юникод U+0030) в шрифте, применённом к элементу.
+
em
+
Представляет подсчитанный размер шрифта элемента. Если используется в свойстве {{Cssxref("font-size")}}, представляет унаследованный размер шрифта.
+
ex
+
Представляет x-height (обычно высоту буквы x) в шрифте, применённом к элементу. В шрифтах с буквой x это обычно высота букв в нижнем регистре; во многих шрифтах 1ex ≈ 0.5em.
+
ic {{experimental_inline}}
+
Равна используемой в шрифте ширине символа "" (ККЯ, символ "вода", U+6C34).
+
lh {{experimental_inline}}
+
Равна рассчитанному значению свойства {{Cssxref("line-height")}}, переведённому в абсолютные единицы измерения.
+
rem
+
Представляет размер шрифта корневого элемента (обычно {{HTMLElement("html")}}). Когда используется в свойстве {{Cssxref("font-size")}} корневого элемента, представляет значение по умолчанию (в большинстве браузеров 16px, но настройки пользователя могут переопределить это значение).
+
rlh {{experimental_inline}}
+
Равна рассчитанному значению свойства {{Cssxref("line-height")}} корневого эдемента (обычно {{HTMLElement("html")}}), переведённому в абсолютные единицы измерения. Когда используется в свойстве {{Cssxref("font-size")}} корневого элемента, представляет значение по умолчанию.
+
+ +
Единицы, зависящие от размеров экрана
+ +

Эти единицы определяют значение <length> относительно размеров экрана, то есть видимой части документа. эти единицы недопустимы в блоках {{cssxref("@page")}}.

+ +
+
vh
+
Равна 1% высоты блока содержимого.
+
vw
+
Равна 1% ширины блока содержимого.
+
vi {{experimental_inline}}
+
Равна 1% размера блока содержимого по направлению выстраивания строчных элементов.
+
vb {{experimental_inline}}
+
Равна 1% размера блока содержимого по направлению выстраивания блочных элементов.
+
vmin
+
Равна vh или vw в зависимости от того, что из них меньше.
+
vmax
+
Равна vh или vw в зависимости от того, что из них больше.
+
+ +

Абсолютные единицы измерения

+ +

Абсолютные единицы измерения представляют физические расстояния, когда известны физические свойтсва устройства вывода. Одна из единиц привязывается к физической единице, а все остальные к ней. Привязка делается по-разному для устройств с низким разрешением, таких как экраны, и высоким, таких как принтеры.

+ +

Для устройств с маленьким dpi (dots per inch — количество точек на дюйм) единица измерения px представляет физический пиксель; остальные единицы определяются относительно него. Таким образом, 1in определяется как 96px, что равно 72pt. Последствием такого способа определения является то, что длины, описанные в дюймах (in), сантиметрах (cm) или миллиметрах (mm) необязательно равны одноимённым физическим единицам.

+ +

Для устройств с высоким dpi дюймы (in),сантиметры (cm) и миллиметры (mm) такие же, как и соответствующие физические единицы. Таким образов, единица px определяется относительно их (1/96 одного дюйма).

+ +
+

Обратите внимание: Многие пользователи увеличивают стандартный размер шрифта браузера для удобства чтения. Длины, заданные абсолютными единицами могут вызвать проблемы с доступностью, так как они привязаны к физическим величинам и не масштабируются при изменении настроек. Поэтому предпочтительнее использовать относительные единицы (такие как em или rem) в свойстве font-size.

+
+ +
+
px
+
Один пиксель. Для устройств с дисплеев традиционно представляет одну точку. Тем не менее, на принтерах и экранах с высоким разрешением один пиксель CSS равен нескольким пикселям дисплея. 1px = 1/96  от 1in.
+
cm
+
Один сантиметр. 1cm = 96px/2.54.
+
mm
+
Один миллиметр. 1mm = 1/10 от 1cm.
+
Q {{experimental_inline}}
+
Четверть миллиметра. 1Q = 1/40 от 1cm.
+
in
+
Один дюйм. 1in = 2.54cm = 96px.
+
pc
+
Одна пайка. 1pc = 12pt = 1/6 от 1in.
+
pt
+
Одна точка. 1pt = 1/72 от1in.
+
mozmm {{non-standard_inline}}, удалена в Firefox 59
+
Экспериметальная единица, которая равна одному физическому миллиметру вне зависимости от размера и разрешения экрана. Такая единица требуется очень редко, но может понадобиться, особенно на маленьких устройствах.
+
+ +

Интерполяция

+ +

При анимации значения <length> интерполируются как реальные числа с плавающей запятой. Интерполяция происходит над рассчитанным значением. Скорость интерполяции определяется временной функцией анимации.

+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('CSS4 Values', '#lengths', '<length>')}}{{Spec2('CSS4 Values')}}Добавлены единицы vi, vb, ic, lh, и rlh.
{{SpecName('CSS3 Values', '#lengths', '<length>')}}{{Spec2('CSS3 Values')}}Добавлены единицы ch, rem, vw, vh, vmin, vmax, и Q.
{{SpecName('CSS2.1', 'syndata.html#length-units', '<length>')}}{{Spec2('CSS2.1')}}Явно определены единицы empt, pc, и px.
{{SpecName('CSS1', '#length-units', '<length>')}}{{Spec2('CSS1')}}Первое определение. Неявно определены единицы empt, pc, и px.
+ +

Поддержка браузерами

+ + + +

{{Compat("css.types.length")}}

diff --git a/files/ru/web/css/media_queries/testing_media_queries/index.html b/files/ru/web/css/media_queries/testing_media_queries/index.html new file mode 100644 index 0000000000..878621ebd3 --- /dev/null +++ b/files/ru/web/css/media_queries/testing_media_queries/index.html @@ -0,0 +1,83 @@ +--- +title: Тестирование медиа-запросов программно +slug: Web/CSS/Media_Queries/Тестирование_медиа_запросы +tags: + - Запросы + - медиа-запросы +translation_of: Web/CSS/Media_Queries/Testing_media_queries +--- +
{{cssref}}
+ +

 {{Glossary("DOM")}} предоставляет возможности, позволяющие тестировать результат  медиа-запросов программно, с помощью интерфейса {{domxref("MediaQueryList") }}, его методов и свойств. Однажды, создав объект {{domxref("MediaQueryList") }} вы можете проверить результат запроса или получать уведомление, при изменении результата.

+ +

Создание списка медиа-запросов

+ +

Прежде, чем вы сможете оценить результаты медиа-запросов, вам необходимо создать объект {{domxref("MediaQueryList") }} , отражающий запрос. Для этого используйется метод {{domxref("window.matchMedia") }}.

+ +

Например, настройка списка запросов, который определяет, находится ли устройство в альбомной или книжной ориентации:

+ +
var mediaQueryList = window.matchMedia("(orientation: portrait)");
+
+ +

Проверка результата запроса

+ +

После того, как вы создали свой список медиа-запросов, вы можете проверить результат запроса, посмотрев на значение его свойства matches:

+ +
if (mediaQueryList.matches) {
+  /* Окно просмотра в настоящее время находится в книжной ориентации */
+} else {
+  /* Окно просмотра в настоящее время находится в альбомной ориентации */
+}
+
+ +

Получение уведомлений о запросах

+ +

Если вам необходимо постоянно следить за изменениями в результате запроса, эффективнее зарегистрировать слушатель, чем вытаскивать результат запросов.  Для этого вызовите метод addListener() объекта {{domxref("MediaQueryList") }} с функцией обратного вызова, которая вызывается при изменении статуса медиа-запроса (например, тест медиа-запроса переходит от true к false):

+ +
var mediaQueryList = window.matchMedia("(orientation: portrait)"); // Создание списка запросов.
+function handleOrientationChange(mql) { ... } // Определение функции обратного вызова для слушателя событий.
+mediaQueryList.addListener(handleOrientationChange); // Добавление функции обратного вызова в качестве слушателя к списку запросов.
+
+handleOrientationChange(mediaQueryList); // Запуск обработчика изменений, один раз.
+
+ +

Этот код создает список медиа-запросов для тестирование ориентации, а затем добавляет к нему слушатель событий. После добавления слушателя, мы, также, непосредственно вызываем слушателя. Это заставляет нашего слушателя выполнять настройки, основываясь на текущей ориентации устройства; в противном случае, наш код может предполагать, что устройство находится в книжной ориентации при запуске, даже если оно фактически находится в альбомном положении.

+ +

Функция handleOrientationChange() будет следить за результатом запроса и обрабатывать все, что нам нужно сделать при изменении ориентации:

+ +
function handleOrientationChange(evt) {
+  if (evt.matches) {
+    /* Окно просмотра в настоящее время находится в книжной ориентации */
+  } else {
+    /* Окно просмотра в настоящее время находится в альбомной ориентации */
+  }
+}
+
+ +

Выше, мы определяем параметры как evt — event объект. Это имеет значение, поскольку новые реализации MediaQueryList обрабатывают слушатели событий стандартным способом. Они больше не используют нестандартный механизм  {{domxref("MediaQueryListListener")}} , а используют стандартную настройку слушателя событий, передавая объект event  {{domxref("MediaQueryListEvent")}} как аргумент функции обратного вызова.

+ +

Этот event объект также включает свойства {{domxref("MediaQueryListEvent.media","media")}} и {{domxref("MediaQueryListEvent.matches","matches")}}, поэтому вы можете запросить эти свойства MediaQueryList путем прямого доступа к нему или доступа к event объекту.

+ +

Уведомление о завершении запроса

+ +

Для прекращения уведомлений об изменении значения вашего медиа-запроса вызовите метод removeListener() для {{domxref("MediaQueryList") }}, передав ему имя, ранее определенной функции:

+ +
mediaQueryList.removeListener(handleOrientationChange);
+
+ +

Поддержка браузеров

+ +

MediaQueryList interface

+ + + +

{{Compat("api.MediaQueryList")}}

+ +

See also

+ +
    +
  • Media queries
  • +
  • {{domxref("window.matchMedia()") }}
  • +
  • {{domxref("MediaQueryList") }}
  • +
  • {{domxref("MediaQueryListEvent") }}
  • +
diff --git "a/files/ru/web/css/media_queries/\321\202\320\265\321\201\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265_\320\274\320\265\320\264\320\270\320\260_\320\267\320\260\320\277\321\200\320\276\321\201\321\213/index.html" "b/files/ru/web/css/media_queries/\321\202\320\265\321\201\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265_\320\274\320\265\320\264\320\270\320\260_\320\267\320\260\320\277\321\200\320\276\321\201\321\213/index.html" deleted file mode 100644 index 878621ebd3..0000000000 --- "a/files/ru/web/css/media_queries/\321\202\320\265\321\201\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265_\320\274\320\265\320\264\320\270\320\260_\320\267\320\260\320\277\321\200\320\276\321\201\321\213/index.html" +++ /dev/null @@ -1,83 +0,0 @@ ---- -title: Тестирование медиа-запросов программно -slug: Web/CSS/Media_Queries/Тестирование_медиа_запросы -tags: - - Запросы - - медиа-запросы -translation_of: Web/CSS/Media_Queries/Testing_media_queries ---- -
{{cssref}}
- -

 {{Glossary("DOM")}} предоставляет возможности, позволяющие тестировать результат  медиа-запросов программно, с помощью интерфейса {{domxref("MediaQueryList") }}, его методов и свойств. Однажды, создав объект {{domxref("MediaQueryList") }} вы можете проверить результат запроса или получать уведомление, при изменении результата.

- -

Создание списка медиа-запросов

- -

Прежде, чем вы сможете оценить результаты медиа-запросов, вам необходимо создать объект {{domxref("MediaQueryList") }} , отражающий запрос. Для этого используйется метод {{domxref("window.matchMedia") }}.

- -

Например, настройка списка запросов, который определяет, находится ли устройство в альбомной или книжной ориентации:

- -
var mediaQueryList = window.matchMedia("(orientation: portrait)");
-
- -

Проверка результата запроса

- -

После того, как вы создали свой список медиа-запросов, вы можете проверить результат запроса, посмотрев на значение его свойства matches:

- -
if (mediaQueryList.matches) {
-  /* Окно просмотра в настоящее время находится в книжной ориентации */
-} else {
-  /* Окно просмотра в настоящее время находится в альбомной ориентации */
-}
-
- -

Получение уведомлений о запросах

- -

Если вам необходимо постоянно следить за изменениями в результате запроса, эффективнее зарегистрировать слушатель, чем вытаскивать результат запросов.  Для этого вызовите метод addListener() объекта {{domxref("MediaQueryList") }} с функцией обратного вызова, которая вызывается при изменении статуса медиа-запроса (например, тест медиа-запроса переходит от true к false):

- -
var mediaQueryList = window.matchMedia("(orientation: portrait)"); // Создание списка запросов.
-function handleOrientationChange(mql) { ... } // Определение функции обратного вызова для слушателя событий.
-mediaQueryList.addListener(handleOrientationChange); // Добавление функции обратного вызова в качестве слушателя к списку запросов.
-
-handleOrientationChange(mediaQueryList); // Запуск обработчика изменений, один раз.
-
- -

Этот код создает список медиа-запросов для тестирование ориентации, а затем добавляет к нему слушатель событий. После добавления слушателя, мы, также, непосредственно вызываем слушателя. Это заставляет нашего слушателя выполнять настройки, основываясь на текущей ориентации устройства; в противном случае, наш код может предполагать, что устройство находится в книжной ориентации при запуске, даже если оно фактически находится в альбомном положении.

- -

Функция handleOrientationChange() будет следить за результатом запроса и обрабатывать все, что нам нужно сделать при изменении ориентации:

- -
function handleOrientationChange(evt) {
-  if (evt.matches) {
-    /* Окно просмотра в настоящее время находится в книжной ориентации */
-  } else {
-    /* Окно просмотра в настоящее время находится в альбомной ориентации */
-  }
-}
-
- -

Выше, мы определяем параметры как evt — event объект. Это имеет значение, поскольку новые реализации MediaQueryList обрабатывают слушатели событий стандартным способом. Они больше не используют нестандартный механизм  {{domxref("MediaQueryListListener")}} , а используют стандартную настройку слушателя событий, передавая объект event  {{domxref("MediaQueryListEvent")}} как аргумент функции обратного вызова.

- -

Этот event объект также включает свойства {{domxref("MediaQueryListEvent.media","media")}} и {{domxref("MediaQueryListEvent.matches","matches")}}, поэтому вы можете запросить эти свойства MediaQueryList путем прямого доступа к нему или доступа к event объекту.

- -

Уведомление о завершении запроса

- -

Для прекращения уведомлений об изменении значения вашего медиа-запроса вызовите метод removeListener() для {{domxref("MediaQueryList") }}, передав ему имя, ранее определенной функции:

- -
mediaQueryList.removeListener(handleOrientationChange);
-
- -

Поддержка браузеров

- -

MediaQueryList interface

- - - -

{{Compat("api.MediaQueryList")}}

- -

See also

- -
    -
  • Media queries
  • -
  • {{domxref("window.matchMedia()") }}
  • -
  • {{domxref("MediaQueryList") }}
  • -
  • {{domxref("MediaQueryListEvent") }}
  • -
diff --git a/files/ru/web/css/pseudo-classes/index.html b/files/ru/web/css/pseudo-classes/index.html new file mode 100644 index 0000000000..2c280be32b --- /dev/null +++ b/files/ru/web/css/pseudo-classes/index.html @@ -0,0 +1,146 @@ +--- +title: Псевдоклассы +slug: Web/CSS/Псевдо-классы +tags: + - CSS + - Reference + - Псевдоклассы + - Селекторы +translation_of: Web/CSS/Pseudo-classes +--- +
{{CSSRef}}
+ +

Псевдокласс в CSS — это ключевое слово, добавленное к селектору, которое определяет его особое состояние. Например, {{ Cssxref(":hover") }} может быть использован для изменения цвета кнопки при наведении курсора на неё.

+ +
div:hover {
+  background-color: #F89B4D;
+}
+ +

Псевдоклассы дают возможность стилизовать элемент на основе не только отношений в DOM-дереве, но и основываясь на внешних факторах, таких как история посещений (например, {{ cssxref(":visited") }}), состояние содержимого (вроде {{ cssxref(":checked") }} у некоторых элементов формы) или позиции курсора мыши (например, {{ cssxref(":hover") }} определяет, находится ли курсор мыши над элементом).

+ +
+

Примечание: В отличие от псевдоклассов, псевдоэлементы могут быть использованы для стилизации определённой части элемента.

+
+ +

Синтаксис

+ +
selector:pseudo-class {
+  property: value;
+}
+
+ +

Как и с обычными классами, можно совмещать вместе в одном селекторе любое число псевдоклассов.

+ +

Список стандартных псевдоклассов

+ +
+
    +
  • {{ Cssxref(":active") }}
  • +
  • {{ cssxref(':any')}}
  • +
  • {{ cssxref(':any-link')}}
  • +
  • {{ Cssxref(":checked") }}
  • +
  • {{ Cssxref(":default") }}
  • +
  • {{ Cssxref(":defined") }}
  • +
  • {{ Cssxref(":dir", ":dir()")}}
  • +
  • {{ Cssxref(":disabled") }}
  • +
  • {{ Cssxref(":empty") }}
  • +
  • {{ Cssxref(":enabled") }}
  • +
  • {{ Cssxref(":first") }}
  • +
  • {{ Cssxref(":first-child") }}
  • +
  • {{ Cssxref(":first-of-type") }}
  • +
  • {{ Cssxref(":fullscreen") }}
  • +
  • {{ Cssxref(":focus") }}
  • +
  • {{ Cssxref(":hover") }}
  • +
  • {{ Cssxref(":indeterminate") }}
  • +
  • {{ Cssxref(":in-range") }}
  • +
  • {{ Cssxref(":invalid") }}
  • +
  • {{ Cssxref(":lang", ":lang()") }}
  • +
  • {{ Cssxref(":last-child") }}
  • +
  • {{ Cssxref(":last-of-type") }}
  • +
  • {{ Cssxref(":left") }}
  • +
  • {{ Cssxref(":link") }}
  • +
  • {{ Cssxref(":not", ":not()") }}
  • +
  • {{ Cssxref(":nth-child", ":nth-child()") }}
  • +
  • {{ Cssxref(":nth-last-child", ":nth-last-child()") }}
  • +
  • {{ Cssxref(":nth-last-of-type", ":nth-last-of-type()") }}
  • +
  • {{ Cssxref(":nth-of-type", ":nth-of-type()") }}
  • +
  • {{ Cssxref(":only-child") }}
  • +
  • {{ Cssxref(":only-of-type") }}
  • +
  • {{ Cssxref(":optional") }}
  • +
  • {{ Cssxref(":out-of-range") }}
  • +
  • {{ Cssxref(":read-only") }}
  • +
  • {{ Cssxref(":read-write") }}
  • +
  • {{ Cssxref(":required") }}
  • +
  • {{ Cssxref(":right") }}
  • +
  • {{ Cssxref(":root") }}
  • +
  • {{ Cssxref(":scope") }}
  • +
  • {{ Cssxref(":target") }}
  • +
  • {{ Cssxref(":valid") }}
  • +
  • {{ Cssxref(":visited") }}
  • +
+
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{ SpecName('Fullscreen') }}{{ Spec2('Fullscreen') }}Определён :fullscreen.
{{ SpecName('HTML WHATWG') }}{{ Spec2('HTML WHATWG') }}Нет изменений от {{ SpecName('HTML5 W3C') }}.
{{SpecName('CSS4 Selectors')}}{{Spec2('CSS4 Selectors')}}Определены :any-link, :local-link, :scope, :active-drop-target, :valid-drop-target, :invalid-drop-target, :current, :past, :future, :placeholder-shown, :user-error, :blank, :nth-match(), :nth-last-match(), :nth-column(), :nth-last-column() и :matches().
+ Нет существенных изменений для псевдоклассов, определённых в {{SpecName('CSS3 Selectors')}} и {{SpecName('HTML5 W3C')}} (не рассматрия семантическое значение).
{{ SpecName('HTML5 W3C') }}{{ Spec2('HTML5 W3C') }}Определено семантическое значение в HTML контексте для  :link, :visited, :active, :enabled, :disabled, :checked и :indeterminate.
+ Определены :default, :valid, :invalid, :in-range, :out-of-range, :required, :optional, :read-only, :read-write и :dir().
{{ SpecName('CSS3 Basic UI') }}{{ Spec2('CSS3 Basic UI') }}Определены :default, :valid, :invalid, :in-range, :out-of-range, :required, :optional, :read-only и :read-write, но без связанного семантического значения.
{{SpecName('CSS3 Selectors')}}{{Spec2('CSS3 Selectors')}}Определены :target, :root, :nth-child(), :nth-last-of-child(), :nth-of-type(), :nth-last-of-type(), :last-child, :first-of-type, :last-of-type, :only-child, :only-of-type, :empty и :not().
+ Определён синтаксис для :enabled, :disabled, :checked и :indeterminate, но без связанного семантического значения.
+ Нет значительных изменений для псевдоклассов, определённых в {{SpecName('CSS2.1')}}.
{{SpecName('CSS2.1')}}{{Spec2('CSS2.1')}}Определены :lang(), :first-child, :hover и :focus.
+ Нет значительных изменений для псевдоклассов, определённых в {{SpecName('CSS1')}}.
{{SpecName('CSS1')}}{{Spec2('CSS1')}}Определены :link, :visited и :active, но без связанного семантического значения.
+ +

См. также

+ + diff --git a/files/ru/web/css/replaced_element/index.html b/files/ru/web/css/replaced_element/index.html new file mode 100644 index 0000000000..a252cbad33 --- /dev/null +++ b/files/ru/web/css/replaced_element/index.html @@ -0,0 +1,49 @@ +--- +title: Замещаемый элемент +slug: Web/CSS/Замещаемый_элемент +tags: + - CSS + - Reference + - замещаемый элемент +translation_of: Web/CSS/Replaced_element +--- +
{{CSSRef}}
+ +

В CSS, замещаемый элемент — это элемент, чьё представление выходит за рамки CSS. Другими словами, это внешний объект, чьё представление независимо от модели форматирования CSS.

+ +

Замещаемые элементы

+ +

Типичные замещаемые элементы:

+ +
    +
  • {{HTMLElement("iframe")}}
  • +
  • {{HTMLElement("video")}}
  • +
  • {{HTMLElement("embed")}}
  • +
  • {{HTMLElement("img")}}
  • +
+ +

Некоторые элементы рассматриваются как замещаемые только в некоторых случаях:

+ +
    +
  • {{HTMLElement("audio")}}
  • +
  • {{HTMLElement("canvas")}}
  • +
  • {{HTMLElement("object")}}
  • +
  • {{HTMLElement("applet")}}
  • +
+ +

Спецификация HTML также указывает, что элемент {{HTMLElement("input")}} может быть замещаемым, поскольку элемент {{HTMLElement("input")}} с типом image является замещаемым элементом наподобие {{HTMLElement("img")}}. Однако другие элементы форм, включая другие типы элементов {{HTMLElement("input")}}, явно отнесены к незамещаемым элементам (для описания их отображения по умолчанию, которое может быть разным на разных платформах, спецификация использует термин «Виджеты»).

+ +

Объекты, добавляемые с помощью CSS-свойства {{cssxref("content")}} являются анонимными замещаемыми элементами. Они «анонимные», так как они не существуют в HTML-разметке.

+ +

Использование CSS с замещаемыми элементами

+ +

CSS обрабатывает замещаемые элементы особым образом в некоторых случаях, например при расчёте внешних отступов и некоторых значений auto.

+ +

Заметим, что у некоторых замещаемых элементов, но не у всех, есть внутренние размеры или определённая базовая линия, которая используется CSS свойствами вроде {{cssxref("vertical-align")}}.

+ +

См. также

+ +
    +
  • Спецификация HTML https://html.spec.whatwg.org/multipage/rendering.html#replaced-elements
  • +
  • {{CSS_key_concepts()}}
  • +
diff --git a/files/ru/web/css/specified_value/index.html b/files/ru/web/css/specified_value/index.html new file mode 100644 index 0000000000..4f143afb74 --- /dev/null +++ b/files/ru/web/css/specified_value/index.html @@ -0,0 +1,43 @@ +--- +title: Указанное значение +slug: Web/CSS/Указанное_значение +tags: + - CSS + - CSS Reference +translation_of: Web/CSS/specified_value +--- +

{{CSSRef}}

+ +

Указанное значение CSS свойства может устанавливаться одним из 3 следующих способов.

+ +
    +
  1. Если в таблице стилей документа указано значение свойства, которое будет использоваться. Например, если свойство {{cssxref("color")}} устанавливается в green, то цвет текста соответствующего элемента становится зелёным.
  2. +
  3. Если в таблице стилей документа указано значение, которое может наследоваться от родительского элемента (если возможно). Например, у нас есть параграф ({{HTMLElement("p")}}) внутри {{HTMLElement("div")}}, а к {{HTMLElement("div")}} применено CSS свойство font со значением "Arial", а у {{HTMLElement("p")}} не установлено свойство font, то он унаследует значение шрифта "Arial".
  4. +
  5. Если не выполняется не то, не другое, начальное значение элемента применяется из CSS спецификации.
  6. +
+ +

Спецификации

+ + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName("CSS2.1", "cascade.html#specified-value", "cascaded value")}}{{Spec2("CSS2.1")}}Изначальное определение
+ +

Смотрите также

+ + diff --git a/files/ru/web/css/syntax/index.html b/files/ru/web/css/syntax/index.html new file mode 100644 index 0000000000..1adfb2fb04 --- /dev/null +++ b/files/ru/web/css/syntax/index.html @@ -0,0 +1,76 @@ +--- +title: Синтаксис +slug: Web/CSS/Синтаксис +translation_of: Web/CSS/Syntax +--- +
{{cssref}}
+ +
Основная задача Каскадных Стилей — это рассказать движку браузера, как отрисовать элементы страницы — каким цветом, как позиционировать их на странице, как украшать, и так далее. Синтаксис CSS построен следуя этой идее, и состоит из следующих основных блоков:
+ +
+ +
    +
  • Свойство (property) — идентификатор действия, которое будет применено к элементу (например, цвет, или размер границы, и т.д.).
  • +
  • Значение (value) — описывает, как именно свойство будет обработано браузером. Каждое свойство имеет набор допустимых значений, определенных формальными правилами, а также семантический смысл, реализованный движком браузера.
  • +
+ +

Объявления CSS

+ +

Задание CSS свойствам определенных значений — это основная функция CSS. Пара свойство-значение называется объявлением. Работа CSS движка заключается в поиске соответсвий между объявлениями стилей и элементом на странице, чтобы правильно отобразить и форматировать этот элемент.

+ +

И свойство, и значения регистрозависимы. Пара свойство-значение разделяется двоеточием, ':' (U+003A COLON), а пробелы до, между и после свойства или значения игнорируются.

+ +

css syntax - declaration.png

+ +

В CSS существует более ста различных свойств, и бесконечное число допустимых значений. Не все пары свойств и значений допускаются, и каждое свойство определяет, каковы допустимые значения. Когда значение не подходит для данного свойства, объявление считается недействительной и целиком игнорируются CSS-движком.

+ +

Блоки объявлений CSS

+ +

Объявления группируются в блоки, структура которых состоит из открывающейся , '{' (U+007B LEFT CURLY BRACKET), и закрывающейся, '}' (U+007D RIGHT CURLY BRACKET) фигурных скобок.

+ +

css syntax - block.png

+ +

Такие блоки называются блоками объявлений, и объявления в них разделяются точкой с запятой, ';' (U+003B SEMICOLON). Блок объявлений может быть пустым, т.е. не содержать объявлений. Пробелы между объявлениями игнорируются. Последнее объявление блока не нуждается в точке с запятой, хотя считается хорошим тоном добавить ее для того, чтобы не допустить упущение этого знака при добавлении другого объявления в будущем.

+ +

css syntax - declarations block.png

+ +
Содержимое блока объявлений CSS, т. е. объявления, разделенные точкой с запятой. Блок объявлений может быть помещен внутри атрибута style HTML-документа без фигурных скобок.
+ +

CSS rulesets

+ +

If style sheets could only apply a declaration to each element of a Web page, they would be pretty useless. The real goal is to apply different declarations to different parts of the document.

+ +

CSS allows this by associating conditions with declarations blocks. Each (valid) declaration block is preceded by a selector which is a condition selecting some elements of the page. The pair selector-declarations block is called a ruleset, or often simply a rule.

+ +

css syntax - ruleset.png

+ +

As an element of the page may be matched by several selectors, and therefore by several rules eventually containing a given property several times, with different values, the CSS standard defines which one has precedence over the other and must be applied: this is called the cascade algorithm.

+ +
It is important to note that even if a ruleset characterized by a group of selectors is a kind of shorthand replacing rulesets with a single selector each, this doesn't apply to the validity of the ruleset itself.
+
+This leads to an important consequence: if one single basic selector is invalid, like when using an unknown pseudo-element or pseudo-class, the whole selector is invalid and therefor the entire rule is ignored (as invalid too).
+ +

CSS statements

+ +

Rulesets are the main building blocks of a style sheet, which often consists of only a big list of them. But there is other information that a Web author wants to convey in the style sheet, like the character set, other external style sheets to import, font face or list counter descriptions and many more. It will use other and specific kinds of statements to do that.

+ +

A statement is a building block that begins with any non-space characters and ends at the first closing brace or semi-colon (outside a string, non-escaped and not included into another {}, () or [] pair).

+ +

css syntax - statements Venn diag.png

+ +

There are different kinds of statements:

+ +
    +
  • Rulesets (or rules) that, as seen, associate a collection of CSS declarations to a condition described by a selector.
  • +
  • At-rules that start with an at sign, '@' (U+0040 COMMERCIAL AT), followed by an identifier and then continuing up the end of the statement, that is up to the next semi-colon (;) outside of a block, or the end of the next block. Each type of at-rules, defined by the identifier, may have its own internal syntax, and semantics of course. They are used to convey meta-data information (like {{ cssxref("@charset") }} or {{ cssxref("@import") }}), conditional information (like {{ cssxref("@media") }} or {{ cssxref("@document") }}), or descriptive information (like {{ cssxref("@font-face") }}).
  • +
+ +

Any statement which isn't a rule or an at-rule is invalid and ignored.

+ +

There is another group of statements, the nested statements, these are statements that can be used in a specific subset of at-rules, the conditional group rules. These statements only apply if a specific condition is matched: the @media at-rule content is applied only if the device on which runs the browser matches the expressed condition; the @document at-rule content is applied only if the current page matches some conditions, and so on. In CSS1 and CSS2.1, only rulesets could be used inside a conditional group rules. That was very restrictive and this restriction was lifted in CSS Conditionals Level 3. Now, though it still is experimental and not supported by every browser, a conditional group rules can contain a wider range of content, rulesets but also some, but not all, at-rules.

+ +

See also

+ +
    +
  • {{ CSS_key_concepts()}}
  • +
diff --git a/files/ru/web/css/url/index.html b/files/ru/web/css/url/index.html deleted file mode 100644 index 82965bf827..0000000000 --- a/files/ru/web/css/url/index.html +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: -slug: Web/CSS/url -tags: - - Адрес - - Типы данных - - относительный адрес -translation_of: Web/CSS/url() -translation_of_original: Web/CSS/url ---- -
{{CssRef}}
- -

Тип данных CSS <url> обозначает указатели на ресурсы, такие как изображения или шрифты. URL-адреса могут быть использованы в многочисленных свойствах CSS, таких как {{Cssxref("background-image")}}, {{Cssxref("cursor")}} или {{cssxref("list-style")}}.

- -
-

URI или URL? Существует разница между {{Glossary("URI")}} и {{Glossary("URL")}}. URI просто идентифицирует ресурс. URL является типом URI, и описывает месторасположение ресурса.URI может быть либо URL-адресом, либо именем ресурса ({{Glossary("URN")}}).

- -

В CSS Уровень 1, фунциональная нотация url()описывала только истинные URL-адреса. В CSS Уровень 2, определение url() было расширено для описания любого URI, будь то URL или URN. Неожиданно, что  url() может быть использовано для создания типа данных CSS <uri>. Это изменение было не только неожиданным, но и ненужным, так как URN почти не используется в реальном CSS. Для избежания путанницы, CSS Уровень 3 вернулся к более узкому, первоначальному определению. Сейчас url() означает только истинное значение <url>.

-
- -

Синтаксис

- -

Тип данных <url> является указанием к использованию функциональной нотации url(). Он  может быть задан без кавычек или с использованием одинарных или двойных кавычек. Допускаются относительные URL-адреса, относящиеся к URL-адресу страницы стилей (а не к URL-адресу веб-страницы).

- -
<a_css_property>: url("http://mysite.example.com/mycursor.png")
-<a_css_property>: url('http://mysite.example.com/mycursor.png')
-<a_css_property>: url(http://mysite.example.com/mycursor.png)
-
- -
-

Примечание: Контрольные символы выше 0x7e не допустимы в URL-адресах без кавычек, начиная с Firefox 15. Смотри {{Bug(752230)}} для более детальной информации.

-
- -

Примеры

- -
.topbanner {
-  background: url("topbanner.png") #00D no-repeat fixed;
-}
-
- -
ul {
-  list-style: square url(http://www.example.com/redball.png);
-}
-
- -

Спецификации

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
СпецификацияСтатусКомментарий
{{SpecName('CSS4 Values', '#urls', '<url>')}}{{Spec2('CSS4 Values')}} 
{{SpecName('CSS3 Values', '#urls', '<url>')}}{{Spec2('CSS3 Values')}}Нет значительных изменений по сравнению с CSS Уровень 2 (Revision 1).
{{Specname('CSS2.1', 'syndata.html#uri', '<uri>')}}{{Spec2('CSS2.1')}}Нет значительных изменений по сравнению с CSS Уровень 1.
{{SpecName('CSS1', '#url', '<url>')}}{{Spec2('CSS1')}}первое определение.
- -

Поддержка браузерами

- - - -
{{Compat("css.types.url")}}
- -

Смотрите также

- -
    -
  • {{cssxref("<gradient>")}}
  • -
  • {{cssxref("element()")}}
  • -
  • {{cssxref("_image","image()")}}
  • -
  • {{cssxref("image-set","image-set()")}}
  • -
  • {{cssxref("cross-fade")}}
  • -
diff --git a/files/ru/web/css/visual_formatting_model/index.html b/files/ru/web/css/visual_formatting_model/index.html new file mode 100644 index 0000000000..7a5de35909 --- /dev/null +++ b/files/ru/web/css/visual_formatting_model/index.html @@ -0,0 +1,209 @@ +--- +title: Модель визуального форматирования +slug: Web/Guide/CSS/Visual_formatting_model +translation_of: Web/CSS/Visual_formatting_model +--- +

{{CSSRef}}

+ +

Модель визуального форматирования CSS  - это алгоритм, используемый для обработки документа и его визуального отображения. Это базовая концепция CSS. Модель визуального форматирования задаёт трансформацию каждого элемента в документе и создаёт ноль, одну или несколько боксов, согласно боксовой модели CSS. Расположение (layout) каждого бокса определяется:

+ +
    +
  • размерами бокса: точно заданными или заданными ограничениями. Если размеры не заданы, это правило игнорируется;
  • +
  • типом бокса: inline, inline-level, atomic inline-level, block box;
  • +
  • схемой позиционирования: normal flow, float или absolute;
  • +
  • другими элементами дерева: дочерними и соседними;
  • +
  • размерами и расположением окна просмотра ({{glossary("viewport")}});
  • +
  • внутренними размерами содержащихся изображений;
  • +
  • другой внешней информацией.
  • +
+ +

Бокс отображается относительно краев содержащего его блока. Как правило, бокс определяет родительский блок для своих потомков. Однако, стоит заметить, что бокс не ограничен содержащим его блоком. Такое поведение слоев, выходящих за пределы своих содержащих блоков, называется переполенинем (overflow).

+ +

Генерация бокса

+ +

Генерация бокса - часть алгоритма модели визуального форматирования, процедура, генерирующая блоки из элементов. Различные типы боксов определяют различное поведение в контексте форматирования. Тип бокса зависит от свойства CSS {{ cssxref("display") }}.

+ +

Блочные эклементы и блок-боксы

+ +

Говорят, что элемент является блочным, когда вычисленное значение его CSS свойства {{ cssxref("display") }} равно: blocklist-item, или table. Блочный элемент визуально форматируется как блок (например, параграф), предназначенный для вертикальной компоновки (в столбик).

+ +

Каждый элемент блочного уровня участвует в контексте блочного форматирования. Каждый элемент блочного уровня генерирует как миниум один блок-бокс, названный главным блок-боксом. Некоторые элементы, например, такие как list-item, создают дополнительные боксы для хранения маркеров и других типографических элементов, содержащихся в list item. Большинство блочных элементов генерирует только один, главный блок-бокс.

+ +

Главный блок-бокс содержит сгенериованные боксы-потомки и сгенериованный контекст. Он так же будет боксом, участвующем в схеме позиционирования.

+ +

venn_blocks.pngЭлемент блочного уровня так же может быть блоком-контейнером. Блок-контейнер - это блок, который содержит либо только другие элементы блочного уровня, либо создаёт контекст инлайнового форматирования и, таким образом, содержит только инлайновые элементы.

+ +

Важно понимать, что понятие блочного элемента и понятие блочного контейнера - это разные вещи. Первое описывает, как блок будет себя вести по отношению к своему родителю и своим соседям/братьям. А второе - описывает, как блок будет взаимодействовать со своими потомками. Некоторые элементы блочного уровня, например, таблицы, не являются содержащими блоками. И наоборот, некоторые блоки-контейнеры, например, ячейки таблицы, не являются элементами блочного уровня.

+ +

Элементы блочного уровня, которые так же являются контейнерами, называются блок-боксами.

+ +

Анонимные блок-боксы

+ +

В некоторых случаях алгоритм визуального форматирования  вынужден добавлять дополнительные боксы. Так как эти боксы невозможно как-то проименовать и к ним невозможно применить css-селекторы, поэтому эти боксы называют анонимными.

+ +

Из-за того, что к анонимным боксам невозможно применить селекторы, их невозможно изменить с помощью таблицы стилей. Это значит, что все наследуемые CSS свойства для них будут иметь значение inherit, а все ненаследуемые свойства будут иметь значение initial.

+ +

Блоки-контейнеры содержат либо только инлайн-боксы, либо только элементы блочного уровня. Но, как правило, документ содержит и те и другие. В этом случае анонимные блок-боксы создаются вокруг примыкающих к ним инлайн-боксов.

+ +

Пример

+ +

Возьмём следующий HTML код (со стилями по умолчанию, то есть элементы {{ HTMLElement("div") }} и {{ HTMLElement("p") }} имеют значение display:block :

+ +
<div>Some inline text <p>followed by a paragraph</p> followed by more inline text.</div>
+ +

Здесь создались два анонимных блока: один для текста перед параграфом (Some inline text), и второй для текста после параграфа (followed by more inline text.). И у нас получилась вот такая структура:

+ +

anonymous_block-level_boxes.png

+ +

Выглядеть это будет так:

+ +
Some inline text
+followed by a paragraph
+followed by more inline text.
+ +

В отличие от параграфа {{ HTMLElement("p") }}, Web разработчик не может напрямую контролировать стили этих двух анонимных боксов. Те свойства, которые наследуются, берут своё значение от элемента {{ HTMLElement("div") }}, например {{ cssxref("color") }}, определяющий цвет текста. А другие значения, ненаследуемые, устанавливаются в значение initial. Например, у них не будет своего свойства {{ cssxref("background-color") }}, он всегда будет в состоянии "прозрачный" (transparent), значении по умолчанию для этого свойства, и поэтому будет видно тот background, который установлен у элемента <div>. А вот для параграфа <p> можно установить своё свойство цвета фона. Таким образом, эти два анонимных бокса будут иметь один и тот же цвет текста.

+ +

Ещё один случай, который приводит к созданию анонимных блок-боксов, это случай, когда инлайн-бокс содержит один или несколько блок-боксов. В этом случае элемент, содержащий блок-боксы, делится на два инлайн-бокса - один перед, а второй после блок-бокса. И потом инлайн-элементы перед и после блок-бокса дополнительно заключаются в анонимные блок-боксы. Таким образом блок-бокс становится соседом для анонимных блок-боксов, содержащих инлайн-элементы.

+ +

Если есть несколько блок-боксов, идущих подряд, без инлайн-элементов между ними, то анонимные блок-боксы создаются только перед и после такого набора блок-боксов.

+ +

Пример

+ +

Возьмём следующий HTML код, где установим для элемента {{ HTMLElement("p") }} значение display:inline и для элемента {{ HTMLElement("span") }} значение display:block :

+ +
<p>Some <em>inline</em> text <span>followed by a paragraph</span> followed by more inline text.</p>
+ +

Создадутся два анонимных блок-бокса, один для текста перед элементом span (Some inline text) и один для текста после него (followed by more inline text), и у нас получится вот такая структура:

+ +

+ +

Выглядеть она будет так:

+ +
Some inline text
+followed by a paragraph
+followed by more inline text.
+ +

Элементы инлайн-уровня и инлайн-боксы

+ +

Элементы, которые называются элементами инлайн-уровня - это элементы, у которых вычисленное значение CSS свойства {{ cssxref("display") }} установлено в : inline, inline-block или inline-table. Визуально они не представляют собой какие-то отдельные блоки, но они они распологаются в одну линию с другим контентом инлайн-уровня. Например, содержание параграфа, с различным форматированием, таким как подчёркивание или картинка, состоит из элементов инлайн-уровня.

+ +

venn_inlines.png

+ +
+

Эта диаграмма использует устаревшую терминологию; см. примечания ниже. К тому же она некорректна, потому что жёлтый эллипс справа по определению должен быть изображён одинаковым по размеру с эллипсом слева или больше него  (it could be a mathematical superset), потому что в спецификации сказано: "Элементв инлайн-уровня генерируют боксы инлайн-уровня, участвующие в форматировании инлайн-уровня", см. CSS 2.2, глава 9.2.2

+
+ +

Элементы инлайн-уровня создают боксы инлайн-уровня, которые определены как боксы, участвующие в контексте форматирования инлайн-уровня. Inline boxes are both inline-level boxes and boxes, whose contents participate in their container's inline formatting context. This is the case, for example, for all non-replaced boxes with display:inline. Inline-level boxes, whose contents do not participate in an inline formatting context, are called atomic inline-level boxes. These boxes, generated by replaced inline-level elements or by elements with a calculated {{ cssxref("display") }} value of inline-block or inline-table, are never split into several boxes, as is possible with inline boxes.

+ +
Note: Initially, atomic inline-level boxes were called atomic inline boxes. This was unfortunate, as they are not inline boxes. This was corrected in an erratum to the spec. Nevertheless, you can harmlessly read atomic inline-level box each time you meet atomic inline box in the literature, as this is only a name change.
+ +
Atomic inline boxes cannot be split into several lines in an inline formatting context. +
+
<style>
+  span {
+    display:inline; /* default value*/
+  }
+</style>
+<div style="width:20em;">
+   The text in the span <span>can be split in several
+   lines as it</span> is an inline box.
+</div>
+
+
+ +

which leads to:

+ +
The text in the span can be split into several lines as it is an inline box.
+ +
<style>
+  span {
+    display:inline-block;
+  }
+</style>
+<div style="width:20em;">
+   The text in the span <span>cannot be split in several
+   lines as it</span> is an inline-block box.
+</div>
+ +
+
+

which leads to:

+ +
The text in the span cannot be split into several lines as it is an inline-block box.
+
+
+ +

Anonymous inline boxes

+ +

As for block boxes, there are a few cases where inline boxes are created automatically by the CSS engine. These inline boxes are also anonymous as they cannot be named by selectors; they inherit the value of all inheritable properties, setting it to initial for all others.

+ +

The most common case where an anonymous inline box is created, is when some text is found as a direct child of a block box creating an inline formatting context. In that case, this text is included in the largest possible anonymous inline box. Also, space content, which would be removed by the behavior set in the {{ cssxref("white-space") }} CSS property, does not generate anonymous inline boxes because they would end empty.

+ +
Example TBD
+ +

Other types of boxes

+ +

Line boxes

+ +

Line boxes are generated by the inline formatting context to represent a line of text. Inside a block box, a line box extends from one border of the box to the other. When there are floats, the line box starts at the rightmost border of the left floats and ends at the leftmost border of the right floats.

+ +

These boxes are technical, and Web authors do not usually have to bother with them.

+ +

Run-in boxes

+ +

Run-in boxes, defined using display:run-in, are boxes that are either block boxes or inline boxes, depending on the type of the following box. They can be used to create a title that runs inside its first paragraph when possible.

+ +
Note: Run-in boxes were removed from the CSS 2.1 standard, as they were insufficiently specified to allow for interoperable implementation. They may reappear in CSS3, but meanwhile, are considered experimental. They should not be used in production.
+ +

Model-induced boxes

+ +

Besides the inline and block formatting contexts, CSS specifies several additional content models that may be applied to elements. These additional models, used to describe specific layouts, may define additional box types:

+ +
    +
  • The table content model may create a table wrapper box and a table box, but also specific boxes like caption boxes.
  • +
  • The multi-column content model may create column boxes between the container box and the content.
  • +
  • The experimental grid, or flex-box content models, also create additional types of boxes.
  • +
+ +

Positioning schemes

+ +

Once boxes are generated, the CSS engine needs to position them on the layout. To do that, it uses one of the following algorithms:

+ +
    +
  • The normal flow - positions each box one after the other.
  • +
  • The floats algorithm - extracts the box from the normal flow and put it to the side of the containing box.
  • +
  • The absolute positioning scheme - positions a box within an absolute coordinate system that is established by its containing element. An absolutely positioned element can cover other elements.
  • +
+ +

Normal flow

+ +

In the normal flow, boxes are laid out one after the other. In a block formatting context, they are laid out vertically; in an inline formatting context, they are laid out horizontally. The normal flow is triggered when the CSS {{ cssxref("position") }} is set to the value static or relative, and if the CSS {{ cssxref("float") }} is set to the value none.

+ +

Example

+ +
When in the normal flow, in a block formatting context, boxes are laid vertically one after the other out.
+
+When in the normal flow, in an inline formatting context, boxes are laid horizontally one after the other out.
+ +
+

There are two sub-cases of the normal flow: static positioning and relative positioning:

+ +
    +
  • In static positioning, triggered by the value static of the {{ cssxref("position") }} property, the boxes are drawn at the exact position defined by the normal flow layout.
  • +
  • In relative positioning, triggered by the value relative of the {{ cssxref("position") }} property, the boxes are drawn with an offset defined by the {{ cssxref("top") }}, {{ cssxref("bottom") }}, {{ cssxref("left") }} and {{ cssxref("right") }} CSS properties.
  • +
+
+ +

Floats

+ +

In the float positioning scheme, specific boxes (called floating boxes or simply floats) are positioned at the beginning, or end of the current line. This leads to the property that text (and more generally anything within the normal flow) flows along the edge of the floating boxes, except if told differently by the {{ cssxref("clear") }} CSS property.

+ +

The float positioning scheme for a box is selected, by setting the {{ cssxref("float") }} CSS property on that box to a value different than none and {{ cssxref("position") }} to static or relative. If {{ cssxref("float") }} is set to left, the float is positioned at the beginning of the line box. If set to right, the float is positioned at the end of the line box. In either case, the line box is shrunk to fit alongside the float.

+ +

Absolute positioning

+ +

In the absolute positioning scheme, boxes are entirely removed from the flow and don't interact with it at all. They are positioned relative to their containing block using the {{ cssxref("top") }}, {{ cssxref("bottom") }}, {{ cssxref("left") }} and {{ cssxref("right") }} CSS properties.

+ +

An element is absolutely positioned if the {{ cssxref("position") }} is set to absolute or fixed.

+ +

With a fixed positioned element, the containing block is the viewport. The position of the element is absolute within the viewport. Scrolling does not change the position of the element.

diff --git "a/files/ru/web/css/\320\264\320\265\320\271\321\201\321\202\320\262\320\270\321\202\320\265\320\273\321\214\320\275\320\276\320\265_\320\267\320\275\320\260\321\207\320\265\320\275\320\270\320\265/index.html" "b/files/ru/web/css/\320\264\320\265\320\271\321\201\321\202\320\262\320\270\321\202\320\265\320\273\321\214\320\275\320\276\320\265_\320\267\320\275\320\260\321\207\320\265\320\275\320\270\320\265/index.html" deleted file mode 100644 index da6231da1f..0000000000 --- "a/files/ru/web/css/\320\264\320\265\320\271\321\201\321\202\320\262\320\270\321\202\320\265\320\273\321\214\320\275\320\276\320\265_\320\267\320\275\320\260\321\207\320\265\320\275\320\270\320\265/index.html" +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: Действительное значение -slug: Web/CSS/Действительное_значение -tags: - - CSS - - Guide - - Web -translation_of: Web/CSS/actual_value ---- -

{{CSSRef}}

- -

Описание

- -

Действительное значение CSS свойства - используемое после всех приближений значение. Например, браузер может отображать рамки только с целым значением пикселей и будет прининудительно округлять ширину.

- -

Спецификации

- - - - - - - - - - - - - - - - -
СпецификацияСтатусКомментарий
{{SpecName('CSS2.1', 'cascade.html#actual-value', 'actual value')}}{{Spec2('CSS2.1')}}Изначальное определение
- -

Смотрите также

- - diff --git "a/files/ru/web/css/\320\267\320\260\320\274\320\265\321\211\320\260\320\265\320\274\321\213\320\271_\321\215\320\273\320\265\320\274\320\265\320\275\321\202/index.html" "b/files/ru/web/css/\320\267\320\260\320\274\320\265\321\211\320\260\320\265\320\274\321\213\320\271_\321\215\320\273\320\265\320\274\320\265\320\275\321\202/index.html" deleted file mode 100644 index a252cbad33..0000000000 --- "a/files/ru/web/css/\320\267\320\260\320\274\320\265\321\211\320\260\320\265\320\274\321\213\320\271_\321\215\320\273\320\265\320\274\320\265\320\275\321\202/index.html" +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: Замещаемый элемент -slug: Web/CSS/Замещаемый_элемент -tags: - - CSS - - Reference - - замещаемый элемент -translation_of: Web/CSS/Replaced_element ---- -
{{CSSRef}}
- -

В CSS, замещаемый элемент — это элемент, чьё представление выходит за рамки CSS. Другими словами, это внешний объект, чьё представление независимо от модели форматирования CSS.

- -

Замещаемые элементы

- -

Типичные замещаемые элементы:

- -
    -
  • {{HTMLElement("iframe")}}
  • -
  • {{HTMLElement("video")}}
  • -
  • {{HTMLElement("embed")}}
  • -
  • {{HTMLElement("img")}}
  • -
- -

Некоторые элементы рассматриваются как замещаемые только в некоторых случаях:

- -
    -
  • {{HTMLElement("audio")}}
  • -
  • {{HTMLElement("canvas")}}
  • -
  • {{HTMLElement("object")}}
  • -
  • {{HTMLElement("applet")}}
  • -
- -

Спецификация HTML также указывает, что элемент {{HTMLElement("input")}} может быть замещаемым, поскольку элемент {{HTMLElement("input")}} с типом image является замещаемым элементом наподобие {{HTMLElement("img")}}. Однако другие элементы форм, включая другие типы элементов {{HTMLElement("input")}}, явно отнесены к незамещаемым элементам (для описания их отображения по умолчанию, которое может быть разным на разных платформах, спецификация использует термин «Виджеты»).

- -

Объекты, добавляемые с помощью CSS-свойства {{cssxref("content")}} являются анонимными замещаемыми элементами. Они «анонимные», так как они не существуют в HTML-разметке.

- -

Использование CSS с замещаемыми элементами

- -

CSS обрабатывает замещаемые элементы особым образом в некоторых случаях, например при расчёте внешних отступов и некоторых значений auto.

- -

Заметим, что у некоторых замещаемых элементов, но не у всех, есть внутренние размеры или определённая базовая линия, которая используется CSS свойствами вроде {{cssxref("vertical-align")}}.

- -

См. также

- -
    -
  • Спецификация HTML https://html.spec.whatwg.org/multipage/rendering.html#replaced-elements
  • -
  • {{CSS_key_concepts()}}
  • -
diff --git "a/files/ru/web/css/\320\277\321\201\320\265\320\262\320\264\320\276-\320\272\320\273\320\260\321\201\321\201\321\213/index.html" "b/files/ru/web/css/\320\277\321\201\320\265\320\262\320\264\320\276-\320\272\320\273\320\260\321\201\321\201\321\213/index.html" deleted file mode 100644 index 2c280be32b..0000000000 --- "a/files/ru/web/css/\320\277\321\201\320\265\320\262\320\264\320\276-\320\272\320\273\320\260\321\201\321\201\321\213/index.html" +++ /dev/null @@ -1,146 +0,0 @@ ---- -title: Псевдоклассы -slug: Web/CSS/Псевдо-классы -tags: - - CSS - - Reference - - Псевдоклассы - - Селекторы -translation_of: Web/CSS/Pseudo-classes ---- -
{{CSSRef}}
- -

Псевдокласс в CSS — это ключевое слово, добавленное к селектору, которое определяет его особое состояние. Например, {{ Cssxref(":hover") }} может быть использован для изменения цвета кнопки при наведении курсора на неё.

- -
div:hover {
-  background-color: #F89B4D;
-}
- -

Псевдоклассы дают возможность стилизовать элемент на основе не только отношений в DOM-дереве, но и основываясь на внешних факторах, таких как история посещений (например, {{ cssxref(":visited") }}), состояние содержимого (вроде {{ cssxref(":checked") }} у некоторых элементов формы) или позиции курсора мыши (например, {{ cssxref(":hover") }} определяет, находится ли курсор мыши над элементом).

- -
-

Примечание: В отличие от псевдоклассов, псевдоэлементы могут быть использованы для стилизации определённой части элемента.

-
- -

Синтаксис

- -
selector:pseudo-class {
-  property: value;
-}
-
- -

Как и с обычными классами, можно совмещать вместе в одном селекторе любое число псевдоклассов.

- -

Список стандартных псевдоклассов

- -
-
    -
  • {{ Cssxref(":active") }}
  • -
  • {{ cssxref(':any')}}
  • -
  • {{ cssxref(':any-link')}}
  • -
  • {{ Cssxref(":checked") }}
  • -
  • {{ Cssxref(":default") }}
  • -
  • {{ Cssxref(":defined") }}
  • -
  • {{ Cssxref(":dir", ":dir()")}}
  • -
  • {{ Cssxref(":disabled") }}
  • -
  • {{ Cssxref(":empty") }}
  • -
  • {{ Cssxref(":enabled") }}
  • -
  • {{ Cssxref(":first") }}
  • -
  • {{ Cssxref(":first-child") }}
  • -
  • {{ Cssxref(":first-of-type") }}
  • -
  • {{ Cssxref(":fullscreen") }}
  • -
  • {{ Cssxref(":focus") }}
  • -
  • {{ Cssxref(":hover") }}
  • -
  • {{ Cssxref(":indeterminate") }}
  • -
  • {{ Cssxref(":in-range") }}
  • -
  • {{ Cssxref(":invalid") }}
  • -
  • {{ Cssxref(":lang", ":lang()") }}
  • -
  • {{ Cssxref(":last-child") }}
  • -
  • {{ Cssxref(":last-of-type") }}
  • -
  • {{ Cssxref(":left") }}
  • -
  • {{ Cssxref(":link") }}
  • -
  • {{ Cssxref(":not", ":not()") }}
  • -
  • {{ Cssxref(":nth-child", ":nth-child()") }}
  • -
  • {{ Cssxref(":nth-last-child", ":nth-last-child()") }}
  • -
  • {{ Cssxref(":nth-last-of-type", ":nth-last-of-type()") }}
  • -
  • {{ Cssxref(":nth-of-type", ":nth-of-type()") }}
  • -
  • {{ Cssxref(":only-child") }}
  • -
  • {{ Cssxref(":only-of-type") }}
  • -
  • {{ Cssxref(":optional") }}
  • -
  • {{ Cssxref(":out-of-range") }}
  • -
  • {{ Cssxref(":read-only") }}
  • -
  • {{ Cssxref(":read-write") }}
  • -
  • {{ Cssxref(":required") }}
  • -
  • {{ Cssxref(":right") }}
  • -
  • {{ Cssxref(":root") }}
  • -
  • {{ Cssxref(":scope") }}
  • -
  • {{ Cssxref(":target") }}
  • -
  • {{ Cssxref(":valid") }}
  • -
  • {{ Cssxref(":visited") }}
  • -
-
- -

Спецификации

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
СпецификацияСтатусКомментарий
{{ SpecName('Fullscreen') }}{{ Spec2('Fullscreen') }}Определён :fullscreen.
{{ SpecName('HTML WHATWG') }}{{ Spec2('HTML WHATWG') }}Нет изменений от {{ SpecName('HTML5 W3C') }}.
{{SpecName('CSS4 Selectors')}}{{Spec2('CSS4 Selectors')}}Определены :any-link, :local-link, :scope, :active-drop-target, :valid-drop-target, :invalid-drop-target, :current, :past, :future, :placeholder-shown, :user-error, :blank, :nth-match(), :nth-last-match(), :nth-column(), :nth-last-column() и :matches().
- Нет существенных изменений для псевдоклассов, определённых в {{SpecName('CSS3 Selectors')}} и {{SpecName('HTML5 W3C')}} (не рассматрия семантическое значение).
{{ SpecName('HTML5 W3C') }}{{ Spec2('HTML5 W3C') }}Определено семантическое значение в HTML контексте для  :link, :visited, :active, :enabled, :disabled, :checked и :indeterminate.
- Определены :default, :valid, :invalid, :in-range, :out-of-range, :required, :optional, :read-only, :read-write и :dir().
{{ SpecName('CSS3 Basic UI') }}{{ Spec2('CSS3 Basic UI') }}Определены :default, :valid, :invalid, :in-range, :out-of-range, :required, :optional, :read-only и :read-write, но без связанного семантического значения.
{{SpecName('CSS3 Selectors')}}{{Spec2('CSS3 Selectors')}}Определены :target, :root, :nth-child(), :nth-last-of-child(), :nth-of-type(), :nth-last-of-type(), :last-child, :first-of-type, :last-of-type, :only-child, :only-of-type, :empty и :not().
- Определён синтаксис для :enabled, :disabled, :checked и :indeterminate, но без связанного семантического значения.
- Нет значительных изменений для псевдоклассов, определённых в {{SpecName('CSS2.1')}}.
{{SpecName('CSS2.1')}}{{Spec2('CSS2.1')}}Определены :lang(), :first-child, :hover и :focus.
- Нет значительных изменений для псевдоклассов, определённых в {{SpecName('CSS1')}}.
{{SpecName('CSS1')}}{{Spec2('CSS1')}}Определены :link, :visited и :active, но без связанного семантического значения.
- -

См. также

- - diff --git "a/files/ru/web/css/\321\200\320\260\320\267\320\274\320\265\321\200/index.html" "b/files/ru/web/css/\321\200\320\260\320\267\320\274\320\265\321\200/index.html" deleted file mode 100644 index 4fd88f8cc2..0000000000 --- "a/files/ru/web/css/\321\200\320\260\320\267\320\274\320\265\321\200/index.html" +++ /dev/null @@ -1,153 +0,0 @@ ---- -title: -slug: Web/CSS/размер -tags: - - CSS - - CSS Тип Данных - - Величина - - Разметка - - длина -translation_of: Web/CSS/length ---- -
{{CSSRef}}
- -

CSS тип данных <length> представляет единицу длины. Длина может быть использована в таких свойствах CSS как {{Cssxref("width")}}, {{Cssxref("height")}}, {{Cssxref("margin")}}, {{Cssxref("padding")}}, {{Cssxref("border-width")}}, {{Cssxref("font-size")}}, и {{Cssxref("text-shadow")}}.

- -
-

Обратите внимание: Хоть значения {{cssxref("<percentage>")}} также определяют размеры и могут использоваться в некоторых свойствах, принимающих значения типа <length>, они не являются <length> значениями.

-
- -

Синтаксис

- -

Тип данных <length> состоит из {{cssxref("<number>")}}, за которым следует одна из единиц измерения, перечисленных ниже. Как и у любых единиц измерения CSS между числом и единицей нет знака пробела. После числа 0 единица измерения необязательна.

- -
-

Обратите внимание: Некоторые свойства допускают использование отрицательных значений <length>, а некоторые нет.

-
- -

Единицы измерения

- -

Относительные единицы измерения

- -

Относительные единицы измерения представляют расстояние, определённое какой-либо другой величиной. В зависимости от единицы, это может быть размер определённого символа, высота строки или размер {{glossary("viewport")}}.

- -
Единицы, зависящие от шрифта
- -

Единицы, зависящие от шрифта, определяют значение <length>, используя размер какого-либо символа или характеристики шрифта, который применяется к элементу или его родителю.

- -
-

Обратите внимание: Эти единицы, особенно em и rem, часто используются для создания адаптивных разметок, которые сохраняют вертикальную структуру страницы даже если пользователь изменяет размер шрифта.

-
- -
-
cap {{experimental_inline}}
-
Представляет высоту заглавных букв в шрифте, применённом к элементу.
-
ch
-
Представляет ширину символа "0" (ноль, символ Юникод U+0030) в шрифте, применённом к элементу.
-
em
-
Представляет подсчитанный размер шрифта элемента. Если используется в свойстве {{Cssxref("font-size")}}, представляет унаследованный размер шрифта.
-
ex
-
Представляет x-height (обычно высоту буквы x) в шрифте, применённом к элементу. В шрифтах с буквой x это обычно высота букв в нижнем регистре; во многих шрифтах 1ex ≈ 0.5em.
-
ic {{experimental_inline}}
-
Равна используемой в шрифте ширине символа "" (ККЯ, символ "вода", U+6C34).
-
lh {{experimental_inline}}
-
Равна рассчитанному значению свойства {{Cssxref("line-height")}}, переведённому в абсолютные единицы измерения.
-
rem
-
Представляет размер шрифта корневого элемента (обычно {{HTMLElement("html")}}). Когда используется в свойстве {{Cssxref("font-size")}} корневого элемента, представляет значение по умолчанию (в большинстве браузеров 16px, но настройки пользователя могут переопределить это значение).
-
rlh {{experimental_inline}}
-
Равна рассчитанному значению свойства {{Cssxref("line-height")}} корневого эдемента (обычно {{HTMLElement("html")}}), переведённому в абсолютные единицы измерения. Когда используется в свойстве {{Cssxref("font-size")}} корневого элемента, представляет значение по умолчанию.
-
- -
Единицы, зависящие от размеров экрана
- -

Эти единицы определяют значение <length> относительно размеров экрана, то есть видимой части документа. эти единицы недопустимы в блоках {{cssxref("@page")}}.

- -
-
vh
-
Равна 1% высоты блока содержимого.
-
vw
-
Равна 1% ширины блока содержимого.
-
vi {{experimental_inline}}
-
Равна 1% размера блока содержимого по направлению выстраивания строчных элементов.
-
vb {{experimental_inline}}
-
Равна 1% размера блока содержимого по направлению выстраивания блочных элементов.
-
vmin
-
Равна vh или vw в зависимости от того, что из них меньше.
-
vmax
-
Равна vh или vw в зависимости от того, что из них больше.
-
- -

Абсолютные единицы измерения

- -

Абсолютные единицы измерения представляют физические расстояния, когда известны физические свойтсва устройства вывода. Одна из единиц привязывается к физической единице, а все остальные к ней. Привязка делается по-разному для устройств с низким разрешением, таких как экраны, и высоким, таких как принтеры.

- -

Для устройств с маленьким dpi (dots per inch — количество точек на дюйм) единица измерения px представляет физический пиксель; остальные единицы определяются относительно него. Таким образом, 1in определяется как 96px, что равно 72pt. Последствием такого способа определения является то, что длины, описанные в дюймах (in), сантиметрах (cm) или миллиметрах (mm) необязательно равны одноимённым физическим единицам.

- -

Для устройств с высоким dpi дюймы (in),сантиметры (cm) и миллиметры (mm) такие же, как и соответствующие физические единицы. Таким образов, единица px определяется относительно их (1/96 одного дюйма).

- -
-

Обратите внимание: Многие пользователи увеличивают стандартный размер шрифта браузера для удобства чтения. Длины, заданные абсолютными единицами могут вызвать проблемы с доступностью, так как они привязаны к физическим величинам и не масштабируются при изменении настроек. Поэтому предпочтительнее использовать относительные единицы (такие как em или rem) в свойстве font-size.

-
- -
-
px
-
Один пиксель. Для устройств с дисплеев традиционно представляет одну точку. Тем не менее, на принтерах и экранах с высоким разрешением один пиксель CSS равен нескольким пикселям дисплея. 1px = 1/96  от 1in.
-
cm
-
Один сантиметр. 1cm = 96px/2.54.
-
mm
-
Один миллиметр. 1mm = 1/10 от 1cm.
-
Q {{experimental_inline}}
-
Четверть миллиметра. 1Q = 1/40 от 1cm.
-
in
-
Один дюйм. 1in = 2.54cm = 96px.
-
pc
-
Одна пайка. 1pc = 12pt = 1/6 от 1in.
-
pt
-
Одна точка. 1pt = 1/72 от1in.
-
mozmm {{non-standard_inline}}, удалена в Firefox 59
-
Экспериметальная единица, которая равна одному физическому миллиметру вне зависимости от размера и разрешения экрана. Такая единица требуется очень редко, но может понадобиться, особенно на маленьких устройствах.
-
- -

Интерполяция

- -

При анимации значения <length> интерполируются как реальные числа с плавающей запятой. Интерполяция происходит над рассчитанным значением. Скорость интерполяции определяется временной функцией анимации.

- -

Спецификации

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('CSS4 Values', '#lengths', '<length>')}}{{Spec2('CSS4 Values')}}Добавлены единицы vi, vb, ic, lh, и rlh.
{{SpecName('CSS3 Values', '#lengths', '<length>')}}{{Spec2('CSS3 Values')}}Добавлены единицы ch, rem, vw, vh, vmin, vmax, и Q.
{{SpecName('CSS2.1', 'syndata.html#length-units', '<length>')}}{{Spec2('CSS2.1')}}Явно определены единицы empt, pc, и px.
{{SpecName('CSS1', '#length-units', '<length>')}}{{Spec2('CSS1')}}Первое определение. Неявно определены единицы empt, pc, и px.
- -

Поддержка браузерами

- - - -

{{Compat("css.types.length")}}

diff --git "a/files/ru/web/css/\321\201\320\270\320\275\321\202\320\260\320\272\321\201\320\270\321\201/index.html" "b/files/ru/web/css/\321\201\320\270\320\275\321\202\320\260\320\272\321\201\320\270\321\201/index.html" deleted file mode 100644 index 1adfb2fb04..0000000000 --- "a/files/ru/web/css/\321\201\320\270\320\275\321\202\320\260\320\272\321\201\320\270\321\201/index.html" +++ /dev/null @@ -1,76 +0,0 @@ ---- -title: Синтаксис -slug: Web/CSS/Синтаксис -translation_of: Web/CSS/Syntax ---- -
{{cssref}}
- -
Основная задача Каскадных Стилей — это рассказать движку браузера, как отрисовать элементы страницы — каким цветом, как позиционировать их на странице, как украшать, и так далее. Синтаксис CSS построен следуя этой идее, и состоит из следующих основных блоков:
- -
- -
    -
  • Свойство (property) — идентификатор действия, которое будет применено к элементу (например, цвет, или размер границы, и т.д.).
  • -
  • Значение (value) — описывает, как именно свойство будет обработано браузером. Каждое свойство имеет набор допустимых значений, определенных формальными правилами, а также семантический смысл, реализованный движком браузера.
  • -
- -

Объявления CSS

- -

Задание CSS свойствам определенных значений — это основная функция CSS. Пара свойство-значение называется объявлением. Работа CSS движка заключается в поиске соответсвий между объявлениями стилей и элементом на странице, чтобы правильно отобразить и форматировать этот элемент.

- -

И свойство, и значения регистрозависимы. Пара свойство-значение разделяется двоеточием, ':' (U+003A COLON), а пробелы до, между и после свойства или значения игнорируются.

- -

css syntax - declaration.png

- -

В CSS существует более ста различных свойств, и бесконечное число допустимых значений. Не все пары свойств и значений допускаются, и каждое свойство определяет, каковы допустимые значения. Когда значение не подходит для данного свойства, объявление считается недействительной и целиком игнорируются CSS-движком.

- -

Блоки объявлений CSS

- -

Объявления группируются в блоки, структура которых состоит из открывающейся , '{' (U+007B LEFT CURLY BRACKET), и закрывающейся, '}' (U+007D RIGHT CURLY BRACKET) фигурных скобок.

- -

css syntax - block.png

- -

Такие блоки называются блоками объявлений, и объявления в них разделяются точкой с запятой, ';' (U+003B SEMICOLON). Блок объявлений может быть пустым, т.е. не содержать объявлений. Пробелы между объявлениями игнорируются. Последнее объявление блока не нуждается в точке с запятой, хотя считается хорошим тоном добавить ее для того, чтобы не допустить упущение этого знака при добавлении другого объявления в будущем.

- -

css syntax - declarations block.png

- -
Содержимое блока объявлений CSS, т. е. объявления, разделенные точкой с запятой. Блок объявлений может быть помещен внутри атрибута style HTML-документа без фигурных скобок.
- -

CSS rulesets

- -

If style sheets could only apply a declaration to each element of a Web page, they would be pretty useless. The real goal is to apply different declarations to different parts of the document.

- -

CSS allows this by associating conditions with declarations blocks. Each (valid) declaration block is preceded by a selector which is a condition selecting some elements of the page. The pair selector-declarations block is called a ruleset, or often simply a rule.

- -

css syntax - ruleset.png

- -

As an element of the page may be matched by several selectors, and therefore by several rules eventually containing a given property several times, with different values, the CSS standard defines which one has precedence over the other and must be applied: this is called the cascade algorithm.

- -
It is important to note that even if a ruleset characterized by a group of selectors is a kind of shorthand replacing rulesets with a single selector each, this doesn't apply to the validity of the ruleset itself.
-
-This leads to an important consequence: if one single basic selector is invalid, like when using an unknown pseudo-element or pseudo-class, the whole selector is invalid and therefor the entire rule is ignored (as invalid too).
- -

CSS statements

- -

Rulesets are the main building blocks of a style sheet, which often consists of only a big list of them. But there is other information that a Web author wants to convey in the style sheet, like the character set, other external style sheets to import, font face or list counter descriptions and many more. It will use other and specific kinds of statements to do that.

- -

A statement is a building block that begins with any non-space characters and ends at the first closing brace or semi-colon (outside a string, non-escaped and not included into another {}, () or [] pair).

- -

css syntax - statements Venn diag.png

- -

There are different kinds of statements:

- -
    -
  • Rulesets (or rules) that, as seen, associate a collection of CSS declarations to a condition described by a selector.
  • -
  • At-rules that start with an at sign, '@' (U+0040 COMMERCIAL AT), followed by an identifier and then continuing up the end of the statement, that is up to the next semi-colon (;) outside of a block, or the end of the next block. Each type of at-rules, defined by the identifier, may have its own internal syntax, and semantics of course. They are used to convey meta-data information (like {{ cssxref("@charset") }} or {{ cssxref("@import") }}), conditional information (like {{ cssxref("@media") }} or {{ cssxref("@document") }}), or descriptive information (like {{ cssxref("@font-face") }}).
  • -
- -

Any statement which isn't a rule or an at-rule is invalid and ignored.

- -

There is another group of statements, the nested statements, these are statements that can be used in a specific subset of at-rules, the conditional group rules. These statements only apply if a specific condition is matched: the @media at-rule content is applied only if the device on which runs the browser matches the expressed condition; the @document at-rule content is applied only if the current page matches some conditions, and so on. In CSS1 and CSS2.1, only rulesets could be used inside a conditional group rules. That was very restrictive and this restriction was lifted in CSS Conditionals Level 3. Now, though it still is experimental and not supported by every browser, a conditional group rules can contain a wider range of content, rulesets but also some, but not all, at-rules.

- -

See also

- -
    -
  • {{ CSS_key_concepts()}}
  • -
diff --git "a/files/ru/web/css/\321\201\320\277\320\276\321\201\320\276\320\261_\321\200\320\260\321\201\320\277\320\276\320\273\320\276\320\266\320\265\320\275\320\270\321\217/index.html" "b/files/ru/web/css/\321\201\320\277\320\276\321\201\320\276\320\261_\321\200\320\260\321\201\320\277\320\276\320\273\320\276\320\266\320\265\320\275\320\270\321\217/index.html" deleted file mode 100644 index dcf1440cb5..0000000000 --- "a/files/ru/web/css/\321\201\320\277\320\276\321\201\320\276\320\261_\321\200\320\260\321\201\320\277\320\276\320\273\320\276\320\266\320\265\320\275\320\270\321\217/index.html" +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: Способ разметки -slug: Web/CSS/Способ_расположения -tags: - - CSS -translation_of: Web/CSS/Layout_mode ---- -

CSS способ разметки (или раскладки, или англ. layout) — это алгоритм определения позиции и размеров блоков, основанный на способе, которым они взаимодействуют с родственными блоками. Существует несколько типов разметки:

- -
    -
  • Обычная (Normal Flow) — все элементы являются частью обычного потока до тех пор, пока вы не переопределите это каким-либо образом. Обычный layout включает в себя блочную раскладку, созданную для расположения отдельных блоков, таких как параграфы, и линейную, для строчных элементов;
  • -
  • Табличная, спроектированная для расположения таблиц;
  • -
  • Float layout — для возможности обозначить элементы плавающими. Такой элемент начинает позиционироваться слева или справа отностительно содержимого обычного потока, элементы которого начинают обтекать него;
  • -
  • Позиционированная — для позиционирования элементов без особого взаимодействия с другими элементами;
  • -
  • Множественные столбцы — для расположения контента колонками, как в газетах;
  • -
  • Флексбокс (CSS Flexible Box Layout) — для расположения сложных страниц, которые плавно могут изменять свой размер; {{ experimental_inline() }}
  • -
  • Сеточная — для расположения элементов относительно фиксированной сетки. {{ experimental_inline() }}
  • -
- -
-

Примечание: не все CSS свойства применимы ко всем способам разметки. Большинство из них применяются к одному или двум из них и не действуют, если применяются на элементе, участвующем в другом режиме разметки.

-
- -

Смотрите также

- -
    -
  • {{ CSS_key_concepts() }}
  • -
diff --git "a/files/ru/web/css/\321\202\320\270\321\205\320\270\320\271/index.html" "b/files/ru/web/css/\321\202\320\270\321\205\320\270\320\271/index.html" deleted file mode 100644 index 1db7dd50b5..0000000000 --- "a/files/ru/web/css/\321\202\320\270\321\205\320\270\320\271/index.html" +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: Комментарии -slug: Web/CSS/Тихий -tags: - - Beginner - - CSS - - CSS Reference - - Комментарии - - Новичку - - Руководство -translation_of: Web/CSS/Comments ---- -
{{CSSRef}}
- -

Описание

- -

Комментарии используются для добавления поясняющих заметок или для того, чтобы предотвратить интеграцию части кода в браузер.

- -

Синтаксис

- -
/* Комментарий */
- -

Примеры

- -
/* Однострочный комментарий */
-
-/*
-Комментарий
-который содержит
-несколько
-строк
-*/
-
- -

Замечания

- -

Данный /* */ синтаксис комментария используется для обоих вариантов, и однострочного и многострочного комментария. Нет других способов добавить комментарий во внешнюю таблицу стилей. Также, когда используется элемент <style>, вы можете использовать <!-- -->, чтобы спрятать CSS от старых браузеров, но это не рекомендуется. Как и в большинстве языков программирования, которые используют синтаксис комментариев /* */ , комментарии нельзя вкладывать друг в друга. Другими словами, данная часть синтаксиса */, которая следует за /* закрывает комментарий.

- -

Спецификации

- - - -

Смотрите также

- - diff --git "a/files/ru/web/css/\321\203\320\272\320\260\320\267\320\260\320\275\320\275\320\276\320\265_\320\267\320\275\320\260\321\207\320\265\320\275\320\270\320\265/index.html" "b/files/ru/web/css/\321\203\320\272\320\260\320\267\320\260\320\275\320\275\320\276\320\265_\320\267\320\275\320\260\321\207\320\265\320\275\320\270\320\265/index.html" deleted file mode 100644 index 4f143afb74..0000000000 --- "a/files/ru/web/css/\321\203\320\272\320\260\320\267\320\260\320\275\320\275\320\276\320\265_\320\267\320\275\320\260\321\207\320\265\320\275\320\270\320\265/index.html" +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: Указанное значение -slug: Web/CSS/Указанное_значение -tags: - - CSS - - CSS Reference -translation_of: Web/CSS/specified_value ---- -

{{CSSRef}}

- -

Указанное значение CSS свойства может устанавливаться одним из 3 следующих способов.

- -
    -
  1. Если в таблице стилей документа указано значение свойства, которое будет использоваться. Например, если свойство {{cssxref("color")}} устанавливается в green, то цвет текста соответствующего элемента становится зелёным.
  2. -
  3. Если в таблице стилей документа указано значение, которое может наследоваться от родительского элемента (если возможно). Например, у нас есть параграф ({{HTMLElement("p")}}) внутри {{HTMLElement("div")}}, а к {{HTMLElement("div")}} применено CSS свойство font со значением "Arial", а у {{HTMLElement("p")}} не установлено свойство font, то он унаследует значение шрифта "Arial".
  4. -
  5. Если не выполняется не то, не другое, начальное значение элемента применяется из CSS спецификации.
  6. -
- -

Спецификации

- - - - - - - - - - - - - - - - -
СпецификацияСтатусКомментарий
{{SpecName("CSS2.1", "cascade.html#specified-value", "cascaded value")}}{{Spec2("CSS2.1")}}Изначальное определение
- -

Смотрите также

- - diff --git a/files/ru/web/events/abort/index.html b/files/ru/web/events/abort/index.html deleted file mode 100644 index d8029e2378..0000000000 --- a/files/ru/web/events/abort/index.html +++ /dev/null @@ -1,70 +0,0 @@ ---- -title: abort -slug: Web/Events/abort -tags: - - Событие -translation_of: Web/API/HTMLMediaElement/abort_event -translation_of_original: Web/Events/abort ---- -

Событие "abort" вызывается когда загрузка какого-либо ресурса была прервана.

- -

Общая информация

- -
-
Спецификация
-
DOM L3
-
Интерфейс
-
{{domxref("UIEvent")}} если событие сгенерировано из пользовательского интерфейса, иначе {{domxref("Event")}}.
-
Всплывание
-
Нет
-
Отменяемость
-
Нет
-
Цель
-
{{domxref("window")}}, {{domxref("Element")}}
-
Действие по умолчанию
-
Нет
-
- -

Свойства

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
СвойствоТипОписание
target {{readonlyInline}}EventTargetЦель события (самый вышележащий элемент в DOM дереве).
type {{readonlyInline}}DOMStringТип события.
bubbles {{readonlyInline}}BooleanПоднимается ли событие вверх как принято или нет.
cancelable {{readonlyInline}}BooleanЯвляется ли событие отменяемым или нет?
view {{readonlyInline}}WindowProxydocument.defaultView (свойство window  объекта document)
detail {{readonlyInline}}long (float)0.
diff --git a/files/ru/web/events/blur/index.html b/files/ru/web/events/blur/index.html deleted file mode 100644 index a29fa0debc..0000000000 --- a/files/ru/web/events/blur/index.html +++ /dev/null @@ -1,153 +0,0 @@ ---- -title: blur (event) -slug: Web/Events/blur -tags: - - DOM - - DOM Events -translation_of: Web/API/Element/blur_event ---- -

Событие blur вызывается когда элемент теряет фокус. Главное отличие между этим событием и  focusout только в том что у последнего есть фаза всплытия.

- -

Основная информация

- -
-
Спецификация
-
DOM L3
-
Интерфейс
-
{{domxref("FocusEvent")}}
-
Всплытие
-
Нет
-
Отменяемый
-
Нет
-
Цель
-
Элемент
-
Действие по умолчанию
-
Нет
-
- -

{{NoteStart}}Значение {{domxref("Document.activeElement")}} меняется в зависимости от браузера во время выполнения этого события ({{bug(452307)}}): IE10 устанавливает его к элементу на который будет перемещен фокус, в то время как Firefox и Chrome обычно устанавливают его к body документа{{NoteEnd}}

- -

Свойства

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyTypeDescription
target {{readonlyInline}}{{domxref("EventTarget")}}Event target (DOM element)
type {{readonlyInline}}{{domxref("DOMString")}}The type of event.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Whether the event normally bubbles or not.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Whether the event is cancellable or not.
relatedTarget {{readonlyInline}}{{domxref("EventTarget")}} (DOM element)null
- -

Делегирование события

- -

Есть два способа реализовать делегирование этого события: использовать событие focusout в браузерах которые поддерживают его (все браузеры, Firefox с 52+), или установить параметр "useCapture" метода addEventListener на true:

- -

HTML Content

- -
<form id="form">
-  <input type="text" placeholder="text input">
-  <input type="password" placeholder="password">
-</form>
- -

JavaScript Content

- -
var form = document.getElementById("form");
-form.addEventListener("focus", function( event ) {
-  event.target.style.background = "pink";
-}, true);
-form.addEventListener("blur", function( event ) {
-  event.target.style.background = "";
-}, true);
- -

{{EmbedLiveSample('Event_delegation')}}

- -

Совместимость с браузерами

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support5{{CompatVersionUnknown}}[1]612.15.1
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support4.053{{CompatUnknown}}10.012.15.1
-
- -

[1] В Gecko до 24 {{geckoRelease(24)}} интефейс для этого события был {{domxref("Event")}}, не {{domxref("FocusEvent")}}. Смотреть ({{bug(855741)}}).

- -

Похожие события

- -
    -
  • {{event("focus")}}
  • -
  • {{event("blur")}}
  • -
  • {{event("focusin")}}
  • -
  • {{event("focusout")}}
  • -
diff --git a/files/ru/web/events/domcontentloaded/index.html b/files/ru/web/events/domcontentloaded/index.html deleted file mode 100644 index 7702dcfd24..0000000000 --- a/files/ru/web/events/domcontentloaded/index.html +++ /dev/null @@ -1,146 +0,0 @@ ---- -title: DOMContentLoaded -slug: Web/Events/DOMContentLoaded -tags: - - события -translation_of: Web/API/Window/DOMContentLoaded_event ---- -

Событие DOMContentLoaded происходит когда весь HTML был полностью загружен и пройден парсером, не дожидаясь окончания загрузки таблиц стилей, изображений и фреймов. Значительно отличающееся от него событие load используется для отслеживания только полностью загруженной страницы. Широко распространённой ошибкой является использование load в ситуации когда DOMContentLoaded является более подходящим, будьте внимательны.

- -

{{Note("Синхронный JavaScript останавливает парсинг DOM.")}}

- -

{{Note("Существуют различные библиотеки, как общего назначения так и специализированные, предлагающие кросс-браузерные методы, позволяющие определить, что DOM готов к использованию.")}}

- -

Ускорение работы

- -

Если вы хотите чтобы DOM был пройден парсером насколько возможно быстро, сразу после запроса пользователем страницы, вы можете попробовать выполнять JavaScript асинхронно и оптимизировать загрузку таблиц стилей которые обычно замедляют загрузку документа поскольку загружаясь одновременно "крадут" трафик у основного документа.

- -

Основная информация

- -
-
Спецификация
-
HTML5
-
Интерфейс 
-
Event
-
Всплывает
-
Да
-
Отменяемое
-
Да (несмотря на то, что в спецификации указано как простое событие, которое не является отменяемым)
-
Цель 
-
Document
-
Default Action
-
Нет.
-
- -

Свойства

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
СвойствоТипОписание
target {{readonlyInline}}{{domxref("EventTarget")}}The event target (the topmost target in the DOM tree).
type {{readonlyInline}}{{domxref("DOMString")}}Тип события.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Whether the event normally bubbles or not.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Возможно ли отменить событие.
- -

Пример

- -
<script>
-  document.addEventListener("DOMContentLoaded", function(event) {
-    console.log("DOM fully loaded and parsed");
-  });
-</script>
-
- -
<script>
-  document.addEventListener("DOMContentLoaded", function(event) {
-    console.log("DOM fully loaded and parsed");
-  });
-
-for(var i=0; i<1000000000; i++)
-{} // this synchronous script is going to delay parsing of the DOM. So the DOMContentLoaded event is going to launch later.
-</script>
-
- -

Поддержка браузерами

- -

{{CompatibilityTable}}

- - - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка1.0[1]{{CompatGeckoDesktop("1")}}[1]9.0[2]9.03.1[1]
- - - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{CompatVersionUnknown}}[1]{{CompatGeckoMobile("1")}}[1]{{CompatUnknown}}[2]{{CompatVersionUnknown}}{{CompatVersionUnknown}}[1]
- -

[1] Всплытие для этого события поддерживается как минимум с версий Gecko 1.9.2, Chrome 6, и Safari 4.

- -

[2] Internet Explorer 8 поддерживает событие readystatechange, которое можно использовать для определения готовности DOM. В более ранних версиях Internet Explorer,это событие можно определить циклическим выполнением document.documentElement.doScroll("left");, это событие будет выбрасывать ошибку если DOM не готов.

- -

Связанные события

- -
    -
  • {{event("DOMContentLoaded")}}
  • -
  • {{event("readystatechange")}}
  • -
  • {{event("load")}}
  • -
  • {{event("beforeunload")}}
  • -
  • {{event("unload")}}
  • -
diff --git a/files/ru/web/events/error/index.html b/files/ru/web/events/error/index.html deleted file mode 100644 index 787fb9a4fa..0000000000 --- a/files/ru/web/events/error/index.html +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: error -slug: Web/Events/error -tags: - - DOM - - UI события - - Видео - - Запись - - Медия - - Обработка ошибок - - Ошибки - - Событие - - аудио - - события -translation_of: Web/API/Element/error_event ---- -

Событие error возникает, когда произошла какая-либо ошибка. Точные обстоятельства могут быть различными, потому что события с этим именем используются множеством различных API.

- -

Общая информация

- -
-
Спецификация
-
DOM L3
-
Интерфейс
-
{{domxref("UIEvent")}} если создается элементом пользовательского интерфейса, {{domxref("MediaRecorderErrorEvent")}} если генерируется API записи MediaStream, и {{domxref("Event")}} иначе.
-
Вплывающее
-
Нет
-
Отменяемое
-
Нет
-
Цель
-
Элемент
-
Действие по умолчанию
-
Нет
-
- -

Свойства

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyTypeDescription
target {{readonlyInline}}EventTargetЦель события (наиболее верхлежащий элемент в DOM дереве).
type {{readonlyInline}}DOMStringТип события.
bubbles {{readonlyInline}}BooleanЯвляется ли событие вплывающим в стандартных условиях или нет.
cancelable {{readonlyInline}}BooleanЯвляется ли событие отменяемым или нет.
view {{readonlyInline}}WindowProxydocument.defaultView (свойство window объекта document)
detail {{readonlyInline}}long (float)0.
- -

Для MediaStream Recording событий

- -

Эти события типа {{domxref("MediaRecorderErrorEvent")}}.

- -

{{page("/en-US/docs/Web/API/MediaRecorderErrorEvent", "Properties")}}

- -

Смотрите также

- -
-
{{domxref("GlobalEventHandlers.onerror")}}
-
События отсылаются в {{domxref("Window.onerror")}} и {{domxref("Element.onerror")}}
-
{{domxref("HTMLMediaElement.onerror")}}
-
События отсылаются в {{domxref("HTMLMediaElement")}}, включая {{HTMLElement("audio")}} и {{HTMLElement("video")}}
-
{{domxref("MediaRecorder.onerror")}}
-
События отсылаются в {{domxref("MediaRecorder.onerror")}}, типа {{domxref("MediaRecorderErrorEvent")}}
-
diff --git a/files/ru/web/events/focusin/index.html b/files/ru/web/events/focusin/index.html deleted file mode 100644 index 02f27b66fb..0000000000 --- a/files/ru/web/events/focusin/index.html +++ /dev/null @@ -1,123 +0,0 @@ ---- -title: focusin -slug: Web/Events/focusin -translation_of: Web/API/Element/focusin_event ---- -

Событие focusin срабатывает, когда элемент получает фокус. Главное отличие от focus в том, что последний не всплывает.

- -

Общая информация

- -
-
Specification
-
DOM L3
-
Interface
-
{{domxref("FocusEvent")}}
-
Bubbles
-
Yes
-
Cancelable
-
No
-
Target
-
Element
-
Default Action
-
None.
-
- -

Свойства

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyTypeDescription
target {{readonlyInline}}{{domxref("EventTarget")}}Event target losing focus.
type {{readonlyInline}}{{domxref("DOMString")}}The type of event.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Whether the event normally bubbles or not.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Whether the event is cancellable or not.
relatedTarget {{readonlyInline}}{{domxref("EventTarget")}} (DOM element)Event target receiving focus.
- -

Browser compatibility

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatNo}}[1]{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatNo}}[1]{{CompatVersionUnknown}}{{CompatUnknown}}{{CompatVersionUnknown}}
-
- -

[1] Событие пока что не поддерживается в Firefox, см. {{Bug("687787")}}. Вместо него можно использовать событие focus, которое совместимо с делегированием событий.

- - - -
    -
  • {{event("focus")}}
  • -
  • {{event("blur")}}
  • -
  • {{event("focusin")}}
  • -
  • {{event("focusout")}}
  • -
diff --git a/files/ru/web/events/focusout/index.html b/files/ru/web/events/focusout/index.html deleted file mode 100644 index 742f52af03..0000000000 --- a/files/ru/web/events/focusout/index.html +++ /dev/null @@ -1,126 +0,0 @@ ---- -title: focusout -slug: Web/Events/focusout -translation_of: Web/API/Element/focusout_event ---- -

Событие focusout вызывается перед потерей элементом фокуса. Главное отличие между этим событием и blur в том, что у последнего нет фазы всплытия.

- -

 

- -

Основная информация

- -
-
Спецификация
-
DOM L3
-
Интерфейс
-
{{domxref("FocusEvent")}}
-
Всплытие
-
Да
-
Отменяемый
-
Нет
-
Цель
-
Элемент
-
Действие по умолчанию
-
Нет.
-
- -

Свойства

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
СвойствоТипОписание
target {{readonlyInline}}{{domxref("EventTarget")}}Цель события, теряющая фокус.
type {{readonlyInline}}{{domxref("DOMString")}}Тип события.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Всплывает ли событие при нормальных условиях.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Возможно ли отменить событие.
relatedTarget {{readonlyInline}}{{domxref("EventTarget")}} (DOM-элемент)Цель события, получающая фокус.
- -

Browser compatibility

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoDesktop(52)}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoMobile(52)}}{{CompatVersionUnknown}}{{CompatUnknown}}{{CompatVersionUnknown}}
-
- - - -
    -
  • {{event("focus")}}
  • -
  • {{event("blur")}}
  • -
  • {{event("focusin")}}
  • -
diff --git a/files/ru/web/events/load/index.html b/files/ru/web/events/load/index.html deleted file mode 100644 index a8d456806d..0000000000 --- a/files/ru/web/events/load/index.html +++ /dev/null @@ -1,88 +0,0 @@ ---- -title: load -slug: Web/Events/load -translation_of: Web/API/Window/load_event ---- -

Событие load происходит когда ресурс и его зависимые ресурсы закончили загружаться.

- -

General info

- -
-
Спецификация
-
DOM L3
-
Интерфейс
-
UIEvent
-
Всплывает
-
Да
-
Отменяемое
-
Нет
-
Цель
-
Window
-
Default Action
-
Нет.
-
- -

Свойства

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyTypeDescription
target {{readonlyInline}}EventTargetThe event target (the topmost target in the DOM tree).
type {{readonlyInline}}DOMStringThe type of event.
bubbles {{readonlyInline}}BooleanWhether the event normally bubbles or not.
cancelable {{readonlyInline}}BooleanWhether the event is cancellable or not.
view {{readonlyInline}}WindowProxydocument.defaultView (window of the document)
detail {{readonlyInline}}long (float)0.
- -

Пример

- -
<script>
-  window.addEventListener("load", function(event) {
-    console.log("All resources finished loading!");
-  });
-</script>
-
- -

 

- -

Связанные события

- -
    -
  • {{event("DOMContentLoaded")}}
  • -
  • {{event("readystatechange")}}
  • -
  • {{event("load")}}
  • -
  • {{event("beforeunload")}}
  • -
  • {{event("unload")}}
  • -
diff --git a/files/ru/web/events/loadstart/index.html b/files/ru/web/events/loadstart/index.html deleted file mode 100644 index b725b05b30..0000000000 --- a/files/ru/web/events/loadstart/index.html +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: loadstart -slug: Web/Events/loadstart -translation_of: Web/API/XMLHttpRequest/loadstart_event ---- -

Событие loadstart происходит, когда начинается загрузка.

- -

Общая информация

- -
-
Спецификация
-
Progress
-
Интерфейс
-
ProgressEvent
-
Распространяется
-
Нет
-
Отменяемое
-
Нет
-
Цель
-
Element
-
Действие по умолчанию
-
Нет
-
- -

Свойства

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyTypeDescription
target {{readonlyInline}}{{domxref("EventTarget")}}The event target (the topmost target in the DOM tree).
type {{readonlyInline}}{{domxref("DOMString")}}The type of event.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Whether the event normally bubbles or not.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Whether the event is cancellable or not.
lengthComputable {{readonlyInline}}{{jsxref("Boolean")}}Specifies whether or not the total size of the transfer is known. Read only.
loaded {{readonlyInline}}unsigned long (long)The number of bytes transferred since the beginning of the operation. This doesn't include headers and other overhead, but only the content itself. Read only.
total {{readonlyInline}}unsigned long (long)The total number of bytes of content that will be transferred during the operation. If the total size is unknown, this value is zero. Read only.
- -

Связанные свойства

- -
    -
  • {{event("loadstart")}}
  • -
  • {{event("progress")}}
  • -
  • {{event("error")}}
  • -
  • {{event("abort")}}
  • -
  • {{event("load")}}
  • -
  • {{event("loadend")}}
  • -
- -

См. также

- - diff --git a/files/ru/web/events/readystatechange/index.html b/files/ru/web/events/readystatechange/index.html deleted file mode 100644 index 5a268b033f..0000000000 --- a/files/ru/web/events/readystatechange/index.html +++ /dev/null @@ -1,90 +0,0 @@ ---- -title: readystatechange -slug: Web/Events/readystatechange -tags: - - события -translation_of: Web/API/Document/readystatechange_event ---- -

{{ApiRef}}

- -

Событие readystatechange срабатывает, когда изменяется атрибут документа readyState.

- -

Основная информация

- -
-
Спецификация
-
HTML5
-
 
-
Интерфейс
-
Event
-
Всплывает
-
Нет
-
Отменяемое
-
Нет
-
Цель
-
Document
-
Действие по умолчаанию
-
Нет
-
- -

Свойства

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
СвойствоТипОписание
target {{readonlyInline}}{{domxref("EventTarget")}}Цель события (Самая верхняя цель в дереве DOM).
type {{readonlyInline}}{{domxref("DOMString")}}Тип события.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Всплывает ли событие.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Возможно ли отменить событие.
- -

Примеры

- -
document.readyState === "complete";
-// true
-
-
-// Альтернатива DOMContentLoaded
-document.onreadystatechange = function () {
-    if (document.readyState === "interactive") {
-        initApplication();
-    }
-}
-
- -

Поддержка браузерами

- -

Данное событие давно поддерживается Internet Explorer и может быть использовано в качестве альтернативы событию DOMContentLoaded (см. примечание [2] в разделе  Поддержка браузерами).

- -

Связанные события

- -
    -
  • {{event("DOMContentLoaded")}}
  • -
  • {{event("readystatechange")}}
  • -
  • {{event("load")}}
  • -
  • {{event("beforeunload")}}
  • -
  • {{event("unload")}}
  • -
diff --git a/files/ru/web/events/transitionend/index.html b/files/ru/web/events/transitionend/index.html deleted file mode 100644 index dfb8542da6..0000000000 --- a/files/ru/web/events/transitionend/index.html +++ /dev/null @@ -1,165 +0,0 @@ ---- -title: transitionend -slug: Web/Events/transitionend -tags: - - CSS -translation_of: Web/API/HTMLElement/transitionend_event ---- -

Событие transitionend срабатывает, когда CSS transition закончил свое выполнение. В случае, когда анимация удаляется до ее завершения(например, если transition-property [en-US] удаляется), то событие не срабатывает.

- -

Общая информация

- -
-
Интерфейс
-
{{domxref("TransitionEvent")}}
-
Всплывает
-
Да
-
Отменяемое
-
Да
-
Элемент
-
{{domxref("document")}}, {{domxref("element")}}
-
Действие по умолчанию
-
Нет
-
- -

Свойства

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyTypeDescription
target {{readonlyInline}}{{domxref("EventTarget")}}The event target (the topmost target in the DOM tree).
type {{readonlyInline}}{{domxref("DOMString")}}The type of event.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Whether the event normally bubbles or not.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Whether the event is cancellable or not.
propertyName {{readonlyInline}}{{domxref("DOMString")}}The name of the CSS property associated with the transition.
elapsedTime {{readonlyInline}}FloatThe amount of time the transition has been running, in seconds, as of the time the event was generated. This value is not affected by the value of transition-delay.
pseudoElement {{readonlyInline}}{{domxref("DOMString")}}The name (beginning with two colons) of the CSS pseudo-element on which the transition occured (in which case the target of the event is that pseudo-element's corresponding element), or the empty string if the transition occurred on an element (which means the target of the event is that element).
- -

Пример

- -
/*
- * Прослушивать событие transitionend на определенном элементе, т.е. #slidingMenu
- * Затем, вызвать определенную функцию, т.е. showMessage()
- */
-function showMessage() {
-    alert('Transition закончил свое выполнение');
-}
-
-var element = document.getElementById("slidingMenu");
-element.addEventListener("transitionend", showMessage, false);
-
- -

Спецификация

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName("CSS3 Transitions", "#transition-events", "transitionend")}}{{ Spec2('CSS3 Transitions') }}Initial definition.
- -

Совместимость с браузерами

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support1.0 as webkitTransitionEnd{{ CompatGeckoDesktop("2.0") }}1010.5 as oTransitionEnd
- 12 as otransitionend
- 12.10 as transitionend
3.2 as webkitTransitionEnd
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support2.1 as webkitTransitionEnd{{ CompatGeckoMobile("2.0") }}{{ CompatUnknown() }}10 as oTransitionEnd
- 12 as otransitionend
- 12.10 as transitionend
3.2 as webkitTransitionEnd
-
- -

Также

- -
    -
  • The {{ domxref("TransitionEvent") }} interface and the transitionend event.
  • -
diff --git a/files/ru/web/events/unhandledrejection/index.html b/files/ru/web/events/unhandledrejection/index.html deleted file mode 100644 index 5248e75748..0000000000 --- a/files/ru/web/events/unhandledrejection/index.html +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: unhandledrejection -slug: Web/Events/unhandledrejection -translation_of: Web/API/Window/unhandledrejection_event ---- -

Событие unhandledrejection происходит, когда {{jsxref("Promise")}} завершен с ошибкой, но на данную ошибку не установлен обработчик.

- - - - - - - - - - - - - - - - - - - - -
ВсплытиеНет
Возможность отменыНет
Target objectsdefaultView
Интерфейс{{domxref("PromiseRejectionEvent")}}
- -

Пример

- -
window.addEventListener("unhandledrejection", function (event) {
-  console.warn("Внимание: Необработанная ошибка Promise. Позор вам! Причина: "
-               + event.reason);
-});
-
- -

Inheritance

- -

Событие unhandledrejection реализует {{domxref("PromiseRejectionEvent")}} интерфейс, который наследуется от {{domxref("Event")}}. Вы можете использовать свойства и методы, определенные в данных интерфейсах.

- -

{{InheritanceDiagram('','','', 'PromiseRejectionEvent')}}

- -

Смотрите также

- -
    -
  • {{Event("rejectionhandled")}}
  • -
  • {{domxref("PromiseRejectionEvent")}}
  • -
  • {{domxref("Promise")}}
  • -
diff --git a/files/ru/web/guide/ajax/getting_started/index.html b/files/ru/web/guide/ajax/getting_started/index.html new file mode 100644 index 0000000000..e06b408228 --- /dev/null +++ b/files/ru/web/guide/ajax/getting_started/index.html @@ -0,0 +1,258 @@ +--- +title: С чего начать +slug: Web/Guide/AJAX/С_чего_начать +tags: + - AJAX +translation_of: Web/Guide/AJAX/Getting_Started +--- +

 

+ +

В этой статье рассмотрены основные принципы работы AJAX и даны два простых примера, использующих эту технологию.

+ +

Что такое AJAX?

+ +

Ajax означает Асинхронный JavaScript и XML. В основе технологии лежит использование нестандартного объекта XMLHttpRequest, необходимого для взаимодействия со скриптами на стороне сервера. Объект может как отправлять, так и получать информацию в различных форматах включая XML, HTML и даже текстовые файлы. Самое привлекательное в Ajax — это его асинхронный принцип работы. С помощью этой технологии можно осуществлять взаимодействие с сервером без необходимости перезагрузки страницы. Это позволяет обновлять содержимое страницы частично, в зависимости от действий пользователя.

+ +

Две особенности, которые мы рассмотрим:

+ +
    +
  • Отправление запросов серверу без перезагрузки страницы
  • +
  • Работа с XML документами
  • +
+ +

Шаг 1 — Как послать HTTP запрос

+ +

Для того, чтобы послать HTTP запрос на сервер используя JavaScript, вам необходим экземпляр класса, который позволит это сделать. Такой класс впервые был введен в Internet Explorer как объект ActiveX, называемый XMLHTTP. Позже в Mozilla, Safari и другие браузеры был введен класс XMLHttpRequest, который поддерживал методы и свойства изначального объекта ActiveX от Microsoft.

+ +

В результате, чтобы создать кросс-браузерный объект требуемого класса, вы можете сделать следующее:

+ +
var httpRequest;
+if (window.XMLHttpRequest) { // Mozilla, Safari, ...
+    httpRequest = new XMLHttpRequest();
+} else if (window.ActiveXObject) { // IE
+    httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
+}
+
+ +

(В целях наглядности, код выше является немного упрощенным. Более жизненный пример будет рассмотрен в шаге 3 этой статьи)

+ +

Некоторые версии некоторых броузеров Mozilla не будут корректно работать, если ответ сервера не содержит заголовка XML mime-type. Чтобы решить эту проблему, вы можете использовать вызовы дополнительных методов для переопределения заголовка полученного от сервера, если он отличен от text/xml.

+ +
httpRequest = new XMLHttpRequest();
+httpRequest.overrideMimeType('text/xml');
+
+ +

Далее вам необходимо решить, что вы будете делать после получения ответа сервера. На этом этапе вам необходимо указать объекту, какая JavaScript функция будет обрабатывать ответ. Это делается путем присваивания свойству onreadystatechange имени JavaScript функции, которую вы собираетесь использовать:

+ +

httpRequest.onreadystatechange = nameOfTheFunction;

+ +

Заметьте, что после названия функции нет скобок и не указано параметров, потому что вы просто присваиваете ссылку на функцию, а не вызываете ее. К тому же, вместо указания имени функции, вы можете использовать возможность JavaScript объявлять функции на лету (так называемые «анонимные функции») и указывать действия, которые тотчас же будут обрабатывать ответ:

+ +
httpRequest.onreadystatechange = function(){
+    // какой-нибудь код
+};
+
+ +

Далее, после того как вы объявили что будет происходить после получения ответа, вам необходимо сделать запрос. Вы должны вызвать методы класса open() и send():

+ +
httpRequest.open('GET', 'http://www.example.org/some.file', true);
+httpRequest.send(null);
+
+ +
    +
  • Первый параметр вызова функции open() — метод HTTP запроса (GET, POST, HEAD или любой другой метод, который вы хотите использовать). Используйте методы в соответствии с HTTP стандартами, иначе некоторые браузеры (такие как Firefox) могут не обработать запрос. Информация о допустимых HTTP запросах доступна по адресу спецификации W3C
  • +
  • Второй параметр — URL запрашиваемой страницы. Из соображений безопасности возможность запрашивать страницы сторонних доменов недоступна. Убедитесь, что вы используете одинаковое доменное имя на всех страницах, иначе вы получите ошибку 'доступ запрещен' при вызове функции open(). Типичной ошибкой при доступе к сайту через site.ru является отправка запроса на www.site.ru.
  • +
  • Третий параметр указывает, является ли запрос асинхронным. Если он TRUE, то выполнение JavaScript продолжится во время ожидания ответа сервера. В этом и заключается асинхронность технологии.
  • +
+ +

Параметром метода send() могут быть любые данные, которые вы хотите послать на сервер. Данные должны быть сформированы в строку запроса:

+ +

name=value&anothername=othervalue&so=on

+ +

Заметьте, что если вы хотите отправить данные методом POST, вы должны изменить MIME-тип запроса с помощью следующей строки:

+ +
httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+
+ +

Иначе сервер проигнорирует данные отправленные методом POST.

+ +

Шаг 2 — Обрабатываем ответ сервера

+ +

Отправляя запрос, вы указали имя функции JavaScript, обрабатывающей ответ.

+ +

httpRequest.onreadystatechange = nameOfTheFunction;

+ +

Давайте посмотрим, что эта функция должна делать. Во-первых, функция должна проверять статус запроса. Если значение переменной статуса 4, то это означает, что ответ от сервера получен и его можно обрабатывать.

+ +
if (httpRequest.readyState == 4) {
+    // все в порядке, ответ получен
+} else {
+    // все еще не готово
+}
+
+ +

Полный список значений кодов readyState такой:

+ +
    +
  • 0 (uninitialized)
  • +
  • 1 (loading)
  • +
  • 2 (loaded)
  • +
  • 3 (interactive)
  • +
  • 4 (complete)
  • +
+ +

(Источник)

+ +

Следующее, что нужно проверить — это статус HTTP-ответа. Все возможные коды можно посмотреть на сайте W3C. Для наших целей нам интересен только код ответа 200 OK.

+ +
if (httpRequest.status == 200) {
+    // великолепно!
+} else {
+    // с запросом возникли проблемы,
+    // например, ответ может быть 404 (Не найдено)
+    // или 500 (Внутренняя ошибка сервера)
+}
+
+ +

Теперь, после проверки состояния запроса и статуса HTTP-ответа, вы можете делать с данными, полученными от сервера, все что угодно. Есть два способа получить доступ к данным:

+ +
    +
  • httpRequest.responseText – возвращает ответ сервера в виде строки текста.
  • +
  • httpRequest.responseXML – возвращает ответ сервера в виде объекта XMLDocument, который вы можете обходить используя функции JavaScript DOM
  • +
+ +

Шаг 3 — Простой пример

+ +

Давайте соберем все вместе и сделаем простой пример HTTP-запроса. Наш JavaScript запросит HTML документ test.html, который содержит текст "I'm a test." и выведет содержимое файла в диалоговом окне.

+ +
<script type="text/javascript" language="javascript">
+    function makeRequest(url) {
+        var httpRequest = false;
+
+        if (window.XMLHttpRequest) { // Mozilla, Safari, ...
+            httpRequest = new XMLHttpRequest();
+            if (httpRequest.overrideMimeType) {
+                httpRequest.overrideMimeType('text/xml');
+                // Читайте ниже об этой строке
+            }
+        } else if (window.ActiveXObject) { // IE
+            try {
+                httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
+            } catch (e) {
+                try {
+                    httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
+                } catch (e) {}
+            }
+        }
+
+        if (!httpRequest) {
+            alert('Не вышло :( Невозможно создать экземпляр класса XMLHTTP ');
+            return false;
+        }
+        httpRequest.onreadystatechange = function() { alertContents(httpRequest); };
+        httpRequest.open('GET', url, true);
+        httpRequest.send(null);
+
+    }
+
+    function alertContents(httpRequest) {
+
+        if (httpRequest.readyState == 4) {
+            if (httpRequest.status == 200) {
+                alert(httpRequest.responseText);
+            } else {
+                alert('С запросом возникла проблема.');
+            }
+        }
+
+    }
+</script>
+<span
+    style="cursor: pointer; text-decoration: underline"
+    onclick="makeRequest('test.html')">
+        Сделать запрос
+</span>
+
+ +


+ В этом примере:

+ +
    +
  • Пользователь нажимает на ссылку "Сделать запрос" в броузере;
  • +
  • Это вызывает функцию makeRequest() с параметром test.html — именем HTML файла;
  • +
  • Посылается запрос, после чего (onreadystatechange) выполнение передается alertContents();
  • +
  • alertContents() проверяет получен ли ответ и все ли с ним в порядке, после чего содержимое файла test.html выводится в диалоговом окне.
  • +
+ +

Вы можете попробовать пример в действии здесь, а сам тестовый файл можно посмотреть здесь.

+ +

Замечание: Строка httpRequest.overrideMimeType('text/xml'); вызовет ошибки в консоли JavaScript в Firefox 1.5 или более позднем, как описано в https://bugzilla.mozilla.org/show_bug.cgi?id=311724, если страница вызванная с помощью XMLHttpRequest не является правильным XML (например, если это обычный текст). На самом деле это корректное поведение.

+ +

Замечание 2: Если вы посылаете запрос не на статический XML-файл, а на серверный скрипт, возвращающий XML, то нужно установить некоторые заголовки ответа, если вы планируете сделать вашу страницу работоспособной в Internet Explorer помимо Mozilla. Если вы не установите заголовок Content-Type: application/xml, IE будет сообщать об ошибке JavaScript, 'Object Expected', после строки, где вы пытаетесь получить доступ к XML элементу. Если вы не установите заголовок Cache-Control: no-cache броузер будет кэшировать ответ и никогда не будет повторно отправлять запрос, что сделает отладку весьма «забавной».

+ +

Замечание 3: Если переменная httpRequest используется глобально, то конкурирующие функции, вызывающие makeRequest() могут конкурировать друг с другом, вызывая состязания. Объявление переменной httpRequest локально в функции и передача ее в alertContent() предотвращает состязания.

+ +

Замечание 4: При привязывании функции обратного вызова к onreadystatechange нельзя указывать аргументов. По этой причине не работает следующий код:

+ +
httpRequest.onreadystatechange = alertContents(httpRequest); // (не работает)
+
+ +

Таким образом, для успешной регистрации функции, вы должны передать ей аргументы косвенно через анонимную функцию или используя httpRequest как глобальную переменную. Вот пример:

+ +
httpRequest.onreadystatechange = function() { alertContents(httpRequest); };  //1 (одновременный запрос)
+httpRequest.onreadystatechange = alertContents;  //2 (глобальная переменная)
+
+ +

Первый способ позволяет делать несколько запросов одновременно, а второй используется, когда переменная httpRequest является глобальной.

+ +

Замечание 5: В случае ошибки взаимодействия (например, если сервер упал), при попытке доступа к переменной .status метода onreadystatechange будет сгенерировано исключение. Убедитесь, что if...then заключено в try...catch. (См. https://bugzilla.mozilla.org/show_bug.cgi?id=238559).

+ +
function alertContents(httpRequest) {
+
+        try {
+            if (httpRequest.readyState == 4) {
+                if (httpRequest.status == 200) {
+                    alert(httpRequest.responseText);
+                } else {
+                    alert('С запросом возникла проблема.');
+                }
+            }
+        }
+        catch( e ) {
+            alert('Произошло исключение: ' + e.description);
+        }
+
+    }
+
+ +

Шаг 4 — Работа с XML ответом

+ +

В предыдущем примере, после того как был получен ответ на HTTP-запрос мы использовали responseText запрашиваемого объекта, который содержал данные файла test.html. Теперь давайте попробуем использовать свойство responseXML.

+ +

Прежде всего, давайте создадим правильный XML документ, который мы будем запрашивать. Документ (test.xml) содержит следующее:

+ +
<?xml version="1.0" ?>
+<root>
+    I'm a test.
+</root>
+
+ +

В скрипте нам всего лишь необходимо заменить строку запроса на:

+ +
...
+onclick="makeRequest('test.xml')">
+...
+
+ +

Далее в alertContents() нам нужно заменить строку alert(httpRequest.responseText); на:

+ +
var xmldoc = httpRequest.responseXML;
+var root_node = xmldoc.getElementsByTagName('root').item(0);
+alert(root_node.firstChild.data);
+
+ +

Этот код берет объект XMLDocument, возвращаемый responseXML и использует методы DOM для доступа к данным, содержащимся в документе XML. Посмотреть test.xml можно здесь, а обновленный скрипт здесь.

+ +

Чтобы узнать больше о методах DOM, посмотрите реализация DOM в Mozilla.

+ +

{{ languages( { "ca": "ca/AJAX/Primers_passos", "de": "de/AJAX/Getting_Started", "en": "en/AJAX/Getting_Started", "es": "es/AJAX/Primeros_Pasos", "fr": "fr/AJAX/Premiers_pas", "it": "it/AJAX/Iniziare", "ja": "ja/AJAX/Getting_Started", "ko": "ko/AJAX/Getting_Started", "pl": "pl/AJAX/Na_pocz\u0105tek", "pt": "pt/AJAX/Como_come\u00e7ar", "zh-cn": "cn/AJAX/\u5f00\u59cb" } ) }}

diff --git "a/files/ru/web/guide/ajax/\321\201_\321\207\320\265\320\263\320\276_\320\275\320\260\321\207\320\260\321\202\321\214/index.html" "b/files/ru/web/guide/ajax/\321\201_\321\207\320\265\320\263\320\276_\320\275\320\260\321\207\320\260\321\202\321\214/index.html" deleted file mode 100644 index e06b408228..0000000000 --- "a/files/ru/web/guide/ajax/\321\201_\321\207\320\265\320\263\320\276_\320\275\320\260\321\207\320\260\321\202\321\214/index.html" +++ /dev/null @@ -1,258 +0,0 @@ ---- -title: С чего начать -slug: Web/Guide/AJAX/С_чего_начать -tags: - - AJAX -translation_of: Web/Guide/AJAX/Getting_Started ---- -

 

- -

В этой статье рассмотрены основные принципы работы AJAX и даны два простых примера, использующих эту технологию.

- -

Что такое AJAX?

- -

Ajax означает Асинхронный JavaScript и XML. В основе технологии лежит использование нестандартного объекта XMLHttpRequest, необходимого для взаимодействия со скриптами на стороне сервера. Объект может как отправлять, так и получать информацию в различных форматах включая XML, HTML и даже текстовые файлы. Самое привлекательное в Ajax — это его асинхронный принцип работы. С помощью этой технологии можно осуществлять взаимодействие с сервером без необходимости перезагрузки страницы. Это позволяет обновлять содержимое страницы частично, в зависимости от действий пользователя.

- -

Две особенности, которые мы рассмотрим:

- -
    -
  • Отправление запросов серверу без перезагрузки страницы
  • -
  • Работа с XML документами
  • -
- -

Шаг 1 — Как послать HTTP запрос

- -

Для того, чтобы послать HTTP запрос на сервер используя JavaScript, вам необходим экземпляр класса, который позволит это сделать. Такой класс впервые был введен в Internet Explorer как объект ActiveX, называемый XMLHTTP. Позже в Mozilla, Safari и другие браузеры был введен класс XMLHttpRequest, который поддерживал методы и свойства изначального объекта ActiveX от Microsoft.

- -

В результате, чтобы создать кросс-браузерный объект требуемого класса, вы можете сделать следующее:

- -
var httpRequest;
-if (window.XMLHttpRequest) { // Mozilla, Safari, ...
-    httpRequest = new XMLHttpRequest();
-} else if (window.ActiveXObject) { // IE
-    httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
-}
-
- -

(В целях наглядности, код выше является немного упрощенным. Более жизненный пример будет рассмотрен в шаге 3 этой статьи)

- -

Некоторые версии некоторых броузеров Mozilla не будут корректно работать, если ответ сервера не содержит заголовка XML mime-type. Чтобы решить эту проблему, вы можете использовать вызовы дополнительных методов для переопределения заголовка полученного от сервера, если он отличен от text/xml.

- -
httpRequest = new XMLHttpRequest();
-httpRequest.overrideMimeType('text/xml');
-
- -

Далее вам необходимо решить, что вы будете делать после получения ответа сервера. На этом этапе вам необходимо указать объекту, какая JavaScript функция будет обрабатывать ответ. Это делается путем присваивания свойству onreadystatechange имени JavaScript функции, которую вы собираетесь использовать:

- -

httpRequest.onreadystatechange = nameOfTheFunction;

- -

Заметьте, что после названия функции нет скобок и не указано параметров, потому что вы просто присваиваете ссылку на функцию, а не вызываете ее. К тому же, вместо указания имени функции, вы можете использовать возможность JavaScript объявлять функции на лету (так называемые «анонимные функции») и указывать действия, которые тотчас же будут обрабатывать ответ:

- -
httpRequest.onreadystatechange = function(){
-    // какой-нибудь код
-};
-
- -

Далее, после того как вы объявили что будет происходить после получения ответа, вам необходимо сделать запрос. Вы должны вызвать методы класса open() и send():

- -
httpRequest.open('GET', 'http://www.example.org/some.file', true);
-httpRequest.send(null);
-
- -
    -
  • Первый параметр вызова функции open() — метод HTTP запроса (GET, POST, HEAD или любой другой метод, который вы хотите использовать). Используйте методы в соответствии с HTTP стандартами, иначе некоторые браузеры (такие как Firefox) могут не обработать запрос. Информация о допустимых HTTP запросах доступна по адресу спецификации W3C
  • -
  • Второй параметр — URL запрашиваемой страницы. Из соображений безопасности возможность запрашивать страницы сторонних доменов недоступна. Убедитесь, что вы используете одинаковое доменное имя на всех страницах, иначе вы получите ошибку 'доступ запрещен' при вызове функции open(). Типичной ошибкой при доступе к сайту через site.ru является отправка запроса на www.site.ru.
  • -
  • Третий параметр указывает, является ли запрос асинхронным. Если он TRUE, то выполнение JavaScript продолжится во время ожидания ответа сервера. В этом и заключается асинхронность технологии.
  • -
- -

Параметром метода send() могут быть любые данные, которые вы хотите послать на сервер. Данные должны быть сформированы в строку запроса:

- -

name=value&anothername=othervalue&so=on

- -

Заметьте, что если вы хотите отправить данные методом POST, вы должны изменить MIME-тип запроса с помощью следующей строки:

- -
httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
-
- -

Иначе сервер проигнорирует данные отправленные методом POST.

- -

Шаг 2 — Обрабатываем ответ сервера

- -

Отправляя запрос, вы указали имя функции JavaScript, обрабатывающей ответ.

- -

httpRequest.onreadystatechange = nameOfTheFunction;

- -

Давайте посмотрим, что эта функция должна делать. Во-первых, функция должна проверять статус запроса. Если значение переменной статуса 4, то это означает, что ответ от сервера получен и его можно обрабатывать.

- -
if (httpRequest.readyState == 4) {
-    // все в порядке, ответ получен
-} else {
-    // все еще не готово
-}
-
- -

Полный список значений кодов readyState такой:

- -
    -
  • 0 (uninitialized)
  • -
  • 1 (loading)
  • -
  • 2 (loaded)
  • -
  • 3 (interactive)
  • -
  • 4 (complete)
  • -
- -

(Источник)

- -

Следующее, что нужно проверить — это статус HTTP-ответа. Все возможные коды можно посмотреть на сайте W3C. Для наших целей нам интересен только код ответа 200 OK.

- -
if (httpRequest.status == 200) {
-    // великолепно!
-} else {
-    // с запросом возникли проблемы,
-    // например, ответ может быть 404 (Не найдено)
-    // или 500 (Внутренняя ошибка сервера)
-}
-
- -

Теперь, после проверки состояния запроса и статуса HTTP-ответа, вы можете делать с данными, полученными от сервера, все что угодно. Есть два способа получить доступ к данным:

- -
    -
  • httpRequest.responseText – возвращает ответ сервера в виде строки текста.
  • -
  • httpRequest.responseXML – возвращает ответ сервера в виде объекта XMLDocument, который вы можете обходить используя функции JavaScript DOM
  • -
- -

Шаг 3 — Простой пример

- -

Давайте соберем все вместе и сделаем простой пример HTTP-запроса. Наш JavaScript запросит HTML документ test.html, который содержит текст "I'm a test." и выведет содержимое файла в диалоговом окне.

- -
<script type="text/javascript" language="javascript">
-    function makeRequest(url) {
-        var httpRequest = false;
-
-        if (window.XMLHttpRequest) { // Mozilla, Safari, ...
-            httpRequest = new XMLHttpRequest();
-            if (httpRequest.overrideMimeType) {
-                httpRequest.overrideMimeType('text/xml');
-                // Читайте ниже об этой строке
-            }
-        } else if (window.ActiveXObject) { // IE
-            try {
-                httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
-            } catch (e) {
-                try {
-                    httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
-                } catch (e) {}
-            }
-        }
-
-        if (!httpRequest) {
-            alert('Не вышло :( Невозможно создать экземпляр класса XMLHTTP ');
-            return false;
-        }
-        httpRequest.onreadystatechange = function() { alertContents(httpRequest); };
-        httpRequest.open('GET', url, true);
-        httpRequest.send(null);
-
-    }
-
-    function alertContents(httpRequest) {
-
-        if (httpRequest.readyState == 4) {
-            if (httpRequest.status == 200) {
-                alert(httpRequest.responseText);
-            } else {
-                alert('С запросом возникла проблема.');
-            }
-        }
-
-    }
-</script>
-<span
-    style="cursor: pointer; text-decoration: underline"
-    onclick="makeRequest('test.html')">
-        Сделать запрос
-</span>
-
- -


- В этом примере:

- -
    -
  • Пользователь нажимает на ссылку "Сделать запрос" в броузере;
  • -
  • Это вызывает функцию makeRequest() с параметром test.html — именем HTML файла;
  • -
  • Посылается запрос, после чего (onreadystatechange) выполнение передается alertContents();
  • -
  • alertContents() проверяет получен ли ответ и все ли с ним в порядке, после чего содержимое файла test.html выводится в диалоговом окне.
  • -
- -

Вы можете попробовать пример в действии здесь, а сам тестовый файл можно посмотреть здесь.

- -

Замечание: Строка httpRequest.overrideMimeType('text/xml'); вызовет ошибки в консоли JavaScript в Firefox 1.5 или более позднем, как описано в https://bugzilla.mozilla.org/show_bug.cgi?id=311724, если страница вызванная с помощью XMLHttpRequest не является правильным XML (например, если это обычный текст). На самом деле это корректное поведение.

- -

Замечание 2: Если вы посылаете запрос не на статический XML-файл, а на серверный скрипт, возвращающий XML, то нужно установить некоторые заголовки ответа, если вы планируете сделать вашу страницу работоспособной в Internet Explorer помимо Mozilla. Если вы не установите заголовок Content-Type: application/xml, IE будет сообщать об ошибке JavaScript, 'Object Expected', после строки, где вы пытаетесь получить доступ к XML элементу. Если вы не установите заголовок Cache-Control: no-cache броузер будет кэшировать ответ и никогда не будет повторно отправлять запрос, что сделает отладку весьма «забавной».

- -

Замечание 3: Если переменная httpRequest используется глобально, то конкурирующие функции, вызывающие makeRequest() могут конкурировать друг с другом, вызывая состязания. Объявление переменной httpRequest локально в функции и передача ее в alertContent() предотвращает состязания.

- -

Замечание 4: При привязывании функции обратного вызова к onreadystatechange нельзя указывать аргументов. По этой причине не работает следующий код:

- -
httpRequest.onreadystatechange = alertContents(httpRequest); // (не работает)
-
- -

Таким образом, для успешной регистрации функции, вы должны передать ей аргументы косвенно через анонимную функцию или используя httpRequest как глобальную переменную. Вот пример:

- -
httpRequest.onreadystatechange = function() { alertContents(httpRequest); };  //1 (одновременный запрос)
-httpRequest.onreadystatechange = alertContents;  //2 (глобальная переменная)
-
- -

Первый способ позволяет делать несколько запросов одновременно, а второй используется, когда переменная httpRequest является глобальной.

- -

Замечание 5: В случае ошибки взаимодействия (например, если сервер упал), при попытке доступа к переменной .status метода onreadystatechange будет сгенерировано исключение. Убедитесь, что if...then заключено в try...catch. (См. https://bugzilla.mozilla.org/show_bug.cgi?id=238559).

- -
function alertContents(httpRequest) {
-
-        try {
-            if (httpRequest.readyState == 4) {
-                if (httpRequest.status == 200) {
-                    alert(httpRequest.responseText);
-                } else {
-                    alert('С запросом возникла проблема.');
-                }
-            }
-        }
-        catch( e ) {
-            alert('Произошло исключение: ' + e.description);
-        }
-
-    }
-
- -

Шаг 4 — Работа с XML ответом

- -

В предыдущем примере, после того как был получен ответ на HTTP-запрос мы использовали responseText запрашиваемого объекта, который содержал данные файла test.html. Теперь давайте попробуем использовать свойство responseXML.

- -

Прежде всего, давайте создадим правильный XML документ, который мы будем запрашивать. Документ (test.xml) содержит следующее:

- -
<?xml version="1.0" ?>
-<root>
-    I'm a test.
-</root>
-
- -

В скрипте нам всего лишь необходимо заменить строку запроса на:

- -
...
-onclick="makeRequest('test.xml')">
-...
-
- -

Далее в alertContents() нам нужно заменить строку alert(httpRequest.responseText); на:

- -
var xmldoc = httpRequest.responseXML;
-var root_node = xmldoc.getElementsByTagName('root').item(0);
-alert(root_node.firstChild.data);
-
- -

Этот код берет объект XMLDocument, возвращаемый responseXML и использует методы DOM для доступа к данным, содержащимся в документе XML. Посмотреть test.xml можно здесь, а обновленный скрипт здесь.

- -

Чтобы узнать больше о методах DOM, посмотрите реализация DOM в Mozilla.

- -

{{ languages( { "ca": "ca/AJAX/Primers_passos", "de": "de/AJAX/Getting_Started", "en": "en/AJAX/Getting_Started", "es": "es/AJAX/Primeros_Pasos", "fr": "fr/AJAX/Premiers_pas", "it": "it/AJAX/Iniziare", "ja": "ja/AJAX/Getting_Started", "ko": "ko/AJAX/Getting_Started", "pl": "pl/AJAX/Na_pocz\u0105tek", "pt": "pt/AJAX/Como_come\u00e7ar", "zh-cn": "cn/AJAX/\u5f00\u59cb" } ) }}

diff --git "a/files/ru/web/guide/ajax/\321\201_\321\207\320\265\320\263\320\276_\320\275\320\260\321\207\320\260\321\202\321\214_question_/index.html" "b/files/ru/web/guide/ajax/\321\201_\321\207\320\265\320\263\320\276_\320\275\320\260\321\207\320\260\321\202\321\214_question_/index.html" deleted file mode 100644 index f66d6b1dbf..0000000000 --- "a/files/ru/web/guide/ajax/\321\201_\321\207\320\265\320\263\320\276_\320\275\320\260\321\207\320\260\321\202\321\214_question_/index.html" +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: С чего начать? -slug: Web/Guide/AJAX/С_чего_начать? ---- -

IKFIA -

diff --git a/files/ru/web/guide/api/dom/index.html b/files/ru/web/guide/api/dom/index.html deleted file mode 100644 index 1671813170..0000000000 --- a/files/ru/web/guide/api/dom/index.html +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: DOM developer guide -slug: Web/Guide/API/DOM -tags: - - API - - DOM - - Guide - - NeedsContent - - NeedsTranslation - - TopicStub -translation_of: Web/API/Document_Object_Model -translation_of_original: Web/Guide/API/DOM ---- -

{{draft}}

- -

Объектная модель документа - это API для документов HTML и XML. Она обеспечивает структурное представление документа, позволяя разработчику изменять его содержание и визуальное представление. По сути, она соединяет веб-страницы со скриптами или языками программирования.

- -

Все свойства, методы и события, доступные веб-разработчику для манипулирования и создания веб-страниц, организованы в объекты (например, объект документа, представляющий сам документ, объект таблицы, представляющий элемент таблицы HTML и т. Д.) , Эти объекты доступны через скриптовые языки в самых последних веб-браузерах.

- -

DOM чаще всего используется в сочетании с JavaScript. Тем не менее, DOM был разработан, чтобы быть независимым от какого-либо конкретного языка программирования, делая структурное представление документа доступным из единого, согласованного API. Хотя мы,на этом сайте, сосредоточены на JavaScript реализации DOM могут быть построены для любого языка.

- -

Консорциум World Wide Web устанавливает стандарт для DOM, называемый W3C DOM. Теперь, когда наиболее важные браузеры правильно его реализуют, следует включить мощные кросс-браузерные приложения.

- -

Почему так важен DOM?

- -

"Dynamic HTML" (DHTML) это термин, используемый некоторыми поставщиками для описания комбинации HTML, таблиц стилей и сценариев, позволяющих анимировать документы. Рабочая группа W3C DOM усердно работает над тем, чтобы согласовать совместимые и не зависящие от языка решения (см. также W3C FAQ).

- -

Поскольку Mozilla претендует на звание «Платформа веб-приложений», поддержка DOM является одной из наиболее востребованных функций и необходимой, если Mozilla хочет стать жизнеспособной альтернативой другим браузерам. Пользовательский интерфейс Mozilla (также Firefox и Thunderbird) построен с использованием XUL, используя DOM для управления собственным пользовательским  интерфейсом UI.

- -

More about the DOM

- -

{{LandingPageListSubpages}}

- - - -

«Динамический HTML» (DHTML) - это термин, используемый некоторыми поставщиками для описания комбинации HTML, таблиц стилей и сценариев, позволяющих анимировать документы. Рабочая группа W3C DOM усердно работает над тем, чтобы согласовать совместимые и не зависящие от языка решения (см. Также FAQ по W3C).

- -

Поскольку Mozilla претендует на звание «Платформа веб-приложений», поддержка DOM является одной из наиболее востребованных функций и необходимой, если Mozilla хочет стать жизнеспособной альтернативой другим браузерам. Пользовательский интерфейс Mozilla (также Firefox и Thunderbird) построен с использованием XUL, используя DOM для управления собственным пользовательским интерфейсом.

diff --git a/files/ru/web/guide/api/dom/storage/index.html b/files/ru/web/guide/api/dom/storage/index.html deleted file mode 100644 index b63a374c8c..0000000000 --- a/files/ru/web/guide/api/dom/storage/index.html +++ /dev/null @@ -1,368 +0,0 @@ ---- -title: DOM Storage guide -slug: Web/Guide/API/DOM/Storage -translation_of: Web/API/Web_Storage_API -translation_of_original: Web/Guide/API/DOM/Storage ---- -

 

- -

DOM хранилище (DOM Storage) - это название для набора инструментов, относящихся к хранилищам, впервые представленных в спецификации Web Applications 1.0,  и выделенных теперь в отдельную специкацию W3C Web Storage. DOM хранилище было разработано с целью предоставления альтернативы хранению информации в кукисах. Предполагается, что DOM хранилище предоставляет больше объема, оно более защищено и легче в использовании. Впервые оно было представлено  в браузерах Firefox 2 и Safari 4.

- -
Заметка: DOM хранилище - это не то же самое, что mozStorage (Mozilla's XPCOM interfaces to SQLite) или Session store API (утилита XPCOM - хранилище для использования в расширениях).
- -
-

Заметка: Эта статья скоро будет сильно переработана. Вместо того, чтобы хранить всю информацию на одной странице, она будет разбита на несколько статей, каждая из которых будет описывать разные API хранилища. Отдельная статья, помогающая разобраться в разных API, будет также добавлена.

-
- -

Описание

- -

Механизм DOM хранилища - средство, благодаря которому можно безопасно хранить и позже извлекать пары "ключ / значение". Целью этого является обеспечение комплексного средства, с помощью которого можно разрабатывать интерактивные приложения(включая приложения с продвинутыми возможностями, такими как возможность работать "автономно"("offline") в течение длительных периодов времени).

- -

Браузеры на основе Mozilla, Internet Explorer 8 +, Safari 4 + и Chrome обеспечивают рабочую реализацию спецификации DOM хранилища. (В случае, если нужна кросс-браузерная поддержка функциональности, включая более старые версии IE, будет полезно отметить, что IE также имеет подобную легаси функциональность под названием "USERDATA поведение", которая дополненяет DOM хранилище IE в IE8.)

- -

DOM хранилище удобно, потому что нет других хороших способов хранения разумных объемов данных за любой период времени, встроенных в браузер. Кукисы ограничены в количестве хранимой информации и не обеспечивают поддержку для организации постоянных данных, а другие методы (например, флэш-локальное хранилище) требуют плагина.

- -

Одним из первых известных приложений,  использующих новые функциональные возможности DOM хранилища(в дополнение к USERDATA поведения в Internet Explorer) было halfnote (приложение для заметок), написанное Аароном Будменом. В своем приложении, Аарон одновременно сохранял заметки на сервере (когда/если Интернет-подключение  был доступно) и локального хранилища данных(в обратном случае). Это дало возможность пользователю смело писать резервные копии заметок даже при нерегулярном подключении к Интернету.

- -

Хотя идея и реализация halfnote были сравнительно простыми, создание halfnote показывает возможность для нового поколения веб-приложений, которые можно использовать как в онлайн-, так и оффлайн- режиме.

- -

Связь

- -

Ниже приведены глобальные объекты, которые существуют как свойства каждого объекта  window. Это означает, что они могут быть доступны как sessionStorage или window.sessionStorage. (Это важно, потому что вы можете использовать фреймы(IFrames) для хранения или доступа, дополнительные данные кроме того, что сразу же включено на странице.)

- -

Storage

- -

Это конструктор(Storageдля всех экземпляров Storage (sessionStorage и globalStorage[location.hostname]).

- -

Сохранение Storage.prototype.removeKey = function(key){ this.removeItem(this.key(key)) } будет доступно через localStorage.removeKey и sessionStorage.removeKey.

- -

Единицы globalStorage являются экземплярами StorageObsolete, а не Storage.

- -

Storage определен в WhatWG Storage Interface следующим образом:

- -
interface Storage {
-  readonly attribute unsigned long length;
-  [IndexGetter] DOMString key(in unsigned long index);
-  [NameGetter] DOMString getItem(in DOMString key);
-  [NameSetter] void setItem(in DOMString key, in DOMString data);
-  [NameDeleter] void removeItem(in DOMString key);
-  void clear();
-};
-
- -
Заметка: Несмотря на то, что значения доступны для чтения и записи через стандартные способы Javascript, рекомендуется использование getItem и setItem.
- -
Заметка: Обратите внимание, что любые данные, которые хранятся в любом из хранилищ, описанных на этой странице, преобразуются в строку, используя метод.toString. перед тем, как сохранить значение. Попытка сохранить объект приведет к сохранению строки "[object Object]"  вместо объекта или его JSON представления. Самым лучшим и распространенным способом сохранения объектов в формате строки является использование предоставляемых браузером методов JSON для парсинга и сериализации объектов.
- -

sessionStorage

- -

Это глобальный объект (sessionStorage), который сохраняет значения, которые доступны в течение периода текущей сессии. Сессия страницы длится, пока браузер открыт, и восстанавливает свои значения после перегрузки страницы. Открытие страницы в новой вкладке или окне приведет к созданию новой сессии для этой страницы.

- -
// Сохранить данные в текущем хранилизе сессий
-sessionStorage.setItem("username", "John");
-
-// Получить значения сохраненного значения
-alert( "username = " + sessionStorage.getItem("username"));
-
- -

Объект sessionStorage наиболее полезен для хранения временных данных, которые должны быть восстановлены, если страница браузер была случайно перегружена.

- -

Примеры:

- -

Автоматическое сохранение содержимого тестового поля, и если страница была случайно перегружена, то данные не будут потеряны.

- -
 // Получить значение текстового поля, которое мы собираемся отслеживать
- var field = document.getElementById("field");
-
- // Проверяем, что значение поля autosave существует
- // (это будет происходить при случайной перезагрузке страницы)
- if (sessionStorage.getItem("autosave")) {
-    // Восстановить значение тестового поля
-    field.value = sessionStorage.getItem("autosave");
- }
-
- // Прослушивать изменения значения текстового поля
- field.addEventListener("change", function() {
-    // И сохранить результаты в объект хранилища сессий
-    sessionStorage.setItem("autosave", field.value);
- });
-
- -

Больше информации:

- - - -

localStorage

- -

localStorage - это то же самое, что и {{ Anch("sessionStorage") }}, поддерживает правила единого происхождения(same-origin rules), но хранение данных постоянно. localStorage был представлен в Firefox 3.5.

- -
Заметка: Когда браузер переходит в частный режим браузера(private browsing mode), то новая, временная база данных создается для хранения данных локального хранилища; эта база данных очищается и удаляется, как только частный режим браузера выключается.
- -

Совместимость

- -

Объекты Storage - относительно недавнее дополнение стандарта. Это означает, что они не обязательно должны быть реализованы во всех браузерах. Проблему можно решить с помощью включения следующего куска кода в начале вашего скрипта, позволяя использовать объект localStorage в реализациях, которые нативно не поддерживают его.

- -

Следующий алгоритм - это точная имитация объекта localStorage, но использует куки.

- -
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;
-  })());
-}
-
- -
Note: The maximum size of data that can be saved is severely restricted by the use of cookies. With this algorithm, use the functions localStorage.setItem() and localStorage.removeItem() to add, change, or remove a key. The use of methods localStorage.yourKey = yourValue; and delete localStorage.yourKey; to set or delete a key is not a secure way with this code. You can also change its name and use it only to manage a document's cookies regardless of the localStorage object.
- -
Note: By changing the string "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/" to: "; path=/" (and changing the object's name), this will become a sessionStorage polyfill rather than a localStorage polyfill. However, this implementation will share stored values across browser tabs and windows (and will only be cleared when all browser windows have been closed), while a fully-compliant sessionStorage implementation restricts stored values to the current browsing context only.
- -

Here is another, less exact, imitation of the localStorage object. It is simpler than the previous one, but it is compatible with old browsers, like Internet Explorer < 8 (tested and working even in Internet Explorer 6). It also makes use of cookies.

- -
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;
-}
-
- -
Note: The maximum size of data that can be saved is severely restricted by the use of cookies. With this algorithm, use the functions localStorage.getItem(), localStorage.setItem(), and localStorage.removeItem() to get, add, change, or remove a key. The use of method localStorage.yourKey in order to get, set, or delete a key is not permitted with this code. You can also change its name and use it only to manage a document's cookies regardless of the localStorage object.
- -
Note: By changing the string "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/" to: "; path=/" (and changing the object's name), this will become a sessionStorage polyfill rather than a localStorage polyfill. However, this implementation will share stored values across browser tabs and windows (and will only be cleared when all browser windows have been closed), while a fully-compliant sessionStorage implementation restricts stored values to the current browsing context only.
- -

Compatibility and relation with globalStorage

- -

localStorage is also the same as globalStorage[location.hostname], with the exception of being scoped to an HTML5 origin (scheme + hostname + non-standard port) and localStorage being an instance of Storage as opposed to globalStorage[location.hostname] being an instance of StorageObsolete which is covered below. For example, http://example.com is not able to access the same localStorage object as https://example.com but they can access the same globalStorage item. localStorage is a standard interface while globalStorage is non-standard so you shouldn't rely on these.

- -

Please note that setting a property on globalStorage[location.hostname] does not set it on localStorage and extending Storage.prototype does not affect globalStorage items; only extending StorageObsolete.prototype does.

- -

globalStorage

- -
{{ Non-standard_header }}{{ obsolete_header("13.0") }}
- -

globalStorage is obsolete since Gecko 1.9.1 (Firefox 3.5) and unsupported since Gecko 13 (Firefox 13). Just use {{ Anch("localStorage") }} instead. This proposed addition to HTML5 has been removed from the HTML5 specification in favor of {{ Anch("localStorage") }}, which is implemented in Firefox 3.5. This is a global object (globalStorage) 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).

- -
Note: globalStorage is not a Storage instance, but a StorageList instance containing StorageObsolete instances.
- -
// Save data that only scripts on the mozilla.org domain can access
-globalStorage['mozilla.org'].setItem("snippet", "<b>Hello</b>, how are you?");
-
- -

Specifically, the globalStorage 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 globalStorage on this domain (developer.mozilla.org) we'd have the following storage object available to us:

- -
    -
  • globalStorage{{ mediawiki.external('\'developer.mozilla.org\'') }} - All web pages within the developer.mozilla.org sub-domain can both read and write data to this storage object.
  • -
- -

Examples:

- -

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.

- -

Remember a user's username for the particular sub-domain that is being visited:

- -
 globalStorage['developer.mozilla.org'].setItem("username", "John");
-
- -

Keep track of the number of times that a user visits all pages of your domain:

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

Расположение хранилища и очищение данных

- -

In Firefox the DOM storage data is stored in the webappsstore.sqlite file in the profile folder (there's also chromeappsstore.sqlite file used to store browser's own data, notably for the start page - about:home, but potentially for other internal pages with "about:" URLs).

- -
    -
  • DOM Storage can be cleared via "Tools -> Clear Recent History -> Cookies" when Time range is "Everything" (via nsICookieManager::removeAll) -
      -
    • But not when another time range is specified: (bug 527667)
    • -
    • Does not show up in Tools -> Options -> Privacy -> Remove individual cookies (bug 506692)
    • -
    -
  • -
  • DOM Storage is not cleared via Tools -> Options -> Advanced -> Network -> Offline data -> Clear Now.
  • -
  • 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 offline cache when clicking the Remove button.
  • -
- -

See also clearing offline resources cache.

- -

Больше информации

- - - -

Примеры

- -
    -
  • JavaScript Web Storage Tutorial: Creating an Address Book Application - Hands-on tutorial describing how to use the Web Storage API by creating a simple address book application.
  • -
  • offline web applications at hacks.mozilla.org - Showcases an offline app demo and explains how it works.
  • -
  • Noteboard - Note writing application that stores all data locally.
  • -
  • jData - 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.
  • -
  • HTML5 localStorage example - 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.
  • -
  • HTML5 Session Storage - A very simple example of session storage. Also includes a example on local storage. Tested in Firefox 3.6 or higher.
  • -
  • Basic DOMStorage Examples - 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.
  • -
  • halfnote - (displaying broken in Firefox 3) Note writing application that uses DOM Storage.
  • -
- -

Совместимость с браузерами

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
localStorage43.5810.504
sessionStorage52810.504
globalStorage{{ CompatNo }}2-13{{ CompatNo }}{{ CompatNo }}{{ CompatNo }}
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support2.1{{ CompatUnknown }}811iOS 3.2
-
- -

All browsers have varying capacity levels for both localStorage and sessionStorage. Here is a detailed rundown of all the storage capacities for various browsers.

- -
-

Note: since iOS 5.1, Safari Mobile stores localStorage data in the cache folder, which is subject to occasional clean up, at the behest of the OS, typically if space is short.

-
- -

Полезные ссылки

- - - -
{{ HTML5ArticleTOC }}
diff --git a/files/ru/web/guide/api/webrtc/index.html b/files/ru/web/guide/api/webrtc/index.html deleted file mode 100644 index d8fbf01983..0000000000 --- a/files/ru/web/guide/api/webrtc/index.html +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: WebRTC -slug: Web/Guide/API/WebRTC -translation_of: Web/API/WebRTC_API -translation_of_original: Web/Guide/API/WebRTC ---- -

WebRTC (где RTC расшифровывается как Real-Time Communications) - это технология, которая позволяет передавать данные и потоковое аудио/видео между браузерами. Как набор стандартов в целом, WebRTC предоставляет любым поддерживающим этот стандарт, браузерам обмениваться данными и устраивать сеансы телеконференций в режиме точка-точка, без необходимости устанавливать какие-либо плагины и стороннее програмное обеспечение.

- -

Компоненты WebRTC доступны через API JavaScript: Network Stream API, который представляет собой поток аудио и видео данных, PeerConnection API, который позволяет двум и более пользователям общаться браузер-браузер напрямую, DataChannel API, который позволяет обмениваться данными других типов, например в играх в режиме реального времени, текстовые чаты, обмен файлами и так далее.

- -
-

На заметку: Эта документация находится в процессе переезда в свой новый дом.

-
- -

Руководства

- -
-
Обмен данными в режиме точка-точка с WebRTC
-
О том, как наладить обмен данными в режиме точка-точка используя API WebRTC.
-
Введение в архитектуру WebRTC
-
(AKA "WebRTC and the Ocean of Acronyms") WebRTC состоит из множества частей и это может быть причиной сложностей для новичков. Эта статья рассказывает обо всех частях и объясняет то как они между собой связаны.
-
Основы WebRTC
-
Теперь, когда вы уже знаете архитектуру WebRTC, вы можете перейти к этой статье, которая проведет вас через путь создания кросс-браузерного RTC-приложения
-
- -

Ссылки

- -
-
MediaDevices.getUserMedia
-
API захвата медиа (видео/аудио)
-
RTCPeerConnection
-
Интерфейс обработки потоковых данных между двуми пирами.
-
RTCDataChannel
-
Интерфейс передачи произвольных данных через соединение точка-точка.
-
diff --git a/files/ru/web/guide/css/getting_started/cascading_and_inheritance/index.html b/files/ru/web/guide/css/getting_started/cascading_and_inheritance/index.html deleted file mode 100644 index a192eb1d28..0000000000 --- a/files/ru/web/guide/css/getting_started/cascading_and_inheritance/index.html +++ /dev/null @@ -1,152 +0,0 @@ ---- -title: Каскадность и наследование -slug: Web/Guide/CSS/Getting_started/Cascading_and_inheritance -tags: - - Beginner - - CSS - - 'CSS:Getting_Started' - - Guide - - Web - - Веб - - Новичку -translation_of: Learn/CSS/Building_blocks/Cascade_and_inheritance -translation_of_original: Web/Guide/CSS/Getting_started/Cascading_and_inheritance ---- -

{{ CSSTutorialTOC() }}

- -

{{ previousPage("/ru/docs/Web/Guide/CSS/Getting_Started/How_CSS_works", "Как работает CSS")}} Это четвертый раздел руководства CSS для начинающих. Он описывает, как таблицы стилей взаимодействуют в каскаде, и как дочерние элементы наследуют стиль от родительских. Используя наследование, в приведённой ниже задаче вы измените стиль некоторых элементов за один шаг.

- -

Информация: Каскадность и наследование

- -

Окончательный стиль элемента можно указать во многих местах, которые комплексно взаимодействуют между собой. Эти комплексные взаимодействия делают CSS мощным, но в то же время, иногда сбивают с толку и порождают сложности при отладке. 

- -

Три основных источника информации о стилях образовывают каскад. К ним относятся следующие:

- -
    -
  • Стили разметки браузера по умолчанию.
  • -
  • Стили, указанные пользователем при чтении документа.
  • -
  • Стили, связанные с документом их автором. Их можно указывать в трех местах:
  • -
- -
    -
  1. Во внешнем файле: в этом учебном руководстве обсуждается преимущественно этот метод указания стилей.
  2. -
  3. В начале документа (раздел заголовок документа): используйте этот метод только для стилей в пределах этой страницы.
  4. -
  5. Для конкретного элемента в теле документа: это наименее поддерживаемый метод, но может быть использован для тестирования.
  6. -
- -

Стиль пользователя модифицирует стиль браузера по умолчанию. Стиль документа, указанный его автором, изменяет стиль ещё в некоторой мере. В этом обучающем руководстве, вы являетесь автором шаблонного документа, и только вы работаете с авторскими таблицами стилей.

- -
-
Пример
- -

Когда вы читаете этот документ в браузере, часть стилей происходит от стилей для HTML по умолчанию вашего браузера.

- -

Часть стиля может происходить от измененных настроек браузера или измененного файла определения стиля. В Firefox настройки можно изменить в диалоге Предпочтения или же указать стили в файле userContent.css в профиле браузера.

- -

Часть стиля приходит из таблиц стилей, связываемых с документом вики-сервером.

-
- -

Когда вы открываете шаблон документа в браузере, элементы {{ HTMLElement("strong") }} имеют более жирный шрифт по сравнению с остальным текстом. Это следует из настроек HTML стилей браузера по умолчанию.

- -

Элемент {{ HTMLElement("strong") }} красного цвета. Это следует из настроек вашего шаблона таблиц стилей.

- -

Элементы {{ HTMLElement("strong") }} также наследуют большую часть стилей элемента {{ HTMLElement("p") }} поскольку они являются дочерними. Таким же образом элемент {{ HTMLElement("p") }} наследует большую часть стиля элемента {{ HTMLElement("body") }}.

- -

Для стилей в каскаде, авторские таблицы стилей имеют приоритет перед стилями для режимов чтения браузера. Последние, в свою очередь, имеют приоритет перед настройками браузера по умолчанию.

- -

Для наследуемых стилей, собственный стиль дочернего узла имеет приоритет над стилем, унаследованным от родительского узла.

- -

These are not the only priorities that apply. A later page in this tutorial will explain more.

- -
-
Подробнее
- -

CSS также предоставляет способ переопределения стиля в авторском документе для читателя с помощью ключевого слова !important.

- -

Это означает, что как автор документа, вы не всегда можете точно предсказать, что ваши читатели будут видеть в своём браузере.

- -

Если вы хотите знать все детали каскадирования и наследования, ознакомьтесь с документом Assigning property values, Cascading, and Inheritance в спецификации CSS.

-
- -

К действию: Использование наследования

- -
    -
  1. Откройте CSS-файл примера.
  2. -
  3. Добавьте в файл строку кода, представленную ниже. Не имеет особого значения, в какой части CSS-документа вы расположите эту строку. Тем не менее, добавить его в самом верху будет логично, поскольку в документе элемент {{ HTMLElement("p") }} является родительским по отношению к элементу {{ HTMLElement("strong") }} : -
    p {color: blue; text-decoration: underline;}
    -
    -
  4. -
  5. Теперь сохраните документ и обновите страницу в браузере, чтобы увидеть изменения. Весь текст в абзаце будет подчеркнут, в том числе и начальные буквы. Элемент {{ HTMLElement("strong") }} унаследовал подчеркнутый стиль от родительского элемента {{ HTMLElement("p") }} .
    - -

    Обратите внимание, что элементы {{ HTMLElement("strong") }} всё ещё красные. Красный цвет является их собственным стилем, поэтому имеет приоритет перед синим цветом, заданным для родительского элемента {{ HTMLElement("p") }} . 

    -
  6. -
- -

До

- -

HTML

- -
<p>
-<strong>C</strong>ascading
-<strong>S</strong>tyle
-<strong>S</strong>heets
-</p>
-
- -

CSS

- -
strong {color:red}
-
- -

{{ EmbedLiveSample('Before') }}

- -

После

- -

HTML

- -
<p>
-<strong>C</strong>ascading
-<strong>S</strong>tyle
-<strong>S</strong>heets
-</p>
-
- -

CSS

- -
p {color:blue; text-decoration:underline}
-strong {color:red}
- -

{{ EmbedLiveSample('After') }}

- -

 

- -
-
Задание
-Измените таблицу стилей таким образом, чтобы были подчеркнуты только красные буквы: - - - - - - - -
Cascading Style Sheets
- -
-
Возможное решение
- -

Переместите объявление подчеркивания из правила для {{ HTMLElement("p") }} в правило для {{ HTMLElement("strong") }}. В результате файл будет выглядеть следующим образом:

- -
p {color: blue; }
-strong {color: red; text-decoration: underline;}
-
- -

 

-Hide solution
-Посмотреть вариант решения.
- -

 

- -

Что дальше?

- -

{{ nextPage("/ru/docs/Web/Guide/CSS/Getting_Started/Selectors", "Селекторы")}}Ваш пример таблицы стилей определяет стили для тегов <p> и <STRONG>, изменяя стиль соответствующих элементов по всему документу. В следующем разделе описывается, как задать стиль более избирательными методами.

diff --git a/files/ru/web/guide/css/getting_started/color/index.html b/files/ru/web/guide/css/getting_started/color/index.html deleted file mode 100644 index 911a8010b6..0000000000 --- a/files/ru/web/guide/css/getting_started/color/index.html +++ /dev/null @@ -1,345 +0,0 @@ ---- -title: Color -slug: Web/Guide/CSS/Getting_started/Color -translation_of: Learn/CSS/Introduction_to_CSS/Values_and_units#Colors -translation_of_original: Web/Guide/CSS/Getting_started/Color ---- -

{{ CSSTutorialTOC() }}

- -

{{previousPage("/en-US/docs/Web/Guide/CSS/Getting_Started/Text_styles", "Text styles")}}This is the 8th section of the CSS Getting Started tutorial; it explains how you can specify color in CSS. In your sample stylesheet, you introduce background colors.

- -

Information: Color

- -

In this tutorial so far, you have used a limited number of named colors. CSS2 supports 17 named colors in all. Some of the names might not be what you expect:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 black gray silver white 
primariesred lime blue 
secondariesyellow aqua fuchsia 
 maroon orange olive purple green navy teal 
- -

 

- -
-
Details
- -

Your browser might support many more named colors, like:

- - - - - - - - - - - - - - - - -
dodgerblue peachpuff tan firebrick aquamarine 
- -

For details of this extended list, see: SVG color keywords in the CSS 3 Color Module. Beware of using color names that your reader's browsers might not support.

-
- -

For a larger palette, specify the red, green and blue components of the color you want by using a number sign (hash) and three hexadecimal digits in the range 0 – 9, a – f. The letters a – f represent the values 10 – 15:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
black #000
pure red #f00
pure green #0f0
pure blue #00f
white #fff
- -


- For the full palette, specify two hexadecimal digits for each component:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
black #000000
pure red #ff0000
pure green #00ff00
pure blue #0000ff
white #ffffff
- -

You can usually get these six-digit hexadecimal codes from your graphics program or some other tool.

- -
-
Example
- -

With a little practice, you can adjust the three-digit colors manually for most purposes:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Start with pure red: #f00
To make it paler, add some green and blue: #f77
To make it more orange, add a little extra green: #fa7
To darken it, reduce all its components: #c74
To reduce its saturation, make its components more equal: #c98
If you make them exactly equal, you get gray: #ccc
- -

For a pastel shade like pale blue:

- - - - - - - - - - - - - - -
Start with pure white: #fff
Reduce the other components a little: #eef
-
- -
-
More details
- -

You can also specify a color using decimal RGB values in the range 0 – 255, or percentages.

- -

For example, this is maroon (dark red):

- -
rgb(128, 0, 0)
-
- -

For full details of how to specify colors, see: Colors in the CSS Specification.

- -

For information on matching system colors like Menu and ThreeDFace, see: CSS2 System Colors in the CSS Specification.

-
- -

Color properties

- -

You have already used the {{ cssxref("color") }} property on text.

- -

You can also use the {{ cssxref("background-color") }} property to change elements' backgrounds.

- -

Backgrounds can be set to transparent to explicitly remove any color, revealing the parent element's background.

- -
-
Example
- -

The Example boxes in this tutorial use this pale yellow background:

- -
background-color: #fffff4;
-
- -

The More details boxes use this pale gray:

- -
background-color: #f4f4f4;
-
-
- -

 

- -

Action: Using color codes

- -

Color page

- -
    -
  1. Edit your CSS file.
  2. -
  3. Make the change shown down here, to give the initial letters a pale blue background. (The layout and comments in your file probably differ from the file shown here. Keep the layout and comments the way you prefer them.)
  4. -
  5. -

    HTML Content

    - -
    <p id = "first"> <strong>C</strong>ascading <strong class="spinach">S</strong>tyle <strong class="spinach">S</strong>heets</p>
    -<p> <strong>C</strong>ascading <strong>S</strong>tyle <strong>S</strong>heets</p>
    -
    - -

    CSS Content

    - -
    /*** CSS Tutorial: Color page ***/
    -
    -/* page font */
    -body {
    -  font: 16px "Comic Sans MS", cursive;
    -}
    -
    -/* paragraphs */
    -p {
    -  color: blue;
    -}
    -#first {
    -  font-style: italic;
    -}
    -
    -/* initial letters */
    -strong {
    -  background-color: #ddf;
    -  color: red;
    -  font: 200% serif;
    -}
    -
    -.spinach {
    -  color: green;
    -  background-color: #ddf;
    -}
    -
    -
    -
  6. -
  7. Save the file and refresh your browser to see the result.
  8. -
  9. The result should be like this:
  10. -
- -

{{ EmbedLiveSample('Color_page', '', '', '', 'Web/Guide/CSS/Getting_started/Color') }}

- -
-
Challenge
- -

In your CSS file, change all the color names to 3-digit color codes without affecting the result.

- -

(This cannot be done exactly, but you can get close. To do it exactly you need 6-digit codes, and you need to look up the CSS Specification or use a graphics tool to match the colors.)

- -
-
Possible solution
- -

The following values are reasonable approximations of the named colors:

- -
strong {
-  color: #f00; /* red */
-  background-color: #ddf; /* pale blue */
-  font: 200% serif;
-}
-
-.carrot {
-  color: #fa0; /* orange */
-}
-
-.spinach {
-  color: #080; /* dark green */
-}
-
-p {
-  color: #00f; /* blue */
-}
-
- -

 

-Hide solution
-See a solution for the challenge.
- -

What next?

- -

{{nextPage("/en-US/docs/Web/Guide/CSS/Getting_Started/Content", "Content")}}Your sample document and your sample stylesheet strictly separate content from style. The next section explains how you can make exceptions to this strict separation.

diff --git a/files/ru/web/guide/css/getting_started/how_css_works/index.html b/files/ru/web/guide/css/getting_started/how_css_works/index.html deleted file mode 100644 index 9edeb9fe1f..0000000000 --- a/files/ru/web/guide/css/getting_started/how_css_works/index.html +++ /dev/null @@ -1,122 +0,0 @@ ---- -title: Как работает CSS -slug: Web/Guide/CSS/Getting_started/How_CSS_works -translation_of: Learn/CSS/First_steps/How_CSS_works -translation_of_original: Web/Guide/CSS/Getting_started/How_CSS_works ---- -

{{ CSSTutorialTOC() }}

- -

{{ previousPage("/ru/docs/Web/Guide/CSS/Getting_Started/Why_use_CSS", "Зачем нужен CSS?") }} Это третья статья руководства по CSS для начинающих, объясняет, как работает CSS в вашем браузере, а также назначение Объектной Модели Документа (Document Object Model или DOM). Вы также узнаете, как сделать анализ документа.

- -

Информация: Как работает CSS

- -

Когда браузер отображает документ, он должен совместить содержимое документа с информацией о стилях для него. Браузер обрабатывает документ в два этапа:

- -
    -
  1. Браузер преобразует язык разметки и CSS в DOM (Document Object Model). DOM представляет собой документ в памяти компьютера. Он сочетает в себе содержание документа с его стилем.
  2. -
  3. Браузер отображает содержимое DOM.
  4. -
- -

Язык разметки использует элементы для определения структуры документа. Элемент обозначается с использованием тегов, которые представляют собой строки, начинающиеся с символа '<' и заканчивающиеся '>'. Большинство элементов имеет парные теги: открывающий тег и закрывающий тег. Для открывающего тега, поместите имя элемента между '<' и '>'. Для закрывающего тега, поместите '/'  между '<', и именем элемента.

- -

В зависимости от языка разметки, некоторые элементы имеют только начальный тег, или тег, где '/' располагается после имени элемента. Элемент так же может быть контейнером, включающим в себя другие элементы. В этом случае они располагаются между открывающим и закрывающим тегами. Не забывайте всегда закрывать теги внутри контейнера.

- -

DOM имеет древовидную структуру. Каждый элемент, атрибут и запуск текста на языке разметки становится узлом в древовидной структуре. Узлы определяются их взаимодействием с другими узлами DOM. Некоторые элементы становятся родительскими по отношению к другим, дочерним узлам (или узлам-потомкам). В свою очередь, дочерние узлы имеют "братьев" (siblings).

- -

Понимание DOM поможет вам при разработке, отладке и поддержке CSS, поскольку DOM это место, где встречаются CSS и содержимое документа.

- -
-
Пример
- -
 
-В данном примере, тег <p> и его закрывающий тег </p> создают контейнер: - -
<p>
-  <strong>C</strong>ascading
-  <strong>S</strong>tyle
-  <strong>S</strong>heets
-</p>
-
- -

Живой пример

- -

{{ EmbedLiveSample('Информация_Как_работает_CSS', '', '', '', 'Web/Guide/CSS/Getting_started/How_CSS_works') }}

- -

В DOM соответствующий узел P является родительским. Его дочерние узлы - это теги STRONG  и узлы текста. Теги STRONG,  в свою очередь, являются родительскими по отношению к текстовым узлам, которые являются их дочерними узлами:

- -
P
-├─STRONG
-│ └─"C"
-├─"ascading"
-├─STRONG
-│ └─"S"
-├─"tyle"
-├─STRONG
-│ └─"S"
-└─"heets"
-
- -

К действию: Анализ DOM

- -

Использование DOM Inspector

- -

Для анализа DOM, вам потребуется специальная программа. Вы можете использовать расширение DOM Inspector (DOMi) от Mozilla для анализа DOM. Вам просто нужно установить это расширение в браузере (подробнее см. ниже).

- -
    -
  1. Используйте браузер Mozilla, чтобы открыть свой HTML-документ.
  2. -
  3. Из строки меню браузера выберите Инструменты > DOM инспектор, или Инструменты > Веб-разработка > Инспектор. -
    -
    Подробнее
    - -

    Если в вашем браузере Mozilla не установлен DOMi, вы можете установить его с сайта дополнений и перезапустить браузер. Затем возвращайтесь к этому руководству.

    - -

    Если вы не хотите устанавливать DOMi (или вы используете браузер не от Mozilla), то можете воспользоваться Рентген-очками, как описано в секции ниже. Или вы можете пропустить эту секцию и перейти к прямо к следующей странице. Если вы пропустите данный раздел, это не помешает вам в дальнейшем освоении руководства.

    -
    -
  4. -
  5. В DOMi разверните узлы вашего документа, нажав на их стрелки. -

    Замечание:  Пустые места в вашем HTML файле DOMi может отображать как пустые текстовые узлы, которые можно игнорировать.

    - -

    Часть результата может выглядеть следующим образом, в зависимости от того, какие узлы вы развернули:

    - -
    │ ▼╴P
    -│ │ │ ▼╴STRONG
    -│ │ └#text
    -│ ├╴#text
    -│ ►╴STRONG
    -│ │
    - -

    При выборе любого узла, вы можете использовать правую панель DOMi's для поиска информации об узле. Например, когда вы выбираете текстовый узел, DOMi показывает вам текст в соответствующей панели.

    - -

    При выборе узла элемента, DOMi анализирует его и предоставляет огромное количество информации, которая содержится в правой панели. Информация о стилях - лишь часть информации, которую там можно просмотреть.

    -
  6. -
- -
-
Задача
- -

В DOMi, кликните на узле STRONG.

- -

Используйте правую панель ДОМи, чтобы выяснить, где цвет для этого узла установлен на красный, и где его внешний вид сделан толще, чем обычный текст.

- -
-
Possible solution
- -

In the menu above the right-hand pane, choose CSS Rules. You see two items listed, one that references an internal resource and one that references your stylesheet file. The internal resource defines the font-weight property as bolder; your stylesheet defines the color property as red.

-Hide solution
-Посмотреть решение задачи.
- -

Использование Рентген-очков

- -

Рентген-очки показывают меньше информации, чем DOM Инспектор, но проще в установке и использовании.

- -
    -
  1. Перейдите на домашнюю страницу X-Ray Goggles.
  2. -
  3. Перетащите ссылку X-Ray Googles с этой страницы на панель закладок.
  4. -
  5. Откройте HTML-документ.
  6. -
  7. Запустите Рентген-очки, кликнув по появившейся закладке.
  8. -
  9. Передвигайте курсор мыши по документу для просмотра элементов в документе.
  10. -
- -

Что дальше?

- -

{{ nextPage("/ru/docs/Web/Guide/CSS/Getting_Started/Cascading_and_inheritance", "Каскадность и наследование") }}Если вы решили задачу, то увидели, что информация о стиле из более чем одного места взаимодействует для создания окончательного стиля для элемента. На следующей странице объясняется больше об этих взаимодействиях.

diff --git a/files/ru/web/guide/css/getting_started/index.html b/files/ru/web/guide/css/getting_started/index.html deleted file mode 100644 index b2f6ebed77..0000000000 --- a/files/ru/web/guide/css/getting_started/index.html +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: CSS для начинающих -slug: Web/Guide/CSS/Getting_started -tags: - - Beginner - - CSS - - 'CSS:Getting_Started' - - Guide - - Needs - - NeedsBeginnerUpdate - - NeedsTranslation - - NeedsUpdate - - TopicStub - - Web - - Новичку - - Руководство -translation_of: Learn/CSS/First_steps -translation_of_original: Web/Guide/CSS/Getting_started ---- -

Это руководство (самоучитель) познакомит вас с базовыми возможностями и языком (синтаксом) Каскадных таблиц стилей (CSS). CSS используется для изменения внешнего вида структурированного документа, такого как веб-страница. Руководство также включает простые упражнения, которые вы сможете выполнить на своем компьютере и увидеть, как работает CSS, а также его возможности в современных браузерах.

- -

Данное руководство создано для новичков и всех, кто хотел бы освежить свои знания основ CSS. Если у вас уже есть опыт работы с CSS, на главной странице вы можете найти список обучающих ресурсов, подходящих для вашего уровня.

- - - -

Что вам нужно для того, чтобы начать

- -
    -
  • Текстовый редактор
  • -
  • Современный браузер
  • -
  • Опыт работы с текстовым редактором и браузером
  • -
- -

В данном руководстве вам будут встречаться упражнения, которые вам предлагается выполнить для лучшего понимания материала. Их выполнение не является обязательным: вы можете просто читать материал и смотреть на иллюстрации.

- -

Важно: Руководство включает в себя материалы по работе с цветом в CSS. Эти материалы будет легче пройти, если у вас цветной монитор и нормальное цветовое зрение.

- -

Как пользоваться руководством

- -

Наилучшим вариантом будет внимательное и постепенное чтение разделов в строгой последовательности. Если вы пропустите какой-то раздел, вам может оказаться что-то непонятно в следующих главах.

- -

Часть I: Основы CSS

- -

На каждой странице, используйте секцию Информация, чтобы понять, как работает CSS. Используйте секцию К действию, чтобы попробовать использовать CSS на вашем компьютере.

- -

Чтобы проверить усвоенные знания, вам будет полезно решить задачу в конце каждой страницы. Верные решения задач вы всегда можете найти под их описанием в виде ссылки - таким образом, вы не сможете увидеть их случайно.

- -

Чтобы добиться более глубокого понимания CSS, читайте информацию в блоках с заголовком Подробнее. А также не забудьте посетить приведенные там ссылки.

- -

Часть II: Возможности CSS

- -

Вторая часть руководства содержит примеры, которые продемонстрируют вам возможности CSS применительно к другим web-технологиям и технологиям Mozilla. 

- -
    -
  1. JavaScript
  2. -
  3. SVG графика
  4. -
  5. XML данные
  6. -
  7. XBL байдинг bindings
  8. -
  9. Пользовательские интерфейсы XUL
  10. -
diff --git a/files/ru/web/guide/css/getting_started/readable_css/index.html b/files/ru/web/guide/css/getting_started/readable_css/index.html deleted file mode 100644 index 9e9a4231a9..0000000000 --- a/files/ru/web/guide/css/getting_started/readable_css/index.html +++ /dev/null @@ -1,166 +0,0 @@ ---- -title: Чистый СSS код -slug: Web/Guide/CSS/Getting_started/Readable_CSS -translation_of: Learn/CSS/Introduction_to_CSS/Syntax#Beyond_syntax_make_CSS_readable -translation_of_original: Web/Guide/CSS/Getting_started/Readable_CSS ---- -

{{ CSSTutorialTOC() }}

- -

{{ previousPage("/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors", "Selectors")}}Это 6-я статья руководства CSS для начинающих; здесь обсуждается стиль и грамматика самого языка CSS. Вы можете изменить пусть к вашему файлу CSS на более удобный для чтения.

- -

Информация: Чистый код CSS

- -

Вы можете добавлять пустое пространство и комментарии к вашим стилям, чтобы сделать их более читабельными. Также вы можете группировать селекторы вместе, в случае если те же самые правила стиля применяются к разным элементам.

- -

Пустое пространство

- -

Пустое пространство означает фактические пробелы, табуляцию, а также новые строки. Вы можете использовать их, чтобы сделать ваш код более читабельным.

- -

В макете страницы, данное пространство — это та часть, которая остается без опознавательных знаков: отступы от других элементов (margin) и пространство между колонками и строками.

- -

Ваш пример файла CSS в настоящее время имеет правила в одной строке, и почти минимум пробелов. В комплексе стилей эта схема будет усложнять читаемость, а значит в нее будет трудно вносить изменения.

- -

Стиль написания который вы выбираете, как правило, зависит от личных предпочтений, но если ваши css являются частью общих проектов, могут возникнуть трудности с понимаем вашего написания кода.

- -
-
Примеры
- -

Некоторые люди пытаются написать код максимально компактно и пишут код в одну строку, даже если он достаточно долгий:

- -
.carrot {color: orange; text-decoration: underline; font-style: italic;}
-
- -

Некоторые люди предпочитают писать каждое свойство-значение в отдельной строке:

- -
.carrot
-{
-color: orange;
-text-decoration: underline;
-font-style: italic;
-}
-
- -

Некоторые используют отступы — 2 или 4 пробела или табы:

- -
.carrot {
-  color: orange;
-  text-decoration: underline;
-  font-style: italic;
-}
-
- -

Некоторые люди все выстраивают вертикально (но такое расположение не лучший вариант для поддержки):

- -
.carrot
-    {
-    color           : orange;
-    text-decoration : underline;
-    font-style      : italic;
-    }
-
- -

Некоторые люди используют смешанный пробелы для повышения читаемости.

- -
.vegetable         { color: green; min-height:  5px; min-width:  5px }
-.vegetable.carrot  { color: orange;    height: 90px;     width: 10px }
-.vegetable.spinach { color: darkgreen; height: 30px;     width: 30px }
-
-
- -

Некоторые используют вкладки для компоновки элементов, а другие только пробелы.

- -

Комментарии

- -

Комментарии в CSS имеют следующий вид: /* комментарий */.

- -

Вы можете использовать комментарии, чтобы сделать фактические комментарии в css, а также чтобы закомментировать временно часть кода с целью тестирования.

- -

Часть стилей, которая будет закомментирована, не будет отображатся браузером. Будьте осторожны при комментировании кода, поскольку важно сохранить правильный синтаксис остального кода.

- -
-
Пример
- -
/* стиль для начальной буквой C в первом пункте*/
-.carrot {
-  color:            orange;
-  text-decoration:  underline;
-  font-style:       italic;
-  }
-
-
- -

Группировка селекторов

- -

Когда многие элементы имеют один и тот же стиль, вы можете указывать группу селекторов, разделяя их запятыми. Декларация применится для всех выбранных элементов.

- -

В другом месте в таблице стилей можно указать те же селекторы уже индивидуально, чтобы применить индивидуальные правила стилей для них.

- -
-
Пример
- -

Это правило делает элементы {{HTMLElement ("h1")}}, {{HTMLElement ("h2")}}, и {{HTMLElement ("h3")}} одного цвета.

- -

Удобно определить цвет только в одном месте, в случае, если возможны изменения.

- -
/* цвет для заголовков */
-h1, h2, h3 {color: navy;}
-
-
- -

Действуем: добавление комментариев и улучшения формата

- -
    -
  1. Редактируя ваш CSS-файл убедитесь, что он применяет эти правила (в любом порядке): -
    strong {color: red;}
    -.carrot {color: orange;}
    -.spinach {color: green;}
    -#first {font-style: italic;}
    -p {color: blue;}
    -
    -
  2. -
  3. Сделайте его более читабельным, перестраивая его таким образом, какой будете считать более логичным и применяя пробелы и комментарии на свое усмотрение.
  4. -
  5. Сохраните файл и обновите экран браузера, чтобы убедиться, что ваши изменения не повлияли на роботу стилей: - - - - - - - - - -
    Cascading Style Sheets
    Cascading Style Sheets
    -
  6. -
- -
-
Задание
- -

Закомментируйте часть стиля не меняя остальное, чтобы сделать первую букву вашего документа красной:

- - - - - - - - - - -
Cascading Style Sheets
Cascading Style Sheets
- -

(Существует более чем один способ сделать это).

- -
-
Possible solution
-One way to do this is to put comment delimiters around the rule for .carrot: - -
/*.carrot {
-  color: orange;
-}*/
-Hide solution
-Посмотреть решение задания.
- -

Что дальше?

- -

{{ nextPage("/en-US/docs/Web/Guide/CSS/Getting_Started/Text_styles", "Text styles") }}Ваш образец таблицы стилей использовал курсивный текст и подчеркнутый текст. На следующей странице описаны несколько способов, чтобы указать внешний вид текста в вашем документе.

diff --git a/files/ru/web/guide/css/getting_started/selectors/index.html b/files/ru/web/guide/css/getting_started/selectors/index.html deleted file mode 100644 index 797aefefa3..0000000000 --- a/files/ru/web/guide/css/getting_started/selectors/index.html +++ /dev/null @@ -1,434 +0,0 @@ ---- -title: Selectors -slug: Web/Guide/CSS/Getting_started/Selectors -translation_of: Learn/CSS/Building_blocks/Selectors -translation_of_original: Web/Guide/CSS/Getting_started/Selectors ---- -

{{ CSSTutorialTOC() }}

- -

{{ previousPage("/en-US/docs/Web/Guide/CSS/Getting_Started/Cascading_and_inheritance", "Cascading & inheritance")}}Это пятый раздел руководства CSS для начинающих. В нем объясняется, как можно выборочно применять стили и каким образом различные типы селекторов имеют разные приоритеты.  

- -

Некоторые атрибуты добавляются к тегам в шаблоне документа, и эти атрибуты используются в шаблоне таблицы стилей.

- -

Информация: Селекторы

- -

Ранее мы уже встречались с селекторами. Мы создали строку в файле стилей следующего вида:

- -
strong {
-  color: red;
-}
-
- -

В терминологии CSS эта строка полностью является правилом CSS. Это правило начинается со strong, что и называется селектором CSS. Селектор выбирает, к каким элементам DOM применяется правило.

- -
-
Подробности
- -

Часть внутри фигурных скобок называется объявлением.

- -

Ключевое слово colorсвойство, а red - значение.

- -

Точка с запятой после пары "свойство-значение" отделяет её от других пар "свойство-значение" в том же объявлении.

- -

Этот учебник ссылается на селектор типа strong как на селектор тега. Спецификация CSS ссылается на него как на селектор типа.

-
- -

На этой странице учебника объясняются дополнительные сведения о селекторах, которые можно использовать в правилах CSS.

- -

В дополнение к именам тегов, вы можете использовать в селекторах значения атрибутов. Это позволит вашим правилам быть более избирательными.

- -

Два атрибута имеют особый статус в CSS. Это class и id.

- -

Селекторы классов

- -

Используйте атрибут class в элементе, чтобы назначить элемент именованному классу. Выбор имени класса целиком за вами. Множество элементов в документе может иметь одно и то же значение класса.

- -

В вашей таблице стилей используйте точку перед именем класса для использования его в качестве селектора.

- -

Селекторы ID

- -

Используйте атрибут id в элементе, чтобы назначить идентификатор элементу. Это зависит от вас, какое имя вы выберете для ID. Идентификационное имя должно быть уникальным в документе.

- -

В таблице стилей введите знак решетки перед идентификатором, когда вы используете его в селекторе.

- -
-
Пример
-Этот HTML тэг имеет оба элемента, атрибут class и id: - -
<p class="key" id="principal">
-
- -

Значение идентификатора id, principal, должно быть уникально в документе, но разные тэги в документе, могут иметь одинаковое имя class со значением key.

- -

Это правило делает все классы(class) со значениемkey зелёными. (Они даже не должны быть все элементами {{ HTMLElement("p") }}.)

- -
.key {
-  color: green;
-}
-
- -

Это правило делает один элемент с идентификатором (id) и значением principal полужирным:

- -
#principal {
-  font-weight: bolder;
-}
-
-
- -

Селекторы Атрибутов

- -

Вы не ограничены двумя специальными атрибутами, class и id. Вы можете определить другие атрибуты используя квадратные скобки. Внутри скобок вы задаёте имя атрибута, так же можно указать оператор соответствия и значение. Дополнительно, соответствие может быть установлено как чувствительное к регистру если дописать " i" после значения, но пока не все браузеры это поддерживают. Примеры:

- -
-
[disabled]
-
Выбирает все элементы с атрибутом "disabled".
-
[type='button']
-
Выбирает элементы с типом "button".
-
[class~=key]
-
Выбирает элементы со значением класса(class) "key" (но не такие как например "keyed", "monkey", "buckeye"). По сути эквивалентно .key.
-
[lang|=es]
-
Выбирает элементы определённые как Spanish. Это включает "es" и "es-MX" но не включает "eu-ES" (что является языком Basque).
-
[title*="example" i]
-
Выбирает элементы в состав которых входит "example", игнорируя регистр. В браузерах, которые не поддерживают флаг "i", этот селектор возможно не найдет ни один элемент.
-
a[href^="https://"]
-
Выбирает все защищённые ссылки.
-
img[src$=".png"]
-
Косвенно выбирает изображения PNG; любые изображения которые являются изображениями PNG но, чей адрес URL не заканчивается на ".png" (такие как в строке запроса) не будут выбраны.
-
- -

Селекторы псевдокласса

- -

Псевдокласс класса CSS - это ключевое слово, добавленное в селектор, который задает особое состояние выбранного элемента. Например {{Cssxref (": hover")}} применит стиль, когда пользователь наводит на элемент, указанный селектором.

- -

Псевдо-классы вместе с псевдоэлементами позволяют применять стиль к элементу не только по отношению к содержанию дерева документов, но и по отношению к внешним факторам, таким как история навигатора ({{ cssxref(":visited") }}, для примера), статус его содержимого (наподобии {{ cssxref(":checked") }} на некоторых элементах формы) или положение мыши (наподобии {{ cssxref(":hover") }} который позволяет узнать, находится ли мышь над элементом или нет). Чтобы просмотреть полный список селекторов, посетите CSS3 Спецификация работы селекторов.

- -
-
Синтаксис
- -
selector:pseudo-class {
-  property: value;
-}
-
-
- -

Список псевдоклассов

- -
    -
  • {{ Cssxref(":link") }}
  • -
  • {{ Cssxref(":visited") }}
  • -
  • {{ Cssxref(":active") }}
  • -
  • {{ Cssxref(":hover") }}
  • -
  • {{ Cssxref(":focus") }}
  • -
  • {{ Cssxref(":first-child") }}
  • -
  • {{ Cssxref(":last-child") }}
  • -
  • {{ Cssxref(":nth-child") }}
  • -
  • {{ Cssxref(":nth-last-child") }}
  • -
  • {{ Cssxref(":nth-of-type") }}
  • -
  • {{ Cssxref(":first-of-type") }}
  • -
  • {{ Cssxref(":last-of-type") }}
  • -
  • {{ Cssxref(":empty") }}
  • -
  • {{ Cssxref(":target") }}
  • -
  • {{ Cssxref(":checked") }}
  • -
  • {{ Cssxref(":enabled") }}
  • -
  • {{ Cssxref(":disabled") }}
  • -
- -

Информация: Специфичность

- -

Несколько правил могут иметь селектор, каждый из которых соответствует одному и тому же элементу. Если свойство задано только одним правилом, конфликт не возникает, и свойство устанавливается в элементе. Если к элементу применяется более одного правила и устанавливает одно и то же свойство, тогда CSS дает приоритет правилу, которое имеет более конкретный селектор. Селектор ID более специфичен, чем селектор класса, псевдокласса или атрибута, который, в свою очередь, более специфичен, чем селектор тегов или псевдоэлементов.

- -
-
Подробнее
- -

Вы также можете комбинировать селектор, создавая более конкретный селектор. Например, селектор .key выбирает все элементы, с ключом имени класса key. Селектор p.key отбирает только {{ HTMLElement("p") }} элементы, которые имеют имя класса key.

-
- -

Если таблица стилей имеет противоречивые правила, и они одинаково специфичны, тогда CSS дает приоритет правилу, которое позже находится в таблице стилей.

- -

Если у вас возникла проблема с конфликтующими правилами, попробуйте разрешить это, сделав одно из правил более конкретным, чтобы оно имело приоритет. Если вы не можете этого сделать, попробуйте переместить одно из правил ближе к концу таблицы стилей, чтобы оно имело приоритет.

- -

Информация: Селекторы на основе отношений

- -

CSS имеет несколько способов выбора элементов на основе отношений между элементами. Вы можете использовать их, чтобы сделать селектора более конкретными.

- - - - - - - - - - - - - - - - - - - - - - - - - -
Общие селекторы, основанные на отношениях
СелекторВыбрано
A EЛюбой E элемент, что является потомком одного из A элемента (то есть: дочерний, или один из дочернего, т.д.)
A > EЛюбой E элемент, что явлется  дочерним (т.е. прямой потомок)  A элемента.
E:first-childЛюбой E элемент, что является первым дочерним элементом родительского элемента.
B + EЛюбой E элемент, что является следующим "братом" B элемента (то есть: следующий ребенок того же родителя)
- -

Вы можете комбинировать их для выражения сложных отношений.

- -

Вы можете так же использовать символ * (звездочка), что подразумевает "любой элемент".

- -
-
Пример
- -

Таблица HTML имеет аттрибут id , но строки и ячейки не имеют отдельных идентификаторов:

- -
<table id="data-table-1">
-...
-<tr>
-<td>Prefix</td>
-<td>0001</td>
-<td>default</td>
-</tr>
-...
-
- -

Эти правила делают первую ячейку в каждой строке подчеркнутой, а "брат" первой ячейки каждой строки зачеркнутой (в примере 2-я ячейка) . Они влияют только на одну конкретную таблицу в документе::

- -
#data-table-1 td:first-child {text-decoration: underline;}
-#data-table-1 td:first-child + td {text-decoration: line-through;}
-
- -

Резульат  выглядит  наподобии:

- - - - - - - -
- - - - - - - - -
Prefix0001default
-
-
- -
-
Подробно
- -

Обычным способом, если вы делаете селектор более конкретным, вы увеличиваете его приоритет.

- -

Если вы используете эти методы, вы избегаете необходимость указывать в атрибутах class или id на множестве тегов в вашем документе. Вместо этого, CSS выполнит эту работу.

- -

В больших конструкциях, где скорость важна, вы можете сделать свои таблицы стилей более эффективными, избегая сложных правил, которые зависят от отношений между элементами.

- -

Дополнительные примеры о таблицах, смотрите Tables на странице ссылок CSS.

-
- -

Действие: Использование селекторов class и ID

- -
    -
  1. Измените свой HTML-файл и продублируйте абзац, скопировав его и вставив в него.
  2. -
  3. Затем добавьте аттрибуты id и class  в первую копию, а аттрибут id во вторую копию, как показано ниже. Кроме того, скопируйте и вставьте весь файл снова: -
    <!doctype html>
    -<html>
    -  <head>
    -  <meta charset="UTF-8">
    -  <title>Sample document</title>
    -  <link rel="stylesheet" href="style1.css">
    -  </head>
    -  <body>
    -    <p id="first">
    -      <strong class="carrot">C</strong>ascading
    -      <strong class="spinach">S</strong>tyle
    -      <strong class="spinach">S</strong>heets
    -    </p>
    -    <p id="second">
    -      <strong>C</strong>ascading
    -      <strong>S</strong>tyle
    -      <strong>S</strong>heets
    -    </p>
    -  </body>
    -</html>
    -
    -
  4. -
  5. Теперь отредактируйте свой файл CSS. Замените все содержимое на: -
    strong { color: red; }
    -.carrot { color: orange; }
    -.spinach { color: green; }
    -#first { font-style: italic; }
    -
    -
  6. -
  7. Сохраните файлы и обновите свой браузер, чтобы увидеть результат: - - - - - - - - - -
    Cascading Style Sheets
    Cascading Style Sheets
    - -

    Вы можете попробовать перестроить строки в вашем файле CSS, чтобы показать, что порядок не имеет никакого эффекта.

    - -

    Селекторы классов .carrot и .spinach имеют приоритет над селектором тега strong.

    - -

    Селектор ID #first имеет приоритет над селекторами класс и тег.

    -
  8. -
- -
-
Вызовы
- -
    -
  1. Не изменяя свой HTML-файл, добавьте в свой CSS-файл одно правило, которое сохраняет все начальные буквы того же цвета, что и сейчас, но делает весь текст во втором абзаце синим: - - - - - - - - - - -
    Cascading Style Sheets
    Cascading Style Sheets
    -
  2. -
  3. Теперь измените правило, которое вы только что добавили (не изменяя ничего другого), чтобы сделать первый абзац синим: - - - - - - - - - -
    Cascading Style Sheets
    Cascading Style Sheets
    -
  4. -
- -
-
Possible solution
- -
    -
  1. Add a rule with an ID selector of #second and a declaration color: blue;, as shown below: - -
    #second { color: blue; }
    -
    - A more specific selector, p#second also works.
  2. -
  3. Change the selector of the new rule to be a tag selector using p: -
    p { color: blue; }
    -
    -
  4. -
-Hide solution
-See a solution for the challenge.
- -

Действие: Использование селекторов псевдокласса

- -
    -
  1. Создайте HTML-файл со следующим содержимым: - -
    <!doctype html>
    -<html>
    -  <head>
    -  <meta charset="UTF-8">
    -  <title>Sample document</title>
    -  <link rel="stylesheet" href="style1.css">
    -  </head>
    -  <body>
    -    <p>Go to our <a class="homepage" href="http://www.example.com/" title="Home page">Home page</a>.</p>
    -  </body>
    -</html>
    -
    -
  2. -
  3. Теперь отредактируйте свой файл CSS. Замените все содержимое на: -
    a.homepage:link, a.homepage:visited {
    -  padding: 1px 10px 1px 10px;
    -  color: #fff;
    -  background: #555;
    -  border-radius: 3px;
    -  border: 1px outset rgba(50,50,50,.5);
    -  font-family: georgia, serif;
    -  font-size: 14px;
    -  font-style: italic;
    -  text-decoration: none;
    -}
    -
    -a.homepage:hover, a.homepage:focus, a.homepage:active {
    -  background-color: #666;
    -}
    -
    -
  4. -
  5. Сохраните файлы и обновите свой браузер, чтобы увидеть результат (наведите указатель мыши на следующую ссылку, чтобы увидеть эффект): - - - - - - -
    Перейдите к нашей Домашняя страница 
    -
  6. -
- -

Действие: Использование селекторов на основе отношений и псевдоклассов

- -

С помощью селекторов, основанных на связях и псевдоклассах, вы можете создавать сложные каскадные алгоритмы. Это обычная техника, используемая, например, для создания чисто-CSS выпадающее меню ( это только CSS, без использования JavaScript). Суть этого метода заключается в создании правила следующего вида:

- -
div.menu-bar ul ul {
-  display: none;
-}
-
-div.menu-bar li:hover > ul {
-  display: block;
-}
- -

для применения к структуре HTML, наподобии следующей:

- -
<div class="menu-bar">
-  <ul>
-    <li>
-      <a href="example.html">Menu</a>
-      <ul>
-        <li>
-          <a href="example.html">Link</a>
-        </li>
-        <li>
-          <a class="menu-nav" href="example.html">Submenu</a>
-          <ul>
-            <li>
-              <a class="menu-nav" href="example.html">Submenu</a>
-              <ul>
-                <li><a href="example.html">Link</a></li>
-                <li><a href="example.html">Link</a></li>
-                <li><a href="example.html">Link</a></li>
-                <li><a href="example.html">Link</a></li>
-              </ul>
-            </li>
-            <li><a href="example.html">Link</a></li>
-          </ul>
-        </li>
-      </ul>
-    </li>
-  </ul>
-</div>
-
- -

Смотрите наш полный Пример CSS-основанного выпадающего меню для возможной реплики.

- -

Что дальше?

- -

Ваша таблица стилей начинает выглядеть плотной и сложной. Следующая секция описывает пути CSS легкого чтения. {{nextPage("/en-US/docs/Web/Guide/CSS/Getting_Started/Readable_CSS", "Readable CSS")}}

diff --git "a/files/ru/web/guide/css/getting_started/svg_\320\270_css/index.html" "b/files/ru/web/guide/css/getting_started/svg_\320\270_css/index.html" deleted file mode 100644 index a69c4281af..0000000000 --- "a/files/ru/web/guide/css/getting_started/svg_\320\270_css/index.html" +++ /dev/null @@ -1,213 +0,0 @@ ---- -title: SVG и CSS -slug: Web/Guide/CSS/Getting_started/SVG_и_CSS -translation_of: Web/SVG/Tutorial/SVG_and_CSS ---- -
{{CSSTutorialTOC}}
- -

На этой странице показано, как использовать CSS со специальным языком для создания графики: SVG.

- -

Вы сделаете небольшой пример, которые можно будет запустить в любом браузере с поддержкой SVG.

- -

Это вторая секция Части II Руководство по CSS.
- Предыдущая секция: JavaScript
- Следующая секция: Данные XML

- -

Общая информация: SVG

- -

SVG (Scalable Vector Graphics) является подмножеством языка XML и предназначен для создания графики.

- -

SVG можно использовать для статических изображений, а также для анимаций и создания пользовательских интерфейсов.

- -

Как и прочие языки, основанные на XML, SVG поддерживает использование таблиц стилей CSS, что позволяет отделить различные варианты визуального отображения от структуры данных.

- -

Кроме того, таблицы стилей, которые вы используете в других языках разметки документов, могут содержать ссылку на SVG графику, в тех местах, где необходимо изображение. Например, в таблице стилей, для вашего HTML документа, можно указать ссылку (URL) на SVG графику в свойстве background.

- - - - - - - - -
Немного подробностей
-

На момент написания статьи (середина 2011года), большинство современных браузеров имеет базовую поддержку SVG, в том числе Internet Explorer 9 и выше. Некоторые дополнительные возможности SVG не поддерживаются, либо поддерживаются лишь частично, в определенных браузерах. Для более подробной информации о текущей поддержке SVG, см. SVG tables on caniuse.com, либо в таблицах совместимости SVG element reference, для информации о поддержке отдельных элементов.

- -

В остальные версии можно добавить поддержку SVG, установив дополнительный плагин, например, предоставленный компанией Adobe.

- -

Более подробная информация о SVG в Mozilla, представлена на станице SVG в этой wiki.

-
- -

За дело: Демонстрация SVG

- -

Создайте новый документ SVG, как обычный текстовый файл, doc8.svg. Скопируйте и вставьте содержимое блока ниже, убедитесь, что пролистали его полностью, чтобы скопировать все:

- -
<?xml version="1.0" standalone="no"?>
-
-<?xml-stylesheet type="text/css" href="style8.css"?>
-
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
-  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-
-<svg width="600px" height="600px" viewBox="-300 -300 600 600"
-  xmlns="http://www.w3.org/2000/svg" version="1.1"
-  xmlns:xlink="http://www.w3.org/1999/xlink">
-
-<title>SVG demonstration</title>
-<desc>Mozilla CSS Getting Started - SVG demonstration</desc>
-
-<defs>
-  <g id="segment" class="segment">
-    <path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z"/>
-    <path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10"/>
-    </g>
-  <g id="quadrant">
-    <use xlink:href="#segment"/>
-    <use xlink:href="#segment" transform="rotate(18)"/>
-    <use xlink:href="#segment" transform="rotate(36)"/>
-    <use xlink:href="#segment" transform="rotate(54)"/>
-    <use xlink:href="#segment" transform="rotate(72)"/>
-    </g>
-  <g id="petals">
-    <use xlink:href="#quadrant"/>
-    <use xlink:href="#quadrant" transform="rotate(90)"/>
-    <use xlink:href="#quadrant" transform="rotate(180)"/>
-    <use xlink:href="#quadrant" transform="rotate(270)"/>
-    </g>
-  <radialGradient id="fade" cx="0" cy="0" r="200"
-      gradientUnits="userSpaceOnUse">
-    <stop id="fade-stop-1" offset="33%"/>
-    <stop id="fade-stop-2" offset="95%"/>
-    </radialGradient>
-  </defs>
-
-<text id="heading" x="-280" y="-270">
-  SVG demonstration</text>
-<text  id="caption" x="-280" y="-250">
-  Move your mouse pointer over the flower.</text>
-
-<g id="flower">
-  <circle id="overlay" cx="0" cy="0" r="200"
-    stroke="none" fill="url(#fade)"/>
-  <use id="outer-petals" xlink:href="#petals"/>
-  <use id="inner-petals" xlink:href="#petals"
-    transform="rotate(9) scale(0.33)"/>
-  </g>
-
-</svg>
-
- -

Создайте новый файл CSS, style8.css. копируйте и вставьте содержимое блока ниже, убедитесь, что пролистали его полностью, чтобы скопировать все:

- -
/*** SVG demonstration ***/
-
-/* page */
-svg {
-  background-color: beige;
-  }
-
-#heading {
-  font-size: 24px;
-  font-weight: bold;
-  }
-
-#caption {
-  font-size: 12px;
-  }
-
-/* flower */
-#flower:hover {
-  cursor: crosshair;
-  }
-
-/* gradient */
-#fade-stop-1 {
-  stop-color: blue;
-  }
-
-#fade-stop-2 {
-  stop-color: white;
-  }
-
-/* outer petals */
-#outer-petals {
-  opacity: .75;
-  }
-
-#outer-petals .segment-fill {
-  fill: azure;
-  stroke: lightsteelblue;
-  stroke-width: 1;
-  }
-
-#outer-petals .segment-edge {
-  fill: none;
-  stroke: deepskyblue;
-  stroke-width: 3;
-  }
-
-#outer-petals .segment:hover > .segment-fill {
-  fill: plum;
-  stroke: none;
-  }
-
-#outer-petals .segment:hover > .segment-edge {
-  stroke: slateblue;
-  }
-
-/* inner petals */
-#inner-petals .segment-fill {
-  fill: yellow;
-  stroke: yellowgreen;
-  stroke-width: 1;
-  }
-
-#inner-petals .segment-edge {
-  fill: none;
-  stroke: yellowgreen;
-  stroke-width: 9;
-  }
-
-#inner-petals .segment:hover > .segment-fill {
-  fill: darkseagreen;
-  stroke: none;
-  }
-
-#inner-petals .segment:hover > .segment-edge {
-  stroke: green;
-  }
-
- -

Откройте документ в вашем браузере с поддержкой SVG. Переместите указатель мыши на изображение.

- -

Эта wiki не поддерживает вставку SVG в страницы, поэтому мы не имеем возможности продемонстрировать это здесь. Изображение будет выглядеть так:

- - - - - - - -
SVG demonstration
- -

Примечания к демонстрации:

- -
    -
  • Документ SVG привязывается к таблице стилей общепринятым способом.
  • -
  • SVG содержит собственные свойства CSS и их значения. Некоторые из них похожи на значения CSS для HTML.
  • -
- - - - - - - - -
Задание
Измение таблицу стилей так, чтобы все внутренние лепестки становились розовыми, по наведению курсора на одного из них, при этом нельзя менять принцип работы других лепестков.
- -

Посмотреть решение к этому заданию.

- -

Что дальше?

- -

В этой демонстрации, ваш браузер с поддержкой SVG уже знает, как отображать элементы  SVG. Таблица стилей всего лишь некоторым образом меняет отображение. То же самое происходит с документами HTML и XUL. Однако CSS можно использовать для любых документов XML, в которых нет предусмотренного по умолчанию способа отображения элементов. Данный пример продемонстрирован на следующей странице: Данные XML

diff --git a/files/ru/web/guide/css/getting_started/text_styles/index.html b/files/ru/web/guide/css/getting_started/text_styles/index.html deleted file mode 100644 index a25565cf79..0000000000 --- a/files/ru/web/guide/css/getting_started/text_styles/index.html +++ /dev/null @@ -1,152 +0,0 @@ ---- -title: Text styles -slug: Web/Guide/CSS/Getting_started/Text_styles -translation_of: Learn/CSS/Styling_text/Fundamentals -translation_of_original: Web/Guide/CSS/Getting_started/Text_styles ---- -

{{ CSSTutorialTOC() }}

- -

{{previousPage("/en-US/docs/Web/Guide/CSS/Getting_Started/Readable_CSS", "Readable CSS")}}This is the 7th section of the CSS Getting Started tutorial; it gives more examples of text styles. You modify your sample stylesheet to use different fonts.

- -

Information: Text styles

- -

CSS имеет несколько свойств для стилизации текста.

- -

There is a convenient shorthand property, {{ cssxref("font") }}, which you can use to specify several aspects at once—for example:

- -
    -
  • Bold, italic, and small-caps (small capitals)
  • -
  • Size
  • -
  • Line height
  • -
  • Font typeface
  • -
- -
-
Example
- -
p {
-font: italic 75%/125% "Comic Sans MS", cursive;
-}
-
- -

This rule sets various font properties, making all paragraphs italic.

- -

The font size is set to three-quarters of the size in each paragraph's parent element, and the line height is set to 125% (a little more spaced than normal).

- -

The font typeface is set to Comic Sans MS, but if this typeface is not available then the browser will use its default cursive (hand-written) typeface.

- -

The rule has the side-effect of turning off bold and small-caps (setting them to normal).

-
- -

Font faces

- -

You cannot predict what typefaces the readers of your document will have. When you specify font typefaces, it is a good idea to give a list of alternatives in order of preference.

- -

End the list with one of the built-in default typefaces: serif, sans-serif, cursive, fantasy or monospace.

- -

If the typeface does not support some features in the document, then the browser can substitute a different typeface. For example, the document might contain special characters that the typeface does not support. If the browser can find another typeface that has those characters, then it will use the other typeface.

- -

To specify a typeface on its own, use the {{ cssxref("font-family") }} property.

- -

Font sizes

- -

Browser users can override the default font sizes or change the text size while they read a page, so it makes good sense for you to use relative sizes wherever you can.

- -

You can use some built-in values for font sizes, like small, medium and large. You can also use values relative to the font size of the parent element like: smaller, larger, 150% or 1.5em. An "em" is equivalent to the width of the letter "m" (for the font size of the parent element); thus 1.5em is one-and-a-half times the size of the font of the parent element.

- -

If necessary you can specify an actual size like: 14px (14 pixels) for a display device or 14pt (14 points) for a printer. This is not accessible for visually impaired users because it does not allow them to change the size. A more accessible strategy is to set a built-in value like medium on a top-level element of the document, and then set relative sizes for all its descendent elements.

- -

To specify a font size on its own, use the {{ cssxref("font-size") }} property.

- -

Line height

- -

The line height specifies the spacing between lines. If your document has long paragraphs with many lines, a larger-than-normal spacing makes it easier to read, especially if the font size is small.

- -

To specify a line height on its own, use the {{ cssxref("line-height") }} property.

- -

Decoration

- -

The separate {{ cssxref("text-decoration") }} property can specify other styles, like underline or line-through. You can set it to none to explicitly remove any decoration.

- -

Other properties

- -

To specify italic on its own, use {{ cssxref("font-style") }}: italic;
- To specify bold on its own, use {{ cssxref("font-weight") }}: bold;
- To specify small capitals on its own, use {{ cssxref("font-variant") }}: small-caps;

- -

To turn any of these off individually, you can specify the value normal or inherit.

- -
-
More details
- -

You can specify text styles in a variety of other ways.

- -

For example, some of the properties mentioned here have other values that you can use.

- -

In a complex stylesheet, avoid using the shorthand font property because of its side-effects (resetting other individual properties).

- -

For full details of the properties that relate to fonts, see Fonts in the CSS Specification. For full details of text decoration, see Text.

- -

If you don't want to depend on the typefaces installed on users' systems, you can use {{ cssxref("@font-face") }} to specify an online font. However, this requires that the users have a browser that supports this rule.

-
- -

Action: Specifying fonts

- -

For a simple document, you can set the font of the {{ HTMLElement("body") }} element and the rest of the document inherits the settings.

- -
    -
  1. Edit your CSS file.
  2. -
  3. Add the following rule to change the font throughout the document. The top of the CSS file is a logical place for it, but it has the same effect wherever you put it: -
    body {
    -font: 16px "Comic Sans MS", cursive;
    -}
    -
    -
  4. -
  5. Add a comment explaining the rule, and add white space to make it match your preferred layout.
  6. -
  7. Save the file and refresh your browser to see the effect. If your system has Comic Sans MS, or another cursive font that does not support italic, then your browser chooses a different font face for the italic text in the first line: - - - - - - - - - -
    Cascading Style Sheets
    Cascading Style Sheets
    -
  8. -
  9. From your browser's menu bar, choose View > Text Size > Increase (or View > Zoom > Zoom In). Even though you specified 16 pixels in the style, a user reading the document can change the size.
  10. -
- -
-
Challenge
- -

Without changing anything else, make all six initial letters twice the size in the browser's default serif font:

- - - - - - - - - - -
Cascading Style Sheets
Cascading Style Sheets
- -
-
Possible solution
- -

Add the following style declaration to the strong rule:

- -
  font: 200% serif;
-
-If you use separate declarations for font-size and font-family, then the font-style setting on the first paragraph is not overridden. - -

 

-Hide solution
-See a solution for the challenge.
- -

What next?

- -

{{nextPage("/en-US/docs/Web/Guide/CSS/Getting_Started/Color", "Color")}}Your sample document already uses several named colors. The next section lists the names of standard colors and explains how you can specify others.

diff --git a/files/ru/web/guide/css/getting_started/what_is_css/index.html b/files/ru/web/guide/css/getting_started/what_is_css/index.html deleted file mode 100644 index 95df2fe915..0000000000 --- a/files/ru/web/guide/css/getting_started/what_is_css/index.html +++ /dev/null @@ -1,120 +0,0 @@ ---- -title: Что такое CSS? -slug: Web/Guide/CSS/Getting_started/What_is_CSS -tags: - - Beginner - - CSS - - 'CSS:Getting_Started' - - Example - - Guide - - Веб - - Новичку -translation_of: Learn/CSS/First_steps/How_CSS_works -translation_of_original: Web/Guide/CSS/Getting_started/What_is_CSS ---- -
{{ CSSTutorialTOC() }}
- -

{{previousPage("/ru/docs/Web/Guide/CSS/Getting_Started", "CSS для начинающих")}} Эта первая статья руководства по CSS для начинающих кратко объясняет, что такое Cascading Style Sheets (CSS). С её помощью вы сможете создать простой документ, который будете использовать в дальнейших разделах.

- -

Информация: Что такое CSS

- -

Каскадные таблицы стилей (Cascading Style Sheets = CSS) — это язык, который отвечает за визуальное представление документов пользователю.

- -

Под документом мы будем понимать набор информации о структуре страницы, описываемый языком разметки.

- -

А представление документа пользователю, в свою очередь, означает его преобразование в удобную для восприятия форму. Браузеры, такие как Firefox, Chrome или Internet Explorer, были созданы для визуального отображения документов, например, на экране компьютера, проекторе или вывода через принтер.

- -
-

Примеры

- -
    -
  • Страница сайта, которую вы сейчас читаете — это документ. Структура информации, которую вы видите на странице, обычно описывается при помощи языка разметки HTML (HyperText Markup Language — Язык ГиперТекстовой Разметки)
  • -
  • Диалоговые окна в компьютерных программах, также называемые модальными окнами, как правило, также являются документами. Такие окна могут также быть описаны с помощью языка разметки, такого как XUL (XML User Interface Language — XML’ный Язык Пользовательского Интерфейса), которые можно найти, например, в некоторых приложениях от Mozilla.
  • -
-
- -

В этом руководстве блоки с заголовком Подробнее, как нижеследующий, содержат дополнительную информацию и ссылки на ресурсы, позволяющие более глубоко изучить вопрос, которому посвящен тот или иной раздел. Вы можете сразу же воспользоваться этими материалами или же пропустить эти блоки и вернуться к ним позже.

- -
-
Подробнее
- -

Документ это не то же самое, что файл. Но, тем не менее, документ может храниться в одном файле.

- -

Со страницей, которую вы сейчас читаете, дела обстоят немного сложнее. Когда ваш браузер запрашивает данную страницу, сервер обращается к базе данных и генерирует документ, собирая его по частям из нескольких документов, каждый из которых, в свою очередь, может располагаться в нескольких файлах. Однако в этом руководстве вы также сможете работать с документами, каждый из которых представлен одним файлом.

- -

Больше информации о документах и языках разметки вы найдете в других разделах этого сайта:

- - - - - - - - - - - - - - - - - - - - -
HTMLо веб-страницах
XMLо структуре документов в общем
SVGо графике
XULо пользовательских интерфейсах в Mozilla
- -

Во второй части данного руководства вы встретите примеры этих языков разметки.

-
- -
-
Подробнее
- -

В терминах CSS программа, которая выводит документ пользователю, так называемому user agent (UA). Браузер — один из видов UA. CSS, таким образом, не предназначен только для браузеров или визуального представления, но в первой части данного руководства вы будете работать с CSS только в браузере.

- -

Прочие определения и термины, имеющие отношение к CSS, вы можете найти в Определениях спецификации CSS, созданной World Wide Web Consortium (W3C), международным сообществом которое установило открытые стандарты web.

-
- -

К действию: Создание документа

- -
    -
  1. Создайте новую папку на вашем компьютере для упражнений.
  2. -
  3. Откройте текстовый редактор и создайте новый текстовый файл. Этот файл будет содержать документ для нескольких следующих упражнений.
  4. -
  5. Скопируйте и вставьте HTML, приведенный ниже, а затем сохраните ваш файл под именем doc1.html. -
    <!DOCTYPE html>
    -<html>
    -  <head>
    -  <meta charset="UTF-8">
    -  <title>Sample document</title>
    -  </head>
    -
    -  <body>
    -    <p>
    -      <strong>C</strong>ascading
    -      <strong>S</strong>tyle
    -      <strong>S</strong>heets
    -    </p>
    -  </body>
    -</html>
    - -

    {{ LiveSampleLink('Action.3A_Creating_a_document', 'Посмотреть демо') }}

    -
  6. -
  7. Откройте новую вкладку или новое окно в вашем браузере и откройте только что созданный файл. -

    Вы должны увидеть строку, в которой заглавные буквы выделены полужирным начертанием:

    - - - - - - - -
    Cascading Style Sheets
    - -

    То, что вы увидите на самом деле, может немного отличаться потому, что настройки по умолчанию вашего браузера и данной энциклопедии наверняка будут отличаться: небольшие различия в шрифте, пробелах и цветах не очень-то и важны.

    -
  8. -
- -

Что дальше?

- -

{{nextPage("/ru/docs/Web/Guide/CSS/Getting_Started/Why_use_CSS", "Зачем нужен CSS?")}}В документе, который вы создали, CSS пока что не использовался. В следующем разделе вы научитесь использовать CSS для стилизации документа.

diff --git a/files/ru/web/guide/css/getting_started/why_use_css/index.html b/files/ru/web/guide/css/getting_started/why_use_css/index.html deleted file mode 100644 index 3041d28920..0000000000 --- a/files/ru/web/guide/css/getting_started/why_use_css/index.html +++ /dev/null @@ -1,110 +0,0 @@ ---- -title: Зачем нужен CSS? -slug: Web/Guide/CSS/Getting_started/Why_use_CSS -tags: - - Beginner - - CSS - - 'CSS:Getting_Started' - - Example - - Guide - - Web - - Веб - - Новичку - - Руководство -translation_of: Learn/CSS/First_steps/How_CSS_works -translation_of_original: Web/Guide/CSS/Getting_started/Why_use_CSS ---- -

{{ CSSTutorialTOC() }}

- -

{{ previousPage("/ru/docs/Web/Guide/CSS/Getting_Started/What_is_CSS", "Что такое CSS?") }}Это вторая статья руководства по CSS для начинающих, объясняющая взаимосвязь между CSS и документами. В ней вы узнаете, как добавить CSS стили для документа, который вы создали в процессе изучения первой статьи.

- -

Информация: Зачем нужен CSS?

- -

CSS используется для определения стилей ваших документов, в том числе дизайна, верстки и вариаций макета для различных устройств и размеров экрана. Вы можете разместить стили CSS внутри тега <HEAD> документа с встроенной таблицей стилей, или приложить отдельный CSS-файл, который будет определять ваши стили извне. Чтобы привязать внешнюю таблицу стилей к документу, просто добавьте ссылку на таблицу стилей в заголовке <HEAD> документа.

- -

У внешней таблицы стилей есть множество преимуществ. Сохранение стилей отдельно от содержания HTML:

- -
    -
  • Помогает избежать дублирования
  • -
  • Облегчает обслуживание
  • -
  • Позволяет делать изменения для всего сайта в одном месте
  • -
- -
-
Пример
- -

Используя CSS, вы храните информацию о стилях в общих файлах, которые доступны всем страницам. Например, когда документы ссылаются на те таблицы стилей, которые определяют цвет заголовков h2, вы можете применить стиль для тегов заголовков h2 на глобальном уровне путем изменения одного атрибута CSS.

- -

Когда пользователь открывает веб-страницу, браузер загружает информацию стиля вместе с содержанием страницы.

- -

Когда пользователь открывает веб-страницу в режиме печати, вы можете предоставить различную информацию о стилях которая сделает страницу более лёгкой для чтения.

-
- -

Как заставить HTML и CSS работать вместе? В целом, HTML используется для описания содержимого документа, а не его стиля. CSS же используется, чтобы указать стиль документа, но не содержание. Позже в руководстве вы увидите некоторые исключения из этого правила.

- -
-
Подробнее
- -

Язык разметки, типа HTML также обеспечивает некоторые способы задания стилей.

- -

Например, в HTML вы можете использовать тег <B>, чтобы сделать текст жирным, либо указать цвет фона страницы в теге <BODY>.

- -

При использовании CSS, задание стилей средствами языка разметки обычно не используется, поскольку вся информация о стилях легко доступна для чтения и изменения в CSS-файле.

-
- -

Действие: Создание таблицы стилей

- -
    -
  1. Создайте новый текстовый файл в том же каталоге, что и doc1.html, созданный в первой статье.
  2. -
  3. Сохраните его как style1.css. Этот файл будет вашей таблицей стилей.
  4. -
  5. Скопируйте и вставьте в CSS-файл приведённую ниже строку, после чего сохраните файл: -
    strong {color: red;}
    -
    -
  6. -
- -

Привязка таблицы стилей к документу

- -
    -
  1. Для привязки вашего документа к таблице стилей, необходимо внести в HTML-файл некоторые исправления. Добавьте строки, приведённые ниже: -
    <!DOCTYPE html>
    -<html>
    -  <head>
    -  <meta charset="UTF-8">
    -  <title>Sample document</title>
    -  <link rel="stylesheet" href="style1.css">
    -  </head>
    -  <body>
    -    <p>
    -      <strong>C</strong>ascading
    -      <strong>S</strong>tyle
    -      <strong>S</strong>heets
    -    </p>
    -  </body>
    -</html>
    -
    -
  2. -
  3. Сохраните файл, и откройте его в браузере. Таблица стилей сделает заглавные буквы красными:
  4. -
- -

{{ EmbedLiveSample('Действие_Создание_таблицы_стилей', '', '', '', 'Web/Guide/CSS/Getting_started/Why_use_CSS') }}

- -

{{ LiveSampleLink('Action.3A_Creating_a_stylesheet', 'Просмотреть демо') }}

- -
-
Задание
- -

В дополнение к красному, в CSS имеются и другие названия цветов.

- -

Не открывая подсказку, подберите ещё пять цветовых имён, которые будут работать в CSS.

- -
-
Возможное решение
- -

CSS поддерживает общие названия цветов, например orange, yellow, blue, green, или black. Он также поддерживает некоторые более экзотические названия типа chartreuse, fuschia, или burlywood. Посмотрите значения цвета CSS, чтобы ознакомится с полным списком поддерживаемых цветов, а так же методов их задания.

-Скрыть решение
-Посмотреть решение задания.
- -

Что дальше?

- -

{{nextPage("/ru/docs/Web/Guide/CSS/Getting_started/How_CSS_works", "Как работает CSS.")}}  Теперь, когда у вас есть образец документа, связанный с отдельной таблицей стилей, вы готовы узнать больше о том, как ваш браузер объединяет их при отображении документа.

diff --git "a/files/ru/web/guide/css/getting_started/\321\202\320\260\320\261\320\273\320\270\321\206\321\213/index.html" "b/files/ru/web/guide/css/getting_started/\321\202\320\260\320\261\320\273\320\270\321\206\321\213/index.html" deleted file mode 100644 index 82b7edae60..0000000000 --- "a/files/ru/web/guide/css/getting_started/\321\202\320\260\320\261\320\273\320\270\321\206\321\213/index.html" +++ /dev/null @@ -1,525 +0,0 @@ ---- -title: Таблицы -slug: Web/Guide/CSS/Getting_started/Таблицы -tags: - - CSS - - Веб - - Руководство -translation_of: Learn/CSS/Building_blocks/Styling_tables -translation_of_original: Web/Guide/CSS/Getting_started/Tables ---- -

{{CSSTutorialTOC}}{{previousPage("/ru/docs/Web/Guide/CSS/Getting_Started/Layout", "Layout")}}

- -

Это 13-я секция руководства CSS Начало работы; оно описывает более продвинутые селекторы и некоторые специфичные способы, которыми вы можете стилизовать таблицу. Вы создаете новый пример документа, содержащий таблицу и таблицу стилей для неё.

- -

Информация: Таблицы

- -

Таблица распологает информацию в прямоугольной сетке. Некоторые таблицы могут быть сложными, и для сложных таблиц разные браузеры выдают разный результат.

- -

Когда вы проектируете ваш документ, используйте таблицы для выражения отношений между кусочками информации. Поэтому это не важно, если различные браузеры отображают информацию слегка различными способами, потому что значение остается ясным.

- -

Не используйте таблицы необычным способом для создания особенной визуальной разметки. Техники на предыдущей странице руководства (Разметка) предпочтительнее для этой цели.

- -

Структура таблицы

- -

В таблице, каждый кусок информации отображается в ячейке (cell).

- -

Ячейки, лежащие на одной линии, составляют строку (row).

- -

В некоторыех таблицах, строки могут быть сгруппирированы. Специальная группа строк в начале таблицы - заголовок (header), в конце - нижний колонтитул (footer). Главные строки таблицы - тело (body), и они могут быть также сгруппирированы.

- -

Ячейки в линии сверху вниз, составляют столбец (column), но столбцы имеют ограниченное приминение в таблицах CSS.

- -
-
Пример
- -

Таблица Селекторов, основанных на отношении в Селекторы имеет десять ячеек в пяти строках.

- -

Первая строка - заголовок. Остальные четыре строки - тело таблицы. Нижнего колонтитула нет.

- -

У неё два столбца.

-
- -

Это руководство охватывает только простые таблицы, где результат довольно предсказуемый. В простой таблице, каждая ячейка занимает только одну ячейку в строке и в столбце. Вы можете использовать CSS для сложных таблиц, где ячейки занимают диапазон ячеек более чем одна в строке или столбце, но таблицы, подобно этим находятся вне пределов этого руководства.

- -

Рамки

- -

Ячейки не имеют границ.

- -

У ячеек нет рамок и наполнений. По умолчанию, рамки разделены значениями таблицы, свойство {{cssxref("border-spacing")}}. Вы можете также полностью удалить пространство, установив свойство таблицы {{cssxref("border-collapse")}} в collapse.

- -
-
Пример
- -

Здесь три таблицы.

- -

У таблицы слева интервал рамки 0.5 em. У таблицы по центру он составляет ноль. Таблица справа имеет сжатые границы:

- - - - - - - - - -
- - - - - - - - - - - -
ClubsHearts
DiamondsSpades
-
- - - - - - - - - - - -
ClubsHearts
DiamondsSpades
-
- - - - - - - - - - - -
ClubsHearts
DiamondsSpades
-
-
- -

Заголовок

- -

{{HTMLElement("caption")}} элемент - это метка, которая применяется ко всей таблице. По умолчанию, она отображается вверху таблицы.

- -

Чтобы переместить её вниз, установите её свойство {{cssxref("caption-side")}} в bottom. Это свойство наследуется, поэтому, в качестве альтернативы вы можете установить это свойство у таблицы или у другого элемента предка.

- -

Чтобы стилизовать заголовок текста, используйте любое из обычных свойств для текста.

- -
-
Пример
- -

У этой таблицы заголовок внизу

- -
#demo-table > caption {
-  caption-side: bottom;
-  font-style: italic;
-  text-align: right;
-}
-
- - - - - - - -
- - - - - - - -
Подходит
- - - - - - - - - - - -
КлубыСердца
АлмазыЛопаты
-
-
-
- -

Пустые ячейки

- -

Вы можете отобразить пустые ячейки (т.е. их рамки и фон) указывав {{cssxref("empty-cells")}}: show; для элемента таблицы.

- -

Вы можете скрыть их, указав empty-cells: hide;. Тогда, если у элемента родителя ячейки есть фон, он будет отображен через пустую ячейку.

- -
-
Пример
- -

Эти таблицы имеют бледно-зелёный фон. Их ячейки имеют бледно-серый фон и тёмно-серые рамки.

- -

В таблице слева пустая таблица отображается. В таблице справа, она скрыта:

- - - - - - - - -
- - - - - - - - - - - -
 Сердца
АлмазыЛопаты
-
- - - - - - - - - - - -
 Сердца
АлмазыЛопаты
-
-
- -
-
Детали
- -

Для подбробной информации о таблицах, смотрите Таблицы в Спецификации CSS.

- -

Информации там больше, чем в этом руководстве, но она не покрывает различия между браузерами, которые могут влиять на сложные таблицы.

-
- -

Действие: Стилизация таблицы

- -
    -
  1. Создайте новый HTML документ, doc3.html. Скопируйте и вставьте содержимое отсюда: - -
    -
    <!DOCTYPE html>
    -<html>
    -  <head>
    -    <title>Документ примера 3</title>
    -    <link rel="stylesheet" href="style3.css">
    -  </head>
    -  <body>
    -    <table id="demo-table">
    -      <caption>Океаны</caption>
    -      <thead>
    -        <tr>
    -          <th></th>
    -          <th>Площадь</th>
    -          <th>Средняя глубина</th>
    -        </tr>
    -        <tr>
    -          <th></th>
    -          <th>млн. км<sup>2</sup></th>
    -          <th>м</th>
    -        </tr>
    -      </thead>
    -      <tbody>
    -        <tr>
    -          <th>Северный Ледовитый</th>
    -          <td>13,000</td>
    -          <td>1,200</td>
    -        </tr>
    -        <tr>
    -          <th>Атлантический</th>
    -          <td>87,000</td>
    -          <td>3,900</td>
    -        </tr>
    -        <tr>
    -          <th>Тихий</th>
    -          <td>180,000</td>
    -          <td>4,000</td>
    -        </tr>
    -        <tr>
    -          <th>Индийский</th>
    -          <td>75,000</td>
    -          <td>3,900</td>
    -        </tr>
    -        <tr>
    -          <th>Южный</th>
    -          <td>20,000</td>
    -          <td>4,500</td>
    -        </tr>
    -      </tbody>
    -      <tfoot>
    -        <tr>
    -          <th>Общая</th>
    -          <td>361,000</td>
    -          <td></td>
    -        </tr>
    -        <tr>
    -          <th>Средняя</th>
    -          <td>72,000</td>
    -          <td>3,800</td>
    -        </tr>
    -      </tfoot>
    -    </table>
    -  </body>
    -</html>
    -
    -
    -
  2. -
  3. Создайте новую таблицу стилей, style3.css. Скопируйте и вставьте содержимое отсюда: -
    /*** Style for doc3.html (Tables) ***/
    -
    -#demo-table {
    -  font: 100% sans-serif;
    -  background-color: #efe;
    -  border-collapse: collapse;
    -  empty-cells: show;
    -  border: 1px solid #7a7;
    -}
    -
    -#demo-table > caption {
    -  text-align: left;
    -  font-weight: bold;
    -  font-size: 200%;
    -  border-bottom: .2em solid #4ca;
    -  margin-bottom: .5em;
    -}
    -
    -
    -/* basic shared rules */
    -#demo-table th,
    -#demo-table td {
    -  text-align: right;
    -  padding-right: .5em;
    -}
    -
    -#demo-table th {
    -  font-weight: bold;
    -  padding-left: .5em;
    -}
    -
    -
    -/* header */
    -#demo-table > thead > tr:first-child > th {
    -  text-align: center;
    -  color: blue;
    -}
    -
    -#demo-table > thead > tr + tr > th {
    -  font-style: italic;
    -  color: gray;
    -}
    -
    -/* fix size of superscript */
    -#demo-table sup {
    -  font-size: 75%;
    -}
    -
    -/* body */
    -#demo-table td {
    -  background-color: #cef;
    -  padding:.5em .5em .5em 3em;
    -}
    -
    -#demo-table tbody th:after {
    -  content: ":";
    -}
    -
    -
    -/* footer */
    -#demo-table tfoot {
    -  font-weight: bold;
    -}
    -
    -#demo-table tfoot th {
    -  color: blue;
    -}
    -
    -#demo-table tfoot th:after {
    -  content: ":";
    -}
    -
    -#demo-table > tfoot td {
    -  background-color: #cee;
    -}
    -
    -#demo-table > tfoot > tr:first-child td {
    -  border-top: .2em solid #7a7;
    -}
    -
    -
  4. -
  5. Откройте документ в вашем браузере. Он должен выглядеть наподобие этого: - - - - - - -
    -

    Океаны

    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     ПлощадьСредняя глубина
     млн. км2м
    Северный Ледовитый:13,0001,200
    Атлантический:87,0003,900
    Тихий:180,0004,000
    Индийский:75,0003,900
    Южный:20,0004,500
    Общая:361,000 
    Средняя:72,0003,800
    -
    -
    -
  6. -
  7. Сравните правила в таблице стилей с отображенной таблицей, чтобы гарантировать, что вы понимаете действие для каждого правила. Если вы найдете правило, значение которого вы не понимаете, то закомментируйте его и обновите страницу, чтобы посмотреть, что изменилось. Вот несколько заметок об этой таблице: -
      -
    • Заголовок находится снаружи рамки таблицы.
    • -
    • Если у вас установлен минимальный размер точки в Опциях, это может повлиять на верхний индекс в km2.
    • -
    • Три пустые ячейки. Через две из них  позволено показывать фон таблицы. У третьей есть фон и верхняя рамка.
    • -
    • Двоеточия добавлены с помощью таблицы стилей.
    • -
    -
  8. -
- -
-
Вызов
- -

Измените таблицу стилей, чтобы она выглядела, как эта:

- - - - - - - -
-
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 ПлощадьСредняя глубина
 млн. км2м
Северный Ледовитый:13,0001,200
Атлантический:87,0003,900
Тихий:180,0004,000
Индийский:75,0003,900
Южный:20,0004,500
Общая:361,000 
Средняя:72,0003,800
-
-
- -

Океаны

-
-
- -

Посмотреть решение для этой задачи.

- -

Что дальше?

- -

{{nextPage("/ru/docs/Web/Guide/CSS/Getting_Started/Media", "Media")}}Это последняя страница в этом руководстве, которая фокусируется на CSS свойствах и значениях. Для полного обзора свойств и значений, смотрите все свойства таблиц в CSS Спецификациях.

- -

Следующая страница тоже рассматривает цель и структуру CSS таблиц.

diff --git a/files/ru/web/guide/css/index.html b/files/ru/web/guide/css/index.html deleted file mode 100644 index 7529234ef5..0000000000 --- a/files/ru/web/guide/css/index.html +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: Руководство разработчика CSS -slug: Web/Guide/CSS -tags: - - CSS - - Landing - - NeedsTranslation - - TopicStub -translation_of: Learn/CSS -translation_of_original: Web/Guide/CSS ---- -prepare for redirect diff --git a/files/ru/web/guide/css/understanding_z_index/adding_z-index/index.html b/files/ru/web/guide/css/understanding_z_index/adding_z-index/index.html deleted file mode 100644 index 2fff1726d3..0000000000 --- a/files/ru/web/guide/css/understanding_z_index/adding_z-index/index.html +++ /dev/null @@ -1,157 +0,0 @@ ---- -title: Using z-index -slug: Web/Guide/CSS/Understanding_z_index/Adding_z-index -translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/Adding_z-index ---- -
{{cssref}}
- -

The first part of this article, Stacking without the z-index property, explains how stacking is arranged by default. If you want to create a custom stacking order, you can use the {{cssxref("z-index")}} property on a positioned element.

- -

Свойство z-index может иметь значение в целых числах (положительные, ноль, или отрицательные), что представляет собой позицию єлемента вдоль оси z. Если вы не знакомы с осью z, представьте себе страницу как стопку слоев, имеющих собственое порядковое число. Слои представлены в числовом порядке, with larger numbers above smaller numbers.

- -
    -
  • bottom layer (farthest from the observer)
  • -
  • ...
  • -
  • Layer -3
  • -
  • Layer -2
  • -
  • Layer -1
  • -
  • Layer 0 (default rendering layer)
  • -
  • Layer 1
  • -
  • Layer 2
  • -
  • Layer 3
  • -
  • ...
  • -
  • top layer (closest to the observer)
  • -
- -
-

Notes:

- -
    -
  • When no z-index property is specified, elements are rendered on the default rendering layer 0 (zero).
  • -
  • If several elements share the same z-index value (i.e., they are placed on the same layer), stacking rules explained in the section Stacking without z-index apply.
  • -
-
- -

In the following example, the layers' stacking order is rearranged using z-index. The z-index of element #5 has no effect since it is not a positioned element.

- -

{{EmbedLiveSample("Source_code_for_the_example", 600, 400)}}

- -

Source code for the example

- -

HTML

- -
<div id="abs1">
-  <b>DIV #1</b>
-  <br />position: absolute;
-  <br />z-index: 5;
-</div>
-
-<div id="rel1">
-  <b>DIV #2</b>
-  <br />position: relative;
-  <br />z-index: 3;
-</div>
-
-<div id="rel2">
-  <b>DIV #3</b>
-  <br />position: relative;
-  <br />z-index: 2;
-</div>
-
-<div id="abs2">
-  <b>DIV #4</b>
-  <br />position: absolute;
-  <br />z-index: 1;
-</div>
-
-<div id="sta1">
-  <b>DIV #5</b>
-  <br />no positioning
-  <br />z-index: 8;
-</div>
-
- -

CSS

- -
div {
-  padding: 10px;
-  opacity: 0.7;
-  text-align: center;
-}
-
-b {
-  font-family: sans-serif;
-}
-
-#abs1 {
-  z-index: 5;
-  position: absolute;
-  width: 150px;
-  height: 350px;
-  top: 10px;
-  left: 10px;
-  border: 1px dashed #900;
-  background-color: #fdd;
-}
-
-#rel1 {
-  z-index: 3;
-  height: 100px;
-  position: relative;
-  top: 30px;
-  border: 1px dashed #696;
-  background-color: #cfc;
-  margin: 0px 50px 0px 50px;
-}
-
-#rel2 {
-  z-index: 2;
-  height: 100px;
-  position: relative;
-  top: 15px;
-  left: 20px;
-  border: 1px dashed #696;
-  background-color: #cfc;
-  margin: 0px 50px 0px 50px;
-}
-
-#abs2 {
-  z-index: 1;
-  position: absolute;
-  width: 150px;
-  height: 350px;
-  top: 10px;
-  right: 10px;
-  border: 1px dashed #900;
-  background-color: #fdd;
-}
-
-#sta1 {
-  z-index: 8;
-  height: 70px;
-  border: 1px dashed #996;
-  background-color: #ffc;
-  margin: 0px 50px 0px 50px;
-}
-
- -

See also

- - - -
-

Original Document Information

- - -
diff --git a/files/ru/web/guide/css/understanding_z_index/index.html b/files/ru/web/guide/css/understanding_z_index/index.html deleted file mode 100644 index 0074ff2577..0000000000 --- a/files/ru/web/guide/css/understanding_z_index/index.html +++ /dev/null @@ -1,51 +0,0 @@ ---- -title: Понимание CSS z-index -slug: Web/Guide/CSS/Understanding_z_index -tags: - - Advanced - - CSS - - Guide - - NeedsTranslation - - TopicStub - - Understanding_CSS_z-index - - Web - - z-index -translation_of: Web/CSS/CSS_Positioning/Understanding_z_index ---- -

Обычно HTML страницы можно считать двухмерными, потому что текст, картинки и другие элементы расположены на странице без перекрытия. Существует единый нормальный поток отрисовки (rendering flow) и элементы избегают пространства, занятого другими.{{cssxref("z-index")}} атрибут позволяет регулировать порядок наложения объектов друг на друга в процессе отрисовки контента (rendering content).

- -
-

В CSS 2.1, позиция каждого блока была в трех измерениях. В дополнении к их горизонтальной и вертикальной позиции блоки лежали вдоль оси "z" и распологались один поверх другого. Позиция относительно оси "z" особенно актуальна, когда блоки визуально накладываются друг на друга. 

-
- -

(from CSS 2.1 Section 9.9.1 - Layered presentation)

- -

Это означает, что правила стиля CSS позволяют вам позиционировать блоки на слоях в дополнение к обычному слою рендеринга (слой 0). Положение Z каждого слоя выражается как целое число, представляющее порядок наложения для рендеринга. Большие числа означают ближе к наблюдателю. Положение Z можно контролировать с помощью свойства CSS z-index.

- -

Использование z-index кажется чрезвычайно простым: одно свойство, которому присваивается одно целое число, с простым для понимания поведением. Однако, когда z-index применяется к сложным иерархиям элементов HTML, его поведение может быть трудно понять или предсказать. Это обьясняется целым комплексом правил "укладки" элементов. Фактически в спецификации  CSS-2.1 Appendix E (CSS-2.1 Приложение Е) зарезервирован целый раздел, подробно обьясняющий эти правила.

- -

Данная статья попытается объяснить эти правила, с некоторым упрощением и несколькими примерами.

- -
    -
  1. Позиционирование без z-индекса : правила по умолчанию
  2. -
  3. Позиционирование и float : как себя поводят float элементы c позиционированием
  4. -
  5. Использование z-index : Using z-index to change default stacking
  6. -
  7. The stacking context : Notes on the stacking context
  8. -
  9. Stacking context example 1 : 2-level HTML hierarchy, z-index on the last level
  10. -
  11. Stacking context example 2 : 2-level HTML hierarchy, z-index on all levels
  12. -
  13. Stacking context example 3 : 3-level HTML hierarchy, z-index on the second level
  14. -
- -
-

Информация о документе

- -
    -
  • Автор: Paolo Lombardi
  • -
  • Эта статья - английский перевод статьи, которую я написал на итальянском для YappY. Я даю право делиться всем контентом: Creative Commons: Attribution-Sharealike license
  • -
  • Дата последнего обновления: 9 июля 2005 г.
  • -
- -

Примечание автора: спасибо Владимиру Паланту и Роду Уайтли за обзор.

- -
-
diff --git a/files/ru/web/guide/css/understanding_z_index/stacking_without_z-index/index.html b/files/ru/web/guide/css/understanding_z_index/stacking_without_z-index/index.html deleted file mode 100644 index 7f4eb09133..0000000000 --- a/files/ru/web/guide/css/understanding_z_index/stacking_without_z-index/index.html +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: Stacking without z-index -slug: Web/Guide/CSS/Understanding_z_index/Stacking_without_z-index -tags: - - CSS - - z-index -translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_without_z-index ---- -

« CSS « Понимание CSS z-index

- -

Наложения без Z-индекса

- -

Когда элементы не имеют z-индека, они накладываються в таком порядке(снизу вверх):

- -

1. Фон и границы корневого элемента.

- -

2. Дочерние блоки в нормальном потоке в порядке размещения(в HTML порядке).

- -

3. Дочерние позиционированные элементы, в порядке размещения (в HTML порядке).

- -

В следующем примере, абсолютно и относительно спозиционированным блокам определена величина  и позиция таким образом, чтобы продемонстировать правила наложения.

- -
-

Заметки:

- -
    -
  • Given a homogeneous group of elements without any z-index property, such as the positioned blocks (DIV #1 to #4) in the example, the element's stacking order is their order in the HTML hierarchy, regardless of their position.
  • -
  • -

    Standard blocks (DIV #5) in the normal flow, without any positioning property, are always rendered before positioned elements, and appear below them, even if they come later in the HTML hierarchy. 

    -
  • -
-
- -

understanding_zindex_01.png

- -

Пример

- -

HTML

- -
<div id="absdiv1">
-    <br /><span class="bold">DIV #1</span>
-    <br />position: absolute; </div>
-<div id="reldiv1">
-    <br /><span class="bold">DIV #2</span>
-    <br />position: relative; </div>
-<div id="reldiv2">
-    <br /><span class="bold">DIV #3</span>
-    <br />position: relative; </div>
-<div id="absdiv2">
-    <br /><span class="bold">DIV #4</span>
-    <br />position: absolute; </div>
-<div id="normdiv">
-    <br /><span class="bold">DIV #5</span>
-    <br />no positioning </div>
-
- -

CSS

- -
 .bold {
-     font-weight: bold;
-     font: 12px Arial;
- }
- #normdiv {
-     height: 70px;
-     border: 1px dashed #999966;
-     background-color: #ffffcc;
-     margin: 0px 50px 0px 50px;
-     text-align: center;
- }
- #reldiv1 {
-     opacity: 0.7;
-     height: 100px;
-     position: relative;
-     top: 30px;
-     border: 1px dashed #669966;
-     background-color: #ccffcc;
-     margin: 0px 50px 0px 50px;
-     text-align: center;
- }
- #reldiv2 {
-     opacity: 0.7;
-     height: 100px;
-     position: relative;
-     top: 15px;
-     left: 20px;
-     border: 1px dashed #669966;
-     background-color: #ccffcc;
-     margin: 0px 50px 0px 50px;
-     text-align: center;
- }
- #absdiv1 {
-     opacity: 0.7;
-     position: absolute;
-     width: 150px;
-     height: 350px;
-     top: 10px;
-     left: 10px;
-     border: 1px dashed #990000;
-     background-color: #ffdddd;
-     text-align: center;
- }
- #absdiv2 {
-     opacity: 0.7;
-     position: absolute;
-     width: 150px;
-     height: 350px;
-     top: 10px;
-     right: 10px;
-     border: 1px dashed #990000;
-     background-color: #ffdddd;
-     text-align: center;
- }
-
- -

Результат

- -

(If the image does not display in CodePen, click the Tidy button in the CSS section)

- -

{{ EmbedLiveSample('Example', '', '', '', 'Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_without_z-index') }}

- -

Так же посмотрите

- - - -
-

Original Document Information

- - -
diff --git a/files/ru/web/guide/css/using_multi-column_layouts/index.html b/files/ru/web/guide/css/using_multi-column_layouts/index.html deleted file mode 100644 index 65e96fcdcf..0000000000 --- a/files/ru/web/guide/css/using_multi-column_layouts/index.html +++ /dev/null @@ -1,124 +0,0 @@ ---- -title: Использование CSS разметки для многих колонок -slug: Web/Guide/CSS/Using_multi-column_layouts -translation_of: Web/CSS/CSS_Columns/Using_multi-column_layouts ---- -

{{CSSRef("CSS Multi-columns")}}

- -

CSS разметка для многих колонок расширяет способ блочной разметки, чтобы позволить легкое описание нескольких колонок текста. Людям сложно читать текст, если строки слишком длинные; это занимает слишком много времени для глаз, чтобы перемещать взгляд с конца одной на начало следующей строки, и они забывают на какой строке находились. Поэтому, чтобы использовать большие дисплеи по максимуму, авторам следует ограничить ширину колонок текст расположенных бок о бок, как в газетах.

- -

К несчастью, это невозможно сделать с CSS и HTML без принудительного разбиения колонки в фиксированных позициях, или строго ограничить допустимую разметку в тексте, или использовать экстраординарный скрипт. Это ограничение снимается с помощью добавления новых CSS свойств, чтобы расширить традиционный блочный способ разметки.

- -

Использование колонок

- -

Количество колонок и ширина

- -

Два свойства CSS контролируют появятся ли колонки и как много их будет: {{ Cssxref("column-count") }} and {{ Cssxref("column-width") }}.

- -

Свойство column-count устанавливает количество колонок определённым числом. Пример,

- -
<div style="column-count:2;">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
-sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
-quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
-Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
-nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa
-qui officia deserunt mollit anim id est laborum</div>
-
- -

отобразит содержимое в двух колонках (если вы используете многоколоночно совместимый браузер):

- -

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

- -

Свойство column-width устанавливает минимальную желаемую ширину колонки. Если column-count также не установлено, тогда браузер автоматически сделает столько колонок, сколько нужно, чтобы заполнить  доступную ширину.

- -
<div style="column-width:20em;">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
-sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
-quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
-Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
-nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa
-qui officia deserunt mollit anim id est laborum</div>
-
- -

становится:

- -

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

- -

Подробные детали описаны в CSS3 спецификации.

- -

В многоколончатом блоке, содержимое автоматически перетекает из одной колонки в следующую, как это необходимо. Вся HTML, CSS и DOM функциональность поддерживается внутри колонок, как например редактирование и печать.

- -

Краткая запись columns

- -

В большинстве случаев веб-разработчики используют одно из двух свойств CSS: {{ cssxref("column-count") }} или {{ cssxref("column-width") }}. Так как значения для этих свойств не пересекаются, то часто удобно использовать короткую запись {{ cssxref("columns") }}. Пример:

- -

CSS объявление  column-width:12em может быть заменено:

- -
<div style="columns:12em">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
-sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
-quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
-Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
-nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa
-qui officia deserunt mollit anim id est laborum</div>
-
- -

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

- -

CSS объявление column-count:4 может быть заменено:

- -
<div style="columns:4">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
-sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
-quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
-Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
-nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa
-qui officia deserunt mollit anim id est laborum</div>
-
- -

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

- -

Два CSS объявления column-width:8em и column-count:12 могут быть заменены:

- -
<div style="columns:12 8em">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
-sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
-quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
-Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
-nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa
-qui officia deserunt mollit anim id est laborum</div>
-
- -

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

- -

Выравнивание высоты

- -

CSS3-спецификация колонок требует, чтобы высота колонки была выровнена, т.е. браузер автоматически устанавливает максимальную высоту колонки, для того, чтобы высота содержимого в каждой из них была приблизительно одинаковая. Firefox так и делает.

- -

Однако, в некоторых ситуациях полезно установить максимальную высоту колонок явно, тогда расположение содержимого, начиная с первой колонки и последующих созданных, как необходимо, возможно, перекроют правую границу. Поэтому, если высота ограничена, с помощью CSS {{ cssxref("height") }} или {{ cssxref("max-height") }} свойств на многоколончатом блоке, каждой колонке разрешено расти до этой высоты, но не более, пока не добавится новая колонка. Этот режим также более эффективен для разметки.

- -

Промежутки между колонками

- -

Существует промежуток между колонками. По умолчанию рекомендовано значение 1em. Это значение можно изменить, применяя свойство {{ Cssxref("column-gap") }} на многоколончатом блоке:

- -
<div style="column-width:20em; column-gap:2em;">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
-sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
-quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
-Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
-nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa
-qui officia deserunt mollit anim id est laborum</div>
-
- -

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

- -

Постепенное ухудшение

- -

Свойства колонки будут просто проигнорированы браузерами, которые не поддерживают многоколончатый режим. Поэтому соответственно легче создать разметку, которая отобразит содержимое в одной колонке и будет использовать несколько колонок в тех браузерах, которые поддерживают многоколончатый режим.

- -

Обратите внимание, что не все браузеры поддерживают эти свойства без префикса. Чтобы использовать эти свойства в большинстве современных браузеров, каждое свойство должно быть написано трижды: одно с префиксом {{ property_prefix("-moz") }} , одно с префиксом {{ property_prefix("-webkit") }} и третье без префикса.

- -

Заключение

- -

CSS3 колонки - примитивная разметка, которая поможет Веб-разработчикам лучше воспользоваться реальным участком экрана. Разработчики с воображением могут найти много способов для их использования, особенно с автоматическим выравниванием высоты.

- -

Смотрите также

- - diff --git a/files/ru/web/guide/css/visual_formatting_model/index.html b/files/ru/web/guide/css/visual_formatting_model/index.html deleted file mode 100644 index 7a5de35909..0000000000 --- a/files/ru/web/guide/css/visual_formatting_model/index.html +++ /dev/null @@ -1,209 +0,0 @@ ---- -title: Модель визуального форматирования -slug: Web/Guide/CSS/Visual_formatting_model -translation_of: Web/CSS/Visual_formatting_model ---- -

{{CSSRef}}

- -

Модель визуального форматирования CSS  - это алгоритм, используемый для обработки документа и его визуального отображения. Это базовая концепция CSS. Модель визуального форматирования задаёт трансформацию каждого элемента в документе и создаёт ноль, одну или несколько боксов, согласно боксовой модели CSS. Расположение (layout) каждого бокса определяется:

- -
    -
  • размерами бокса: точно заданными или заданными ограничениями. Если размеры не заданы, это правило игнорируется;
  • -
  • типом бокса: inline, inline-level, atomic inline-level, block box;
  • -
  • схемой позиционирования: normal flow, float или absolute;
  • -
  • другими элементами дерева: дочерними и соседними;
  • -
  • размерами и расположением окна просмотра ({{glossary("viewport")}});
  • -
  • внутренними размерами содержащихся изображений;
  • -
  • другой внешней информацией.
  • -
- -

Бокс отображается относительно краев содержащего его блока. Как правило, бокс определяет родительский блок для своих потомков. Однако, стоит заметить, что бокс не ограничен содержащим его блоком. Такое поведение слоев, выходящих за пределы своих содержащих блоков, называется переполенинем (overflow).

- -

Генерация бокса

- -

Генерация бокса - часть алгоритма модели визуального форматирования, процедура, генерирующая блоки из элементов. Различные типы боксов определяют различное поведение в контексте форматирования. Тип бокса зависит от свойства CSS {{ cssxref("display") }}.

- -

Блочные эклементы и блок-боксы

- -

Говорят, что элемент является блочным, когда вычисленное значение его CSS свойства {{ cssxref("display") }} равно: blocklist-item, или table. Блочный элемент визуально форматируется как блок (например, параграф), предназначенный для вертикальной компоновки (в столбик).

- -

Каждый элемент блочного уровня участвует в контексте блочного форматирования. Каждый элемент блочного уровня генерирует как миниум один блок-бокс, названный главным блок-боксом. Некоторые элементы, например, такие как list-item, создают дополнительные боксы для хранения маркеров и других типографических элементов, содержащихся в list item. Большинство блочных элементов генерирует только один, главный блок-бокс.

- -

Главный блок-бокс содержит сгенериованные боксы-потомки и сгенериованный контекст. Он так же будет боксом, участвующем в схеме позиционирования.

- -

venn_blocks.pngЭлемент блочного уровня так же может быть блоком-контейнером. Блок-контейнер - это блок, который содержит либо только другие элементы блочного уровня, либо создаёт контекст инлайнового форматирования и, таким образом, содержит только инлайновые элементы.

- -

Важно понимать, что понятие блочного элемента и понятие блочного контейнера - это разные вещи. Первое описывает, как блок будет себя вести по отношению к своему родителю и своим соседям/братьям. А второе - описывает, как блок будет взаимодействовать со своими потомками. Некоторые элементы блочного уровня, например, таблицы, не являются содержащими блоками. И наоборот, некоторые блоки-контейнеры, например, ячейки таблицы, не являются элементами блочного уровня.

- -

Элементы блочного уровня, которые так же являются контейнерами, называются блок-боксами.

- -

Анонимные блок-боксы

- -

В некоторых случаях алгоритм визуального форматирования  вынужден добавлять дополнительные боксы. Так как эти боксы невозможно как-то проименовать и к ним невозможно применить css-селекторы, поэтому эти боксы называют анонимными.

- -

Из-за того, что к анонимным боксам невозможно применить селекторы, их невозможно изменить с помощью таблицы стилей. Это значит, что все наследуемые CSS свойства для них будут иметь значение inherit, а все ненаследуемые свойства будут иметь значение initial.

- -

Блоки-контейнеры содержат либо только инлайн-боксы, либо только элементы блочного уровня. Но, как правило, документ содержит и те и другие. В этом случае анонимные блок-боксы создаются вокруг примыкающих к ним инлайн-боксов.

- -

Пример

- -

Возьмём следующий HTML код (со стилями по умолчанию, то есть элементы {{ HTMLElement("div") }} и {{ HTMLElement("p") }} имеют значение display:block :

- -
<div>Some inline text <p>followed by a paragraph</p> followed by more inline text.</div>
- -

Здесь создались два анонимных блока: один для текста перед параграфом (Some inline text), и второй для текста после параграфа (followed by more inline text.). И у нас получилась вот такая структура:

- -

anonymous_block-level_boxes.png

- -

Выглядеть это будет так:

- -
Some inline text
-followed by a paragraph
-followed by more inline text.
- -

В отличие от параграфа {{ HTMLElement("p") }}, Web разработчик не может напрямую контролировать стили этих двух анонимных боксов. Те свойства, которые наследуются, берут своё значение от элемента {{ HTMLElement("div") }}, например {{ cssxref("color") }}, определяющий цвет текста. А другие значения, ненаследуемые, устанавливаются в значение initial. Например, у них не будет своего свойства {{ cssxref("background-color") }}, он всегда будет в состоянии "прозрачный" (transparent), значении по умолчанию для этого свойства, и поэтому будет видно тот background, который установлен у элемента <div>. А вот для параграфа <p> можно установить своё свойство цвета фона. Таким образом, эти два анонимных бокса будут иметь один и тот же цвет текста.

- -

Ещё один случай, который приводит к созданию анонимных блок-боксов, это случай, когда инлайн-бокс содержит один или несколько блок-боксов. В этом случае элемент, содержащий блок-боксы, делится на два инлайн-бокса - один перед, а второй после блок-бокса. И потом инлайн-элементы перед и после блок-бокса дополнительно заключаются в анонимные блок-боксы. Таким образом блок-бокс становится соседом для анонимных блок-боксов, содержащих инлайн-элементы.

- -

Если есть несколько блок-боксов, идущих подряд, без инлайн-элементов между ними, то анонимные блок-боксы создаются только перед и после такого набора блок-боксов.

- -

Пример

- -

Возьмём следующий HTML код, где установим для элемента {{ HTMLElement("p") }} значение display:inline и для элемента {{ HTMLElement("span") }} значение display:block :

- -
<p>Some <em>inline</em> text <span>followed by a paragraph</span> followed by more inline text.</p>
- -

Создадутся два анонимных блок-бокса, один для текста перед элементом span (Some inline text) и один для текста после него (followed by more inline text), и у нас получится вот такая структура:

- -

- -

Выглядеть она будет так:

- -
Some inline text
-followed by a paragraph
-followed by more inline text.
- -

Элементы инлайн-уровня и инлайн-боксы

- -

Элементы, которые называются элементами инлайн-уровня - это элементы, у которых вычисленное значение CSS свойства {{ cssxref("display") }} установлено в : inline, inline-block или inline-table. Визуально они не представляют собой какие-то отдельные блоки, но они они распологаются в одну линию с другим контентом инлайн-уровня. Например, содержание параграфа, с различным форматированием, таким как подчёркивание или картинка, состоит из элементов инлайн-уровня.

- -

venn_inlines.png

- -
-

Эта диаграмма использует устаревшую терминологию; см. примечания ниже. К тому же она некорректна, потому что жёлтый эллипс справа по определению должен быть изображён одинаковым по размеру с эллипсом слева или больше него  (it could be a mathematical superset), потому что в спецификации сказано: "Элементв инлайн-уровня генерируют боксы инлайн-уровня, участвующие в форматировании инлайн-уровня", см. CSS 2.2, глава 9.2.2

-
- -

Элементы инлайн-уровня создают боксы инлайн-уровня, которые определены как боксы, участвующие в контексте форматирования инлайн-уровня. Inline boxes are both inline-level boxes and boxes, whose contents participate in their container's inline formatting context. This is the case, for example, for all non-replaced boxes with display:inline. Inline-level boxes, whose contents do not participate in an inline formatting context, are called atomic inline-level boxes. These boxes, generated by replaced inline-level elements or by elements with a calculated {{ cssxref("display") }} value of inline-block or inline-table, are never split into several boxes, as is possible with inline boxes.

- -
Note: Initially, atomic inline-level boxes were called atomic inline boxes. This was unfortunate, as they are not inline boxes. This was corrected in an erratum to the spec. Nevertheless, you can harmlessly read atomic inline-level box each time you meet atomic inline box in the literature, as this is only a name change.
- -
Atomic inline boxes cannot be split into several lines in an inline formatting context. -
-
<style>
-  span {
-    display:inline; /* default value*/
-  }
-</style>
-<div style="width:20em;">
-   The text in the span <span>can be split in several
-   lines as it</span> is an inline box.
-</div>
-
-
- -

which leads to:

- -
The text in the span can be split into several lines as it is an inline box.
- -
<style>
-  span {
-    display:inline-block;
-  }
-</style>
-<div style="width:20em;">
-   The text in the span <span>cannot be split in several
-   lines as it</span> is an inline-block box.
-</div>
- -
-
-

which leads to:

- -
The text in the span cannot be split into several lines as it is an inline-block box.
-
-
- -

Anonymous inline boxes

- -

As for block boxes, there are a few cases where inline boxes are created automatically by the CSS engine. These inline boxes are also anonymous as they cannot be named by selectors; they inherit the value of all inheritable properties, setting it to initial for all others.

- -

The most common case where an anonymous inline box is created, is when some text is found as a direct child of a block box creating an inline formatting context. In that case, this text is included in the largest possible anonymous inline box. Also, space content, which would be removed by the behavior set in the {{ cssxref("white-space") }} CSS property, does not generate anonymous inline boxes because they would end empty.

- -
Example TBD
- -

Other types of boxes

- -

Line boxes

- -

Line boxes are generated by the inline formatting context to represent a line of text. Inside a block box, a line box extends from one border of the box to the other. When there are floats, the line box starts at the rightmost border of the left floats and ends at the leftmost border of the right floats.

- -

These boxes are technical, and Web authors do not usually have to bother with them.

- -

Run-in boxes

- -

Run-in boxes, defined using display:run-in, are boxes that are either block boxes or inline boxes, depending on the type of the following box. They can be used to create a title that runs inside its first paragraph when possible.

- -
Note: Run-in boxes were removed from the CSS 2.1 standard, as they were insufficiently specified to allow for interoperable implementation. They may reappear in CSS3, but meanwhile, are considered experimental. They should not be used in production.
- -

Model-induced boxes

- -

Besides the inline and block formatting contexts, CSS specifies several additional content models that may be applied to elements. These additional models, used to describe specific layouts, may define additional box types:

- -
    -
  • The table content model may create a table wrapper box and a table box, but also specific boxes like caption boxes.
  • -
  • The multi-column content model may create column boxes between the container box and the content.
  • -
  • The experimental grid, or flex-box content models, also create additional types of boxes.
  • -
- -

Positioning schemes

- -

Once boxes are generated, the CSS engine needs to position them on the layout. To do that, it uses one of the following algorithms:

- -
    -
  • The normal flow - positions each box one after the other.
  • -
  • The floats algorithm - extracts the box from the normal flow and put it to the side of the containing box.
  • -
  • The absolute positioning scheme - positions a box within an absolute coordinate system that is established by its containing element. An absolutely positioned element can cover other elements.
  • -
- -

Normal flow

- -

In the normal flow, boxes are laid out one after the other. In a block formatting context, they are laid out vertically; in an inline formatting context, they are laid out horizontally. The normal flow is triggered when the CSS {{ cssxref("position") }} is set to the value static or relative, and if the CSS {{ cssxref("float") }} is set to the value none.

- -

Example

- -
When in the normal flow, in a block formatting context, boxes are laid vertically one after the other out.
-
-When in the normal flow, in an inline formatting context, boxes are laid horizontally one after the other out.
- -
-

There are two sub-cases of the normal flow: static positioning and relative positioning:

- -
    -
  • In static positioning, triggered by the value static of the {{ cssxref("position") }} property, the boxes are drawn at the exact position defined by the normal flow layout.
  • -
  • In relative positioning, triggered by the value relative of the {{ cssxref("position") }} property, the boxes are drawn with an offset defined by the {{ cssxref("top") }}, {{ cssxref("bottom") }}, {{ cssxref("left") }} and {{ cssxref("right") }} CSS properties.
  • -
-
- -

Floats

- -

In the float positioning scheme, specific boxes (called floating boxes or simply floats) are positioned at the beginning, or end of the current line. This leads to the property that text (and more generally anything within the normal flow) flows along the edge of the floating boxes, except if told differently by the {{ cssxref("clear") }} CSS property.

- -

The float positioning scheme for a box is selected, by setting the {{ cssxref("float") }} CSS property on that box to a value different than none and {{ cssxref("position") }} to static or relative. If {{ cssxref("float") }} is set to left, the float is positioned at the beginning of the line box. If set to right, the float is positioned at the end of the line box. In either case, the line box is shrunk to fit alongside the float.

- -

Absolute positioning

- -

In the absolute positioning scheme, boxes are entirely removed from the flow and don't interact with it at all. They are positioned relative to their containing block using the {{ cssxref("top") }}, {{ cssxref("bottom") }}, {{ cssxref("left") }} and {{ cssxref("right") }} CSS properties.

- -

An element is absolutely positioned if the {{ cssxref("position") }} is set to absolute or fixed.

- -

With a fixed positioned element, the containing block is the viewport. The position of the element is absolute within the viewport. Scrolling does not change the position of the element.

diff --git a/files/ru/web/guide/events/creating_and_triggering_events/index.html b/files/ru/web/guide/events/creating_and_triggering_events/index.html new file mode 100644 index 0000000000..9e7a8f099b --- /dev/null +++ b/files/ru/web/guide/events/creating_and_triggering_events/index.html @@ -0,0 +1,92 @@ +--- +title: Создание и вызов событий +slug: Web/Guide/Events/Создание_и_вызов_событий +tags: + - DOM + - JavaScript + - events + - события +translation_of: Web/Guide/Events/Creating_and_triggering_events +--- +

Эта статья демонстрирует, как создавать и вызывать пользовательские DOM-события. Такие события часто называют исскуственными событиями, по отношению к событиям, производимым браузером.

+ +

Создание собственных событий

+ +

События могут быть созданы с помощью  конструктора Event:

+ +
var event = new Event('build');
+
+// Подписываемся на событие
+elem.addEventListener('build', function (e) { ... }, false);
+
+// Вызываем событие
+elem.dispatchEvent(event);
+ +

Этот конструктор поддерживается во всех современных браузерах (кроме Internet Explorer). Более подробную информацию смотрите ниже "Старомодный способ".

+ +

Добавление пользовательских данных – CustomEvent()

+ +

Чтобы добавить больше данных к объекту event, существует интерфейс CustomEvent, и вы можете использовать свойство detail, чтобы передать собственные данные. Например, событие может быть создано так:

+ +
var event = new CustomEvent('build', { 'detail': elem.dataset.time });
+ +

Это позволит вам получить доступ к дополнительным данным в обработчике:

+ +
function eventHandler(e) {
+  log('The time is: ' + e.detail);
+}
+
+ +

Старомодный способ

+ +

Старый способ создать событие использует API в стиле Java. Пример:

+ +
// Создание события
+var event = document.createEvent('Event');
+
+// Назначить имя событию
+event.initEvent('build', true, true);
+
+// Слушаем событие
+document.addEventListener('build', function (e) {
+  // e.target соотетствует объекту document
+}, false);
+
+// target события может быть любой элемент
+document.dispatchEvent(event);
+
+
+ +

Вызов встроенных событий

+ +

Этот пример показывает симуляцию клика (программно сгенерированное событие клика) по галочке чекбокса, используя DOM-методы. Просмотр действующих примеров.

+ +
function simulateClick() {
+  var event = new MouseEvent('click', {
+    'view': window,
+    'bubbles': true,
+    'cancelable': true
+  });
+  var cb = document.getElementById('checkbox');
+  var canceled = !cb.dispatchEvent(event);
+  if (canceled) {
+    // A handler called preventDefault.
+    alert("canceled");
+  } else {
+    // None of the handlers called preventDefault.
+    alert("not canceled");
+  }
+}
+ +

Совместимость с браузерами

+ +

{{Compat("api.Event.Event")}}

+ +

Смотрите также

+ +
    +
  • {{domxref("document.createEvent()")}}
  • +
  • {{domxref("Event.initEvent()")}}
  • +
  • {{domxref("EventTarget.dispatchEvent()")}}
  • +
  • {{domxref("EventTarget.addEventListener()")}}
  • +
diff --git "a/files/ru/web/guide/events/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\320\270_\320\262\321\213\320\267\320\276\320\262_\321\201\320\276\320\261\321\213\321\202\320\270\320\271/index.html" "b/files/ru/web/guide/events/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\320\270_\320\262\321\213\320\267\320\276\320\262_\321\201\320\276\320\261\321\213\321\202\320\270\320\271/index.html" deleted file mode 100644 index 9e7a8f099b..0000000000 --- "a/files/ru/web/guide/events/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\320\270_\320\262\321\213\320\267\320\276\320\262_\321\201\320\276\320\261\321\213\321\202\320\270\320\271/index.html" +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: Создание и вызов событий -slug: Web/Guide/Events/Создание_и_вызов_событий -tags: - - DOM - - JavaScript - - events - - события -translation_of: Web/Guide/Events/Creating_and_triggering_events ---- -

Эта статья демонстрирует, как создавать и вызывать пользовательские DOM-события. Такие события часто называют исскуственными событиями, по отношению к событиям, производимым браузером.

- -

Создание собственных событий

- -

События могут быть созданы с помощью  конструктора Event:

- -
var event = new Event('build');
-
-// Подписываемся на событие
-elem.addEventListener('build', function (e) { ... }, false);
-
-// Вызываем событие
-elem.dispatchEvent(event);
- -

Этот конструктор поддерживается во всех современных браузерах (кроме Internet Explorer). Более подробную информацию смотрите ниже "Старомодный способ".

- -

Добавление пользовательских данных – CustomEvent()

- -

Чтобы добавить больше данных к объекту event, существует интерфейс CustomEvent, и вы можете использовать свойство detail, чтобы передать собственные данные. Например, событие может быть создано так:

- -
var event = new CustomEvent('build', { 'detail': elem.dataset.time });
- -

Это позволит вам получить доступ к дополнительным данным в обработчике:

- -
function eventHandler(e) {
-  log('The time is: ' + e.detail);
-}
-
- -

Старомодный способ

- -

Старый способ создать событие использует API в стиле Java. Пример:

- -
// Создание события
-var event = document.createEvent('Event');
-
-// Назначить имя событию
-event.initEvent('build', true, true);
-
-// Слушаем событие
-document.addEventListener('build', function (e) {
-  // e.target соотетствует объекту document
-}, false);
-
-// target события может быть любой элемент
-document.dispatchEvent(event);
-
-
- -

Вызов встроенных событий

- -

Этот пример показывает симуляцию клика (программно сгенерированное событие клика) по галочке чекбокса, используя DOM-методы. Просмотр действующих примеров.

- -
function simulateClick() {
-  var event = new MouseEvent('click', {
-    'view': window,
-    'bubbles': true,
-    'cancelable': true
-  });
-  var cb = document.getElementById('checkbox');
-  var canceled = !cb.dispatchEvent(event);
-  if (canceled) {
-    // A handler called preventDefault.
-    alert("canceled");
-  } else {
-    // None of the handlers called preventDefault.
-    alert("not canceled");
-  }
-}
- -

Совместимость с браузерами

- -

{{Compat("api.Event.Event")}}

- -

Смотрите также

- -
    -
  • {{domxref("document.createEvent()")}}
  • -
  • {{domxref("Event.initEvent()")}}
  • -
  • {{domxref("EventTarget.dispatchEvent()")}}
  • -
  • {{domxref("EventTarget.addEventListener()")}}
  • -
diff --git a/files/ru/web/guide/graphics/index.html b/files/ru/web/guide/graphics/index.html new file mode 100644 index 0000000000..57dd4238e1 --- /dev/null +++ b/files/ru/web/guide/graphics/index.html @@ -0,0 +1,41 @@ +--- +title: Графика для Web +slug: Web/Guide/Графика +translation_of: Web/Guide/Graphics +--- +

Современным веб-сайтам и веб-приложениям часто требуется отображать графику. Статические изображения легко отобразить с помощью элемента {{HTMLElement("img")}}, или с помощью CSS свойства  {{cssxref("background-image")}}. Часто требуется создавать графику на лету, или модифицировать ее каким-либо образом после. Как это проделать можно узнать в следующих статьях.

+ +
+
+

2D графика

+ +
+
Канвас
+
Элемент {{HTMLElement("canvas")}} представляет удобный API для рисования 2D графики с помощью JavaScript.
+
SVG
+
Масштабируемая Векторная Графика (Scalable Vector Graphics) позволяет рисовать линии, кривые, и другие геометрические фигуры. С их помощью можно создавать масштабируемые изображения, которые не теряют в качестве при изменении размера в отличии от растровой графики.
+
+ +

View All...

+
+ +
+

3D графика

+ +
+
WebGL
+
Руководство по быстрому старту с WebGL. WebGL предоставляет API для работы с 3D графиками в веб. Эта технология позволяет Вам использовать стандартный OpenGL ES в веб контексте.
+
+ +

Видео

+ +
+
Использование HTML5 видео и аудио
+
Встраивание видео и аудио в HTML документ и управление проигрыванием.
+
WebRTC
+
RTC в WebRTC означает Real-Time Communications, технология которая позволяет стримить аудио/видео и данные между клиентами браузера (пирами).
+
+
+
+ +

 

diff --git a/files/ru/web/guide/html/drag_and_drop/drag_operations/index.html b/files/ru/web/guide/html/drag_and_drop/drag_operations/index.html deleted file mode 100644 index 2dcdb6babb..0000000000 --- a/files/ru/web/guide/html/drag_and_drop/drag_operations/index.html +++ /dev/null @@ -1,314 +0,0 @@ ---- -title: Drag Operations -slug: Web/Guide/HTML/Drag_and_drop/Drag_operations -translation_of: Web/API/HTML_Drag_and_Drop_API/Drag_operations ---- -

{{DefaultAPISidebar("HTML Drag and Drop API")}}

- -

Ниже описаны шаги, которые происходят при drag and drop операции.

- -

Drag операции описываются в документе, используя {{domxref("DataTransfer")}} интерфейс. Этот документ не использует не{{domxref("DataTransferItem")}} интерфейс, не{{domxref("DataTransferItemList")}} интерфейс.

- -

draggable атрибуты

- -

На веб-странице, в некоторых случаях используется поведение drag (перетаскивания) по умолчанию. Включая выделенный текст, изображения и ссылки. Когда изображение иои ссылка переносятся, URL изображения или ссылки устанавливается в качестве данных drag и перетаскивание начинается. Для других элементов, они должны быть частью выделения для выполнения перетаскивания по умолчанию. Чтобы увидеть это в действии, выделите область веб-страницы, а затем нажмите и удерживайте кнопку мыши и перетащите выделение. Появится специфичный для ОС рендеринг выделенного фрагмента и будет следовать за указателем мыши при перетаскивании. Однако это поведение является только drag поведением по умолчанию, если нет слушателей, определяющих данные для перетаскивания.

- -

В HTML, кроме поведения по умолчанию изображений, ссылок и выделенных областей, ноикакие другие элементы по умолчанию не переносятся.

- -

Для перетаскивания других HTML-элементов, должны быть выполнены три пункта :

- -
    -
  1. Установить {{htmlattrxref("draggable")}}="true" на элемент, который вы хотите сделать перетаскиваемым.
  2. -
  3. Добавить слушатель события {{event("dragstart")}}.
  4. -
  5. Установить данные перетаскивания в слушатель выше.
  6. -
- -

Вот пример, который позволяет перетаскивать часть содержимого.

- -
<p draggable="true" ondragstart="event.dataTransfer.setData('text/plain', 'This text may be dragged')">
-  This text <strong>may</strong> be dragged.
-</p>
-
- -

Атрибут {{htmlattrxref("draggable")}} установлен в  "true", т.о. этот элемент становится перетаскиваемым. Если этот атрибут был опущен или установлен в "false", то элемент не может быть перенесен, и вместо этого будет выбран текст.

- -

Атрибут {{htmlattrxref("draggable")}} может быть использован для любого элемента, включаяизображения и ссылки. Однако, для последних двух, значение по умолчанию - true, т.о. вы можете только использвать атрибут  {{htmlattrxref("draggable")}} со значением false для отключение перетаскивания этих элементов.

- -
-

Примечание: Когда элемент становится перетаскиваемыми, tтекст или другие элементы в нем больше не могут быть выбраны обычным способом, щелкая и перетаскивая мышью. Вместо этого пользователь должен удерживать клавишу Alt  чтобы выбрать текст с помощью мыши или клавиатуры.

-
- -

Начало операции перетаскивания

- -

В примере, слушатель добавлен для события {{event("dragstart")}} с использованием атрибута{{domxref("GlobalEventHandlers.ondragstart","ondragstart")}}.

- -
<p draggable="true" ondragstart="event.dataTransfer.setData('text/plain', 'This text may be dragged')">
-  This text <strong>may</strong> be dragged.
-</p>
-
- -

Когда пользователь начинает перетаскивание, запускается событиеdrag, the {{event("dragstart")}}.

- -

В этом примере слушатель {{event("dragstart")}} добавлен к самому перемещаемом элементу. Однако, вы можете слушать более высокого предка, так как событие перетаскивание высплывает вверх как и большинство событий.

- -

Внутри события {{event("dragstart")}}, вы можете указать drag данные, изображжение отклика, drag-эффекты, все это описано ниже. Однако, обязательны только drag данные. (Изображение и drag-эффекты по умолчанию, подходят в большинстве ситуаций)

- -

Drag-данные

- -

Все {{domxref("DragEvent","drag events")}} имеют свойство, называемое{{domxref("DragEvent.dataTransfer","dataTransfer")}}, которое содержит drag-данные (dataTransfer это {{domxref("DataTransfer")}} object).

- -

Когда происходит перетаскивание, данные должны быть связаны с перетаскиванием, которое определяет, что перетаскивается. Например, при перетаскивании выделенного текста в текстовое поле данные, связанные с элементом данных перетаскивания, являются самим текстом. Аналогично, при перетаскивании ссылки на веб-странице элемент данных перетаскивания является URL-адресом ссылки.

- -

{{domxref("DataTransfer","drag data")}} содержит два параметра, тип (или формат) данных, и значение данных. Формат это строковый тип (такой как text/plain текстовых данных), значение - строка текста. Когда начинается перетаскивание, вы добавляете данные, предоставляя тип и данные. Во время перетаскивания в слушателе события для событий {{event("dragenter")}} и {{event("dragover")}} , вы используете типы данных перетаскиваемых данных, чтобы проверить, разрешено ли удаление. Например, цель drop, которая принимает ссылки, будет проверять тип text/uri-list. В течение события drop, слушатель будет получать данные тащат и вставить его на место.

- -

Свойство {{domxref("DataTransfer","drag data's")}} {{domxref("DataTransfer.types","types")}} возвращает список MIME-типов {{domxref("DOMString")}}, таких как text/plain или image/jpeg. Вы также можете создавать свои собственные типы. Большинство основные используемых типов описаны в  Recommended Drag Types.

- -

Перетаскивание может включать элементы данных нескольких различных типов. Это позволяет предоставлять данные в более специфических типах, часто пользовательских, но по предоставляет резервные данные для drop, которые не поддерживают более специфические типы. Как правило, наименее специфичным типом будут обычные текстовые данные, использующие тип text/plain. Эти данные будут простым текстовым представлением.

- -

Установка элементов drag-данных {{domxref("DragEvent.dataTransfer","dataTransfer")}}, используя метод {{domxref("DataTransfer.setData","setData()")}}. Требуется два аргумента: тип данных и значение данных. Например:

- -
event.dataTransfer.setData("text/plain", "Text to drag");
-
- -

Здесь, значение -  "Text to drag", формат -  text/plain.

- -

Вы можете предусмотреть данные в нескольких форматах. Сделаем это, вызовем метод  {{domxref("DataTransfer.setData","setData()")}} несколько раз с различными форматами. Вы должны вызывать его с форматами от большей специфичности к меньшей.

- -
const dt = event.dataTransfer;
-dt.setData("application/x.bookmark", bookmarkString);
-dt.setData("text/uri-list", "https://www.mozilla.org");
-dt.setData("text/plain", "https://www.mozilla.org");
-
- -

Добавлены данные трех различных форматов. Первый тип - application/x.bookmark, пользовательский тип.Другие приложения не поддерживают данный тип, но вы можете использовать пользовательский тип для перетаскивания между областями в одном приложениее или на одной странице.

- -

Предоставляя данные и в других типах, мы также можем поддерживать перетаскивание в другие приложения в менее специфичных формах. Тип application/x.bookmark может предоставлять данные с  более подробной информацией для использования в приложении, в то время как другие типы могут включать только один URL-адрес или текстовую версию.

- -

Обратите внимание, что и text/uri-list и text/plain cодержат одни и те же данные в этом примере.  Это часто бывает так, но это не обязательно.

- -

Если вы попытаетесь добавить данные дважды с тем же форматом, новые данные заменят старые данные, но в той же позиции в списке типов, что и старые данные.

- -

Вы можете очистить данные, используя метод {{domxref("DataTransfer.clearData","clearData()")}}, который принимает один аргумент: тип данных для удаления.

- -
event.dataTransfer.clearData("text/uri-list");
-
- -

Аргумент type в методе {{domxref("DataTransfer.clearData","clearData()")}} опционален. Если type не указан, данные, связанные со всеми типами, удаляются. Если перетаскивание не содержит элементов данных перетаскивания или все элементы были впоследствии очищены, то перетаскивание не произойдет.

- -

Настройка изображения отклика drag

- -

Когда происходит перетаскивание, полупрозрачное изображение генерируется из цели перетаскивания (событие "{{event("dragstart")}}" элемента срабатывает), и следует за указателем пользователя во время перетаскивания. Это изображение создается автоматически, поэтому вам не нужно создавать его самостоятельно. Однако вы можете использовать {{domxref("DataTransfer.setDragImage","setDragImage()")}} для задания пользовательского изображения отклика перетаскивания.

- -
event.dataTransfer.setDragImage(image, xOffset, yOffset);
-
- -

Необходимы три аргумента. Первый - это ссылка на изображение. Эта ссылка обычно относится к элементу <img>, но также может относиться к элементу <canvas> или любому другому элементу. Изображение отклика будет генерироваться из того, как изображение выглядит на экране, для изображений они будут нарисованы в их первоначальном размере. Второй и третий аргументы метода {{domxref("DataTransfer.setDragImage","setDragImage()")}} - это смещения, в которых изображение должно появляться относительно указателя мыши.

- -

Также можно использовать изображения и canvas, которых нет в документе. Этот метод полезен при рисовании пользовательских изображений перетаскивания с помощью элемента canvas, как показано в следующем примере:

- -
function dragWithCustomImage(event) {
-  const canvas = document.createElement("canvas");
-  canvas.width = canvas.height = 50;
-
-  const ctx = canvas.getContext("2d");
-  ctx.lineWidth = 4;
-  ctx.moveTo(0, 0);
-  ctx.lineTo(50, 50);
-  ctx.moveTo(0, 50);
-  ctx.lineTo(50, 0);
-  ctx.stroke();
-
-  const dt = event.dataTransfer;
-  dt.setData('text/plain', 'Data to Drag');
-  dt.setDragImage(canvas, 25, 25);
-}
-
- -

В этом примере мы делаем один canvas перетаскивания. Поскольку размер холста составляет 50×50 пикселей, мы используем смещение половины этого (25), чтобы изображение было центрировано на указателе мыши.

- -

Drag эффекты

- -

При перетаскивании можно выполнить несколько операций. Операция  copy используется для указания на то, что перетаскиваемые данные будут скопированы из текущего местоположения в место перетаскивания. Операция move используется для указания на то, что перетаскиваемые данные будут перемещены, а операция link используется для указания на то, что между исходным и удаляемым местоположениями будет создана некоторая форма связи или соединения.

- -

Вы можете указать, какая из трех операций разрешена для источника перетаскивания, установив свойство {{domxref("DataTransfer.effectAllowed","effectAllowed")}} в слушателе событий{{event("dragstart")}}.

- -
event.dataTransfer.effectAllowed = "copy";
-
- -

В этом примере разрешена только копия.

- -

Вы можете комбинировать значения различными способами:

- -
-
none
-
никакая операция не разрешена
-
copy
-
только copy
-
move
-
только move
-
link
-
только link
-
copyMove
-
только copy или move
-
copyLink
-
только copy или link
-
linkMove
-
только link или move
-
all
-
только copy, move, или link
-
uninitialized
-
Значение по умолчанию all.
-
- -

Обратите внимание, что эти значения должны использоваться так, как указано выше. Например, установка свойства {{domxref("DataTransfer.effectAllowed","effectAllowed")}} на copyMove позволяет выполнять операцию копирования или перемещения, но не позволяет пользователю выполнять операцию связывания. Если вы не измените свойство {{domxref("DataTransfer.effectAllowed","effectAllowed")}},  то любая операция разрешена, как и со значением 'all'. Поэтому вам не нужно настраивать это свойство, если вы не хотите исключить определенные типы.

- -

Во время операции перетаскивания, слушатель для событий {{event("dragenter")}} или {{event("dragover")}} может проверить свойство {{domxref("DataTransfer.effectAllowed","effectAllowed")}} , какие операции разрешены. Связанное свойство,  {{domxref("DataTransfer.dropEffect","dropEffect")}}, должно быть установлено в пределах одного из этих событий, чтобы указать, какая единственная операция должна быть выполнена. Допустимые значения для {{domxref("DataTransfer.dropEffect","dropEffect")}} - none, copy, move, или link. Комбинированные значения для этого свойства не используются.

- -

С событиями {{event("dragenter")}} и {{event("dragover")}}, свойство {{domxref("DataTransfer.dropEffect","dropEffect")}} инициализируется в соответствии с запросом пользователя. Пользователь может изменить желаемый эффект, нажав клавиши-модификаторы. Хотя точные используемые клавиши различаются в зависимости от платформы, обычно клавиши  Shift и Control используются для переключения между копированием, перемещением и связыванием. Указатель мыши изменится, чтобы указать, какая операция требуется. Например, для copy курсор может появиться со знаком плюс рядом с ним.

- -

Вы можете изменять свойство {{domxref("DataTransfer.dropEffect","dropEffect")}} во время событий {{event("dragenter")}} или {{event("dragover")}}, например, определенная drop-цель поддерживает только определенные операции. Вы можете изменить свойство {{domxref("DataTransfer.dropEffect","dropEffect")}}, чтобы переопределить действие пользователя, и обеспечить выполнение специфичной  операции перетаскивания при ее наступлении. Обратите внимание, что этот эффект должен быть указан в списке свойств {{domxref("DataTransfer.effectAllowed","effectAllowed")}}. В противном случае ему будет присвоено другое допустимое значение.

- -
event.dataTransfer.dropEffect = "copy";
-
- -

В этом примере выполняется эффект копирования.

- -

Вы можете использовать значение none, чтобы указать, что в этом месте не допускается удаление, хотя в этом случае лучше не отменять событие.

- -

В событиях {{event("drop")}} и {{event("dragend")}}, yвы можете проверить свойства {{domxref("DataTransfer.dropEffect","dropEffect")}} для определения того, какой эффект был в конечном итоге выбран.  Если выбран эффект "move",то исходные данные должны быть удалены из источника перетаскивания в событии{{event("dragend")}}.

- -

Указание drop-целей

- -

Слушатель для событий {{event("dragenter")}} и {{event("dragover")}} используются для указания допустимых drop-целей, то есть мест, где могут быть сброшены перетаскиваемые элементы. Большинство областей веб-страницы или приложения не являются допустимыми местами для сброса данных. Таким образом, обработка этих событий по умолчанию не допускает сброса перетаскиваемых данных.

- -

Если вы хотите разрешить сброс переносимых данных, вы должны предотвратить обработку по умолчанию, отменив оба события dragenter и dragover.  Это можно сделать, либо вернув false из определенных атрибутом слушателя событий, либо вызвав метод {{domxref("Event.preventDefault","preventDefault()")}} событие. Последнее может быть более осуществимо в функции, определенной в отдельном скрипте.

- -
<div ondragover="return false">
-<div ondragover="event.preventDefault()">
-
- -

Вызывая метод {{domxref("Event.preventDefault","preventDefault()")}} во время обоих событий {{event("dragenter")}} и {{event("dragover")}} укажите, что падение разрешено в этом месте. Однако обычно вы захотите вызвать метод  {{domxref("Event.preventDefault","preventDefault()")}} события только в определенных ситуациях (например, только при перетаскивании ссылки).

- -

Для этого вызовите функцию, которая проверяет условие и отменяет событие только при его выполнении. Если условие не выполнено, не отменяйте событие, и сброс перетаскиваемых данных не произойдет, если пользователь отпустит кнопку мыши.

- -

Наиболее распространенным является принятие или отклонение сброса в зависимости от типа данных перетаскивания при передаче данных — например, разрешение для изображений, ссылок или и того, и другого. Для этого вы можете проверить свойство {{domxref("DataTransfer.types","types")}} события {{domxref("DragEvent.dataTransfer","dataTransfer")}} (свойство). Свойство {{domxref("DataTransfer.types","types")}} возвращает массив из строк, добавленных при начале перетаскивания, в порядке от наиболее значимого к наименее значимому.

- -
function doDragOver(event) {
-  const isLink = event.dataTransfer.types.includes("text/uri-list");
-  if (isLink) {
-    event.preventDefault();
-  }
-}
- -

В этом примере мы используем метод includes  чтобы проверить, присутствует ли тип text/uri-list в списке типов. Если это так, мы отменим событие, так что сброс становится разрешен. Если перетаскиваемые данные не содержат ссылки, событие не будет отменено, и сброс не может произойти в этом месте.

- -

Вы также можете установить либо свойство {{domxref("DataTransfer.effectAllowed","effectAllowed")}}, либо свойство{{domxref("DataTransfer.dropEffect","dropEffect")}}, либо оба одновременно, если вы хотите указать более конкретные сведения о типе операции, которая будет выполнена. Естественно, изменение любого свойства не будет иметь никакого эффекта, если вы не отмените событие.

- -

Drop Feedback

- -

There are several ways in which you can indicate to the user that a drop is allowed at a certain location. The mouse pointer will update as necessary depending on the value of the {{domxref("DataTransfer.dropEffect","dropEffect")}} property.

- -

Although the exact appearance depends on the user's platform, typically a plus sign icon will appear for a 'copy' for example, and a 'cannot drop here' icon will appear when a drop is not allowed. This mouse pointer feedback is sufficient in many cases.

- -

However, you can also update the user interface with an insertion point or highlight as needed. For simple highlighting, you can use the :-moz-drag-over CSS pseudoclass on a drop target.

- -
.droparea:-moz-drag-over {
-  outline: 1px solid black;
-}
-
- -

In this example, the element with the class droparea will receive a 1 pixel black outline while it is a valid drop target, that is, if the {{domxref("Event.preventDefault","preventDefault()")}} method was called during the {{event("dragenter")}} event.

- -
-

Note: You must cancel the {{event("dragenter")}} event for this pseudoclass to apply, as this state is not checked for the {{event("dragover")}} event.

-
- -

For more complex visual effects, you can also perform other operations during the {{event("dragenter")}} event. For example, by inserting an element at the location where the drop will occur. This might be an insertion marker, or an element that represents the dragged element in its new location. To do this, you could create an image or separator element and simply insert it into the document during the {{event("dragenter")}} event.

- -

The {{event("dragover")}} event will fire at the element the mouse is pointing at. Naturally, you may need to move the insertion marker around a {{event("dragover")}} event as well. You can use the event's {{domxref("MouseEvent.clientX","clientX")}} and {{domxref("MouseEvent.clientY","clientY")}} properties as with other mouse events to determine the location of the mouse pointer.

- -

Finally, the {{event("dragleave")}} event will fire at an element when the drag leaves the element. This is the time when you should remove any insertion markers or highlighting. You do not need to cancel this event. Any highlighting or other visual effects specified using the :-moz-drag-over pseudoclass will be removed automatically. The {{event("dragleave")}} event will always fire, even if the drag is cancelled, so you can always ensure that any insertion point cleanup can be done during this event.

- -

Performing a Drop

- -

When the user releases the mouse, the drag and drop operation ends.

- -

If the mouse is released over an element that is a valid drop target, that is, one that cancelled the last {{event("dragenter")}} or {{event("dragover")}} event, then the drop will be successful, and a {{event("drop")}} event will fire at the target. Otherwise, the drag operation is cancelled, and no {{event("drop")}} event is fired.

- -

During the {{event("drop")}} event, you should retrieve that data that was dropped from the event and insert it at the drop location. You can use the {{domxref("DataTransfer.dropEffect","dropEffect")}} property to determine which drag operation was desired.

- -

As with all drag-related events, the event's {{domxref("DataTransfer","dataTransfer")}} property will hold the data that is being dragged. The {{domxref("DataTransfer.getData","getData()")}} method may be used to retrieve the data again.

- -
function onDrop(event) {
-  const data = event.dataTransfer.getData("text/plain");
-  event.target.textContent = data;
-  event.preventDefault();
-}
-
- -

The {{domxref("DataTransfer.getData","getData()")}} method takes one argument, the type of data to retrieve. It will return the string value that was set when {{domxref("DataTransfer.setData","setData()")}} was called at the beginning of the drag operation. An empty string will be returned if data of that type does not exist. (Naturally, though, you would likely know that the right type of data was available, as it was previously checked during a {{event("dragover")}} event.)

- -

In the example here, once the data has been retrieved, we insert the string as the textual content of the target. This has the effect of inserting the dragged text where it was dropped, assuming that the drop target is an area of text such as a p or div element.

- -

In a web page, you should call the {{domxref("Event.preventDefault","preventDefault()")}} method of the event if you have accepted the drop, so that the browser's default handling is not triggered by the dropped data as well. For example, when a link is dragged to a web page, Firefox will open the link. By cancelling the event, this behavior will be prevented.

- -

You can retrieve other types of data as well. If the data is a link, it should have the type text/uri-list. You could then insert a link into the content.

- -
function doDrop(event) {
-  const lines = event.dataTransfer.getData("text/uri-list").split("\n");
-  lines.filter(line => !line.startsWith("#"))
-    .forEach(line => {
-      const link = document.createElement("a");
-      link.href = line;
-      link.textContent = line;
-      event.target.appendChild(link);
-    })
-  event.preventDefault();
-}
-
- -

This example inserts a link from the dragged data. As the name implies, the text/uri-list type actually may contain a list of URLs, each on a separate line. The above code uses split to break the string into lines, then iterates over the list of lines, and inserts each as a link into the document. (Note also that links starting with a number sign (#) are skipped, as these are comments.)

- -

For simple cases, you can use the special type URL just to retrieve the first valid URL in the list. For example:

- -
const link = event.dataTransfer.getData("URL");
-
- -

This eliminates the need to check for comments or iterate through lines yourself. However, it is limited to only the first URL in the list.

- -

The URL type is a special type. It is used only as a shorthand, and it does not appear within the list of types specified in the {{domxref("DataTransfer.types","types")}} property.

- -

Sometimes you may support some different formats, and you want to retrieve the data that is most specific that is supported. In the following example, three formats are supported by a drop target.

- -

The following example returns the data associated with the best-supported format:

- -
function doDrop(event) {
-  const supportedTypes = ["application/x-moz-file", "text/uri-list", "text/plain"];
-  const types = event.dataTransfer.types.filter(type => supportedTypes.includes(type));
-  if (types.length) {
-    const data = event.dataTransfer.getData(types[0]);
-  }
-  event.preventDefault();
-}
-
- -

Окончание перетаскивания

- -

Как только перетаскивание завершено, событие {{event("dragend")}} запускается в источнике перетаскивания (тот же элемент, который получил событие {{event("dragstart")}}). Это событие сработает, если перетаскивание было успешным[1] или если оно было отменено. Однако вы можете использовать свойство {{domxref("DataTransfer.dropEffect","dropEffect")}} для определения, какая операция удаления произошла.

- -

Если свойство {{domxref("DataTransfer.dropEffect","dropEffect")}} имеет значение none во время события {{event("dragend")}}, то перетаскивание было отменено. В противном случае эффект указывает, какая операция была выполнена. Источник может использовать эту информацию после операции перемещения для удаления перетаскиваемого элемента из старого расположения. Свойство {{domxref("DataTransfer.mozUserCancelled","mozUserCancelled")}} будет присвоено значение true, если пользователь отменил перетаскивание (нажав Escape), и false если перетаскивание было отменено по другим причинам, таким как недопустимая цель перетаскивания, или если оно было успешным.

- -

Сброс может произойти внутри того же окна или над другим приложением. Событие{{event("dragend")}}будет срабатывать всегда, независимо от этого. Свойство события {{domxref("MouseEvent.screenX","screenX")}} и {{domxref("MouseEvent.screenY","screenY")}} будут установлены в координаты экрана, где произошел сброс.

- -

Когда событие {{event("dragend")}} завершило распространение, операция перетаскивания завершена.

- -

[1]: В Gecko, {{event("dragend")}} не отправляется, если исходный узел движется или удаляется во время перетаскивания (например, при сбрасывании или {{event("dragover")}}). Bug 460801

- -

Смотрите также

- - diff --git a/files/ru/web/guide/html/drag_and_drop/index.html b/files/ru/web/guide/html/drag_and_drop/index.html deleted file mode 100644 index 86467501fd..0000000000 --- a/files/ru/web/guide/html/drag_and_drop/index.html +++ /dev/null @@ -1,72 +0,0 @@ ---- -title: Drag and drop -slug: Web/Guide/HTML/Drag_and_drop -translation_of: Web/API/HTML_Drag_and_Drop_API ---- -

Firefox и прочие приложения компании Mozilla имеют ряд возможностей для управления drag и drop. Это позволяет пользователю нажать и удерживая зажатой кнопку мыши над элементом, переместить его на другую позицию, отпустив кнопку мыши пользователь может оставить элемент на новой позиции. На протяжении всей операции перемещения полупрозрачное представление элемента следует за курсором мыши. Новая позиция элемента может располагаться в совершенно другом приложении. Веб сайты, и XUL приложения могут использовать эту функциональность для того, чтобы определить какие элементы страницы могут быть перемещены, а также определить элементы куда первые могут быть перемещены.

- -
Эта часть покрывает функциональность drag и drop в Firefox 3.5 (Gecko 1.9.1) а также последующие версии. Для старого API для Firefox 3.0 и ранее, в котором нет соответствующей поддержки данной функциональности, смотрите older API documentation.
- -

Основы Drag и Drop

- -

Использование функциональности drag и drop подразумевает выполнения следующих шагов:

- -
    -
  • Определить переносимый элемент. Присвоить true атрибуту draggable элемента, который мы хотим перенести. Для детальной информации смотрите The Draggable Attribute.
  • -
  • Определить данные, которые могут быть перемещены, они могут быть разного формата. К примеру, текстовые данные, содержащие строку текста который может быть перемещен. Для детальной информации смотрите Drag Data.
  • -
  • (Необязательно) Определить изображение которое будет рядом с указателем мыши на протяжении всей операции перетаскивания.  Если пользовательское изображение не будет определено, будет сгенерирована картинка по умолчанию, в зависимости от элемента, на котором была зажата кнопка мыши (что будет означать, что элемент переносят). Ознакомиться детально с установкой изображения перетаскивания можно по ссылке Setting the Drag Feedback Image.
  • -
  • Определить возможные эффекты переноса. Возможны три таких эффекта: copy показывает, что перемещаемые данные копируются из прежнего места расположения в новое, move показывает, что перемещаемые данные полностью переносятся на новое место, и link показывает, что создается некая форма взаимодействия или связи между исходной точкой и точкой назначения. На протяжении операции перемещения, картинка которая следует за курсором мыши может меняться в зависимости от того, может ли элемент быть перемещен в область под курсором. Если перенос разрешен, перемещение может быть произведено. Смотрите Drag Effects для детальной информации.
  • -
  • Определить область назначения. По умолчанию браузер не позволяет перемещать что-либо на HTML элемент. Однако, чтобы сделать элемент активным для перемещения других элементов на него, просто отмените действие по умолчанию. То есть, подпишитесь на события "ondragenter" или "ondragover". Для детальной информации смотрите Specifying Drop Targets.
  • -
  • Обработать завершение переноса. Вы можете получить данные из переносимого элемента и произвести над ними необходимые операции. Для детальной информации, пожалуйста, смотрите Performing a Drop.
  • -
- -

Mozilla и Firefox поддерживают ряд возможностей, которые выходят за рамку стандартной модели спецификации. Они позволяют пользователю перемещать несколько элементов и перемещать нестроковые данные. Для детальной информации смотрите Dragging and Dropping Multiple Items.

- -

Для того, чтобы ознакомиться с общим списком данных поддерживаемых операцией drag and drop смотрите Recommended Drag Types.

- -

Также доступны примеры с лучшей практикой использования операции drag and drop для перемещения данных разных типов:

- - - -

Смотри DataTransfer для ссылки на объект DataTransfer.

- -

События Drag

- -

Ряд событий срабатывают на протяжении всей процедуры drag and drop. Запомните, что только drag-события срабатывают на протяжении операции перемещения; события мыши, такие как mousemove - нет. Также запомните, что события dragstart и dragend не срабатывают при попытке перенести файл из операционной системы в браузер.

- -

Свойство dataTransfer всех событий перемещения содержит данные про все drag и drop операции.

- -
-
dragstart
-
Срабатывает когда элeмент начал перемещаться. В момент срабатывания события dragstart пользователь начинает перетаскивание элемента. Обработчик данного события может быть использован для сохранения информации о перемещаемом объекте, а также для изменения изображения, которое будет ассоциировано с перемещением. Дaнное событие не срабатывает, когда некоторый файл будет переноситься из операционной системы в браузер. Для детальной информации Starting a Drag Operation.
-
dragenter
-
Срабатывает, когда перемещаемый элемент попадает на элемент-назначение. Обработчик этого события показывает, что элемент находится над объектом на который он может быть перенесен. Если же обработчика нет, либо он не совершает никаких действий перемещение по умолчанию запрещено. Это событие также используется для того, чтобы подсветить либо промаркировать объект над которым происходит перемещения в случае, если перемещение на данный элемент разрешено. Для детальной информации смотрите Specifying Drop Targets.
-
dragover
-
Данное событие срабатывает каждые несколько сотен милисекунд, когда перемещаемый элемент оказывается над зоной, принимающей перетаскиваемые элементы. Для детальной информации смотрите Specifying Drop Targets.
-
dragleave
-
Это событие запускается в момент перетаскивания, когда курсор мыши выходит за пределы элемента. Обработчикам следует убрать любую подсветку или иные индикаторы, указывавшие на присутствие курсора, чтобы тем самым обозначить реакцию на прекращение перетаскивания.
-
drag
-
Запускается при перемещении элемента или выделенного текста.
-
drop
-
Событие drop вызывается для элемента, над которым произошло "сбрасывание" перемещаемого элемента. Событие отвечает за извлечение "сброшенных" данных и их вставку. Событие будет срабатывать только при завершении операции перетаскивания, например, событие не сработает, если пользователь отменит перетаскивание нажатием Esc, или не донесет элемент, до цели. Для детальной информации смотрите Performing a Drop.
-
dragend
-
Источник перетаскивания получит событие dragend, когда перетаскивание завершится, было оно удачным или нет. Это событие не вызывается при перетаскивании файла в браузер из ОС.   Для детальной информации смотрите Finishing a Drag.
-
- -

Смотрите также

- - diff --git a/files/ru/web/guide/html/html5/constraint_validation/index.html b/files/ru/web/guide/html/html5/constraint_validation/index.html new file mode 100644 index 0000000000..5a5fccec8c --- /dev/null +++ b/files/ru/web/guide/html/html5/constraint_validation/index.html @@ -0,0 +1,343 @@ +--- +title: Constraint validation +slug: HTML/HTML5/Constraint_validation +tags: + - Селекторы +translation_of: Web/Guide/HTML/HTML5/Constraint_validation +--- +

Создание веб форм всегда было комплексной задачей. В то время как сама по себе разметка формы - задача не сложная, проверка каждого поля на валидность - сложнее, а информирование юзера о проблеме - может стать головной болью. Стандарт HTML5 предоставил новые механизмы для форм: были добавлены новые семантические типы для элемента {{ HTMLElement("input") }} и обязательная валидация, чтобы облегчить работу по проверке содержимого формы на стороне браузера. Проще говоря, обычная проверка может быть выполнена без JavaScript, простой установкой новых аттрибутов; более сложные ограничения могут быть реализованы через HTML5 Constraint Validation API.

+ +
Внимание: HTML5 Constraint validation не отменяет валидацию на стороне сервера. Несмотря на то что на сервер будет отправляться меньше запросов с невалидными данными, такие запросы всё ещё могут быть отправлены менее "сговорчивыми" браузерами (например, браузерами без поддержки HTML5 и без JavaScript) или плохими парнями, пытающимися взломать ваше веб-приложение. Следовательно, как и в случае с HTML4, вам всё ещё нужно проверять ввод на стороне сервера, таким образом, чтобы это было согласовано с валидацией на стороне клиента.
+ +

Внутренние и базовые ограничения

+ +

В HTML5, базовые ограничения описываются двумя способами:

+ +
    +
  • Использованием наиболее семантически подходящего значения для {{ htmlattrxref("type", "input") }} аттрибута элемента {{ HTMLElement("input") }}, например, выбор типа email автоматически создаёт ограничение, которое проверяет, является ли значение e-mail адресом.
  • +
  • Установкой значений для аттрибутов, связанных с валидацией, описывая базовые ограничения без использования JavaScript.
  • +
+ +

Семантические типы input-ов

+ +

Аттрибуты, присущие элементам {{ htmlattrxref("type", "input") }}:

+ + + + + + + + + + + + + + + + + + + + + +
Input typeОпределение ограниченияСвязанное с этим нарушение
<input type="URL">Значение должно быть абсолютным URL, одним из: +
    +
  • валидным URI (как описано в RFC 3986)
  • +
  • валидным IRI, без query сомпонента (как описано в RFC 3987)
  • +
  • валидным IRI, без query сомпонента и без неэкранированных не-ASCII символов (как описано в RFC 3987)
  • +
  • валидным IRI, при условии, что кодировка документа UTF-8 или UTF-16 (как описано в RFC 3987)
  • +
+
Type mismatch constraint violation
 <input type="email">Значение должно следовать ABNF: 1*( atext / "." ) "@" ldh-str 1*( "." ldh-str ) где: +
    +
  • atext (описан в RFC 5322) - US-ASCII символ (A to Z and a-z), цифра (от 0 до 9) или один из следующих: 
    + ! # $ % & ' * + - / = ? ` { } | ~ специальных символов,
  • +
  • ldh-str (описан в RFC 1034) - US-ASCII символы, цифры и "-", сгруппированы по словам и разделённые точкой (.).
  • +
+ +
Внимание: если установлен аттрибут {{ htmlattrxref("multiple", "input") }}, в поле могут быть вписаны несколько e-mail адресов, разделённых запятыми. Если любое из этих условий не выполнено, будет вызвано Type mismatch constraint violation.
+
Type mismatch constraint violation
+ +

Следует учесть, что большинство типов input не имеют "нативных" ограничений, а некоторые из них просто лишены валидации или имеют автоматическую корректировку невалидных значений по умолчанию. 

+ +

Аттрибуты валидации

+ +

Ниже перечислены аттрибуты, которые описывают базовые ограничения:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
АттрибутТипы input с поддержкой аттрибутаВозможные значенияОписание ограниченияСвязанное нарушение
{{ htmlattrxref("pattern", "input") }}text, search, url, tel, email, passwordРегулярное выражение JavaScript (по стандарту ECMAScript 5, флаги global, ignoreCase, и multiline отключены)Значение должно подходить под паттернPattern mismatch constraint violation
{{ htmlattrxref("min", "input") }}range, numberВалидное числоЗначение поля должно быть больше или равно значению аттрибутаUnderflow constraint violation
date, month, weekВалидная дата
datetime, datetime-local, timeВалидная дата и время
{{ htmlattrxref("max", "input") }}range, numberВалидное числоЗначение поля должно быть меньше или равно значению аттрибутаOverflow constraint violation
date, month, weekВалидная дата
datetime, datetime-local, timeВалидная дата и время
{{ htmlattrxref("required", "input") }}text, search, url, tel, email, password, date, datetime, datetime-local, month, week, time, number, checkbox, radio, file; also on the {{ HTMLElement("select") }} and {{ HTMLElement("textarea") }} elementsникакое так как это Boolean аттрибут: его присутствие означает true, а отсутствие - falseЗначение должно быть не пустым (если установлено).Missing constraint violation
{{ htmlattrxref("step", "input") }}dateЦелое число днейПока в аттрибут step не установлен любой литерал, значение может быть min + любое число, крастное шагу.Step mismatch constraint violation
monthЦелое число месяцев
weekЦелое число недель
datetime, datetime-local, timeЦелое число секунд
range, numberЦелое число
{{ htmlattrxref("maxlength", "input") }}text, search, url, tel, email, password; также на элементе {{ HTMLElement("textarea") }}Длина (целое число)Количество символов (знаков) не должно превышать значение аттрибута.Too long constraint violation
+ +

Процесс валидации ограничений

+ +

Constraint validation is done through the Constraint Validation API either on a single form element or at the form level, on the {{ HTMLElement("form") }} element itself. The constraint validation is done in the following ways:

+ +
    +
  • By a call to the checkValidity() method of a form-related DOM interface (HTMLInputElement, HTMLSelectElement, HTMLButtonElement or HTMLTextAreaElement), which evaluates the constraints only on this element, allowing a script to get this information. (This is typically done by the user-agent when determining which of the CSS pseudo-classes, {{ Cssxref(":valid") }} or {{ Cssxref(":invalid") }}, applies.)
  • +
  • By a call to the checkValidity() function on the HTMLFormElement interface, which is called statically validating the constraints.
  • +
  • By submitting the form itself, which is called interactively validating the constraints.
  • +
+ +
Note: + +
    +
  • If the {{ htmlattrxref("novalidate", "form") }} attribute is set on the {{ HTMLElement("form") }} element, interactive validation of the constraints doesn't happen.
  • +
  • Calling the send() method on the HTMLFormElement interface doesn't trigger a constraint validation. In other words, this method sends the form data to the server even if doesn't satisfy the constraints.
  • +
+
+ +

Complex constraints using HTML5 Constraint API

+ +

Using JavaScript and the Constraint API, it is possible to implement more complex constraints, for example, constraints combining several fields, or constraints involving complex calculations.

+ +

Basically, the idea is to trigger JavaScript on some form field event (like onchange) to calculate whether the constraint is violated, and then to use the method field.setCustomValidity() to set the result of the validation: an empty string means the constraint is satisfied, and any other string means there is an error and this string is the error message to display to the user.

+ +

Constraint combining several fields: Postal code validation

+ +

The postal code format varies from one country to another. Not only do most countries allow an optional prefix with the country code (like D- in Germany, F- in France or Switzerland), but some countries have postal codes with only a fixed number of digits; others, like the UK, have more complex structures, allowing letters at some specific positions.

+ +
+

Note: This is not a comprehensive postal code validation library, but rather a demonstration of the key concepts. 

+
+ +

As an example, we will add a script checking the constraint validation for this simple form:

+ +
<form>
+    <label for="ZIP">ZIP : </label>
+    <input type="text" id="ZIP">
+    <label for="Country">Country : </label>
+    <select id="Country">
+      <option value="ch">Switzerland</option>
+      <option value="fr">France</option>
+      <option value="de">Germany</option>
+      <option value="nl">The Netherlands</option>
+    </select>
+    <input type="submit" value="Validate">
+</form>
+ +

This displays the following form: 

+ +

+ +

First, we write a function checking the constraint itself:

+ +
function checkZIP() {
+  // For each country, defines the pattern that the ZIP has to follow
+  var constraints = {
+    ch : [ '^(CH-)?\\d{4}$', "Switzerland ZIPs must have exactly 4 digits: e.g. CH-1950 or 1950" ],
+    fr : [ '^(F-)?\\d{5}$' , "France ZIPs must have exactly 5 digits: e.g. F-75012 or 75012" ],
+    de : [ '^(D-)?\\d{5}$' , "Germany ZIPs must have exactly 5 digits: e.g. D-12345 or 12345" ],
+    nl : [ '^(NL-)?\\d{4}\\s*([A-RT-Z][A-Z]|S[BCE-RT-Z])$',
+                    "Nederland ZIPs must have exactly 4 digits, followed by 2 letters except SA, SD and SS" ]
+  };
+
+  // Read the country id
+  var country = document.getElementById("Country").value;
+
+  // Get the NPA field
+  var ZIPField = document.getElementById("ZIP");
+
+  // Build the constraint checker
+  var constraint = new RegExp(constraints[country][0], "");
+    console.log(constraint);
+
+
+  // Check it!
+  if (constraint.test(ZIPField.value)) {
+    // The ZIP follows the constraint, we use the ConstraintAPI to tell it
+    ZIPField.setCustomValidity("");
+  }
+  else {
+    // The ZIP doesn't follow the constraint, we use the ConstraintAPI to
+    // give a message about the format required for this country
+    ZIPField.setCustomValidity(constraints[country][1]);
+  }
+}
+
+ +

Then we link it to the onchange event for the {{ HTMLElement("select") }} and the oninput event for the {{ HTMLElement("input") }}:

+ +
window.onload = function () {
+    document.getElementById("Country").onchange = checkZIP;
+    document.getElementById("ZIP").oninput = checkZIP;
+}
+ +

You can see a live example of the postal code validation.  

+ +

Limiting the size of a file before its upload

+ +

Another common constraint is to limit the size of a file to be uploaded. Checking this on the client side before the file is transmitted to the server requires combining the Constraint API, and especially the field.setCustomValidity() method, with another JavaScript API, here the HTML5 File API.

+ +

Here is the HTML part:

+ +
<label for="FS">Select a file smaller than 75 kB : </label>
+<input type="file" id="FS">
+ +

This displays:

+ +

+ +

 

+ +

The JavaScript reads the file selected, uses the File.size() method to get its size, compares it to the (hard coded) limit, and calls the Constraint API to inform the browser if there is a violation:

+ +
function checkFileSize() {
+  var FS = document.getElementById("FS");
+  var files = FS.files;
+
+  // If there is (at least) one file selected
+  if (files.length > 0) {
+     if (files[0].size > 75 * 1024) { // Check the constraint
+       FS.setCustomValidity("The selected file must not be larger than 75 kB");
+       return;
+     }
+  }
+  // No custom constraint violation
+  FS.setCustomValidity("");
+}
+ +

 

+ +

Finally we hook the method with the correct event:

+ +
window.onload = function () {
+  document.getElementById("FS").onchange = checkFileSize;
+}
+ +

You can see a live example of the File size constraint validation.

+ +

Visual styling of constraint validation

+ +

Apart from setting constraints, web developers want to control what messages are displayed to the users and how they are styled.

+ +

Controlling the look of elements

+ +

The look of elements can be controlled via CSS pseudo-classes.

+ +

:required and :optional CSS pseudo-classes

+ +

The :required and :optional pseudo-classes allow writing selectors that match form elements that have the {{ htmlattrxref("required") }} attribute, or that don't have it.

+ + +

:-moz-placeholder CSS pseudo-class

+ +

See :-moz-placeholder.

+ +

:valid :invalid CSS pseudo-classes

+ +

The :valid and :invalid pseudo-classes are used to represent <input> elements whose content validates and fails to validate respectively according to the input's type setting. These classes allow the user to style valid or invalid form elements to make it easier to identify elements that are either formatted correctly or incorrectly.

+ +

Default styles

+ +

Controlling the text of constraints violation

+ +

The x-moz-errormessage attribute

+ +

The x-moz-errormessage attribute is a Mozilla extension that allows you to specify the error message to display when a field does not successfully validate.

+ +
+

Note: This extension is non-standard.

+
+ +

Constraint API's element.setCustomValidity()

+ +

The element.setCustomValidity(error) method is used to set a custom error message to be displayed when a form is submitted. The method works by taking a string parameter error. If error is a non-empty string, the method assumes validation was unsuccessful and displays error as an error message. If error is an empty string, the element is considered validated and resets the error message.

+ +

Constraint API's ValidityState object

+ +

The DOM ValidityState interface represents the validity states that an element can be in, with respect to constraint validation. Together, they help explain why an element's value fails to validate, if it's not valid.

+ +

Examples of personalized styling

+ +

HTML4 fallback

+ +

Trivial fallback

+ +

JS fallback

+ +

Conclusion

diff --git a/files/ru/web/guide/html/html5/index.html b/files/ru/web/guide/html/html5/index.html new file mode 100644 index 0000000000..dca2e39993 --- /dev/null +++ b/files/ru/web/guide/html/html5/index.html @@ -0,0 +1,171 @@ +--- +title: HTML5 +slug: HTML/HTML5 +tags: + - HTML5 +translation_of: Web/Guide/HTML/HTML5 +--- +

HTML5 — последняя версия стандарта HTML. Термин имеет два определения:

+ +
    +
  • Новая версия языка HTML, с новыми элементами, атрибутами и новым поведением.
  • +
  • Набор технологий, позволяющий создавать разнообразные сайты и Web-приложения.
  • +
+ +

Эта страница создана в помощь всем разработчикам Open Web и ссылается на множество материалов, сгруппированных по функциям:

+ +
    +
  • Семантика: позволяет точнее описывать, что из себя представляет ваш контент;
  • +
  • Связь: новые способы общения с сервером;
  • +
  • Оффлайн и Хранилище: методы, позволяющие сохранять информацию локально на стороне клиента;
  • +
  • Мультимедиа:создание и взаимодействие с видео и звуком;
  • +
  • 2D/3D Графика и эффекты: способы значительно разнообразить  представление;
  • +
  • Доступ к устройствам: использование разных устройств для ввода и вывода информации;
  • +
  • Стилизация: создание изощренных и совершенных тем.
  • +
+ + + + + + + + +
+

СЕМАНТИКА

+ +
+
Секции и контуры в HTML5
+
Контурные и секционные элементы в HTML5: {{ HTMLElement("section") }}, {{ HTMLElement("article") }}, {{ HTMLElement("nav") }}, {{ HTMLElement("header") }}, {{ HTMLElement("footer") }}, {{ HTMLElement("aside") }} and {{ HTMLElement("hgroup") }}.
+
Использование HTML5 audio и video
+
{{ HTMLElement("audio") }} и {{ HTMLElement("video") }} элементы вставляют и позволяют управлять мультимедиа контентом.
+
Формы в HTML5
+
Взгляд на улучшение форм в HTML5: API валидации, несколько новых атрибутов, новые значения для аттрибута {{ htmlattrxref("type", "input") }} тега {{ HTMLElement("input") }} и новый элемент {{ HTMLElement("output") }}.
+
Новые семантические элементы
+
Кроме секций, медиа и форм, множество новых тегов, такие как {{ HTMLElement("mark") }}, {{ HTMLElement("figure") }}, {{ HTMLElement("figcaption") }}, {{ HTMLElement("data") }}, {{ HTMLElement("time") }}, {{ HTMLElement("output") }}, {{ HTMLElement("progress") }} и {{ HTMLElement("meter") }}, увеличено количество валидных HTML5 элементов.
+
Улучшение {{HTMLElement("iframe")}}
+
Использование атрубутов {{htmlattrxref("sandbox", "iframe")}}, {{htmlattrxref("seamless", "iframe")}}, and {{htmlattrxref("srcdoc", "iframe") }}, разработчики могут задать нужный уровень безопасности и осуществивить рендеринг тега {{HTMLElement("iframe")}}.
+
MathML
+
Позволяет вставлять математические формулы.
+
Введение в HTML5
+
Эта статья знакомит вас с тем, как указать на то, что вы используете HTML5 в вашем веб-дизайне или веб-приложении.
+
HTML5-совместимый парсер
+
Анализатор, который превращает байты HTML документа в DOM, был расширен и точно определяет поведение, чтобы даже в случае неверного HTML, исход был предсказуемым и одинаков во всех HTML5-совместимых браузерах.
+
+
+ +

СВЯЗЬ

+ +
+
Web Sockets
+
Позволяет создать постоянное соединение между страницей и сервером и обмениваться данными через него.
+
Server-sent события
+
Позволяет серверу отправлять события клиенту, а не по классической парадигме, где сервер может передавать данные только в ответ на запрос клиента.
+
WebRTC
+
Эта технология, где RTC создает возможость общения в реальном времени, позволяет подключаться к другим людям и контролировать видеоконференции непосредственно в браузере, без необходимости плагинов и внешний приложений.
+
+ +

ОФФЛАЙН И ХРАНИЛИЩЕ

+ +
+
Оффлайн ресурсы: кеш приложения
+
Firefox полностью поддерживает спецификацию HTML5 по оффлайн ресурсам. Другие браузеры также имеют поддержку спецификации на должном уровне
+
Online and offline events
+
Firefox 3 поддерживает WHATWG online и offline события, которые позволяют приложениям и расширениям обнаружить есть ли активное подключение к Интернет, а также определить, когда соединение портится или улучшается.
+
WHATWG сессионное или постоянное хранилище (aka DOM Storage)
+
Постоянное или сессионое храилище позволяет веб-приложениям хранить структурированны данные на стороне клиента.
+
IndexedDB
+
Веб-стандарт для хранения значительных количеств структурированных данных в браузере и для быстрого их поиска, используя индексы.
+
Using files from web applications
+
Поддержка HTML5 File API была добавлена в Gecko, сделав возможным веб-приложениям иметь доступ к файлам, выбираемых пользователем. Это включает поддержку множества файлов, используя {{ HTMLElement("input") }} с типом file, имеющих атрибут multiple. Ещё это FileReader.
+
+ +

МУЛЬТИМЕДИА

+ +
+
Использование HTML5 audio и video
+
{{ HTMLElement("audio") }} и {{ HTMLElement("video") }} элементы вставляют и позволяют управлять мультимедиа контентом.
+
WebRTC
+
Эта технология, где RTC создает возможость общения в реальном времени, позволяет подключаться к другим людям и контролировать видеоконференции непосредственно в браузере, без необходимости плагинов и внешний приложений.
+
Использование Camera API
+
Позволяет контролировать, манипулировать и хранить изображения с камеры устройства.
+
+ +

ГРАФИКА И ЭФФЕКТЫ

+ +
+
Canvas Tutorial
+
Узнайте о элементе {{ HTMLElement("canvas") }} и узнайте, как рисовать графику и другие элементы в Firefox.
+
HTML5 text API для <canvas>
+
HTML5 text API сейчас поддерживается в {{ HTMLElement("canvas") }}.
+
WebGL
+
WebGL приносит 3D в веб, соответстсвует OpenGL ES 2.0, может использоваться в HTML5 через {{ HTMLElement("canvas") }}.
+
SVG
+
Основанный на XML формат векторных изображений, который может быть непосредственно вставлен в HTML.
+
+ +
+
+
+
+

производительность и интеграция

+ +
+
Web Workers
+
Позволяет делегировать выполнение JavaScript в фоновые потоки, это позволит предотвратить замедление интерактивных событий.
+
XMLHttpRequest Level 2
+
Позволяет извлечь асинхронно некоторые части страницы, что позволяет отобразить динамический контент, изменяющейся время от времени или от действий пользователя. Это технология, лежащая в основе AJAX.
+
JIT-компилирование движков JavaScript
+
Новое поколение движков JavaScript гораздо более мощных, приводящих к большей производительности.
+
History API
+
Позволяет управлять историей браузера. Это особенно полезно страниц, интерактивно загружающих новую информацию.
+
contentEditable атрибут: трансформируйте свой сайт в википедию!
+
HTML5 стандартизировал атрибут contentEditable. Узнайте больше об этой фиче.
+
Drag and drop
+
HTML5 drag and drop API позволяет перетаскивать элементы по сайту или на него. Также простейшее API для использования расширениями или иными приложениями.
+
Управление фокусом в HTML
+
Поддержка новый атрибутов HTML5 activeElement and hasFocus.
+
Обработчики протоколов для Web
+
Вы можете зарегистровать веб-приложения, как обработчики протоколов, используя метод navigator.registerProtocolHandler().
+
requestAnimationFrame
+
Контролирует анимации для обеспечения оптимальной производительности.
+
Fullscreen API
+
Позволяет использовать весь экран для веб-приложения, без отображения UI браузера.
+
Pointer Lock API
+
Позволяет блокировать курсор, так чтобы игры и подобные приложения не теряли фокус, когда указатель достигает предела окна.
+
Online and offline events
+
Для того, чтобы построить хорошую оффлайн-совместимые веб-приложения, вы должны знать, когда ваше приложение без сети. Также, вы должны знать, когда ваше приложение снова вернется в сеть.
+
+ +

доступ к устройствам

+ +
+
Использование Camera API
+
Позволяет контролировать, манипулировать и хранить изображения с камеры устройства.
+
Touch события
+
Обрабатывает события, создаваемые нажатиями пользователя по тач скрину.
+
Геолокация
+
Позволяет браузерам получать местоположение пользователя.
+
Определение ориентации устройства
+
Позволяет среагировать, когда устройство, на котором работает браузер, меняет ориентацию. Это может быть использовано в качестве устройства ввода (например, чтобы сделать игры, которые реагируют на положение устройства) или адаптировать компоновку страницы с ориентацией экрана (вертикальная или горизонтальная).
+
Pointer Lock API
+
Позволяет блокировать курсор, так чтобы игры и подобные приложения не теряли фокус, когда указатель достигает предела окна.
+
+ +

стилизация

+ +

CSS был расширен, чтобы дать возможность стилизировать элементы наиболее оптимальным способом. Его часто называют CSS3, хотя CSS больше не является монолитной спецификацией и различные модули, не все на уровне 3: некоторые на уровне 1, а некоторые на уровне 4, с промежуточными уровнями.

+ +
+
Новые способы стилизирования фона
+
Новая возможность задать тень элемента, используя {{ cssxref("box-shadow") }} или установление множественных фонов.
+
Лучшие границы
+
Не только изображения можно использовать для стилизирования границы, используя {{ cssxref("border-image") }} или его длинные формы записи, а скруглить уголки можно свойством {{ cssxref("border-radius") }}.
+
Анимируйте свой стиль
+
Используйте CSS Переходы, чтобы анимировать изменение состояния элемента или CSS Анимации для анимации частей страницы без запуска событий, вы теперь можете контролировать мобильные элементы на вашей странице.
+
Улучшение типографии
+
Авторы могут лучше контролировать типографию. Например, они могут контролировать {{ cssxref("text-overflow") }} и перенос слов, а также тень текста и его декорированиe. Могут загрузить и применить другой шрифт правилом {{ cssxref("@font-face") }}.
+
Новые презентационные макеты
+
Для того, чтобы улучшить гибкость дизайна, добавили: CSS мульти-колоночный макет и CSS отзывчивый блочный макет.
+
+
diff --git a/files/ru/web/guide/html/html5/introduction_to_html5/index.html b/files/ru/web/guide/html/html5/introduction_to_html5/index.html new file mode 100644 index 0000000000..28b8138f0e --- /dev/null +++ b/files/ru/web/guide/html/html5/introduction_to_html5/index.html @@ -0,0 +1,26 @@ +--- +title: Введение в HTML5 +slug: HTML/HTML5/Введение_в_HTML5 +tags: + - DOCTYPE + - HTML5 + - HTML5 парсер +translation_of: Web/Guide/HTML/HTML5/Introduction_to_HTML5 +--- +

HTML5 - пятая редакция и самая новая версия стандарта HTML. Она предлагает новые возможности, которые предоставляют не только богатую поддержку медиа, но и также расширяет возможности для создания веб-приложений, которые могут взаимодействовать с пользователем, его локальными данными, и серверами проще и эффективнее, чем это было раньше.

+

Because HTML5 is still being developed, changes to the specifications are inevitable. Therefore, not all of its features are supported by all browsers yet. However, Gecko, and by extension, Firefox, has very good initial support for HTML5, and work continues toward supporting more of its features. Gecko began supporting some HTML5 features in version 1.8.1. You can find a list of all of the HTML5 features that Gecko currently supports on the main HTML5 page. For detailed information about multiple browsers' support of HTML5 features, refer to the CanIUse website.

+

Declaring that the document contains HTML5 mark-up with the HTML5 doctype

+

The doctype for HTML5 is very simple. To indicate that your HTML content uses HTML5, simply use:

+
<!DOCTYPE html>
+
+

Doing so will cause even browsers that don't presently support HTML5 to enter into standards mode, which means that they'll interpret the long-established parts of HTML in an HTML5-compliant way while ignoring the new features of HTML5 they don't support.

+

This is much simpler than the former doctypes, and shorter, making it easier to remember and reducing the amount of bytes that must be downloaded.

+

Декларация кодировки с помощью <meta charset>

+

The first thing done on a page is usually indicating the character set that is used. In previous versions of HTML, it was done using a very complex {{HTMLElement("meta")}} element. Now, it is very simple:

+
<meta charset="UTF-8">
+

Place this right after your {{HTMLElement("head") }}, as some browsers restart the parsing of an HTML document if the declared charset is different from what they had anticipated. Also, if you are not currently using UTF-8, it's recommended that you switch to it in your Web pages, as it simplifies character handling in documents using different scripts.

+

Note that HTML5 restricts the valid charset to that compatible with ASCII and using at least 8 bits. This was done to tighten security and prevent some types of attacks.

+

Использование нового HTML5 парсера

+

The parsing rule of HTML5, which analyzes the meaning of mark-up, has been more precisely defined in HTML5. Until the introduction of HTML5, only the meaning of valid mark-up was defined, meaning that as soon as one small error was made in the mark-up (most Web sites have at least one), the behavior was undefined. Essentially, it meant that all browsers behaved differently, which is no longer the case. Now, faced with errors in the mark-up, all compliant browsers must behave exactly in the same way.

+

This requirement helps Web developers quite a bit. While it is true that all modern browsers now use these HTML5 parsing rules, non-HTML5-compliant browsers are still used by some. Keep in mind that it's still highly recommended that one write valid mark-up, as such code is easier to read and maintain, and it greatly decreases the prominence of incompatibilities that exists in various older browsers.

+

Не волнуйтесь - вам не придется ничего менять на вашем веб-сайте - разработчики веб-браузерах сделали все для вас!

diff --git a/files/ru/web/guide/html/sections_and_outlines_of_an_html5_document/index.html b/files/ru/web/guide/html/sections_and_outlines_of_an_html5_document/index.html deleted file mode 100644 index a6236d9c24..0000000000 --- a/files/ru/web/guide/html/sections_and_outlines_of_an_html5_document/index.html +++ /dev/null @@ -1,375 +0,0 @@ ---- -title: Использование разделов и создание структуры HTML документа -slug: Web/Guide/HTML/Sections_and_Outlines_of_an_HTML5_document -tags: - - HTML5 - - Веб - - Для опытных разработчиков - - Обзор - - Пример - - Разделы - - Руководство - - Структура -translation_of: Web/Guide/HTML/Using_HTML_sections_and_outlines ---- -
-

Важно: В настоящее время нет известных реализаций алгоритма построения структуры документа в графических браузерах или пользовательских приложениях, использующих реабилитационные технологии, хотя такой алгоритм внедрен в другие приложения, например, в средствах проверки соответствия спецификации. Поэтому алгоритм построения структуры нельзя использовать для передачи структуры документа пользователям. Авторы рекомендуют использовать для этой цели степень важности заголовков (h1-h6).

-
- -

Спецификация HTML5 предлагает разработчикам несколько новых элементов, позволяющих описывать структуру веб-документа с помощью стандартной семантики. В настоящей статье описываются эти элементы и способы их использования для создания требуемой структуры любого документа.

- -

Структура документа в HTML 4

- -

Структура документа, т. е. семантическая структура контента, заключенного в теги  <body> и </body>, является основой для представления страницы пользователю. HTML4 использует для описания структуры страницы разделы и подразделы. Раздел определяется элементом ({{HTMLElement("div")}}) с включенными в него элементами заголовка ({{HTMLElement("h1")}}, {{HTMLElement("h2")}}, {{HTMLElement("h3")}}, {{HTMLElement("h4")}}, {{HTMLElement("h5")}} или {{HTMLElement("h6")}}), содержащими его название. Структура документа определяется отношениями между этими элементами.

- -

Так, следующая разметка:

- -
-
<div class="section" id="forest-elephants" >
-  <h1>Лесные слоны</h1>
-  <p>В данном разделе мы поговорим о малоизвестных лесных слонах.
-    ...продолжение данного раздела...
-  <div class="subsection" id="forest-habitat" >
-    <h2>Среда обитания</h2>
-    <p>Лесные слоны живут не на деревьях, а под ними.
-     ...продолжение данного подраздела...
-  </div>
-</div>
-
-
- -

обеспечивает следующую структуру:

- -
1. Лесные слоны
-   1.1 Среда обитания
-
- -

Для задания нового раздела не обязательно использовать элементы {{HTMLElement("div")}}. Для этого достаточно наличия элемента заголовка. Поэтому, разметка

- -
<h1>Лесные слоны</h1>
- <p>В данном разделе мы поговорим о малоизвестных лесных слонах.
-    ...продолжение данного раздела...
-  <h2>Среда обитания</h2>
-  <p>Лесные слоны живут не на деревьях, а под ними.
-    ...продолжение данного подраздела...
-  <h2>Рацион</h2>
-<h1>Монгольская песчанка</h1>
-
- -

обеспечивает следующую структуру:

- -
1. Лесные слоны
-   1.1 Среда обитания
-   1.2 Рацион
-2. Монгольская песчанка
-
- -

Какие проблемы решает HTML5

- -

Определение структуры документа и неявный алгоритм создания структуры в HTML 4 не отличаются четкостью, что порождает множество проблем:

- -
    -
  1. Использование {{HTMLElement("div")}} для задания семантических разделов, без задания специальных значений для атрибутов class не позволяет автоматизировать алгоритм создания структуры («Является ли данный {{HTMLElement("div")}} частью структуры страницы, определяющим раздел или подраздел, или он используется исключительно для управления стилем?»). Другими словами, спецификация HTML4 не дает точного определения разделу и четких правил его определения. Автоматическое создание структуры имеет большое значение, особенно в случае с реабилитационными технологиями, представляющими информацию пользователю в соответствии со структурой документа. HTML5 позволяет больше не использовать элементы {{HTMLElement("div")}} в алгоритме построения структуры благодаря добавлению нового элемента {{HTMLElement("section")}}.
  2. -
  3. Объединить несколько документов в один непросто: включение подчиненного документа в основной документ требует изменения уровня элементов заголовков для сохранения правильной структуры. В HTML5 эта проблема решена благодаря новым элементам задания разделов ({{HTMLElement("article")}}, {{HTMLElement("section")}}, {{HTMLElement("nav")}} и {{HTMLElement("aside")}}), которые всегда являются подразделами ближайшего родительского раздела, независимо от того, какие разделы создаются внутренними заголовками.
  4. -
  5. В HTML4 каждый раздел является частью структуры документа. Однако часто документы отличаются сложной, нелинейной структурой. Документ может включать специальные разделы, информация в которых не является частью основного контента, хотя и связана с ним, например, рекламный блок или поясняющая заметка. HTML5 добавляет элемент {{HTMLElement("aside")}}, позволяющий исключить такие разделы из основной структуры.
  6. -
  7. Опять же, поскольку в HTML4 каждый раздел является частью структуры документа, как быть с разделами, содержащими информацию, касающуюся не конкретного документа, а всего сайта, например, логотипы, оглавления или информация об авторских правах и правовые положения. В HTML5 для этих целей добавлено три новых элемента: {{HTMLElement("nav")}} для наборов ссылок, например, оглавления, {{HTMLElement("footer")}} и {{HTMLElement("header")}} для информации, касающейся всего сайта. Обратите внимание, что {{HTMLElement("header")}} и {{HTMLElement("footer")}} не создают разделы как {{HTMLElement("section")}}, а, скорее, обеспечивают семантическую разметку частей раздела.
  8. -
- -

В общем, HTML5 обеспечивает большую точность при задании разделов и оглавлений, позволяя строить более предсказуемую структуру документа, что дает браузерам возможность более качественно обслуживать пользователей.

- -

Алгоритм создания структуры HTML5

- -

Задание разделов в HTML5

- -

Весь контент, находящийся внутри {{HTMLElement("body")}}, является частью раздела. Разделы в HTML5 могут быть вложенными. Помимо основного раздела, определяемого элементом {{HTMLElement("body")}}, границы разделов определяются явным или неявным образом. Явным образом заданные разделы – это контент внутри тегов {{HTMLElement("body")}},  {{HTMLElement("section")}},  {{HTMLElement("article")}},  {{HTMLElement("aside")}} и {{HTMLElement("nav")}}. 

- -
Note: Каждый раздел может иметь собственную иерархию заголовков. Следовательно, даже вложенный раздел может иметь {{HTMLElement("h1")}}. См. «Задание заголовков в HTML5».
- -

Например:

- -
<section>
-  <h1>Лесные слоны</h1>
-  <section>
-    <h1>Введение</h1>
-    <p>В данном разделе мы поговорим о малоизвестных лесных слонах.</p>
-  </section>
-  <section>
-    <h1>Среда обитания</h1>
-    <p>Лесные слоны живут не на деревьях, а под ними.</p>
-  </section>
-  <aside>
-    <p>рекламный блок</p>
-  </aside>
-</section>
-<footer>
-  <p>(c) 2010 The Example company</p>
-</footer>
- -

Данный фрагмент HTML задает раздел верхнего уровня:

- -
<section>
-  <h1>Лесные слоны</h1>
-  <section>
-    <h1>Введение</h1>
-    <p>В данном разделе мы поговорим о малоизвестных лесных слонах.</p>
-  </section>
-  <section>
-    <h1>Среда обитания</h1>
-    <p>Лесные слоны живут не на деревьях, а под ними.</p>
-  </section>
-  <aside>
-    <p>рекламный блок</p>
-  </aside>
-</section>
-<footer>
-  <p>(c) 2010 The Example company</p>
-</footer>
- -

Данный раздел имеет три подраздела:

- -
<section>
-  <h1>Лесные слоны</h1>
-
-  <section>
-    <h1>Введение</h1>
-    <p>В данном разделе мы поговорим о малоизвестных лесных слонах.</p>
-  </section>
-
-  <section>
-    <h1>Среда обитания</h1>
-    <p>Лесные слоны живут не на деревьях, а под ними.</p>
-  </section>
-
-  <aside>
-    <p>рекламный блок</p>
-  </aside>
-</section>
-
-<footer>
-  <p>(c) 2010 The Example company</p>
-</footer>
- -

В результате получаем следующую структуру:

- -
1. Лесные слоны
-   1.1 Введение
-   1.2 Среда обитания
-
- -

Задание заголовков в HTML5

- -

Хотя структура определяется элементами задания структуры, она будет практически бесполезна без заголовка. Основное правило очень простой: первый элемент заголовка (это может быть {{HTMLElement("h1")}}, {{HTMLElement("h2")}}, {{HTMLElement("h3")}}, {{HTMLElement("h4")}}, {{HTMLElement("h5")}}, {{HTMLElement("h6")}}) задает заголовок текущего раздела.

- -

Элемент заголовка имеет определенную степень важности, определяемую цифрой в его названии, таким образом, {{HTMLElement("h1")}} имеет максимальную степень важности, а {{HTMLElement("h6")}} минимальную. Соотношение степеней важности имеет смысл только внутри раздела; структура документа определяется структурами разделов, а не степенью важности заголовков разделов. Например, данный код:

- -
<section>
-  <h1>Лесные слоны</h1>
-  <p>В данном разделе мы поговорим о малоизвестных лесных слонах.
-    ...продолжение данного раздела...
-  <section>
-    <h2>Среда обитания</h2>
-    <p>Лесные слоны живут не на деревьях, а под ними.
-        ...продолжение данного подраздела...
-  </section>
-</section>
-<section>
-  <h3>Монгольская песчанка</h3>
-  <p>В данном разделе мы расскажем о монгольской песчанке.
-     ...продолжение данного раздела...
-</section>
- -

приводит к следующей структуре:

- -
1. Лесные слоны
-   1.1 Среда обитания
-2. Монгольская песчанка
- -

Обратите внимание, что степень важности элемента заголовка (в данном примере {{HTMLElement("h1")}} для первого раздела верхнего уровня, {{HTMLElement("h2")}} для подраздела {{HTMLElement("h3")}} для второго раздела верхнего уровня) роли не играет. (В качестве заголовка явно заданного раздела может использоваться заголовок с любой степенью важности, хотя такая практика и не рекомендуется.)

- -

Неявное задание разделов

- -

Поскольку элементы задания разделов HTML5 Sectioning Elements не являются обязательными для задания структуры, можно задавать разделы и не используя их, чтобы обеспечить совместимость с веб-сайтами, созданными на HTML4. Это называется неявным заданием разделов.

- -

Элементы заголовков ({{HTMLElement("h1")}} — {{HTMLElement("h6")}}) задают новый, неявный раздел, когда не являются первым заголовком своего родительского, явно заданного раздела. То, как этот неявно заданный раздел располагается в структуре документа, определяется отношением важности его заголовка в важности предыдущего заголовка в родительском разделе. Если его степень важности ниже, чем у предыдущего заголовка, он открывает неявно заданный подраздел раздела. Следующий код:

- -
<section>
-  <h1>Лесные слоны</h1>
-  <p>В данном разделе мы поговорим о малоизвестных лесных слонах.
-    ...продолжение данного раздела...
-  <h3 class="implicit subsection">Среда обитания</h3>
-  <p>Лесные слоны живут не на деревьях, а под ними.
-    ...продолжение данного подраздела...
-</section>
- -

приводит к следующей структуре:

- -
1. Лесные слоны
-   1.1 Среда обитания (неявно задано элементом h3)
-
- -

Если степень важности такого заголовка совпадает со степенью важности предыдущего заголовка, он закрывает предыдущий раздел (который мог быть задан неявно!) и открывает новый неявно заданный раздел на том же уровне: 

- -
<section>
-  <h1>Лесные слоны</h1>
-  <p>В данном разделе мы поговорим о малоизвестных лесных слонах.
-    ...продолжение данного раздела...
-  <h1 class="implicit section">Монгольская песчанка</h1>
-  <p>Монгольская песчанка – это небольшое симпатичное млекопитающее.
-    ...продолжение данного раздела...
-</section>
- -

приводит к следующей структуре:

- -
1. Лесные слоны
-2. Монгольская песчанка (неявно задано элементом h1, который одновременно закрывает предыдущий раздел)
-
- -

Если степень важности такого заголовка выше, чем у предыдущего заголовка, он закрывает предыдущий раздел и открывает новый неявно заданный раздел на более высоком уровне:

- -
<body>
-  <h1>Млекопитающие</h1>
-  <h2>Киты</h2>
-  <p>В данном разделе мы поговорим о китах.
-    ...продолжение данного раздела...
-  <section>
-    <h3>Лесные слоны</h3>
-    <p>В данном разделе мы поговорим о малоизвестных лесных слонах.
-    ...продолжение данного раздела...
-    <h3>Монгольская песчанка</h3>
-      <p>Песчанки распространились далеко за пределы Монголии.
-         ...продолжение данного подраздела...
-    <h2>Рептилии</h2>
-      <p>Рептилии – это холоднокровные животные.
-          ...продолжение данного раздела...
-  </section>
-</body>
- -

приводит к следующей структуре:

- -
1. Млекопитающие
-   1.1 Киты (неявно задается элементом h2)
-   1.2 Лесные слоны (явным образом задается элементом раздела)
-   1.3 Монгольская песчанка (неявно задается элементом h3, который одновременно закрывает предыдущий раздел)
-2. Рептилии (неявно задается элементом h2, который одновременно закрывает предыдущий раздел)
-
- -

Эта не та структура, которую можно было бы ожидать, бегло просмотрев теги заголовков. Чтобы разметка стала понятна человеку, а также чтобы степень важности заголовка соответствовала уровню вложенности раздела, рекомендуется использовать наглядные теги для открытия и закрытия разделов. Однако спецификация HTML5 этого не требует. Поэтому, если браузеры отображают структуру документа не так, как ожидалось, проверьте, нет ли в документе разделов, не явно закрытых элементами заголовков.

- -

Исключение из общего правила соответствия степени важности тега уровню вложенности раздела делается для разделов, которые могут использоваться в нескольких документах. Например, раздел может храниться в системе управления контентом и добавляться в документы при их генерировании. В этом случае рекомендуется начинать с {{HTMLElement("h1")}} в качестве главного заголовка многократно используемого раздела. Уровень вложенности многократно используемого раздела будет определяться иерархией разделов документа, в который он добавляется. Теги для явного задания разделов по-прежнему останутся полезными и в этом конкретном случае.

- -

Корни задания разделов

- -

 Корень задания разделов – это элемент HTML, который может иметь собственную структуру, однако входящие в нее разделы и заголовки, не входят в структуру его родительского элемента. Помимо {{HTMLElement("body")}}, который является логическим корнем задания разделов документа, такими элементами часто являются элементы, добавляющие внешний контент на страницу: {{HTMLElement("blockquote")}}, {{HTMLElement("details")}}, {{HTMLElement("fieldset")}}, {{HTMLElement("figure")}} и {{HTMLElement("td")}}.

- -

Например:

- -
<section>
-  <h1>Лесные слоны</h1>
-  <section>
-    <h2>Введение</h2>
-    <p>В данном разделе мы поговорим о малоизвестных лесных слонах</p>
-  </section>
-  <section>
-    <h2>Среда обитания</h2>
-    <p>Лесные слоны живут не на деревьях, а под ними. Давайте рассмотрим, что говорят ученые в «<cite>Лесной слон на Борнео</cite>»:</p>
-    <blockquote>
-       <h1>Борнео</h1>
-       <p>Лесной слон живет на Борнео...</p>
-    </blockquote>
-  </section>
-</section>
-
- -

Данный пример приводит к следующей структуре:

- -
1. Лесные слоны
-   1.1 Введение
-   1.2 Среда обитания
- -

Данная структура не включает внутреннюю структуру элемента {{HTMLElement("blockquote")}}, который, будучи внешней цитатой, является корнем задания разделов и изолирует свою внутреннюю структуру.

- -

Разделы, не входящие в структуру

- -

 HTML5 вводит два новых элемента, позволяющих задавать разделы, не входящие в основную структуру веб-документа:

- -
    -
  1. Элемент вспомогательного раздела {{HTMLElement("aside")}} задает раздел, который, хотя и связан с основным элементом, не принадлежит к основной структуре, например, поясняющая заметка или реклама. Он имеет собственную структуру, однако не входит в основную структуру страницы.
  2. -
  3. Элемент навигационного раздела {{HTMLElement("nav")}} задает раздел, содержащий навигационные ссылки. Таких элементов в документе может быть несколько, например, один со внутренними ссылками на страницу, например, оглавление, а другой – с ссылками для навигации по сайту. Такие ссылки не являются частью основной структуры документа и как правило пропускаются экранными дикторами.
  4. -
- -

Шапки и подвалы

- -

HTML5 также добавляет два новых элемента, которые могут использоваться для разметки верхнего и нижнего колонтитулов страниц:

- -
    -
  1. Элемент шапки {{HTMLElement("header")}} задает шапку страницы (как правило, логотип и название сайта, а также горизонтальное меню, если имеется) или раздела (которая может включать заголовок раздела, имя автора и т.д.).{{HTMLElement("article")}}, {{HTMLElement("section")}}, {{HTMLElement("aside")}}, и {{HTMLElement("nav")}} могут иметь собственный {{HTMLElement("header")}}. Несмотря на название, этот элемент не обязательно располагается в начале страницы или раздела.
  2. -
  3. Элемент подвала ({{HTMLElement("footer")}}) задает нижний колонтитул страницы (как правило включающий уведомления об авторских правах и другую правовую информацию, а иногда также содержащий какие-либо ссылки) или раздела (может включать дату публикации, информацию о лицензии и т.п. {{HTMLElement("article")}}, {{HTMLElement("section")}}, {{HTMLElement("aside")}} и {{HTMLElement("nav")}} могут иметь собственный {{HTMLElement("footer")}}. Несмотря на название, этот элемент не обязательно располагается в конце страницы или раздела.
  4. -
- -

Эти элементы не создают новые разделы в структуре, а скорее используются для разметки контента внутри разделов страницы.

- -

Адреса в элементах задания разделов

- -

Автор документа часто хочет опубликовать свою контактную информацию, например, имя и адрес. HTML4 позволял сделать это с помощью элемента {{HTMLElement("address")}}, расширенного в HTML5.

- -

Документ может включать несколько разделов, принадлежащих разным авторам. Если раздел создается не автором основной страницы, для задания используется элемент {{HTMLElement("article")}}. В результате элемент {{HTMLElement("address")}} теперь связан с ближайшим родительским {{HTMLElement("body")}} или {{HTMLElement("article")}}.

- -

Использование элементов HTML5 в браузерах, не поддерживающих HTML5

- -

Элементы разделов и заголовков должны работать в большинстве браузеров, не поддерживающих HTML5. Хотя они и не поддерживаются, они не требуют специального интерфейса DOM, им требуется лишь особый стиль CSS, поскольку к неизвестным элементам по умолчанию применяется стиль display:inline:

- -
section, article, aside, footer, header, nav, hgroup {
-  display:block;
-}
-
- -

Конечно, веб-разработчик может применить к ним любой другой стиль, однако следует помнить в браузерах, не поддерживающих HTML5, по умолчанию используется не тот стиль, который требуется для таких элементов. Также обратите внимание на отсутствие в перечне элемента {{HTMLElement("time")}}, поскольку по умолчанию к нему применяется одинаковый стиль как в браузерах, не поддерживающих HTML5, так и в браузерах, совместимых с HTML5.

- -

Данный способ не универсален, поскольку некоторые браузеры не позволяют применять стили к неподдерживаемым элементам. Например, Internet Explorer (версии 8 и более ранней), для которого требуется специальный скрипт:

- -
<!--[if lt IE 9]>
-  <script>
-    document.createElement("header" );
-    document.createElement("footer" );
-    document.createElement("section");
-    document.createElement("aside"  );
-    document.createElement("nav"    );
-    document.createElement("article");
-    document.createElement("hgroup" );
-    document.createElement("time"   );
-  </script>
-<![endif]-->
- -

Этот скрипт запускается в Internet Explorer (8 и более ранней версии), однако требует включенной поддержки скриптов для правильного отображения элементов задания разделов и заголовок HTML5. Если поддержа скриптов выключена, это может стать проблемой, поскольку данные элементы, скорее всего, определяют структуру всей страницы. Поэтому необходимо добавить элемент {{HTMLElement("noscript")}}:

- -
<noscript>
-   <strong>Внимание!</strong>
-   Поскольку ваш браузер не поддерживает HTML5, некоторые элементы воспроизводятся с помощью JScript.
-   Однако в вашем браузере скрипты отключены, пожалуйста, включите их, чтобы браузер смог отобразить данную страницу.
-</noscript>
- -

This leads to the following code to allow the support of the HTML5 sections and headings elements in non-HTML5 browsers, even for Internet Explorer (8 and older), with a proper fallback for the case where this latter browser is configured not to use scripting:

- -
<!--[if lt IE 9]>
-  <script>
-    document.createElement("header" );
-    document.createElement("footer" );
-    document.createElement("section");
-    document.createElement("aside"  );
-    document.createElement("nav"    );
-    document.createElement("article");
-    document.createElement("hgroup" );
-    document.createElement("time"   );
-  </script>
-  <noscript>
-     <strong>Внимание!</strong>
-     Поскольку ваш браузер не поддерживает HTML5, некоторые элементы воспроизводятся с помощью JScript.
-     Однако в вашем браузере скрипты отключены, пожалуйста, включите их, чтобы браузер смог отобразить данную страницу.
-  </noscript>
-<![endif]-->
- -

Заключение

- -

Новые семантические элементы, добавленные в HTML5, обеспечивают стандартизацию описания структуры веб-документа. Они облегчают жизнь пользователям с ограниченными возможностями, просты в использовании, могут без особых проблем поддерживаться в старых браузерах и поэтому настоятельно рекомендуются к применению.

- -
{{HTML5ArticleTOC()}}
diff --git a/files/ru/web/guide/html/tips_for_authoring_fast-loading_html_pages/index.html b/files/ru/web/guide/html/tips_for_authoring_fast-loading_html_pages/index.html deleted file mode 100644 index f34fe049f5..0000000000 --- a/files/ru/web/guide/html/tips_for_authoring_fast-loading_html_pages/index.html +++ /dev/null @@ -1,204 +0,0 @@ ---- -title: Tips for authoring fast-loading HTML pages -slug: Web/Guide/HTML/Tips_for_authoring_fast-loading_HTML_pages -translation_of: Learn/HTML/Howto/Author_fast-loading_HTML_pages ---- -

Эти советы основаны на общих знаниях и экспериментах.

- -

Оптимизированная веб-страница не только обеспечивает более отзывчивый сайт для ваших посетителей, но также снижает нагрузку на ваши веб-серверы и интернет-соединения. Это может иметь решающее значение для сайтов с большим объемом или сайтов, которые имеют всплеск трафика из-за необычных обстоятельств, таких как последние новости

- -

Оптимизация производительности загрузки страницы нужна не только для контента, который будет просматриваться узкополосным модемом или посетителями мобильных устройств. Это так же важно для широкополосного контента и может привести к значительным улучшениям даже для ваших посетителей с самыми быстрыми подключениями.

- -

Советы

- -

Уменьшайте вес страницы

- -

Веб-страницы - безусловно, самый важный фактор в производительности загрузки страницы.

- -

Уменьшение веса страницы за счет устранения ненужных пробелов и комментариев, широко известна как минимизация, и перемещая встроенный скрипт и CSS во внешние файлы, можно улучшить производительность загрузки с минимальными потребностями в других изменениях в структуре страницы.

- -

Такие инструменты, как HTML Tidy , могут автоматически убирать начальные пробелы и лишние пустые строки из допустимого источника HTML. Другие инструменты могут «сжимать» JavaScript, переформатируя источник или запутывая источник и заменяя длинные идентификаторы на более короткие версии

- -

Минимизируйте количество файлов

- -

Уменьшение количества файлов, на которые есть ссылки на веб-странице, уменьшает количество HTTP-соединений, необходимых для загрузки страницы, тем самым сокращая время отправки этих запросов и получения их ответов.

- -

В зависимости от настроек кэша браузера он может отправить запрос с заголовком If-Modified-Since для каждого ссылочного файла, спрашивая, был ли файл изменен с момента последней загрузки. Слишком много времени, затрачиваемое на запрос времени последнего изменения указанных файлов, может задержать первоначальное отображение веб-страницы, так как браузер должен проверить время изменения каждого из этих файлов перед отображением страницы.

- -

Если вы часто используете фоновые изображения в своем CSS, вы можете уменьшить количество запросов на поиск HTTP, объединив изображения в одно, называемое спрайтом изображения. Затем вы просто применяете одно и то же изображение каждый раз, когда вам это нужно для фона, и соответственно корректируете координаты x / y. Этот метод лучше всего работает с элементами, которые будут иметь ограниченные размеры, и не будет работать для каждого использования фонового изображения. Тем не менее, меньшее количество HTTP-запросов и кэширование одного изображения может помочь сократить время загрузки страницы.

- -

Используйте сеть доставки (и дистрибуции) содержимого (Content Delivery Network (CDN))

- -

Для целей этой статьи CDN - это средство уменьшения физического расстояния между вашим сервером и вашим посетителем. По мере увеличения расстояния между вашим сервером и посетителем время загрузки будет увеличиваться. Предположим, ваш сервер веб-сайта находится в Соединенных Штатах и имеет посетителя из Индии; время загрузки страницы будет намного выше для индийского посетителя по сравнению с посетителем из США.

- -

CDN - это географически распределенная сеть серверов, которые работают вместе, чтобы сократить расстояние между пользователем и вашим сайтом. CDN хранят кэшированные версии вашего веб-сайта и предоставляют их посетителям через ближайший к пользователю сетевой узел, тем самым снижая задержку

- -

Дальнейшее чтение:

- - - -

Сократите поиск доменов

- -

Поскольку каждый отдельный домен требует времени для поиска DNS, время загрузки страницы будет расти вместе с количеством отдельных доменов, отображаемых в ссылках CSS, а также в JavaScript и изображениях.

- -

Это не всегда может быть практичным; однако вы всегда должны позаботиться об использовании только минимально необходимого количества разных доменов на своих страницах.

- -

Кэшируйте повторно использованный контент

- -

Убедитесь, что любой контент, который может быть кэширован, кэширован и имеет подходящее время истечения.

- -

В частности, обратите внимание на  заголовок Last-Modified. Это позволяет эффективно кэшировать страницы; с помощью этого заголовка агенту пользователя передается информация о файле, который он хочет загрузить, например, когда он был последний раз изменен. Большинство веб-серверов автоматически добавляют заголовок Last-Modified к статическим страницам (напр. .html, .css), на основе даты последнего изменения, хранящейся в файловой системе. С динамическими страницами (напр. .php, .aspx), это, конечно, не может быть сделано, и заголовок не отправляется.

- -

Так, в частности, для страниц, которые генерируются динамически, небольшое исследование по этой теме полезно. Это может быть несколько сложным, но это сэкономит много запросов страниц на страницах, которые обычно не могут быть кэшированы.

- -

Больше информации:

- -
    -
  1. HTTP Conditional Get for RSS Hackers
  2. -
  3. HTTP 304: Not Modified
  4. -
  5. On HTTP Last-Modified and ETag
  6. -
- -

Оптимально размещайте компоненты на странице

- -

Сначала загрузите содержимое страницы вместе с любым CSS или JavaScript, которые могут потребоваться для его первоначального отображения, чтобы пользователь получил самый быстрый очевидный ответ во время загрузки страницы. Этот контент, как правило, представляет собой текст, и поэтому может получить выгоду от сжатия текста при передаче, что обеспечивает еще более быстрый отклик для пользователя.

- -

Любые динамические функции, требующие полной загрузки страницы перед использованием, должны быть изначально отключены, а затем включены только после загрузки страницы. Это приведет к загрузке JavaScript после содержимого страницы, что улучшит общий вид загрузки страницы.

- -

Уменьшайте количество встроенных скриптов

- -

Встроенные сценарии могут быть дорогими для загрузки страницы, так как синтаксический анализатор должен предполагать, что встроенный сценарий может изменить структуру страницы во время анализа. Сокращение использования встроенных сценариев в целом и сокращение использования document.write() для вывода контента, в частности, может улучшить общую загрузку страницы. Используйте современные методы AJAX для управления содержимым страницы, а не устаревшие подходы, которые основаны на  document.write().

- -

Используйте современный CSS и корректную разметку

- -

Использование современного CSS уменьшает количество текста, может уменьшить потребность в (разделительных) изображениях с точки зрения макета и очень часто может заменить изображения стилизованного текста - это «стоит» намного дороже, чем эквивалентный текст и CSS.

- -

Использование корректной разметки имеет следующие преимущества. Во-первых, браузерам не нужно выполнять исправление ошибок при разборе HTML (это помимо философской проблемы: разрешить ли изменение формата при вводе пользователем, а затем программно «исправить» или нормализовать его; или вместо этого обеспечить строгий формат ввода без допусков).

- -

Кроме того, корректная разметка позволяет спокойно использовать другие инструменты, которые могут предварительно обрабатывать ваши веб-страницы. Например, HTML Tidy может удалить пробелы и необязательные конечные теги; однако он откажется запускать страницу с серьезными ошибками разметки

- -

Разделяйте ваш контент

- -

Использование таблиц для вёрстки макетов устаревший метод, который не должен больше использоваться. Вместо этого для создания макетов нужно использовать <a href="/en-US/docs/Learn/CSS/CSS_layout/Floats">floats</a>, <a href="/en-US/docs/Learn/CSS/CSS_layout/Positioning">positioning</a>, <a href="/en-US/docs/Learn/CSS/CSS_layout/Flexbox">flexbox</a>, или <a href="/en-US/docs/Learn/CSS/CSS_layout/Grids">grids</a>.

- -

Таблицы по-прежнему считаются допустимой разметкой, но их следует использовать для отображения табличных данных. Чтобы браузер быстрее отображал вашу страницу, вам следует избегать вложения таблиц.

- -

Вместо глубоко вложенных таблиц, как в:

- -
<TABLE>
-  <TABLE>
-    <TABLE>
-          ...
-    </TABLE>
-  </TABLE>
-</TABLE>
- -

используйте невложенные таблицы как показано (или div'ы)

- -
<TABLE>...</TABLE>
-<TABLE>...</TABLE>
-<TABLE>...</TABLE>
-
- -

Смотри также: CSS3 Multi-column Layout Spec и CSS3 Flexible Box Layout

- -

Сокращайте и сжимайте активы SVG

- -

SVG, создаваемый большинством графических приложений, часто содержит ненужные метаданные, которые можно удалить. Настройте свои сервера, примените сжатие gzip для ресурсов SVG

- -

Сокращайте и сжимайте ваши изображения

- -

Большие изображения приводят к тому, что загрузка страницы занимает больше времени. Рассмотрите возможность сжатия ваших изображений перед добавлением их на свою страницу.  Есть онлайн-инструменты, такие как <a href="https://compressjpeg.com/">Compress Jpeg</a>, <a href="https://tinypng.com">Tiny PNG</a> и многие другие, доступны онлайн. Вы можете использовать офлайн-инструменты, такие как фотошоп и другие.

- -

Указывайте размеры для изображений и таблиц 

- -

Если браузер может немедленно определить высоту и/или ширину ваших изображений и таблиц, он сможет отображать веб-страницу без необходимости переформатировать содержимое. Это не только ускоряет отображение страницы, но и предотвращает раздражающие изменения в макете страницы после завершения загрузки страницы. По этой причине height и width  должны быть указаны для изображений всегда, когда это возможно.

- -

Таблицы должны использовать CSS селектор: комбинация свойств

- -
  table-layout: fixed;
-
- -

и должны указывать ширину колонок используя HTML теги COL и COLGROUP

- -

Мудро выбирайте требования к пользовательскому агенту

- -

Чтобы добиться наибольших улучшений в дизайне страниц, убедитесь, что для проектов указаны разумные требования к пользовательским агентам. Не требуйте, чтобы ваш контент казался идеальным во всех браузерах, особенно в устаревших.

- -

В идеале ваши базовые минимальные требования должны основываться на рассмотрении современных браузеров, поддерживающих соответствующие стандарты.Это может включать: Firefox 3.6+ на любой платформе, Internet Explorer 8.0+ на Windows, Opera 10+ на Windows, и Safari 4 на Mac OS X.

- -

Примечание. Несмотря на то, что эти атрибуты очень помогают при первой загрузке страницы, вы должны использовать их, но не предполагать, что они будут работать во всех браузерах. Если вы уже следуете всем рекомендациям JavaScript, вам не нужно менять код.

- -

Используйте async и defer, если это возможно

- -

Сделайте сценарии JavaScript такими, чтобы они были совместимы как с async, так и с defer, и по возможности используйте async, особенно если у вас есть несколько тегов script.

- -

При этом страница может перестать отображаться, пока JavaScript все еще загружается. В противном случае браузер не будет отображать ничего после тегов сценария, которые не имеют этих атрибутов.

- -

Примечание. Несмотря на то, что эти атрибуты очень помогают при первой загрузке страницы, вы должны использовать их, но не предполагать, что они будут работать во всех браузерах. Если вы уже следуете всем рекомендациям JavaScript, вам не нужно менять код.

- -

Пример структуры страницы

- -

· HTML

- -
-
· HEAD
-
- -
-
-
-
· LINK ...
- CSS файлы необходимы для отображения веб-страницы. Минимизируйте количество файлов для производительности, сохраняя несвязанные CSS в отдельных файлах для обслуживания.
-
-
-
- -
-
-
-
· SCRIPT ...
- Файлы JavaScript для функций, необходимых при загрузке страницы, но не для любого DHTML, который может работать только после загрузки страницы
-
Минимизируйте количество файлов для повышения производительности, сохраняя несвязанный JavaScript в отдельных файлах для обслуживания.
-
-
-
- -
-
· BODY
-
· Видимое пользователем содержимое страницы небольшими порциями (tables / divs) что можно отобразить, не дожидаясь загрузки полной страницы.
-
- -
-
-
-
· SCRIPT ...
- Любые сценарии, которые будут использоваться для выполнения DHTML. Сценарий DHTML обычно может запускаться только после полной загрузки страницы и инициализации всех необходимых объектов. Нет необходимости загружать эти скрипты перед содержимым страницы. Это только замедляет первоначальный вид загрузки страницы.
-
Минимизируйте количество файлов для повышения производительности, сохраняя несвязанный JavaScript в отдельных файлах для обслуживания
-
Если какие-либо изображения используются для эффектов ролловера, вам следует предварительно загрузить их здесь после загрузки содержимого страницы.
-
-
-
- - - - - -
-

Original Document Information

- -
    -
  • Author(s): Bob Clary, Technology Evangelist, Netscape Communications
  • -
  • Last Updated Date: Published 04 Apr 2003
  • -
  • Copyright Information: Copyright © 2001-2003 Netscape. All rights reserved.
  • -
  • Note: This reprinted article was originally part of the DevEdge site.
  • -
-
- -

 

diff --git a/files/ru/web/guide/html/using_data_attributes/index.html b/files/ru/web/guide/html/using_data_attributes/index.html deleted file mode 100644 index cef001e25a..0000000000 --- a/files/ru/web/guide/html/using_data_attributes/index.html +++ /dev/null @@ -1,129 +0,0 @@ ---- -title: Использование data-* атрибутов -slug: Web/Guide/HTML/Using_data_attributes -tags: - - Guide - - HTML -translation_of: Learn/HTML/Howto/Use_data_attributes ---- -

HTML5 спроектирован с возможностью расширения данных ассоциированных с каким-либо элементом, но в то же время не обязательно имеющих определённое значение. data-* атрибуты позволяют хранить дополнительную информацию в стандартных элементах HTML, без хаков вроде нестандартных атрибутов, лишних DOM-свойств или {{domxref("Node.setUserData()")}}.

- -

Синтаксис HTML

- -

Синтаксис прост — любой атрибут, чьё имя начинается с data-, является data-* атрибутом. Предположим у нас имеется статья и мы хотим сохранить дополнительную информацию без визуального представления. Для этого можно использовать data-атрибуты:

- -
<article
-  id="electriccars"
-  data-columns="3"
-  data-index-number="12314"
-  data-parent="cars">
-...
-</article>
- -

Доступ в JavaScript

- -

Чтение data-атрибутов в JavaScript осуществляется также просто. Для этого можно использовать метод {{domxref("Element.getAttribute", "getAttribute()")}} с параметром, равным полному имени атрибута. Но есть и более простой способ, используя объект {{domxref("HTMLElement.dataset", "dataset")}}.

- -

Чтобы получить data-атрибут можно взять свойство объекта dataset с именем, равным части имени атрибута после data- (обратите внимание, что дефисы в имени преобразуются в camelCase).

- -
var article = document.getElementById('electriccars');
-
-article.dataset.columns // "3"
-article.dataset.indexNumber // "12314"
-article.dataset.parent // "cars"
- -

Каждое свойство является строкой и может быть прочитано и записано. В приведённом выше примере выполнение кода article.dataset.columns = 5 приведёт к тому, что новое значение атрибута станет равным "5".

- -

Доступ в CSS

- -

Заметим, что data-атрибуты являются обычными HTML-аттрибутами, к которым можно получить доступ в CSS. Например, чтобы показать родительские данные о статье можно использовать генерируемый контент и CSS функцию {{cssxref("attr")}}:

- -
article::before {
-  content: attr(data-parent);
-}
- -

Также можно использовать селекторы атрибутов в CSS для изменения стилей в соответствии с данным:

- -
article[data-columns='3']{
-  width: 400px;
-}
-article[data-columns='4']{
-  width: 600px;
-}
- -

Увидеть как это работает можно в примере на JSBin.

- -

Data-аттрибуты также могут использоваться для хранения информации, которая постоянно изменяется, например, счёт в игре. Используя CSS селекторы и возможности JavaScript можно создавать некоторые изящные эффекты, без необходимости писать свои функции отображения. Посмотрите скринкаст чтобы увидеть больше примеров использующих сгенерированный контент и переходы на CSS. Пример кода из скринкаста можно также посмотреть на JSBin.

- -

Проблемы

- -

Не храните данные, которые должны быть видимы и доступны в data-атрибутах. Дело в том, что вспомогательная техника (assistive technology) может не получить к ним доступ. В дополнение, поисковые роботы не индексируют данные, содержащиеся в data-атрибутах.

- -

Печально, что всё простое и полезное в этой жизни не достаётся бесплатно. Internet Explorer 11+ поддерживает этот стандарт, но все более ранние версии не поддерживают dataset. Для поддержки IE 10 и более ранних версий получение доступа к data-атрибутам необходимо осуществлять через {{domxref("Element.getAttribute", "getAttribute()")}}. Также, производительность чтения data-атрибутов по сравнению с хранением этих данных в хранилище данных JS значительно хуже. Использование dataset ещё медленнее, чем чтение данных с getAttribute().

- -

Тем не менее, для пользовательских метаданных, связанных с элементами, data-атрибуты являются отличным решением.

- -

Поддержка в браузерах

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
caniuse
-

IE

-
-

Edge

-
-

Firefox

-
-

Chrome

-
-

Safari

-
-

Opera

-
-

iOS Safari

-
-

Opera Mini*

-
-

Android Browser

-
-

Chrome for Android

-
11+14+52+49+10.1+46+9.3+all4.4+59+
- -

 

- -

Тем не менее, для содержимого, которое не надо показывать это является отличным решением.

- -

См. также

- - diff --git a/files/ru/web/guide/html/using_html_sections_and_outlines/index.html b/files/ru/web/guide/html/using_html_sections_and_outlines/index.html new file mode 100644 index 0000000000..a6236d9c24 --- /dev/null +++ b/files/ru/web/guide/html/using_html_sections_and_outlines/index.html @@ -0,0 +1,375 @@ +--- +title: Использование разделов и создание структуры HTML документа +slug: Web/Guide/HTML/Sections_and_Outlines_of_an_HTML5_document +tags: + - HTML5 + - Веб + - Для опытных разработчиков + - Обзор + - Пример + - Разделы + - Руководство + - Структура +translation_of: Web/Guide/HTML/Using_HTML_sections_and_outlines +--- +
+

Важно: В настоящее время нет известных реализаций алгоритма построения структуры документа в графических браузерах или пользовательских приложениях, использующих реабилитационные технологии, хотя такой алгоритм внедрен в другие приложения, например, в средствах проверки соответствия спецификации. Поэтому алгоритм построения структуры нельзя использовать для передачи структуры документа пользователям. Авторы рекомендуют использовать для этой цели степень важности заголовков (h1-h6).

+
+ +

Спецификация HTML5 предлагает разработчикам несколько новых элементов, позволяющих описывать структуру веб-документа с помощью стандартной семантики. В настоящей статье описываются эти элементы и способы их использования для создания требуемой структуры любого документа.

+ +

Структура документа в HTML 4

+ +

Структура документа, т. е. семантическая структура контента, заключенного в теги  <body> и </body>, является основой для представления страницы пользователю. HTML4 использует для описания структуры страницы разделы и подразделы. Раздел определяется элементом ({{HTMLElement("div")}}) с включенными в него элементами заголовка ({{HTMLElement("h1")}}, {{HTMLElement("h2")}}, {{HTMLElement("h3")}}, {{HTMLElement("h4")}}, {{HTMLElement("h5")}} или {{HTMLElement("h6")}}), содержащими его название. Структура документа определяется отношениями между этими элементами.

+ +

Так, следующая разметка:

+ +
+
<div class="section" id="forest-elephants" >
+  <h1>Лесные слоны</h1>
+  <p>В данном разделе мы поговорим о малоизвестных лесных слонах.
+    ...продолжение данного раздела...
+  <div class="subsection" id="forest-habitat" >
+    <h2>Среда обитания</h2>
+    <p>Лесные слоны живут не на деревьях, а под ними.
+     ...продолжение данного подраздела...
+  </div>
+</div>
+
+
+ +

обеспечивает следующую структуру:

+ +
1. Лесные слоны
+   1.1 Среда обитания
+
+ +

Для задания нового раздела не обязательно использовать элементы {{HTMLElement("div")}}. Для этого достаточно наличия элемента заголовка. Поэтому, разметка

+ +
<h1>Лесные слоны</h1>
+ <p>В данном разделе мы поговорим о малоизвестных лесных слонах.
+    ...продолжение данного раздела...
+  <h2>Среда обитания</h2>
+  <p>Лесные слоны живут не на деревьях, а под ними.
+    ...продолжение данного подраздела...
+  <h2>Рацион</h2>
+<h1>Монгольская песчанка</h1>
+
+ +

обеспечивает следующую структуру:

+ +
1. Лесные слоны
+   1.1 Среда обитания
+   1.2 Рацион
+2. Монгольская песчанка
+
+ +

Какие проблемы решает HTML5

+ +

Определение структуры документа и неявный алгоритм создания структуры в HTML 4 не отличаются четкостью, что порождает множество проблем:

+ +
    +
  1. Использование {{HTMLElement("div")}} для задания семантических разделов, без задания специальных значений для атрибутов class не позволяет автоматизировать алгоритм создания структуры («Является ли данный {{HTMLElement("div")}} частью структуры страницы, определяющим раздел или подраздел, или он используется исключительно для управления стилем?»). Другими словами, спецификация HTML4 не дает точного определения разделу и четких правил его определения. Автоматическое создание структуры имеет большое значение, особенно в случае с реабилитационными технологиями, представляющими информацию пользователю в соответствии со структурой документа. HTML5 позволяет больше не использовать элементы {{HTMLElement("div")}} в алгоритме построения структуры благодаря добавлению нового элемента {{HTMLElement("section")}}.
  2. +
  3. Объединить несколько документов в один непросто: включение подчиненного документа в основной документ требует изменения уровня элементов заголовков для сохранения правильной структуры. В HTML5 эта проблема решена благодаря новым элементам задания разделов ({{HTMLElement("article")}}, {{HTMLElement("section")}}, {{HTMLElement("nav")}} и {{HTMLElement("aside")}}), которые всегда являются подразделами ближайшего родительского раздела, независимо от того, какие разделы создаются внутренними заголовками.
  4. +
  5. В HTML4 каждый раздел является частью структуры документа. Однако часто документы отличаются сложной, нелинейной структурой. Документ может включать специальные разделы, информация в которых не является частью основного контента, хотя и связана с ним, например, рекламный блок или поясняющая заметка. HTML5 добавляет элемент {{HTMLElement("aside")}}, позволяющий исключить такие разделы из основной структуры.
  6. +
  7. Опять же, поскольку в HTML4 каждый раздел является частью структуры документа, как быть с разделами, содержащими информацию, касающуюся не конкретного документа, а всего сайта, например, логотипы, оглавления или информация об авторских правах и правовые положения. В HTML5 для этих целей добавлено три новых элемента: {{HTMLElement("nav")}} для наборов ссылок, например, оглавления, {{HTMLElement("footer")}} и {{HTMLElement("header")}} для информации, касающейся всего сайта. Обратите внимание, что {{HTMLElement("header")}} и {{HTMLElement("footer")}} не создают разделы как {{HTMLElement("section")}}, а, скорее, обеспечивают семантическую разметку частей раздела.
  8. +
+ +

В общем, HTML5 обеспечивает большую точность при задании разделов и оглавлений, позволяя строить более предсказуемую структуру документа, что дает браузерам возможность более качественно обслуживать пользователей.

+ +

Алгоритм создания структуры HTML5

+ +

Задание разделов в HTML5

+ +

Весь контент, находящийся внутри {{HTMLElement("body")}}, является частью раздела. Разделы в HTML5 могут быть вложенными. Помимо основного раздела, определяемого элементом {{HTMLElement("body")}}, границы разделов определяются явным или неявным образом. Явным образом заданные разделы – это контент внутри тегов {{HTMLElement("body")}},  {{HTMLElement("section")}},  {{HTMLElement("article")}},  {{HTMLElement("aside")}} и {{HTMLElement("nav")}}. 

+ +
Note: Каждый раздел может иметь собственную иерархию заголовков. Следовательно, даже вложенный раздел может иметь {{HTMLElement("h1")}}. См. «Задание заголовков в HTML5».
+ +

Например:

+ +
<section>
+  <h1>Лесные слоны</h1>
+  <section>
+    <h1>Введение</h1>
+    <p>В данном разделе мы поговорим о малоизвестных лесных слонах.</p>
+  </section>
+  <section>
+    <h1>Среда обитания</h1>
+    <p>Лесные слоны живут не на деревьях, а под ними.</p>
+  </section>
+  <aside>
+    <p>рекламный блок</p>
+  </aside>
+</section>
+<footer>
+  <p>(c) 2010 The Example company</p>
+</footer>
+ +

Данный фрагмент HTML задает раздел верхнего уровня:

+ +
<section>
+  <h1>Лесные слоны</h1>
+  <section>
+    <h1>Введение</h1>
+    <p>В данном разделе мы поговорим о малоизвестных лесных слонах.</p>
+  </section>
+  <section>
+    <h1>Среда обитания</h1>
+    <p>Лесные слоны живут не на деревьях, а под ними.</p>
+  </section>
+  <aside>
+    <p>рекламный блок</p>
+  </aside>
+</section>
+<footer>
+  <p>(c) 2010 The Example company</p>
+</footer>
+ +

Данный раздел имеет три подраздела:

+ +
<section>
+  <h1>Лесные слоны</h1>
+
+  <section>
+    <h1>Введение</h1>
+    <p>В данном разделе мы поговорим о малоизвестных лесных слонах.</p>
+  </section>
+
+  <section>
+    <h1>Среда обитания</h1>
+    <p>Лесные слоны живут не на деревьях, а под ними.</p>
+  </section>
+
+  <aside>
+    <p>рекламный блок</p>
+  </aside>
+</section>
+
+<footer>
+  <p>(c) 2010 The Example company</p>
+</footer>
+ +

В результате получаем следующую структуру:

+ +
1. Лесные слоны
+   1.1 Введение
+   1.2 Среда обитания
+
+ +

Задание заголовков в HTML5

+ +

Хотя структура определяется элементами задания структуры, она будет практически бесполезна без заголовка. Основное правило очень простой: первый элемент заголовка (это может быть {{HTMLElement("h1")}}, {{HTMLElement("h2")}}, {{HTMLElement("h3")}}, {{HTMLElement("h4")}}, {{HTMLElement("h5")}}, {{HTMLElement("h6")}}) задает заголовок текущего раздела.

+ +

Элемент заголовка имеет определенную степень важности, определяемую цифрой в его названии, таким образом, {{HTMLElement("h1")}} имеет максимальную степень важности, а {{HTMLElement("h6")}} минимальную. Соотношение степеней важности имеет смысл только внутри раздела; структура документа определяется структурами разделов, а не степенью важности заголовков разделов. Например, данный код:

+ +
<section>
+  <h1>Лесные слоны</h1>
+  <p>В данном разделе мы поговорим о малоизвестных лесных слонах.
+    ...продолжение данного раздела...
+  <section>
+    <h2>Среда обитания</h2>
+    <p>Лесные слоны живут не на деревьях, а под ними.
+        ...продолжение данного подраздела...
+  </section>
+</section>
+<section>
+  <h3>Монгольская песчанка</h3>
+  <p>В данном разделе мы расскажем о монгольской песчанке.
+     ...продолжение данного раздела...
+</section>
+ +

приводит к следующей структуре:

+ +
1. Лесные слоны
+   1.1 Среда обитания
+2. Монгольская песчанка
+ +

Обратите внимание, что степень важности элемента заголовка (в данном примере {{HTMLElement("h1")}} для первого раздела верхнего уровня, {{HTMLElement("h2")}} для подраздела {{HTMLElement("h3")}} для второго раздела верхнего уровня) роли не играет. (В качестве заголовка явно заданного раздела может использоваться заголовок с любой степенью важности, хотя такая практика и не рекомендуется.)

+ +

Неявное задание разделов

+ +

Поскольку элементы задания разделов HTML5 Sectioning Elements не являются обязательными для задания структуры, можно задавать разделы и не используя их, чтобы обеспечить совместимость с веб-сайтами, созданными на HTML4. Это называется неявным заданием разделов.

+ +

Элементы заголовков ({{HTMLElement("h1")}} — {{HTMLElement("h6")}}) задают новый, неявный раздел, когда не являются первым заголовком своего родительского, явно заданного раздела. То, как этот неявно заданный раздел располагается в структуре документа, определяется отношением важности его заголовка в важности предыдущего заголовка в родительском разделе. Если его степень важности ниже, чем у предыдущего заголовка, он открывает неявно заданный подраздел раздела. Следующий код:

+ +
<section>
+  <h1>Лесные слоны</h1>
+  <p>В данном разделе мы поговорим о малоизвестных лесных слонах.
+    ...продолжение данного раздела...
+  <h3 class="implicit subsection">Среда обитания</h3>
+  <p>Лесные слоны живут не на деревьях, а под ними.
+    ...продолжение данного подраздела...
+</section>
+ +

приводит к следующей структуре:

+ +
1. Лесные слоны
+   1.1 Среда обитания (неявно задано элементом h3)
+
+ +

Если степень важности такого заголовка совпадает со степенью важности предыдущего заголовка, он закрывает предыдущий раздел (который мог быть задан неявно!) и открывает новый неявно заданный раздел на том же уровне: 

+ +
<section>
+  <h1>Лесные слоны</h1>
+  <p>В данном разделе мы поговорим о малоизвестных лесных слонах.
+    ...продолжение данного раздела...
+  <h1 class="implicit section">Монгольская песчанка</h1>
+  <p>Монгольская песчанка – это небольшое симпатичное млекопитающее.
+    ...продолжение данного раздела...
+</section>
+ +

приводит к следующей структуре:

+ +
1. Лесные слоны
+2. Монгольская песчанка (неявно задано элементом h1, который одновременно закрывает предыдущий раздел)
+
+ +

Если степень важности такого заголовка выше, чем у предыдущего заголовка, он закрывает предыдущий раздел и открывает новый неявно заданный раздел на более высоком уровне:

+ +
<body>
+  <h1>Млекопитающие</h1>
+  <h2>Киты</h2>
+  <p>В данном разделе мы поговорим о китах.
+    ...продолжение данного раздела...
+  <section>
+    <h3>Лесные слоны</h3>
+    <p>В данном разделе мы поговорим о малоизвестных лесных слонах.
+    ...продолжение данного раздела...
+    <h3>Монгольская песчанка</h3>
+      <p>Песчанки распространились далеко за пределы Монголии.
+         ...продолжение данного подраздела...
+    <h2>Рептилии</h2>
+      <p>Рептилии – это холоднокровные животные.
+          ...продолжение данного раздела...
+  </section>
+</body>
+ +

приводит к следующей структуре:

+ +
1. Млекопитающие
+   1.1 Киты (неявно задается элементом h2)
+   1.2 Лесные слоны (явным образом задается элементом раздела)
+   1.3 Монгольская песчанка (неявно задается элементом h3, который одновременно закрывает предыдущий раздел)
+2. Рептилии (неявно задается элементом h2, который одновременно закрывает предыдущий раздел)
+
+ +

Эта не та структура, которую можно было бы ожидать, бегло просмотрев теги заголовков. Чтобы разметка стала понятна человеку, а также чтобы степень важности заголовка соответствовала уровню вложенности раздела, рекомендуется использовать наглядные теги для открытия и закрытия разделов. Однако спецификация HTML5 этого не требует. Поэтому, если браузеры отображают структуру документа не так, как ожидалось, проверьте, нет ли в документе разделов, не явно закрытых элементами заголовков.

+ +

Исключение из общего правила соответствия степени важности тега уровню вложенности раздела делается для разделов, которые могут использоваться в нескольких документах. Например, раздел может храниться в системе управления контентом и добавляться в документы при их генерировании. В этом случае рекомендуется начинать с {{HTMLElement("h1")}} в качестве главного заголовка многократно используемого раздела. Уровень вложенности многократно используемого раздела будет определяться иерархией разделов документа, в который он добавляется. Теги для явного задания разделов по-прежнему останутся полезными и в этом конкретном случае.

+ +

Корни задания разделов

+ +

 Корень задания разделов – это элемент HTML, который может иметь собственную структуру, однако входящие в нее разделы и заголовки, не входят в структуру его родительского элемента. Помимо {{HTMLElement("body")}}, который является логическим корнем задания разделов документа, такими элементами часто являются элементы, добавляющие внешний контент на страницу: {{HTMLElement("blockquote")}}, {{HTMLElement("details")}}, {{HTMLElement("fieldset")}}, {{HTMLElement("figure")}} и {{HTMLElement("td")}}.

+ +

Например:

+ +
<section>
+  <h1>Лесные слоны</h1>
+  <section>
+    <h2>Введение</h2>
+    <p>В данном разделе мы поговорим о малоизвестных лесных слонах</p>
+  </section>
+  <section>
+    <h2>Среда обитания</h2>
+    <p>Лесные слоны живут не на деревьях, а под ними. Давайте рассмотрим, что говорят ученые в «<cite>Лесной слон на Борнео</cite>»:</p>
+    <blockquote>
+       <h1>Борнео</h1>
+       <p>Лесной слон живет на Борнео...</p>
+    </blockquote>
+  </section>
+</section>
+
+ +

Данный пример приводит к следующей структуре:

+ +
1. Лесные слоны
+   1.1 Введение
+   1.2 Среда обитания
+ +

Данная структура не включает внутреннюю структуру элемента {{HTMLElement("blockquote")}}, который, будучи внешней цитатой, является корнем задания разделов и изолирует свою внутреннюю структуру.

+ +

Разделы, не входящие в структуру

+ +

 HTML5 вводит два новых элемента, позволяющих задавать разделы, не входящие в основную структуру веб-документа:

+ +
    +
  1. Элемент вспомогательного раздела {{HTMLElement("aside")}} задает раздел, который, хотя и связан с основным элементом, не принадлежит к основной структуре, например, поясняющая заметка или реклама. Он имеет собственную структуру, однако не входит в основную структуру страницы.
  2. +
  3. Элемент навигационного раздела {{HTMLElement("nav")}} задает раздел, содержащий навигационные ссылки. Таких элементов в документе может быть несколько, например, один со внутренними ссылками на страницу, например, оглавление, а другой – с ссылками для навигации по сайту. Такие ссылки не являются частью основной структуры документа и как правило пропускаются экранными дикторами.
  4. +
+ +

Шапки и подвалы

+ +

HTML5 также добавляет два новых элемента, которые могут использоваться для разметки верхнего и нижнего колонтитулов страниц:

+ +
    +
  1. Элемент шапки {{HTMLElement("header")}} задает шапку страницы (как правило, логотип и название сайта, а также горизонтальное меню, если имеется) или раздела (которая может включать заголовок раздела, имя автора и т.д.).{{HTMLElement("article")}}, {{HTMLElement("section")}}, {{HTMLElement("aside")}}, и {{HTMLElement("nav")}} могут иметь собственный {{HTMLElement("header")}}. Несмотря на название, этот элемент не обязательно располагается в начале страницы или раздела.
  2. +
  3. Элемент подвала ({{HTMLElement("footer")}}) задает нижний колонтитул страницы (как правило включающий уведомления об авторских правах и другую правовую информацию, а иногда также содержащий какие-либо ссылки) или раздела (может включать дату публикации, информацию о лицензии и т.п. {{HTMLElement("article")}}, {{HTMLElement("section")}}, {{HTMLElement("aside")}} и {{HTMLElement("nav")}} могут иметь собственный {{HTMLElement("footer")}}. Несмотря на название, этот элемент не обязательно располагается в конце страницы или раздела.
  4. +
+ +

Эти элементы не создают новые разделы в структуре, а скорее используются для разметки контента внутри разделов страницы.

+ +

Адреса в элементах задания разделов

+ +

Автор документа часто хочет опубликовать свою контактную информацию, например, имя и адрес. HTML4 позволял сделать это с помощью элемента {{HTMLElement("address")}}, расширенного в HTML5.

+ +

Документ может включать несколько разделов, принадлежащих разным авторам. Если раздел создается не автором основной страницы, для задания используется элемент {{HTMLElement("article")}}. В результате элемент {{HTMLElement("address")}} теперь связан с ближайшим родительским {{HTMLElement("body")}} или {{HTMLElement("article")}}.

+ +

Использование элементов HTML5 в браузерах, не поддерживающих HTML5

+ +

Элементы разделов и заголовков должны работать в большинстве браузеров, не поддерживающих HTML5. Хотя они и не поддерживаются, они не требуют специального интерфейса DOM, им требуется лишь особый стиль CSS, поскольку к неизвестным элементам по умолчанию применяется стиль display:inline:

+ +
section, article, aside, footer, header, nav, hgroup {
+  display:block;
+}
+
+ +

Конечно, веб-разработчик может применить к ним любой другой стиль, однако следует помнить в браузерах, не поддерживающих HTML5, по умолчанию используется не тот стиль, который требуется для таких элементов. Также обратите внимание на отсутствие в перечне элемента {{HTMLElement("time")}}, поскольку по умолчанию к нему применяется одинаковый стиль как в браузерах, не поддерживающих HTML5, так и в браузерах, совместимых с HTML5.

+ +

Данный способ не универсален, поскольку некоторые браузеры не позволяют применять стили к неподдерживаемым элементам. Например, Internet Explorer (версии 8 и более ранней), для которого требуется специальный скрипт:

+ +
<!--[if lt IE 9]>
+  <script>
+    document.createElement("header" );
+    document.createElement("footer" );
+    document.createElement("section");
+    document.createElement("aside"  );
+    document.createElement("nav"    );
+    document.createElement("article");
+    document.createElement("hgroup" );
+    document.createElement("time"   );
+  </script>
+<![endif]-->
+ +

Этот скрипт запускается в Internet Explorer (8 и более ранней версии), однако требует включенной поддержки скриптов для правильного отображения элементов задания разделов и заголовок HTML5. Если поддержа скриптов выключена, это может стать проблемой, поскольку данные элементы, скорее всего, определяют структуру всей страницы. Поэтому необходимо добавить элемент {{HTMLElement("noscript")}}:

+ +
<noscript>
+   <strong>Внимание!</strong>
+   Поскольку ваш браузер не поддерживает HTML5, некоторые элементы воспроизводятся с помощью JScript.
+   Однако в вашем браузере скрипты отключены, пожалуйста, включите их, чтобы браузер смог отобразить данную страницу.
+</noscript>
+ +

This leads to the following code to allow the support of the HTML5 sections and headings elements in non-HTML5 browsers, even for Internet Explorer (8 and older), with a proper fallback for the case where this latter browser is configured not to use scripting:

+ +
<!--[if lt IE 9]>
+  <script>
+    document.createElement("header" );
+    document.createElement("footer" );
+    document.createElement("section");
+    document.createElement("aside"  );
+    document.createElement("nav"    );
+    document.createElement("article");
+    document.createElement("hgroup" );
+    document.createElement("time"   );
+  </script>
+  <noscript>
+     <strong>Внимание!</strong>
+     Поскольку ваш браузер не поддерживает HTML5, некоторые элементы воспроизводятся с помощью JScript.
+     Однако в вашем браузере скрипты отключены, пожалуйста, включите их, чтобы браузер смог отобразить данную страницу.
+  </noscript>
+<![endif]-->
+ +

Заключение

+ +

Новые семантические элементы, добавленные в HTML5, обеспечивают стандартизацию описания структуры веб-документа. Они облегчают жизнь пользователям с ограниченными возможностями, просты в использовании, могут без особых проблем поддерживаться в старых браузерах и поэтому настоятельно рекомендуются к применению.

+ +
{{HTML5ArticleTOC()}}
diff --git "a/files/ru/web/guide/html/\321\204\320\276\321\200\320\274\321\213_\320\262_html/index.html" "b/files/ru/web/guide/html/\321\204\320\276\321\200\320\274\321\213_\320\262_html/index.html" deleted file mode 100644 index ad5a8bc7e6..0000000000 --- "a/files/ru/web/guide/html/\321\204\320\276\321\200\320\274\321\213_\320\262_html/index.html" +++ /dev/null @@ -1,149 +0,0 @@ ---- -title: Формы в HTML -slug: Web/Guide/HTML/Формы_в_HTML -tags: - - HTML - - HTML5 - - Введение - - Интернет - - Любитель - - Новичок - - Обзор - - Руководство - - Формы -translation_of: Learn/HTML/Forms/HTML5_updates ---- -

Элементы и атрибуты форм в HTML5 предоставляют большие возможности семантической верстки, чем HTML4, а также позволяет отказаться от использования JavaScript и CSS, которое было ранее необходимо для HTML4. Большие возможности в формах HTML5 делают удобным для пользователей отправление информации с различных веб-сайтов. Они также предоставляют эти возможности для тех пользователей, у которых отключена поддержка JavaScript.

- -

Эта статья описывает изменения в HTML-формах, представленных в HTML5. Для более подробного руководства по использованию формами, просмотрите наше обширное руководство по HTML-формам.

- -

Элемент <input>

- -

В элементе {{HTMLElement("input")}} появились новые значения для атрибута {{htmlattrxref("type", "input")}}. (Просмотрите справочник {{HTMLElement("input")}} для получения полного списка атрибутов, значений и их использования для этого элемента.)

- -
    -
  • search: Элемент представляет из себя поле для поиска. Переходы строк автоматически удаляются из значения value.
  • -
  • tel: Элемент представляет из себя поле для редактирования номера телефона. Переходы строк автоматически удаляются из значения value. Вы можете использовать атрибуты, такие как: {{htmlattrxref("pattern", "input")}} и {{htmlattrxref("maxlength", "input")}}, чтобы запретить ввод неподходящих символов.
  • -
  • url: Элемент представляет из себя поле для редактирования URL. Переходы строк и пробелы автоматически удаляются из значения value.
  • -
  • -

    email: Элемент представляет из себя поле для ввода одного адреса электронной почты. Переходы строк автоматически удаляются из значения value. Может быть предоставлен недействительный адрес эл. почты, но поле ввода запретит отправку формы, если эл. адрес почты не будет соответствовать нормам ABNF.

    - -
    Заметьте: Если установлен атрибут {{htmlattrxref("multiple", "input")}}, то может быть введено несколько адресов электронной почты, разделенных запятой, но, в данный момент, такая возможность не реализована в Firefox.
    -
  • -
- -

Также, элемент {{HTMLElement("input")}} получил новые атрибуты:

- -
    -
  • {{htmlattrxref("list", "input")}}: ID элемента {{HTMLElement("datalist")}}, в котором элементы {{HTMLElement("option")}} используются как подсказки для текстового поля.
  • -
  • {{htmlattrxref("pattern", "input")}}: Регулярное выражение, по которому поверяются вводимые данные. Может использоваться в элементе {{htmlattrxref("type", "input")}} со значениями text, tel, search, url, и email.
  • -
  • {{htmlattrxref("form", "input")}}: Строка, указывающая, к какому элементу {{HTMLElement("form")}} принадлежит элемент. Элемент может быть частью только одной формы.
  • -
  • {{htmlattrxref("formmethod", "input")}}: Строка, указывающая метод передачи данных  (GET or POST), когда форма отправляется на сервер. Он перекрывает значение атрибута {{htmlattrxref("method", "form")}} элемента {{HTMLElement("form")}}, если установлен. Работает только, если {{htmlattrxref("type", "input")}} является image или submit, и если установлен атрибут {{htmlattrxref("form", "input")}}.
  • -
  • {{htmlattrxref("x-moz-errormessage", "input")}} {{non-standard_inline}}: Строка, указывающая на сообщение об ошибке, которое будет показано, если это поле не пройдет валидацию. Этот атрибут - расширение Mozilla и не является стандартом.
  • -
- -

Текстовое поле

- -

<input> с атрибутом type="text" определяет однострочное поле для ввода.

- -
<form>
-  Введите свое имя: <input type="text" name="name">
-</form>
- -

Флажок

- -

<input> с атрибутом type="checkbox" определяет флажок.

- -
<input type="checkbox" name="chk" value="" checked> Подписаться на рассылку
- -

Переключатель

- -

<input> с атрибутом type="radio" определяет радио кнопку.

- -
<form>
-  <input type="radio" name="animal" value="monkey">Обезьяна<br>
-  <input type="radio" name="animal" value="cat">Кот<br>
-  <input type="radio" name="animal" value="other">Другое
-</form>
- -

Элемент <form>

- -

Элемент {{HTMLElement("form")}} получил новый атрибут:

- -
    -
  • {{htmlattrxref("novalidate", "form")}}: Этот атрибут предотвращает валидацию формы перед отправкой.
  • -
- -

Элемент <datalist>

- -

Элемент {{HTMLElement("datalist")}} представляет собой список элементов {{HTMLElement("option")}}, который необходимо предложить при вводе поля {{HTMLElement("input")}}.

- -

Вы можете использовать атрибут {{htmlattrxref("list", "input")}} в элементе {{HTMLElement("input")}}, чтобы связать текстовое поле с элементом {{HTMLElement("datalist")}}.

- -

Элемент <output>

- -

Элемент {{HTMLElement("output")}} представляет собой результат каких-либо вычислений.

- -

Вы можете использовать атрибут {{htmlattrxref("for", "output")}} для указания связи между элементом {{HTMLElement("output")}} и другими элементами в документе, которые повлияли на расчет (к примеру, поля для ввода параметров). Значением атрибута {{htmlattrxref("for", "output")}} является список ID других элементов, разделенный пробелами.

- -

{{non-standard_inline}} Gecko 2.0 (but not necessarily other browser engines) supports defining custom validity constraints and error messages for {{HTMLElement("output")}} elements, and therefore applies the {{Cssxref(":invalid")}}, {{Cssxref(":valid")}}, {{Cssxref(":-moz-ui-invalid")}}, and {{Cssxref(":-moz-ui-valid")}} CSS pseudo-classes to them. This can be helpful in situations where the calculated result violates a business rule, but no specific input value does (for example, "The total of percentages must not exceed 100").

- -

Атрибут placeholder

- -

Атрибут {{htmlattrxref("placeholder", "input")}} в элементах {{HTMLElement("input")}} и {{HTMLElement("textarea")}} отображает подсказки для пользователей, которые показывают, что можно ввести в эти поля. Текст в placeholder не должен содержать символов перевода строки или возврата каретки.

- -

Атрибут autofocus

- -

Атрибут {{htmlattrxref("autofocus", "input")}} позволяет указать для элемента формы автоматическое получение фокуса после полной загрузки страницы, если пользователь сам не переместит фокус на другой элемент, например, этот атрибут можно указать для различных полей ввода. Только один элемент в документе должен иметь этот атрибут, который содержит Boolean значение. Этот атрибут может быть установлен в {{HTMLElement("input")}}, {{HTMLElement("button")}}, {{HTMLElement("select")}} и {{HTMLElement("textarea")}} элементах.  {{htmlattrxref("autofocus", "input")}} нельзя установить в элементах input c атрибутом type установленным в значение hidden (это означает, что ты не можешь автоматически устанавливать фокус в скрытых полях).

- -

DOM свойство label.control

- -

DOM интерфейс HTMLLabelElement , помимо свойств, относящихся к HTML элементу {{HTMLElement("label")}} , предоставляет дополнительное свойство  control, возвращающее поле ввода, для которого предназначен {{HTMLElement("label")}}. Оно либо указывается в атрибуте {{htmlattrxref("for", "label")}} , либо является первым вложенным полем ввода.

- -

Constraint Validation

- -

HTML5 provides syntax and API items to support client-side validation of forms. While this functionality does not replace server-side validation, which is still necessary for security and data integrity, client-side validation can support a better user experience by giving the user immediate feedback about the input data.

- -

If the title attribute is set on the {{HTMLElement("input")}} element, its value is used as tooltip. However, if the validation fails, this tooltip text will be replaced with the associated error message. It is possible to customize this error message using the non-standard {{htmlattrxref("x-moz-errormessage")}} attribute or when calling the setCustomValidity() method.

- -
<input type="email" title="Please, provide an e-mail" x-moz-errormessage="This is not a valid e-mail">
- -
Note: Constraint validation is not supported on {{HTMLElement("button")}} elements in a form; to style a button based on the validity of the associated form, use the {{cssxref(":-moz-submit-invalid")}} pseudo-class.
- -

HTML Syntax for Constraint Validation

- -

The following items in HTML5 syntax can be used to specify constraints on form data.

- -
    -
  • The {{htmlattrxref("required", "input")}} attribute on the {{HTMLElement("input")}}, {{HTMLElement("select")}}, and {{HTMLElement("textarea")}} elements indicates that a value must be supplied. (On the {{HTMLElement("input")}} element, {{htmlattrxref("required", "input")}} applies only in conjunction with certain values of the {{htmlattrxref("type", "input")}} attribute.)
  • -
  • The {{htmlattrxref("pattern", "input")}} attribute on the {{HTMLElement("input")}} element constrains the value to match a specific regular expression.
  • -
  • The {{htmlattrxref("min", "input")}} and {{htmlattrxref("max", "input")}} attributes of the {{HTMLElement("input")}} element constrain the minimum and maximum values that can be entered.
  • -
  • The {{htmlattrxref("step", "input")}} attribute of the {{HTMLElement("input")}} element (when used in combination with the {{htmlattrxref("min", "input")}} and {{htmlattrxref("max", "input")}} attributes) constrains the granularity of values that can be entered. A value that does not correspond an allowed value step does not validate.
  • -
  • The {{htmlattrxref("maxlength", "input")}} attribute of the {{HTMLElement("input")}} and {{HTMLElement("textarea")}} elements constrains the maximum number of characters (in Unicode code points) that the user can enter.
  • -
  • The values url and email for the {{htmlattrxref("type", "input")}} constrain the value to being a valid URL or e-mail address, respectively.
  • -
- -

In addition, you can prevent constraint validation by specifying the {{htmlattrxref("novalidate", "form")}} attribute on the {{HTMLElement("form")}}, or the {{htmlattrxref("formnovalidate", "button")}} attribute on the {{HTMLElement("button")}} element and on the {{HTMLElement("input")}} element (when {{htmlattrxref("type", "input")}} is submit or image). These attributes indicate that the form is not to be validated when it is submitted.

- -

Constraint Validation API

- -

The following DOM properties and methods related to constraint validation are available to client-side scripts:

- -
    -
  • On HTMLFormElement objects, the checkValidity() method, which returns true if all of this form element's associated elements that are subject to constraint validation satisfy their constraints, and false if any do not.
  • -
  • On form-associated elements: -
      -
    • willValidate property, which is false if the element has constraints that are not satisfied.
    • -
    • validity property, which is a ValidityState object representing the validity states that the element is in (i.e., constraint failure or success conditions).
    • -
    • validationMessage property, which is a message describing any constraint failures that pertain to the element.
    • -
    • checkValidity() method, which returns false if the element fails to satisfy any of its constraints, or true otherwise.
    • -
    • setCustomValidity() method, which sets a custom validation message, allowing for constraints to be imposed and validated beyond those that are predefined.
    • -
    -
  • -
- -

See also

- - diff --git a/files/ru/web/guide/performance/index.html b/files/ru/web/guide/performance/index.html new file mode 100644 index 0000000000..8b1d2760da --- /dev/null +++ b/files/ru/web/guide/performance/index.html @@ -0,0 +1,20 @@ +--- +title: Оптимизация и производительность +slug: Web/Guide/Производительность +tags: + - Оптимизация + - Производительность +translation_of: Web/Guide/Performance +--- +

Создаваемые Вами современные веб-приложения и сайты должны иметь хорошую производительность - работать быстро и эффективно, как на персональных компьютерах (десктоп), так и на менее мощных мобильных устройствах. Существуют различные инструменты для тестирования сайтов на производительность. Самые известные из них:

+ + + +

Производительность в web - первостепенная задача для тех, кто заботится о комфорте конечного пользователя.

+ +

{{LandingPageListSubpages}}

diff --git "a/files/ru/web/guide/\320\263\321\200\320\260\321\204\320\270\320\272\320\260/index.html" "b/files/ru/web/guide/\320\263\321\200\320\260\321\204\320\270\320\272\320\260/index.html" deleted file mode 100644 index 57dd4238e1..0000000000 --- "a/files/ru/web/guide/\320\263\321\200\320\260\321\204\320\270\320\272\320\260/index.html" +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: Графика для Web -slug: Web/Guide/Графика -translation_of: Web/Guide/Graphics ---- -

Современным веб-сайтам и веб-приложениям часто требуется отображать графику. Статические изображения легко отобразить с помощью элемента {{HTMLElement("img")}}, или с помощью CSS свойства  {{cssxref("background-image")}}. Часто требуется создавать графику на лету, или модифицировать ее каким-либо образом после. Как это проделать можно узнать в следующих статьях.

- -
-
-

2D графика

- -
-
Канвас
-
Элемент {{HTMLElement("canvas")}} представляет удобный API для рисования 2D графики с помощью JavaScript.
-
SVG
-
Масштабируемая Векторная Графика (Scalable Vector Graphics) позволяет рисовать линии, кривые, и другие геометрические фигуры. С их помощью можно создавать масштабируемые изображения, которые не теряют в качестве при изменении размера в отличии от растровой графики.
-
- -

View All...

-
- -
-

3D графика

- -
-
WebGL
-
Руководство по быстрому старту с WebGL. WebGL предоставляет API для работы с 3D графиками в веб. Эта технология позволяет Вам использовать стандартный OpenGL ES в веб контексте.
-
- -

Видео

- -
-
Использование HTML5 видео и аудио
-
Встраивание видео и аудио в HTML документ и управление проигрыванием.
-
WebRTC
-
RTC в WebRTC означает Real-Time Communications, технология которая позволяет стримить аудио/видео и данные между клиентами браузера (пирами).
-
-
-
- -

 

diff --git "a/files/ru/web/guide/\320\277\321\200\320\276\320\270\320\267\320\262\320\276\320\264\320\270\321\202\320\265\320\273\321\214\320\275\320\276\321\201\321\202\321\214/index.html" "b/files/ru/web/guide/\320\277\321\200\320\276\320\270\320\267\320\262\320\276\320\264\320\270\321\202\320\265\320\273\321\214\320\275\320\276\321\201\321\202\321\214/index.html" deleted file mode 100644 index 8b1d2760da..0000000000 --- "a/files/ru/web/guide/\320\277\321\200\320\276\320\270\320\267\320\262\320\276\320\264\320\270\321\202\320\265\320\273\321\214\320\275\320\276\321\201\321\202\321\214/index.html" +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: Оптимизация и производительность -slug: Web/Guide/Производительность -tags: - - Оптимизация - - Производительность -translation_of: Web/Guide/Performance ---- -

Создаваемые Вами современные веб-приложения и сайты должны иметь хорошую производительность - работать быстро и эффективно, как на персональных компьютерах (десктоп), так и на менее мощных мобильных устройствах. Существуют различные инструменты для тестирования сайтов на производительность. Самые известные из них:

- - - -

Производительность в web - первостепенная задача для тех, кто заботится о комфорте конечного пользователя.

- -

{{LandingPageListSubpages}}

diff --git a/files/ru/web/html/attributes/crossorigin/index.html b/files/ru/web/html/attributes/crossorigin/index.html new file mode 100644 index 0000000000..686989bb0c --- /dev/null +++ b/files/ru/web/html/attributes/crossorigin/index.html @@ -0,0 +1,130 @@ +--- +title: CORS settings attributes +slug: Web/HTML/CORS_settings_attributes +translation_of: Web/HTML/Attributes/crossorigin +--- +

В HTML5 некоторые теги поддерживают CORS, например {{ HTMLElement("img") }} или {{ HTMLElement("video") }}, имеют атрибут crossorigin (crossOrigin свойство), которое позволяет настроить CORS запросы для данных получаемых элементом. Эти атрибуты могут иметь следующие значения:

+ + + + + + + + + + + + + + + + +
Ключевое словоОписание
anonymousCORS запросы от этого элемента не будут передавать учетные данные.
use-credentialsCORS запросы от этого элемента будут передавать учетные данные.
+ +

По умолчанию (если значение атрибута не задано), CORS не используется вообще. Ключевое слово "anonymous" означает что не будет обмена учетных данных(user credentials) через cookies, client-side SSL сертификаты или HTTP аутентификацию как описано в Секции Терминология CORS спецификации.

+ +

Неправильное ключевое слово или пустая строка, будет обработано как anonymous.

+ +

Пример: crossorigin с тегом script

+ +

Используя тег {{HTMLElement("script")}} вы можете указать браузеру выполнять код https://example.com/example-framework.js без передачи user-credentials.

+ +
<script src="https://example.com/example-framework.js"
+        crossorigin="anonymous"></script>
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('HTML WHATWG', 'infrastructure.html#cors-settings-attributes', 'CORS settings attributes')}}{{Spec2('HTML WHATWG')}} 
{{SpecName('HTML WHATWG', 'embedded-content.html#attr-img-crossorigin', 'crossorigin')}}{{Spec2('HTML WHATWG')}} 
+ +

Поддержка браузерами

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Базовая поддержка13{{ CompatGeckoDesktop("8.0") }}11{{ CompatNo() }}{{ CompatVersionUnknown() }}
{{ HTMLElement("video")}}{{ CompatUnknown() }}{{ CompatGeckoDesktop("12.0") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{ CompatUnknown() }}{{ CompatGeckoMobile("8.0") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatVersionUnknown() }}
{{ HTMLElement("video")}}{{ CompatUnknown() }}{{ CompatGeckoMobile("12.0") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
+
+ +

Смотрите также

+ + diff --git a/files/ru/web/html/cors_settings_attributes/index.html b/files/ru/web/html/cors_settings_attributes/index.html deleted file mode 100644 index 686989bb0c..0000000000 --- a/files/ru/web/html/cors_settings_attributes/index.html +++ /dev/null @@ -1,130 +0,0 @@ ---- -title: CORS settings attributes -slug: Web/HTML/CORS_settings_attributes -translation_of: Web/HTML/Attributes/crossorigin ---- -

В HTML5 некоторые теги поддерживают CORS, например {{ HTMLElement("img") }} или {{ HTMLElement("video") }}, имеют атрибут crossorigin (crossOrigin свойство), которое позволяет настроить CORS запросы для данных получаемых элементом. Эти атрибуты могут иметь следующие значения:

- - - - - - - - - - - - - - - - -
Ключевое словоОписание
anonymousCORS запросы от этого элемента не будут передавать учетные данные.
use-credentialsCORS запросы от этого элемента будут передавать учетные данные.
- -

По умолчанию (если значение атрибута не задано), CORS не используется вообще. Ключевое слово "anonymous" означает что не будет обмена учетных данных(user credentials) через cookies, client-side SSL сертификаты или HTTP аутентификацию как описано в Секции Терминология CORS спецификации.

- -

Неправильное ключевое слово или пустая строка, будет обработано как anonymous.

- -

Пример: crossorigin с тегом script

- -

Используя тег {{HTMLElement("script")}} вы можете указать браузеру выполнять код https://example.com/example-framework.js без передачи user-credentials.

- -
<script src="https://example.com/example-framework.js"
-        crossorigin="anonymous"></script>
- -

Спецификации

- - - - - - - - - - - - - - - - - - - - - -
СпецификацияСтатусКомментарий
{{SpecName('HTML WHATWG', 'infrastructure.html#cors-settings-attributes', 'CORS settings attributes')}}{{Spec2('HTML WHATWG')}} 
{{SpecName('HTML WHATWG', 'embedded-content.html#attr-img-crossorigin', 'crossorigin')}}{{Spec2('HTML WHATWG')}} 
- -

Поддержка браузерами

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Базовая поддержка13{{ CompatGeckoDesktop("8.0") }}11{{ CompatNo() }}{{ CompatVersionUnknown() }}
{{ HTMLElement("video")}}{{ CompatUnknown() }}{{ CompatGeckoDesktop("12.0") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{ CompatUnknown() }}{{ CompatGeckoMobile("8.0") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatVersionUnknown() }}
{{ HTMLElement("video")}}{{ CompatUnknown() }}{{ CompatGeckoMobile("12.0") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
-
- -

Смотрите также

- - diff --git a/files/ru/web/html/element/button/index.html b/files/ru/web/html/element/button/index.html new file mode 100644 index 0000000000..ec13035e29 --- /dev/null +++ b/files/ru/web/html/element/button/index.html @@ -0,0 +1,363 @@ +--- +title: